All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Jim Mattson <jmattson@google.com>
Cc: KarimAllah Ahmed <karahmed@amazon.de>,
	the arch/x86 maintainers <x86@kernel.org>,
	kvm list <kvm@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH v6 08/14] KVM/nVMX: Use kvm_vcpu_map when mapping the posted interrupt descriptor table
Date: Thu, 6 May 2021 23:27:27 +0000	[thread overview]
Message-ID: <YJR7X7nN7sFwvesj@google.com> (raw)
In-Reply-To: <CALMp9eR-Kt5wcveYmmmOe7HfWBB4r5nF+SjMfybPRR-b9TXiTg@mail.gmail.com>

On Thu, May 06, 2021, Jim Mattson wrote:
> On Thu, Jan 31, 2019 at 12:28 PM KarimAllah Ahmed <karahmed@amazon.de> wrote:
> >
> > Use kvm_vcpu_map when mapping the posted interrupt descriptor table since
> > using kvm_vcpu_gpa_to_page() and kmap() will only work for guest memory
> > that has a "struct page".
> >
> > One additional semantic change is that the virtual host mapping lifecycle
> > has changed a bit. It now has the same lifetime of the pinning of the
> > interrupt descriptor table page on the host side.
> >
> > Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
> > Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > ---
> > v4 -> v5:
> > - unmap with dirty flag
> >
> > v1 -> v2:
> > - Do not change the lifecycle of the mapping (pbonzini)
> > ---
> >  arch/x86/kvm/vmx/nested.c | 43 ++++++++++++-------------------------------
> >  arch/x86/kvm/vmx/vmx.h    |  2 +-
> >  2 files changed, 13 insertions(+), 32 deletions(-)
> >
> > diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> > index 31b352c..53b1063 100644
> > --- a/arch/x86/kvm/vmx/nested.c
> > +++ b/arch/x86/kvm/vmx/nested.c
> > @@ -230,12 +230,8 @@ static void free_nested(struct kvm_vcpu *vcpu)
> >                 vmx->nested.apic_access_page = NULL;
> >         }
> >         kvm_vcpu_unmap(vcpu, &vmx->nested.virtual_apic_map, true);
> > -       if (vmx->nested.pi_desc_page) {
> > -               kunmap(vmx->nested.pi_desc_page);
> > -               kvm_release_page_dirty(vmx->nested.pi_desc_page);
> > -               vmx->nested.pi_desc_page = NULL;
> > -               vmx->nested.pi_desc = NULL;
> > -       }
> > +       kvm_vcpu_unmap(vcpu, &vmx->nested.pi_desc_map, true);
> > +       vmx->nested.pi_desc = NULL;
> >
> >         kvm_mmu_free_roots(vcpu, &vcpu->arch.guest_mmu, KVM_MMU_ROOTS_ALL);
> >
> > @@ -2868,26 +2864,15 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
> >         }
> >
> >         if (nested_cpu_has_posted_intr(vmcs12)) {
> > -               if (vmx->nested.pi_desc_page) { /* shouldn't happen */
> > -                       kunmap(vmx->nested.pi_desc_page);
> > -                       kvm_release_page_dirty(vmx->nested.pi_desc_page);
> > -                       vmx->nested.pi_desc_page = NULL;
> > -                       vmx->nested.pi_desc = NULL;
> > -                       vmcs_write64(POSTED_INTR_DESC_ADDR, -1ull);
> > +               map = &vmx->nested.pi_desc_map;
> > +
> > +               if (!kvm_vcpu_map(vcpu, gpa_to_gfn(vmcs12->posted_intr_desc_addr), map)) {
> > +                       vmx->nested.pi_desc =
> > +                               (struct pi_desc *)(((void *)map->hva) +
> > +                               offset_in_page(vmcs12->posted_intr_desc_addr));
> > +                       vmcs_write64(POSTED_INTR_DESC_ADDR,
> > +                                    pfn_to_hpa(map->pfn) + offset_in_page(vmcs12->posted_intr_desc_addr));
> >                 }
> 
> Previously, if there was no backing page for the
> vmcs12->posted_intr_desc_addr, we wrote an illegal value (-1ull) into
> the vmcs02 POSTED_INTR_DESC_ADDR field to force VM-entry failure.

The "vmcs_write64(POSTED_INTR_DESC_ADDR, -1ull)" above is for the "impossible"
case where the PI descriptor was already mapped.  The error handling for failure
to map is below.  The (forced) VM-Exit unmap paths don't stuff vmcs02 either.
In other words, I think the bug was pre-existing.

> Now, AFAICT, we leave that field unmodified. For a newly constructed vmcs02,
> doesn't that mean we're going to treat physical address 0 as the address of
> the vmcs02 posted interrupt descriptor?

PA=0 is the happy path.  Thanks to L1TF, that memory is always unused.  If
mapping for a previous VM-Enter succeeded, vmcs02.POSTED_INTR_DESC_ADDR will
hold whatever PA was used for the last VM-Enter.
 
> > -               page = kvm_vcpu_gpa_to_page(vcpu, vmcs12->posted_intr_desc_addr);
> > -               if (is_error_page(page))
> > -                       return;

Error path for failure to map.

> > -               vmx->nested.pi_desc_page = page;
> > -               vmx->nested.pi_desc = kmap(vmx->nested.pi_desc_page);
> > -               vmx->nested.pi_desc =
> > -                       (struct pi_desc *)((void *)vmx->nested.pi_desc +
> > -                       (unsigned long)(vmcs12->posted_intr_desc_addr &
> > -                       (PAGE_SIZE - 1)));
> > -               vmcs_write64(POSTED_INTR_DESC_ADDR,
> > -                       page_to_phys(vmx->nested.pi_desc_page) +
> > -                       (unsigned long)(vmcs12->posted_intr_desc_addr &
> > -                       (PAGE_SIZE - 1)));
> >         }
> >         if (nested_vmx_prepare_msr_bitmap(vcpu, vmcs12))
> >                 vmcs_set_bits(CPU_BASED_VM_EXEC_CONTROL,
> > @@ -3911,12 +3896,8 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
> >                 vmx->nested.apic_access_page = NULL;
> >         }
> >         kvm_vcpu_unmap(vcpu, &vmx->nested.virtual_apic_map, true);
> > -       if (vmx->nested.pi_desc_page) {
> > -               kunmap(vmx->nested.pi_desc_page);
> > -               kvm_release_page_dirty(vmx->nested.pi_desc_page);
> > -               vmx->nested.pi_desc_page = NULL;
> > -               vmx->nested.pi_desc = NULL;
> > -       }
> > +       kvm_vcpu_unmap(vcpu, &vmx->nested.pi_desc_map, true);
> > +       vmx->nested.pi_desc = NULL;
> >
> >         /*
> >          * We are now running in L2, mmu_notifier will force to reload the
> > diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
> > index f618f52..bd04725 100644
> > --- a/arch/x86/kvm/vmx/vmx.h
> > +++ b/arch/x86/kvm/vmx/vmx.h
> > @@ -143,7 +143,7 @@ struct nested_vmx {
> >          */
> >         struct page *apic_access_page;
> >         struct kvm_host_map virtual_apic_map;
> > -       struct page *pi_desc_page;
> > +       struct kvm_host_map pi_desc_map;
> >
> >         struct kvm_host_map msr_bitmap_map;
> >
> > --
> > 2.7.4
> >

  reply	other threads:[~2021-05-06 23:27 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-31 20:24 [PATCH v6 00/14] KVM/X86: Introduce a new guest mapping interface KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 01/14] X86/nVMX: handle_vmon: Read 4 bytes from guest memory KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 02/14] X86/nVMX: Update the PML table without mapping and unmapping the page KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 03/14] X86/KVM: Handle PFNs outside of kernel reach when touching GPTEs KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 04/14] KVM: Introduce a new guest mapping API KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 05/14] X86/nVMX: handle_vmptrld: Use kvm_vcpu_map when copying VMCS12 from guest memory KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 06/14] KVM/nVMX: Use kvm_vcpu_map when mapping the L1 MSR bitmap KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 07/14] KVM/nVMX: Use kvm_vcpu_map when mapping the virtual APIC page KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 08/14] KVM/nVMX: Use kvm_vcpu_map when mapping the posted interrupt descriptor table KarimAllah Ahmed
2021-05-06 23:06   ` Jim Mattson
2021-05-06 23:27     ` Sean Christopherson [this message]
2019-01-31 20:24 ` [PATCH v6 09/14] KVM/X86: Use kvm_vcpu_map in emulator_cmpxchg_emulated KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 10/14] KVM/nSVM: Use the new mapping API for mapping guest memory KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 11/14] KVM/nVMX: Use kvm_vcpu_map for accessing the shadow VMCS KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 12/14] KVM/nVMX: Use kvm_vcpu_map for accessing the enlightened VMCS KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 13/14] KVM/nVMX: Use page_address_valid in a few more locations KarimAllah Ahmed
2019-01-31 20:24 ` [PATCH v6 14/14] kvm, x86: Properly check whether a pfn is an MMIO or not KarimAllah Ahmed
2019-03-18 13:10 ` [PATCH v6 00/14] KVM/X86: Introduce a new guest mapping interface Raslan, KarimAllah
2019-03-18 14:22   ` Konrad Rzeszutek Wilk
2019-03-18 19:16     ` Raslan, KarimAllah
2019-04-29 13:58       ` Konrad Rzeszutek Wilk
2019-04-30 19:31         ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YJR7X7nN7sFwvesj@google.com \
    --to=seanjc@google.com \
    --cc=jmattson@google.com \
    --cc=karahmed@amazon.de \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.