The basic SGX did not enable numa for SGX EPC sections, which result in all EPC sections located in numa node 0. This patch enable SGX numa function in the guest and the EPC section can work with RAM as one numa node. The Guest kernel related log: [ 0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff] [ 0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff] The SRAT table can normally show SGX EPC sections menory info in different numa nodes. The SGX EPC numa related command: ...... -m 4G,maxmem=20G \ -smp sockets=2,cores=2 \ -cpu host,+sgx-provisionkey \ -object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \ -object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \ -numa node,nodeid=0,cpus=0-1,memdev=node0 \ -object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \ -object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \ -numa node,nodeid=1,cpus=2-3,memdev=node1 \ -M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1 \ ...... Signed-off-by: Yang Zhong <yang.zhong@intel.com> Message-Id: <20211101162009.62161-2-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
71 lines
1.8 KiB
C
71 lines
1.8 KiB
C
/*
|
|
* SGX EPC device
|
|
*
|
|
* Copyright (C) 2019 Intel Corporation
|
|
*
|
|
* Authors:
|
|
* Sean Christopherson <sean.j.christopherson@intel.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*/
|
|
#ifndef QEMU_SGX_EPC_H
|
|
#define QEMU_SGX_EPC_H
|
|
|
|
#include "hw/i386/hostmem-epc.h"
|
|
|
|
#define TYPE_SGX_EPC "sgx-epc"
|
|
#define SGX_EPC(obj) \
|
|
OBJECT_CHECK(SGXEPCDevice, (obj), TYPE_SGX_EPC)
|
|
#define SGX_EPC_CLASS(oc) \
|
|
OBJECT_CLASS_CHECK(SGXEPCDeviceClass, (oc), TYPE_SGX_EPC)
|
|
#define SGX_EPC_GET_CLASS(obj) \
|
|
OBJECT_GET_CLASS(SGXEPCDeviceClass, (obj), TYPE_SGX_EPC)
|
|
|
|
#define SGX_EPC_ADDR_PROP "addr"
|
|
#define SGX_EPC_SIZE_PROP "size"
|
|
#define SGX_EPC_MEMDEV_PROP "memdev"
|
|
#define SGX_EPC_NUMA_NODE_PROP "node"
|
|
|
|
/**
|
|
* SGXEPCDevice:
|
|
* @addr: starting guest physical address, where @SGXEPCDevice is mapped.
|
|
* Default value: 0, means that address is auto-allocated.
|
|
* @hostmem: host memory backend providing memory for @SGXEPCDevice
|
|
*/
|
|
typedef struct SGXEPCDevice {
|
|
/* private */
|
|
DeviceState parent_obj;
|
|
|
|
/* public */
|
|
uint64_t addr;
|
|
uint32_t node;
|
|
HostMemoryBackendEpc *hostmem;
|
|
} SGXEPCDevice;
|
|
|
|
/*
|
|
* @base: address in guest physical address space where EPC regions start
|
|
* @mr: address space container for memory devices
|
|
*/
|
|
typedef struct SGXEPCState {
|
|
uint64_t base;
|
|
uint64_t size;
|
|
|
|
MemoryRegion mr;
|
|
|
|
struct SGXEPCDevice **sections;
|
|
int nr_sections;
|
|
} SGXEPCState;
|
|
|
|
bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size);
|
|
void sgx_epc_build_srat(GArray *table_data);
|
|
|
|
static inline uint64_t sgx_epc_above_4g_end(SGXEPCState *sgx_epc)
|
|
{
|
|
assert(sgx_epc != NULL && sgx_epc->base >= 0x100000000ULL);
|
|
|
|
return sgx_epc->base + sgx_epc->size;
|
|
}
|
|
|
|
#endif
|