Add a prerequisite to existence of VMCS fields as some of them exist only on processors that support certain CPU features. This is required to fix KVM unit test VMX_VMCS_ENUM.MAX_INDEX. Originally-by: Lei Wang <lei4.wang@xxxxxxxxx> Signed-off-by: Xin Li (Intel) <xin@xxxxxxxxx> Tested-by: Shan Kang <shan.kang@xxxxxxxxx> --- arch/x86/kvm/vmx/nested.c | 19 +++++++++++++++++-- arch/x86/kvm/vmx/nested_vmcs_fields.h | 13 +++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 arch/x86/kvm/vmx/nested_vmcs_fields.h diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 7f3ac558ace5..4529fd635385 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -49,6 +49,21 @@ static unsigned long *vmx_bitmap[VMX_BITMAP_NR]; #define vmx_vmread_bitmap (vmx_bitmap[VMX_VMREAD_BITMAP]) #define vmx_vmwrite_bitmap (vmx_bitmap[VMX_VMWRITE_BITMAP]) +static bool nested_cpu_has_vmcs_field(struct kvm_vcpu *vcpu, u16 vmcs_field_encoding) +{ + switch (vmcs_field_encoding) { +#define HAS_VMCS_FIELD(x, c) \ + case x: \ + return c; +#define HAS_VMCS_FIELD_RANGE(x, y, c) \ + case x...y: \ + return c; +#include "nested_vmcs_fields.h" + default: + return true; + } +} + struct shadow_vmcs_field { u16 encoding; u16 offset; @@ -5565,7 +5580,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) return nested_vmx_failInvalid(vcpu); offset = get_vmcs12_field_offset(field); - if (offset < 0) + if (offset < 0 || !nested_cpu_has_vmcs_field(vcpu, field)) return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field)) @@ -5691,7 +5706,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf)); offset = get_vmcs12_field_offset(field); - if (offset < 0) + if (offset < 0 || !nested_cpu_has_vmcs_field(vcpu, field)) return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); /* diff --git a/arch/x86/kvm/vmx/nested_vmcs_fields.h b/arch/x86/kvm/vmx/nested_vmcs_fields.h new file mode 100644 index 000000000000..fcd6c32dce31 --- /dev/null +++ b/arch/x86/kvm/vmx/nested_vmcs_fields.h @@ -0,0 +1,13 @@ +#if !defined(HAS_VMCS_FIELD) && !defined(HAS_VMCS_FIELD_RANGE) +BUILD_BUG_ON(1) +#endif + +#ifndef HAS_VMCS_FIELD +#define HAS_VMCS_FIELD(x, c) +#endif +#ifndef HAS_VMCS_FIELD_RANGE +#define HAS_VMCS_FIELD_RANGE(x, y, c) +#endif + +#undef HAS_VMCS_FIELD +#undef HAS_VMCS_FIELD_RANGE -- 2.46.2