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 <fei1.li@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Li Fei1 2020-10-20 15:28:55 +08:00 committed by Fuzhong Liu
parent bb6b226c86
commit 460124f984
6 changed files with 27 additions and 75 deletions

View File

@ -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,

View File

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

View File

@ -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(" })");

View File

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

View File

@ -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 */

View File

@ -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 {