[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] RFC: Nested VMX patch series 04: virtual VMCS structure and APIs
Virtual VMCS structure and access wrapper APIs Thx, Eddie Signed-off-by: Qing He <qing.he@xxxxxxxxx> Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> diff -r f0647d3c60dc xen/arch/x86/hvm/vmx/vvmx.c --- a/xen/arch/x86/hvm/vmx/vvmx.c Sat May 28 23:20:01 2011 +0800 +++ b/xen/arch/x86/hvm/vmx/vvmx.c Mon May 30 15:07:17 2011 +0800 @@ -183,6 +183,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 f0647d3c60dc xen/include/asm-x86/hvm/vmx/vvmx.h --- a/xen/include/asm-x86/hvm/vmx/vvmx.h Sat May 28 23:20:01 2011 +0800 +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h Mon May 30 15:07:17 2011 +0800 @@ -23,6 +23,9 @@ #ifndef __ASM_X86_HVM_VVMX_H__ #define __ASM_X86_HVM_VVMX_H__ +#include <xen/config.h> +#include <asm/types.h> + struct vmcs_struct; struct nestedvmx { @@ -48,5 +51,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-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |