Nested VMX: Define structure and access APIs for virtual VMCS.

Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Acked-by: Tim Deegan <Tim.Deegan@citrix.com>
Committed-by: Tim Deegan <Tim.Deegan@citrix.com>
This commit is contained in:
Eddie Dong committed 2011-06-09 16:24:09 +08:00
1 parent 09fce80165
commit 45c152f107
2 files changed
+134

No files matched your search

+78
View File
@@ -119,6 +119,84 @@ enum vmx_ops_result {
#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)
{
+56
View File
@@ -96,5 +96,61 @@ uint32_t nvmx_vcpu_asid(struct vcpu *v);
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__ */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.