From 460124f984ee687521be23bcc3482b64defa37b3 Mon Sep 17 00:00:00 2001 From: Li Fei1 Date: Tue, 20 Oct 2020 15:28:55 +0800 Subject: [PATCH] dm: e820: refine e820 layout We don't reserve PCI MMIO in e820 Table, it's included in DSDT ACPI Table. About 0xA0000 - 0x100000 entry, we don't have any ACPI Table touch this region. So we could remove it too. After this change, we could only pass the reserved e820 table which we must reserve to OVMF. In this case, the OVMF could trust ACRN-DM and pass the reserved e820 table to guest instead of dropping it. This patch needs the corresponding modify in OVMF. Otherwise, the guest could not boot. Tracked-On: #4550 Signed-off-by: Li Fei1 Acked-by: Wang, Yu1 --- devicemodel/core/sw_load_common.c | 57 ++++--------------------------- devicemodel/core/vmmapi.c | 2 +- devicemodel/hw/pci/core.c | 26 ++++++-------- devicemodel/hw/pci/gvt.c | 8 ++--- devicemodel/include/pci_core.h | 3 ++ devicemodel/include/sw_load.h | 6 ++-- 6 files changed, 27 insertions(+), 75 deletions(-) diff --git a/devicemodel/core/sw_load_common.c b/devicemodel/core/sw_load_common.c index 2fab5e0d2..423995130 100644 --- a/devicemodel/core/sw_load_common.c +++ b/devicemodel/core/sw_load_common.c @@ -52,15 +52,12 @@ static char bootargs[BOOT_ARG_LEN]; * * Begin Limit Type Length * 0: 0 - 0xA0000 RAM 0xA0000 - * 1: 0xA0000 - 0x100000 (reserved) 0x60000 - * 2: 0x100000 - lowmem RAM lowmem - 1MB - * 3: lowmem - 0x80000000 (reserved) 2GB - lowmem - * 4: 0x80000000 - 0x88000000 (reserved) 128MB - * 5: 0xDB000000 - 0xDF000000 (reserved) 64MB - * 6: 0xDF000000 - 0xE0000000 (reserved) 16MB - * 7: 0xE0000000 - 0x100000000 MCFG, MMIO 512MB - * 8: 0x100000000 - 0x140000000 64-bit PCI hole 1GB - * 9: 0x140000000 - highmem RAM highmem - 5GB + * 1: 0x100000 - lowmem RAM lowmem - 1MB + * 2: lowmem - 0x80000000 (reserved) 2GB - lowmem + * 3: 0xE0000000 - 0x100000000 MCFG, MMIO 512MB + * 4: 0x140000000 - highmem RAM highmem - 5GB + * + * FIXME: Do we need to reserve DSM and OPREGION for GVTD here. */ const struct e820_entry e820_default_entries[NUM_E820_ENTRIES] = { { /* 0 to video memory */ @@ -69,12 +66,6 @@ const struct e820_entry e820_default_entries[NUM_E820_ENTRIES] = { .type = E820_TYPE_RAM }, - { /* video memory, ROM (used for e820/mptable/smbios/acpi) */ - .baseaddr = 0xA0000, - .length = 0x60000, - .type = E820_TYPE_RESERVED - }, - { /* 1MB to lowmem */ .baseaddr = 0x100000, .length = 0x48f00000, @@ -87,48 +78,12 @@ const struct e820_entry e820_default_entries[NUM_E820_ENTRIES] = { .type = E820_TYPE_RESERVED }, - { - /* reserve for PRM resource */ - .baseaddr = 0x80000000, - .length = 0x8000000, - .type = E820_TYPE_RESERVED - }, - - { - /* reserve for GVT-d graphics stolen memory. - * The native BIOS allocates the stolen memory by itself, - * and size can be configured by user itself through BIOS GUI. - * For ACRN, we simply hard code to 64MB and static - * reserved the memory region to avoid more efforts in OVMF, - * and user *must* align the native BIOS setting to 64MB. - * - * GPU_GSM_GPA micro in passthrough.c should -+ * align with this address here. - */ - .baseaddr = 0xDB000000, - .length = 0x4000000, - .type = E820_TYPE_RESERVED - }, - - { - /* reserve for GVT */ - .baseaddr = 0xDF000000, - .length = 0x1000000, - .type = E820_TYPE_RESERVED - }, - { /* ECFG_BASE to 4GB */ .baseaddr = PCI_EMUL_ECFG_BASE, .length = (4 * GB) - PCI_EMUL_ECFG_BASE, .type = E820_TYPE_RESERVED }, - { /* 4GB to 5GB */ - .baseaddr = PCI_EMUL_MEMBASE64, - .length = PCI_EMUL_MEMLIMIT64 - PCI_EMUL_MEMBASE64, - .type = E820_TYPE_RESERVED - }, - { /* 5GB to highmem */ .baseaddr = PCI_EMUL_MEMLIMIT64, .length = 0x000100000, diff --git a/devicemodel/core/vmmapi.c b/devicemodel/core/vmmapi.c index 3985ae01b..0614062fb 100644 --- a/devicemodel/core/vmmapi.c +++ b/devicemodel/core/vmmapi.c @@ -223,7 +223,7 @@ vm_create(const char *name, uint64_t req_buf, int *vcpu_num) ctx->gvt_enabled = false; ctx->fd = devfd; - ctx->lowmem_limit = 2 * GB; + ctx->lowmem_limit = PCI_EMUL_MEMBASE32; ctx->highmem_gpa_base = PCI_EMUL_MEMLIMIT64; ctx->name = (char *)(ctx + 1); strncpy(ctx->name, name, strnlen(name, PATH_MAX) + 1); diff --git a/devicemodel/hw/pci/core.c b/devicemodel/hw/pci/core.c index 4150d544c..4f15bf6c8 100644 --- a/devicemodel/hw/pci/core.c +++ b/devicemodel/hw/pci/core.c @@ -99,8 +99,6 @@ struct mmio_rsvd_rgn reserved_bar_regions[REGION_NUMS]; #define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024) /* 1MB per bus */ SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE); -#define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE - static struct pci_vdev_ops *pci_emul_finddev(char *name); static void pci_lintr_route(struct pci_vdev *dev); static void pci_lintr_update(struct pci_vdev *dev); @@ -1375,7 +1373,6 @@ init_pci(struct vmctx *ctx) struct businfo *bi; struct slotinfo *si; struct funcinfo *fi; - size_t lowmem; int bus, slot, func, i; int success_cnt = 0; int error; @@ -1503,12 +1500,11 @@ init_pci(struct vmctx *ctx) * Accesses to memory addresses that are not allocated to system * memory or PCI devices return 0xff's. */ - lowmem = vm_get_lowmem_size(ctx); bzero(&mr, sizeof(struct mem_range)); mr.name = "PCI hole (32-bit)"; mr.flags = MEM_F_RW; - mr.base = lowmem; - mr.size = (4ULL * 1024 * 1024 * 1024) - lowmem; + mr.base = PCI_EMUL_MEMBASE32; + mr.size = PCI_EMUL_MEMLIMIT32 - PCI_EMUL_MEMBASE32; mr.handler = pci_emul_fallback_handler; error = register_mem_fallback(&mr); if (error != 0) @@ -1573,7 +1569,6 @@ deinit_pci(struct vmctx *ctx) struct slotinfo *si; struct funcinfo *fi; int bus, slot, func; - size_t lowmem; struct mem_range mr; /* Release PCI extended config space */ @@ -1584,11 +1579,10 @@ deinit_pci(struct vmctx *ctx) unregister_mem(&mr); /* Release PCI hole space */ - lowmem = vm_get_lowmem_size(ctx); bzero(&mr, sizeof(struct mem_range)); mr.name = "PCI hole (32-bit)"; - mr.base = lowmem; - mr.size = (4ULL * 1024 * 1024 * 1024) - lowmem; + mr.base = PCI_EMUL_MEMBASE32; + mr.size = PCI_EMUL_MEMLIMIT32 - PCI_EMUL_MEMBASE32; unregister_mem_fallback(&mr); /* ditto for the 64-bit PCI host aperture */ @@ -1747,24 +1741,24 @@ pci_bus_write_dsdt(int bus) dsdt_line(" DWordMemory (ResourceProducer, PosDecode, " "MinFixed, MaxFixed, NonCacheable, ReadWrite,"); dsdt_line(" 0x00000000, // Granularity"); - dsdt_line(" 0x%08X, // Range Minimum\n", bi->membase32); + dsdt_line(" 0x%08X, // Range Minimum\n", PCI_EMUL_MEMBASE32); dsdt_line(" 0x%08X, // Range Maximum\n", - bi->memlimit32 - 1); + PCI_EMUL_MEMLIMIT32 - 1); dsdt_line(" 0x00000000, // Translation Offset"); dsdt_line(" 0x%08X, // Length\n", - bi->memlimit32 - bi->membase32); + PCI_EMUL_MEMLIMIT32 - PCI_EMUL_MEMBASE32); dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); /* mmio window (64-bit) */ dsdt_line(" QWordMemory (ResourceProducer, PosDecode, " "MinFixed, MaxFixed, NonCacheable, ReadWrite,"); dsdt_line(" 0x0000000000000000, // Granularity"); - dsdt_line(" 0x%016lX, // Range Minimum\n", bi->membase64); + dsdt_line(" 0x%016lX, // Range Minimum\n", PCI_EMUL_MEMBASE64); dsdt_line(" 0x%016lX, // Range Maximum\n", - bi->memlimit64 - 1); + PCI_EMUL_MEMLIMIT64 - 1); dsdt_line(" 0x0000000000000000, // Translation Offset"); dsdt_line(" 0x%016lX, // Length\n", - bi->memlimit64 - bi->membase64); + PCI_EMUL_MEMLIMIT64 - PCI_EMUL_MEMBASE64); dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); dsdt_line(" })"); diff --git a/devicemodel/hw/pci/gvt.c b/devicemodel/hw/pci/gvt.c index 4f4db2024..b2de3d5fb 100644 --- a/devicemodel/hw/pci/gvt.c +++ b/devicemodel/hw/pci/gvt.c @@ -197,10 +197,10 @@ gvt_init_config(struct pci_gvt *gvt) bar2_end_addr = strtoull(next, &next, 16); ctx = gvt->gvt_pi->vmctx; - if(bar0_start_addr < ctx->lowmem_limit - || bar2_start_addr < ctx->lowmem_limit - || bar0_end_addr > PCI_EMUL_ECFG_BASE - || bar2_end_addr > PCI_EMUL_ECFG_BASE){ + if(bar0_start_addr < PCI_EMUL_MEMBASE32 + || bar2_start_addr < PCI_EMUL_MEMBASE32 + || bar0_end_addr > PCI_EMUL_MEMLIMIT32 + || bar2_end_addr > PCI_EMUL_MEMLIMIT32){ pr_err("gvt pci bases are out of range\n"); return -1; } diff --git a/devicemodel/include/pci_core.h b/devicemodel/include/pci_core.h index 6e5dc1db6..7ce16d1c7 100644 --- a/devicemodel/include/pci_core.h +++ b/devicemodel/include/pci_core.h @@ -40,6 +40,9 @@ #define PCI_BARMAX PCIR_MAX_BAR_0 /* BAR registers in a Type 0 header */ #define PCI_BDF(b, d, f) (((b & 0xFF) << 8) | ((d & 0x1F) << 3) | ((f & 0x7))) +#define PCI_EMUL_MEMBASE32 0x80000000UL /* 2GB */ +#define PCI_EMUL_MEMLIMIT32 0xC0000000UL /* 3GB */ + #define PCI_EMUL_ECFG_BASE 0xE0000000UL /* 3.5GB */ #define PCI_EMUL_MEMBASE64 0x100000000UL /* 4GB */ diff --git a/devicemodel/include/sw_load.h b/devicemodel/include/sw_load.h index ef71e3647..d0fd2c182 100644 --- a/devicemodel/include/sw_load.h +++ b/devicemodel/include/sw_load.h @@ -39,9 +39,9 @@ #define E820_TYPE_ACPI_NVS 4U /* EFI 10 */ #define E820_TYPE_UNUSABLE 5U /* EFI 8 */ -#define NUM_E820_ENTRIES 10 -#define LOWRAM_E820_ENTRY 2 -#define HIGHRAM_E820_ENTRY 9 +#define NUM_E820_ENTRIES 5 +#define LOWRAM_E820_ENTRY 1 +#define HIGHRAM_E820_ENTRY 4 /* Defines a single entry in an E820 memory map. */ struct e820_entry {