[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <535E1BD9.8000800@redhat.com>
Date: Mon, 28 Apr 2014 11:14:01 +0200
From: Paolo Bonzini <pbonzini@...hat.com>
To: Bandan Das <bsd@...hat.com>, kvm@...r.kernel.org
CC: Marcelo Tosatti <mtosatti@...hat.com>,
Gleb Natapov <gleb@...nel.org>, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2] KVM: x86: Check for host supported fields in shadow
vmcs
Il 21/04/2014 21:20, Bandan Das ha scritto:
>
> We track shadow vmcs fields through two static lists,
> one for read only and another for r/w fields. However, with
> addition of new vmcs fields, not all fields may be supported on
> all hosts. If so, copy_vmcs12_to_shadow() trying to vmwrite on
> unsupported hosts will result in a vmwrite error. For example, commit
> 36be0b9deb23161 introduced GUEST_BNDCFGS, which is not supported
> by all processors. Filter out host unsupported fields before
> letting guests use shadow vmcs
>
> Signed-off-by: Bandan Das <bsd@...hat.com>
> ---
> v2:
> - Just compress the original lists instead of creating new ones
> - Change commit message slightly to reflect this change
>
> arch/x86/kvm/vmx.c | 54 ++++++++++++++++++++++++++++++++++++++++++------------
> 1 file changed, 42 insertions(+), 12 deletions(-)
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 7bed3e3..26a632f 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
> [number##_HIGH] = VMCS12_OFFSET(name)+4
>
>
> -static const unsigned long shadow_read_only_fields[] = {
> +static unsigned long shadow_read_only_fields[] = {
> /*
> * We do NOT shadow fields that are modified when L0
> * traps and emulates any vmx instruction (e.g. VMPTRLD,
> @@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = {
> GUEST_LINEAR_ADDRESS,
> GUEST_PHYSICAL_ADDRESS
> };
> -static const int max_shadow_read_only_fields =
> +static int max_shadow_read_only_fields =
> ARRAY_SIZE(shadow_read_only_fields);
>
> -static const unsigned long shadow_read_write_fields[] = {
> +static unsigned long shadow_read_write_fields[] = {
> GUEST_RIP,
> GUEST_RSP,
> GUEST_CR0,
> @@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = {
> HOST_FS_SELECTOR,
> HOST_GS_SELECTOR
> };
> -static const int max_shadow_read_write_fields =
> +static int max_shadow_read_write_fields =
> ARRAY_SIZE(shadow_read_write_fields);
>
> static const unsigned short vmcs_field_to_offset_table[] = {
> @@ -3009,6 +3009,42 @@ static void free_kvm_area(void)
> }
> }
>
> +static void init_vmcs_shadow_fields(void)
> +{
> + int i, j;
> +
> + /* No checks for read only fields yet */
> +
> + for (i = j = 0; i < max_shadow_read_write_fields; i++) {
> +
> + switch (shadow_read_write_fields[i]) {
> + case GUEST_BNDCFGS:
> + if (!vmx_mpx_supported())
> + continue;
> + break;
> + default:
> + break;
> + }
> +
> + if (j < i)
> + shadow_read_write_fields[j] =
> + shadow_read_write_fields[i];
> + j++;
> + }
> + max_shadow_read_write_fields = j;
> +
> + /* 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);
> + }
> + 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)
> {
> int cpu;
> @@ -3039,6 +3075,8 @@ static __init int hardware_setup(void)
> enable_vpid = 0;
> if (!cpu_has_vmx_shadow_vmcs())
> enable_shadow_vmcs = 0;
> + if (enable_shadow_vmcs)
> + init_vmcs_shadow_fields();
>
> if (!cpu_has_vmx_ept() ||
> !cpu_has_vmx_ept_4levels()) {
> @@ -8817,14 +8855,6 @@ static int __init vmx_init(void)
>
> memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
> memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
> - /* shadowed read/write fields */
> - 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);
> - }
> - /* shadowed read only fields */
> - for (i = 0; i < max_shadow_read_only_fields; i++)
> - clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap);
>
> /*
> * Allow direct access to the PC debug port (it is often used for I/O
>
Applying this to kvm/master, thanks.
Paolo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists