|
@@ -3764,6 +3764,25 @@ static void free_kvm_area(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+enum vmcs_field_type {
|
|
|
+ VMCS_FIELD_TYPE_U16 = 0,
|
|
|
+ VMCS_FIELD_TYPE_U64 = 1,
|
|
|
+ VMCS_FIELD_TYPE_U32 = 2,
|
|
|
+ VMCS_FIELD_TYPE_NATURAL_WIDTH = 3
|
|
|
+};
|
|
|
+
|
|
|
+static inline int vmcs_field_type(unsigned long field)
|
|
|
+{
|
|
|
+ if (0x1 & field) /* the *_HIGH fields are all 32 bit */
|
|
|
+ return VMCS_FIELD_TYPE_U32;
|
|
|
+ return (field >> 13) & 0x3 ;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int vmcs_field_readonly(unsigned long field)
|
|
|
+{
|
|
|
+ return (((field >> 10) & 0x3) == 1);
|
|
|
+}
|
|
|
+
|
|
|
static void init_vmcs_shadow_fields(void)
|
|
|
{
|
|
|
int i, j;
|
|
@@ -3789,14 +3808,22 @@ static void init_vmcs_shadow_fields(void)
|
|
|
|
|
|
/* shadowed fields guest access without vmexit */
|
|
|
for (i = 0; i < max_shadow_read_write_fields; i++) {
|
|
|
- clear_bit(shadow_read_write_fields[i],
|
|
|
- vmx_vmwrite_bitmap);
|
|
|
- clear_bit(shadow_read_write_fields[i],
|
|
|
- vmx_vmread_bitmap);
|
|
|
+ unsigned long field = shadow_read_write_fields[i];
|
|
|
+
|
|
|
+ clear_bit(field, vmx_vmwrite_bitmap);
|
|
|
+ clear_bit(field, vmx_vmread_bitmap);
|
|
|
+ if (vmcs_field_type(field) == VMCS_FIELD_TYPE_U64) {
|
|
|
+ clear_bit(field + 1, vmx_vmwrite_bitmap);
|
|
|
+ clear_bit(field + 1, vmx_vmread_bitmap);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (i = 0; i < max_shadow_read_only_fields; i++) {
|
|
|
+ unsigned long field = shadow_read_only_fields[i];
|
|
|
+
|
|
|
+ clear_bit(field, vmx_vmread_bitmap);
|
|
|
+ if (vmcs_field_type(field) == VMCS_FIELD_TYPE_U64)
|
|
|
+ clear_bit(field + 1, vmx_vmread_bitmap);
|
|
|
}
|
|
|
- for (i = 0; i < max_shadow_read_only_fields; i++)
|
|
|
- clear_bit(shadow_read_only_fields[i],
|
|
|
- vmx_vmread_bitmap);
|
|
|
}
|
|
|
|
|
|
static __init int alloc_kvm_area(void)
|
|
@@ -7219,25 +7246,6 @@ static int handle_vmresume(struct kvm_vcpu *vcpu)
|
|
|
return nested_vmx_run(vcpu, false);
|
|
|
}
|
|
|
|
|
|
-enum vmcs_field_type {
|
|
|
- VMCS_FIELD_TYPE_U16 = 0,
|
|
|
- VMCS_FIELD_TYPE_U64 = 1,
|
|
|
- VMCS_FIELD_TYPE_U32 = 2,
|
|
|
- VMCS_FIELD_TYPE_NATURAL_WIDTH = 3
|
|
|
-};
|
|
|
-
|
|
|
-static inline int vmcs_field_type(unsigned long field)
|
|
|
-{
|
|
|
- if (0x1 & field) /* the *_HIGH fields are all 32 bit */
|
|
|
- return VMCS_FIELD_TYPE_U32;
|
|
|
- return (field >> 13) & 0x3 ;
|
|
|
-}
|
|
|
-
|
|
|
-static inline int vmcs_field_readonly(unsigned long field)
|
|
|
-{
|
|
|
- return (((field >> 10) & 0x3) == 1);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Read a vmcs12 field. Since these can have varying lengths and we return
|
|
|
* one type, we chose the biggest type (u64) and zero-extend the return value
|