qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PULL v4 21/43] i386: Update SGX CPUID info according to hardware/KV


From: Philippe Mathieu-Daudé
Subject: Re: [PULL v4 21/43] i386: Update SGX CPUID info according to hardware/KVM/user input
Date: Thu, 9 Sep 2021 15:09:38 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0

On 9/8/21 12:04 PM, Paolo Bonzini wrote:
> 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>

'---' separator goes here.

> 
> 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;

Undocumented, but IIUC this return a boolean.

> +}
> +
>  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);

bool.

> +
>  #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)) {

Missing stub for when CONFIG_SGX=n:

bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
{
    g_assert_not_reached();
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]