All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Yang Zhong <yang.zhong@intel.com>,
	Sean Christopherson <sean.j.christopherson@intel.com>
Subject: [PULL 20/36] i386: Update SGX CPUID info according to hardware/KVM/user input
Date: Mon,  6 Sep 2021 15:10:43 +0200	[thread overview]
Message-ID: <20210906131059.55234-21-pbonzini@redhat.com> (raw)
In-Reply-To: <20210906131059.55234-1-pbonzini@redhat.com>

From: Sean Christopherson <sean.j.christopherson@intel.com>

Expose SGX to the guest if and only if KVM is enabled and supports
virtualization of SGX.  While the majority of ENCLS can be emulated to
some degree, because SGX uses a hardware-based root of trust, the
attestation aspects of SGX cannot be emulated in software, i.e.
ultimately emulation will fail as software cannot generate a valid
quote/report.  The complexity of partially emulating SGX in Qemu far
outweighs the value added, e.g. an SGX specific simulator for userspace
applications can emulate SGX for development and testing purposes.

Note, access to the PROVISIONKEY is not yet advertised to the guest as
KVM blocks access to the PROVISIONKEY by default and requires userspace
to provide additional credentials (via ioctl()) to expose PROVISIONKEY.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Yang Zhong <yang.zhong@intel.com>

v3-->v4:
   - Replaced g_malloc0() with directly ....
Message-Id: <20210719112136.57018-13-yang.zhong@intel.com>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/sgx.c             | 17 +++++++++
 include/hw/i386/sgx-epc.h |  2 +
 target/i386/cpu.c         | 77 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+)

diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index e77deb0b00..5f988c6368 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -18,6 +18,23 @@
 #include "qapi/error.h"
 #include "exec/address-spaces.h"
 
+int sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
+{
+    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    SGXEPCDevice *epc;
+
+    if (pcms->sgx_epc.size == 0 || pcms->sgx_epc.nr_sections <= section_nr) {
+        return 1;
+    }
+
+    epc = pcms->sgx_epc.sections[section_nr];
+
+    *addr = epc->addr;
+    *size = memory_device_get_region_size(MEMORY_DEVICE(epc), &error_fatal);
+
+    return 0;
+}
+
 static int sgx_epc_set_property(void *opaque, const char *name,
                                 const char *value, Error **errp)
 {
diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h
index 2b2490892b..f85fd2a4ca 100644
--- a/include/hw/i386/sgx-epc.h
+++ b/include/hw/i386/sgx-epc.h
@@ -55,4 +55,6 @@ typedef struct SGXEPCState {
     int nr_sections;
 } SGXEPCState;
 
+int sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size);
+
 #endif
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 59cb2c2d03..38cf507199 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -36,6 +36,7 @@
 #ifndef CONFIG_USER_ONLY
 #include "exec/address-spaces.h"
 #include "hw/boards.h"
+#include "hw/i386/sgx-epc.h"
 #endif
 
 #include "disas/capstone.h"
@@ -5334,6 +5335,25 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                 *ecx |= CPUID_7_0_ECX_OSPKE;
             }
             *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */
+
+            /*
+             * SGX cannot be emulated in software.  If hardware does not
+             * support enabling SGX and/or SGX flexible launch control,
+             * then we need to update the VM's CPUID values accordingly.
+             */
+            if ((*ebx & CPUID_7_0_EBX_SGX) &&
+                (!kvm_enabled() ||
+                 !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_EBX) &
+                    CPUID_7_0_EBX_SGX))) {
+                *ebx &= ~CPUID_7_0_EBX_SGX;
+            }
+
+            if ((*ecx & CPUID_7_0_ECX_SGX_LC) &&
+                (!(*ebx & CPUID_7_0_EBX_SGX) || !kvm_enabled() ||
+                 !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_ECX) &
+                    CPUID_7_0_ECX_SGX_LC))) {
+                *ecx &= ~CPUID_7_0_ECX_SGX_LC;
+            }
         } else if (count == 1) {
             *eax = env->features[FEAT_7_1_EAX];
             *ebx = 0;
@@ -5469,6 +5489,63 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
         break;
     }
+    case 0x12:
+#ifndef CONFIG_USER_ONLY
+        if (!kvm_enabled() ||
+            !(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SGX)) {
+            *eax = *ebx = *ecx = *edx = 0;
+            break;
+        }
+
+        /*
+         * SGX sub-leafs CPUID.0x12.{0x2..N} enumerate EPC sections.  Retrieve
+         * the EPC properties, e.g. confidentiality and integrity, from the
+         * host's first EPC section, i.e. assume there is one EPC section or
+         * that all EPC sections have the same security properties.
+         */
+        if (count > 1) {
+            uint64_t epc_addr, epc_size;
+
+            if (sgx_epc_get_section(count - 2, &epc_addr, &epc_size)) {
+                *eax = *ebx = *ecx = *edx = 0;
+                break;
+            }
+            host_cpuid(index, 2, eax, ebx, ecx, edx);
+            *eax = (uint32_t)(epc_addr & 0xfffff000) | 0x1;
+            *ebx = (uint32_t)(epc_addr >> 32);
+            *ecx = (uint32_t)(epc_size & 0xfffff000) | (*ecx & 0xf);
+            *edx = (uint32_t)(epc_size >> 32);
+            break;
+        }
+
+        /*
+         * SGX sub-leafs CPUID.0x12.{0x0,0x1} are heavily dependent on hardware
+         * and KVM, i.e. QEMU cannot emulate features to override what KVM
+         * supports.  Features can be further restricted by userspace, but not
+         * made more permissive.
+         */
+        *eax = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EAX);
+        *ebx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EBX);
+        *ecx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_ECX);
+        *edx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EDX);
+
+        if (count == 0) {
+            *eax &= env->features[FEAT_SGX_12_0_EAX];
+            *ebx &= env->features[FEAT_SGX_12_0_EBX];
+        } else {
+            *eax &= env->features[FEAT_SGX_12_1_EAX];
+            *ebx &= 0; /* ebx reserve */
+            *ecx &= env->features[FEAT_XSAVE_COMP_LO];
+            *edx &= env->features[FEAT_XSAVE_COMP_HI];
+
+            /* FP and SSE are always allowed regardless of XSAVE/XCR0. */
+            *ecx |= XSTATE_FP_MASK | XSTATE_SSE_MASK;
+
+            /* Access to PROVISIONKEY requires additional credentials. */
+            *eax &= ~(1U << 4);
+        }
+#endif
+        break;
     case 0x14: {
         /* Intel Processor Trace Enumeration */
         *eax = 0;
-- 
2.31.1




  parent reply	other threads:[~2021-09-06 13:20 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-06 13:10 [PULL 00/36] (Mostly) x86 changes for 2021-09-06 Paolo Bonzini
2021-09-06 13:10 ` [PULL 01/36] target/i386: VMRUN and VMLOAD canonicalizations Paolo Bonzini
2021-09-06 13:10 ` [PULL 02/36] target/i386: Added VGIF feature Paolo Bonzini
2021-09-06 13:10 ` [PULL 03/36] target/i386: Moved int_ctl into CPUX86State structure Paolo Bonzini
2021-09-06 13:10 ` [PULL 04/36] target/i386: Added VGIF V_IRQ masking capability Paolo Bonzini
2021-09-06 13:10 ` [PULL 05/36] target/i386: Added ignore TPR check in ctl_has_irq Paolo Bonzini
2021-09-06 13:10 ` [PULL 06/36] target/i386: Added changed priority check for VIRQ Paolo Bonzini
2021-09-06 13:10 ` [PULL 07/36] target/i386: Added vVMLOAD and vVMSAVE feature Paolo Bonzini
2021-09-06 13:10 ` [PULL 08/36] configure / meson: Move the GBM handling to meson.build Paolo Bonzini
2021-09-06 13:26   ` Thomas Huth
2021-09-06 13:10 ` [PULL 09/36] memory: Add RAM_PROTECTED flag to skip IOMMU mappings Paolo Bonzini
2021-09-06 13:10 ` [PULL 10/36] hostmem: Add hostmem-epc as a backend for SGX EPC Paolo Bonzini
2021-09-07  6:23   ` Yang Zhong
2021-09-06 13:10 ` [PULL 11/36] qom: Add memory-backend-epc ObjectOptions support Paolo Bonzini
2021-09-06 13:10 ` [PULL 12/36] i386: Add 'sgx-epc' device to expose EPC sections to guest Paolo Bonzini
2021-09-06 13:10 ` [PULL 13/36] vl: Add sgx compound properties to expose SGX " Paolo Bonzini
2021-09-06 13:10 ` [PULL 14/36] i386: Add primary SGX CPUID and MSR defines Paolo Bonzini
2021-09-06 13:10 ` [PULL 15/36] i386: Add SGX CPUID leaf FEAT_SGX_12_0_EAX Paolo Bonzini
2021-09-06 13:10 ` [PULL 16/36] i386: Add SGX CPUID leaf FEAT_SGX_12_0_EBX Paolo Bonzini
2021-09-06 13:10 ` [PULL 17/36] i386: Add SGX CPUID leaf FEAT_SGX_12_1_EAX Paolo Bonzini
2021-09-06 13:10 ` [PULL 18/36] i386: Add get/set/migrate support for SGX_LEPUBKEYHASH MSRs Paolo Bonzini
2021-09-06 13:10 ` [PULL 19/36] i386: Add feature control MSR dependency when SGX is enabled Paolo Bonzini
2021-09-06 13:10 ` Paolo Bonzini [this message]
2021-09-06 13:10 ` [PULL 21/36] i386: kvm: Add support for exposing PROVISIONKEY to guest Paolo Bonzini
2021-09-06 13:10 ` [PULL 22/36] i386: Propagate SGX CPUID sub-leafs to KVM Paolo Bonzini
2021-09-06 13:10 ` [PULL 23/36] Adjust min CPUID level to 0x12 when SGX is enabled Paolo Bonzini
2021-09-06 13:10 ` [PULL 24/36] hw/i386/fw_cfg: Set SGX bits in feature control fw_cfg accordingly Paolo Bonzini
2021-09-06 13:10 ` [PULL 25/36] hw/i386/pc: Account for SGX EPC sections when calculating device memory Paolo Bonzini
2021-09-06 13:10 ` [PULL 26/36] i386/pc: Add e820 entry for SGX EPC section(s) Paolo Bonzini
2021-09-06 13:10 ` [PULL 27/36] i386: acpi: Add SGX EPC entry to ACPI tables Paolo Bonzini
2021-09-06 13:10 ` [PULL 28/36] q35: Add support for SGX EPC Paolo Bonzini
2021-09-06 13:10 ` [PULL 29/36] i440fx: " Paolo Bonzini
2021-09-06 13:10 ` [PULL 30/36] hostmem-epc: Add the reset interface for EPC backend reset Paolo Bonzini
2021-09-06 13:10 ` [PULL 31/36] sgx-epc: Add the reset interface for sgx-epc virt device Paolo Bonzini
2021-09-06 13:10 ` [PULL 32/36] sgx-epc: Avoid bios reset during sgx epc initialization Paolo Bonzini
2021-09-06 13:10 ` [PULL 33/36] hostmem-epc: Make prealloc consistent with qemu cmdline during reset Paolo Bonzini
2021-09-06 13:10 ` [PULL 34/36] Kconfig: Add CONFIG_SGX support Paolo Bonzini
2021-09-06 13:10 ` [PULL 35/36] sgx-epc: Add the fill_device_info() callback support Paolo Bonzini
2021-09-06 13:10 ` [PULL 36/36] doc: Add the SGX doc Paolo Bonzini
2021-09-06 14:03 ` [PULL 00/36] (Mostly) x86 changes for 2021-09-06 Peter Maydell

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=20210906131059.55234-21-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=sean.j.christopherson@intel.com \
    --cc=yang.zhong@intel.com \
    /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.