Re: [PATCH 5/7] qmp: Add the qmp_query_sgx_capabilities()
On 9/9/21 2:06 PM, Yang Zhong wrote: > On Thu, Sep 09, 2021 at 11:36:58AM +0200, Philippe Mathieu-Daudé wrote: >> On 9/9/21 4:51 AM, Yang Zhong wrote: >>> On Wed, Sep 08, 2021 at 10:38:59AM +0200, Philippe Mathieu-Daudé wrote: On 9/8/21 10:19 AM, Yang Zhong wrote: > Libvirt can use qmp_query_sgx_capabilities() to get the host > sgx capabilities. > > Signed-off-by: Yang Zhong > --- > hw/i386/sgx.c | 66 ++ > include/hw/i386/sgx.h | 1 + > qapi/misc-target.json | 18 +++ > target/i386/monitor.c | 5 +++ > tests/qtest/qmp-cmd-test.c | 1 + > 5 files changed, 91 insertions(+) > +SGXInfo *sgx_get_capabilities(Error **errp) > +{ > +SGXInfo *info = NULL; > +uint32_t eax, ebx, ecx, edx; > + > +int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); > +if (fd < 0) { > +error_setg(errp, "SGX is not enabled in KVM"); > +return NULL; > +} Is this Linux specific? >>> >>> Philippe, The /dev/sgx_vepc node is used for KVM side to expose the SGX >>> EPC section to guest. Libvirt then use the '-machine none' qemu command >>> to query host SGX capabilities(especially for host SGX EPC section size) >>> to decide how many SGX VMs will be started in server. If this node doesn't >>> exist, the reason is host can't support SGX or SGX KVM module is not >>> compiled >>> in the kernel. thanks! >> >> Sorry but you didn't answer my question in an obvious way... Yes or no? > > Yes, this is Linux specific. thanks! You made me have a deeper look at the code. So SGX (Kconfig) requires KVM, which is only supported on Linux host. Thus this Linux specific code is only built on Linux host. Thanks.
Re: [PATCH 5/7] qmp: Add the qmp_query_sgx_capabilities()
On Thu, Sep 09, 2021 at 11:36:58AM +0200, Philippe Mathieu-Daudé wrote: > On 9/9/21 4:51 AM, Yang Zhong wrote: > > On Wed, Sep 08, 2021 at 10:38:59AM +0200, Philippe Mathieu-Daudé wrote: > >> On 9/8/21 10:19 AM, Yang Zhong wrote: > >>> Libvirt can use qmp_query_sgx_capabilities() to get the host > >>> sgx capabilities. > >>> > >>> Signed-off-by: Yang Zhong > >>> --- > >>> hw/i386/sgx.c | 66 ++ > >>> include/hw/i386/sgx.h | 1 + > >>> qapi/misc-target.json | 18 +++ > >>> target/i386/monitor.c | 5 +++ > >>> tests/qtest/qmp-cmd-test.c | 1 + > >>> 5 files changed, 91 insertions(+) > >> > >>> +SGXInfo *sgx_get_capabilities(Error **errp) > >>> +{ > >>> +SGXInfo *info = NULL; > >>> +uint32_t eax, ebx, ecx, edx; > >>> + > >>> +int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); > >>> +if (fd < 0) { > >>> +error_setg(errp, "SGX is not enabled in KVM"); > >>> +return NULL; > >>> +} > >> > >> Is this Linux specific? > > > > Philippe, The /dev/sgx_vepc node is used for KVM side to expose the SGX > > EPC section to guest. Libvirt then use the '-machine none' qemu command > > to query host SGX capabilities(especially for host SGX EPC section size) > > to decide how many SGX VMs will be started in server. If this node doesn't > > exist, the reason is host can't support SGX or SGX KVM module is not > > compiled > > in the kernel. thanks! > > Sorry but you didn't answer my question in an obvious way... Yes or no? Yes, this is Linux specific. thanks! Yang
Re: [PATCH 5/7] qmp: Add the qmp_query_sgx_capabilities()
On 9/9/21 4:51 AM, Yang Zhong wrote: > On Wed, Sep 08, 2021 at 10:38:59AM +0200, Philippe Mathieu-Daudé wrote: >> On 9/8/21 10:19 AM, Yang Zhong wrote: >>> Libvirt can use qmp_query_sgx_capabilities() to get the host >>> sgx capabilities. >>> >>> Signed-off-by: Yang Zhong >>> --- >>> hw/i386/sgx.c | 66 ++ >>> include/hw/i386/sgx.h | 1 + >>> qapi/misc-target.json | 18 +++ >>> target/i386/monitor.c | 5 +++ >>> tests/qtest/qmp-cmd-test.c | 1 + >>> 5 files changed, 91 insertions(+) >> >>> +SGXInfo *sgx_get_capabilities(Error **errp) >>> +{ >>> +SGXInfo *info = NULL; >>> +uint32_t eax, ebx, ecx, edx; >>> + >>> +int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); >>> +if (fd < 0) { >>> +error_setg(errp, "SGX is not enabled in KVM"); >>> +return NULL; >>> +} >> >> Is this Linux specific? > > Philippe, The /dev/sgx_vepc node is used for KVM side to expose the SGX > EPC section to guest. Libvirt then use the '-machine none' qemu command > to query host SGX capabilities(especially for host SGX EPC section size) > to decide how many SGX VMs will be started in server. If this node doesn't > exist, the reason is host can't support SGX or SGX KVM module is not > compiled > in the kernel. thanks! Sorry but you didn't answer my question in an obvious way... Yes or no?
Re: [PATCH 5/7] qmp: Add the qmp_query_sgx_capabilities()
On Wed, Sep 08, 2021 at 10:38:59AM +0200, Philippe Mathieu-Daudé wrote: > On 9/8/21 10:19 AM, Yang Zhong wrote: > > Libvirt can use qmp_query_sgx_capabilities() to get the host > > sgx capabilities. > > > > Signed-off-by: Yang Zhong > > --- > > hw/i386/sgx.c | 66 ++ > > include/hw/i386/sgx.h | 1 + > > qapi/misc-target.json | 18 +++ > > target/i386/monitor.c | 5 +++ > > tests/qtest/qmp-cmd-test.c | 1 + > > 5 files changed, 91 insertions(+) > > > +SGXInfo *sgx_get_capabilities(Error **errp) > > +{ > > +SGXInfo *info = NULL; > > +uint32_t eax, ebx, ecx, edx; > > + > > +int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); > > +if (fd < 0) { > > +error_setg(errp, "SGX is not enabled in KVM"); > > +return NULL; > > +} > > Is this Linux specific? Philippe, The /dev/sgx_vepc node is used for KVM side to expose the SGX EPC section to guest. Libvirt then use the '-machine none' qemu command to query host SGX capabilities(especially for host SGX EPC section size) to decide how many SGX VMs will be started in server. If this node doesn't exist, the reason is host can't support SGX or SGX KVM module is not compiled in the kernel. thanks! Yang
Re: [PATCH 5/7] qmp: Add the qmp_query_sgx_capabilities()
On 9/8/21 10:19 AM, Yang Zhong wrote: > Libvirt can use qmp_query_sgx_capabilities() to get the host > sgx capabilities. > > Signed-off-by: Yang Zhong > --- > hw/i386/sgx.c | 66 ++ > include/hw/i386/sgx.h | 1 + > qapi/misc-target.json | 18 +++ > target/i386/monitor.c | 5 +++ > tests/qtest/qmp-cmd-test.c | 1 + > 5 files changed, 91 insertions(+) > +SGXInfo *sgx_get_capabilities(Error **errp) > +{ > +SGXInfo *info = NULL; > +uint32_t eax, ebx, ecx, edx; > + > +int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); > +if (fd < 0) { > +error_setg(errp, "SGX is not enabled in KVM"); > +return NULL; > +} Is this Linux specific?
[PATCH 5/7] qmp: Add the qmp_query_sgx_capabilities()
Libvirt can use qmp_query_sgx_capabilities() to get the host sgx capabilities. Signed-off-by: Yang Zhong --- hw/i386/sgx.c | 66 ++ include/hw/i386/sgx.h | 1 + qapi/misc-target.json | 18 +++ target/i386/monitor.c | 5 +++ tests/qtest/qmp-cmd-test.c | 1 + 5 files changed, 91 insertions(+) diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c index a3cd671a70..854532fb98 100644 --- a/hw/i386/sgx.c +++ b/hw/i386/sgx.c @@ -18,6 +18,72 @@ #include "qapi/error.h" #include "exec/address-spaces.h" #include "hw/i386/sgx.h" +#include "sysemu/hw_accel.h" + +#define SGX_MAX_EPC_SECTIONS8 +#define SGX_CPUID_EPC_INVALID 0x0 + +/* A valid EPC section. */ +#define SGX_CPUID_EPC_SECTION 0x1 +#define SGX_CPUID_EPC_MASK GENMASK(3, 0) + +static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) +{ +return (low & GENMASK_ULL(31, 12)) + + ((high & GENMASK_ULL(19, 0)) << 32); +} + +static uint64_t sgx_calc_host_epc_section_size(void) +{ +uint32_t i, type; +uint32_t eax, ebx, ecx, edx; +uint64_t size = 0; + +for (i = 0; i < SGX_MAX_EPC_SECTIONS; i++) { +host_cpuid(0x12, i + 2, &eax, &ebx, &ecx, &edx); + +type = eax & SGX_CPUID_EPC_MASK; +if (type == SGX_CPUID_EPC_INVALID) { +break; +} + +if (type != SGX_CPUID_EPC_SECTION) { +break; +} + +size += sgx_calc_section_metric(ecx, edx); +} + +return size; +} + +SGXInfo *sgx_get_capabilities(Error **errp) +{ +SGXInfo *info = NULL; +uint32_t eax, ebx, ecx, edx; + +int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); +if (fd < 0) { +error_setg(errp, "SGX is not enabled in KVM"); +return NULL; +} + +info = g_new0(SGXInfo, 1); +host_cpuid(0x7, 0, &eax, &ebx, &ecx, &edx); + +info->sgx = ebx & (1U << 2) ? true : false; +info->flc = ecx & (1U << 30) ? true : false; + +host_cpuid(0x12, 0, &eax, &ebx, &ecx, &edx); +info->sgx1 = eax & (1U << 0) ? true : false; +info->sgx2 = eax & (1U << 1) ? true : false; + +info->section_size = sgx_calc_host_epc_section_size(); + +close(fd); + +return info; +} SGXInfo *sgx_get_info(void) { diff --git a/include/hw/i386/sgx.h b/include/hw/i386/sgx.h index ea8672f8eb..28437cffc6 100644 --- a/include/hw/i386/sgx.h +++ b/include/hw/i386/sgx.h @@ -7,5 +7,6 @@ #include "qapi/qapi-types-misc-target.h" SGXInfo *sgx_get_info(void); +SGXInfo *sgx_get_capabilities(Error **errp); #endif diff --git a/qapi/misc-target.json b/qapi/misc-target.json index e2a347cc23..594fbd1577 100644 --- a/qapi/misc-target.json +++ b/qapi/misc-target.json @@ -376,3 +376,21 @@ # ## { 'command': 'query-sgx', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } + +## +# @query-sgx-capabilities: +# +# Returns information from host SGX capabilities +# +# Returns: @SGXInfo +# +# Since: 6.2 +# +# Example: +# +# -> { "execute": "query-sgx-capabilities" } +# <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, +# "flc": true, "section-size" : 0 } } +# +## +{ 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } diff --git a/target/i386/monitor.c b/target/i386/monitor.c index 0f1b48b4f8..23a6dc3b7d 100644 --- a/target/i386/monitor.c +++ b/target/i386/monitor.c @@ -799,3 +799,8 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict) qapi_free_SGXInfo(info); } + +SGXInfo *qmp_query_sgx_capabilities(Error **errp) +{ +return sgx_get_capabilities(errp); +} diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c index b75f3364f3..1af2f74c28 100644 --- a/tests/qtest/qmp-cmd-test.c +++ b/tests/qtest/qmp-cmd-test.c @@ -101,6 +101,7 @@ static bool query_is_ignored(const char *cmd) "query-sev", "query-sev-capabilities", "query-sgx", +"query-sgx-capabilities", NULL }; int i;