[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Nested VMX: Define structure and access APIs for virtual VMCS.
# HG changeset patch # User Eddie Dong <eddie.dong@xxxxxxxxx> # Date 1307607849 -28800 # Node ID 27ce39a6238d2a988dcc137213dacce9edfceb36 # Parent 3510900d5d7b8c6b4cd1157d62b64f9287ba1716 Nested VMX: Define structure and access APIs for virtual VMCS. Signed-off-by: Qing He <qing.he@xxxxxxxxx> Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> Acked-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> Committed-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> --- diff -r 3510900d5d7b -r 27ce39a6238d xen/arch/x86/hvm/vmx/vvmx.c --- a/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 09 16:24:09 2011 +0800 +++ b/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 09 16:24:09 2011 +0800 @@ -119,6 +119,84 @@ #define CASE_GET_REG(REG, reg) \ case VMX_REG_ ## REG: value = regs->reg; break +static int vvmcs_offset(u32 width, u32 type, u32 index) +{ + int offset; + + offset = (index & 0x1f) | type << 5 | width << 7; + + if ( offset == 0 ) /* vpid */ + offset = 0x3f; + + return offset; +} + +u64 __get_vvmcs(void *vvmcs, u32 vmcs_encoding) +{ + union vmcs_encoding enc; + u64 *content = (u64 *) vvmcs; + int offset; + u64 res; + + enc.word = vmcs_encoding; + offset = vvmcs_offset(enc.width, enc.type, enc.index); + res = content[offset]; + + switch ( enc.width ) { + case VVMCS_WIDTH_16: + res &= 0xffff; + break; + case VVMCS_WIDTH_64: + if ( enc.access_type ) + res >>= 32; + break; + case VVMCS_WIDTH_32: + res &= 0xffffffff; + break; + case VVMCS_WIDTH_NATURAL: + default: + break; + } + + return res; +} + +void __set_vvmcs(void *vvmcs, u32 vmcs_encoding, u64 val) +{ + union vmcs_encoding enc; + u64 *content = (u64 *) vvmcs; + int offset; + u64 res; + + enc.word = vmcs_encoding; + offset = vvmcs_offset(enc.width, enc.type, enc.index); + res = content[offset]; + + switch ( enc.width ) { + case VVMCS_WIDTH_16: + res = val & 0xffff; + break; + case VVMCS_WIDTH_64: + if ( enc.access_type ) + { + res &= 0xffffffff; + res |= val << 32; + } + else + res = val; + break; + case VVMCS_WIDTH_32: + res = val & 0xffffffff; + break; + case VVMCS_WIDTH_NATURAL: + default: + res = val; + break; + } + + content[offset] = res; +} + static unsigned long reg_read(struct cpu_user_regs *regs, enum vmx_regs_enc index) { diff -r 3510900d5d7b -r 27ce39a6238d xen/include/asm-x86/hvm/vmx/vvmx.h --- a/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 09 16:24:09 2011 +0800 +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 09 16:24:09 2011 +0800 @@ -96,5 +96,61 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs); int nvmx_handle_vmxoff(struct cpu_user_regs *regs); +/* + * Virtual VMCS layout + * + * Since physical VMCS layout is unknown, a custom layout is used + * for virtual VMCS seen by guest. It occupies a 4k page, and the + * field is offset by an 9-bit offset into u64[], The offset is as + * follow, which means every <width, type> pair has a max of 32 + * fields available. + * + * 9 7 5 0 + * -------------------------------- + * offset: | width | type | index | + * -------------------------------- + * + * Also, since the lower range <width=0, type={0,1}> has only one + * field: VPID, it is moved to a higher offset (63), and leaves the + * lower range to non-indexed field like VMCS revision. + * + */ + +#define VVMCS_REVISION 0x40000001u + +struct vvmcs_header { + u32 revision; + u32 abort; +}; + +union vmcs_encoding { + struct { + u32 access_type : 1; + u32 index : 9; + u32 type : 2; + u32 rsv1 : 1; + u32 width : 2; + u32 rsv2 : 17; + }; + u32 word; +}; + +enum vvmcs_encoding_width { + VVMCS_WIDTH_16 = 0, + VVMCS_WIDTH_64, + VVMCS_WIDTH_32, + VVMCS_WIDTH_NATURAL, +}; + +enum vvmcs_encoding_type { + VVMCS_TYPE_CONTROL = 0, + VVMCS_TYPE_RO, + VVMCS_TYPE_GSTATE, + VVMCS_TYPE_HSTATE, +}; + +u64 __get_vvmcs(void *vvmcs, u32 vmcs_encoding); +void __set_vvmcs(void *vvmcs, u32 vmcs_encoding, u64 val); + #endif /* __ASM_X86_HVM_VVMX_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |