xref: /openbmc/qemu/hw/i386/sgx.c (revision a7c565a9)
1 /*
2  * SGX common code
3  *
4  * Copyright (C) 2021 Intel Corporation
5  *
6  * Authors:
7  *   Yang Zhong<yang.zhong@intel.com>
8  *   Sean Christopherson <sean.j.christopherson@intel.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2 or later.
11  * See the COPYING file in the top-level directory.
12  */
13 #include "qemu/osdep.h"
14 #include "hw/i386/pc.h"
15 #include "hw/i386/sgx-epc.h"
16 #include "hw/mem/memory-device.h"
17 #include "monitor/qdev.h"
18 #include "qapi/error.h"
19 #include "exec/address-spaces.h"
20 
21 int sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
22 {
23     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
24     SGXEPCDevice *epc;
25 
26     if (pcms->sgx_epc.size == 0 || pcms->sgx_epc.nr_sections <= section_nr) {
27         return 1;
28     }
29 
30     epc = pcms->sgx_epc.sections[section_nr];
31 
32     *addr = epc->addr;
33     *size = memory_device_get_region_size(MEMORY_DEVICE(epc), &error_fatal);
34 
35     return 0;
36 }
37 
38 void pc_machine_init_sgx_epc(PCMachineState *pcms)
39 {
40     SGXEPCState *sgx_epc = &pcms->sgx_epc;
41     X86MachineState *x86ms = X86_MACHINE(pcms);
42     SgxEPCList *list = NULL;
43     Object *obj;
44 
45     memset(sgx_epc, 0, sizeof(SGXEPCState));
46     if (!x86ms->sgx_epc_list) {
47         return;
48     }
49 
50     sgx_epc->base = 0x100000000ULL + x86ms->above_4g_mem_size;
51 
52     memory_region_init(&sgx_epc->mr, OBJECT(pcms), "sgx-epc", UINT64_MAX);
53     memory_region_add_subregion(get_system_memory(), sgx_epc->base,
54                                 &sgx_epc->mr);
55 
56     for (list = x86ms->sgx_epc_list; list; list = list->next) {
57         obj = object_new("sgx-epc");
58 
59         /* set the memdev link with memory backend */
60         object_property_parse(obj, SGX_EPC_MEMDEV_PROP, list->value->memdev,
61                               &error_fatal);
62         object_property_set_bool(obj, "realized", true, &error_fatal);
63         object_unref(obj);
64     }
65 
66     if ((sgx_epc->base + sgx_epc->size) < sgx_epc->base) {
67         error_report("Size of all 'sgx-epc' =0x%"PRIu64" causes EPC to wrap",
68                      sgx_epc->size);
69         exit(EXIT_FAILURE);
70     }
71 
72     memory_region_set_size(&sgx_epc->mr, sgx_epc->size);
73 }
74