lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 19 Apr 2024 10:34:23 -0700
From: Isaku Yamahata <isaku.yamahata@...el.com>
To: Binbin Wu <binbin.wu@...ux.intel.com>
Cc: Isaku Yamahata <isaku.yamahata@...el.com>,
	Sean Christopherson <sean.j.christopherson@...el.com>,
	kvm@...r.kernel.org, linux-kernel@...r.kernel.org,
	isaku.yamahata@...il.com, Paolo Bonzini <pbonzini@...hat.com>,
	erdemaktas@...gle.com, Sean Christopherson <seanjc@...gle.com>,
	Sagi Shahar <sagis@...gle.com>, Kai Huang <kai.huang@...el.com>,
	chen.bo@...el.com, hang.yuan@...el.com, tina.zhang@...el.com,
	isaku.yamahata@...ux.intel.com
Subject: Re: [PATCH v19 110/130] KVM: TDX: Handle TDX PV MMIO hypercall

On Fri, Apr 19, 2024 at 09:42:48AM +0800,
Binbin Wu <binbin.wu@...ux.intel.com> wrote:

> 
> 
> On 4/19/2024 5:22 AM, Isaku Yamahata wrote:
> > On Thu, Apr 18, 2024 at 07:04:11PM +0800,
> > Binbin Wu <binbin.wu@...ux.intel.com> wrote:
> > 
> > > 
> > > On 4/18/2024 5:29 PM, Binbin Wu wrote:
> > > > > +
> > > > > +static int tdx_emulate_mmio(struct kvm_vcpu *vcpu)
> > > > > +{
> > > > > +    struct kvm_memory_slot *slot;
> > > > > +    int size, write, r;
> > > > > +    unsigned long val;
> > > > > +    gpa_t gpa;
> > > > > +
> > > > > +    KVM_BUG_ON(vcpu->mmio_needed, vcpu->kvm);
> > > > > +
> > > > > +    size = tdvmcall_a0_read(vcpu);
> > > > > +    write = tdvmcall_a1_read(vcpu);
> > > > > +    gpa = tdvmcall_a2_read(vcpu);
> > > > > +    val = write ? tdvmcall_a3_read(vcpu) : 0;
> > > > > +
> > > > > +    if (size != 1 && size != 2 && size != 4 && size != 8)
> > > > > +        goto error;
> > > > > +    if (write != 0 && write != 1)
> > > > > +        goto error;
> > > > > +
> > > > > +    /* Strip the shared bit, allow MMIO with and without it set. */
> > > > Based on the discussion
> > > > https://lore.kernel.org/all/ZcUO5sFEAIH68JIA@google.com/
> > > > Do we still allow the MMIO without shared bit?
> > That's independent.  The part is how to work around guest accesses the
> > MMIO region with private GPA.  This part is,  the guest issues
> > TDG.VP.VMCALL<MMMIO> and KVM masks out the shared bit to make it friendly
> > to the user space VMM.
> It's similar.
> The tdvmcall from the guest for mmio can also be private GPA, which is not
> reasonable, right?
> According to the comment, kvm doens't care about if the TD guest issue the
> tdvmcall with private GPA or shared GPA.

I checked the GHCI spec. It clearly states this hypercall is for shared GPA.
We should return error for private GPA.

  This TDG.VP.VMCALL is used to help request the VMM perform
  emulated-MMIO-access operation. The VMM may emulate MMIO space in shared-GPA
  space. The VMM can induce a #VE on these shared-GPA accesses by mapping shared
  GPAs with the suppress-VE bit cleared in the EPT Entries corresponding to
  these mappings

So we'll have something as follows. Compile only tested.

diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 3bf0d6e3cd21..0f696f3fbd86 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1281,24 +1281,34 @@ static int tdx_emulate_mmio(struct kvm_vcpu *vcpu)
        if (write != 0 && write != 1)
                goto error;
 
-       /* Strip the shared bit, allow MMIO with and without it set. */
+       /*
+        * MMIO with TDG.VP.VMCALL<MMIO> allows only shared GPA because
+        * private GPA is for device assignment.
+        */
+       if (kvm_is_private_gpa(gpa))
+               goto error;
+
+       /*
+        * Strip the shared bit because device emulator is assigned to GPA
+        * without shared bit.  We'd like the existing code untouched.
+        */
        gpa = gpa & ~gfn_to_gpa(kvm_gfn_shared_mask(vcpu->kvm));
 
-       if (size > 8u || ((gpa + size - 1) ^ gpa) & PAGE_MASK)
+       /* Disallow MMIO crossing page boundary for simplicity. */
+       if (((gpa + size - 1) ^ gpa) & PAGE_MASK)
                goto error;
 
        slot = kvm_vcpu_gfn_to_memslot(vcpu, gpa_to_gfn(gpa));
        if (slot && !(slot->flags & KVM_MEMSLOT_INVALID))
                goto error;
 
-       if (!kvm_io_bus_write(vcpu, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) {
-               trace_kvm_fast_mmio(gpa);
-               return 1;
-       }
-
-       if (write)
+       if (write) {
+               if (!kvm_io_bus_write(vcpu, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) {
+                       trace_kvm_fast_mmio(gpa);
+                       return 1;
+               }
                r = tdx_mmio_write(vcpu, gpa, size, val);
-       else
+       } else
                r = tdx_mmio_read(vcpu, gpa, size);
        if (!r) {
                /* Kernel completed device emulation. */


-- 
Isaku Yamahata <isaku.yamahata@...el.com>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ