x86_64: Move PCIE config mmio into pci low mmio

By default PCIE config mmio is above pci low mmio, and they are adjacent.
When user could specify pcie config mmio address and size, the specified
address range will be highly overlap with pci low mmio or guest memory,
then it will split pci low mmio or guest memory. Finally three memory
regions exist in the below 4G space: guest ram, pci low mmio and
pcie config mmio.

In order to simplify memory space management, this commit move pcie
config mmio into pci low mmio, and pcie config mmio is reserved from
pci low mmio at the beginning. In this way, only guest ram and pci
low mmio exist in below 4G space.

BUG=None
TEST=boot a vm and check memory layout below 4G.

Change-Id: I0b253b7bf7fb0287a27a88b34ee28b0a0bd2d172
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3578016
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Junichi Uekawa <uekawa@chromium.org>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Xiong Zhang 2022-04-02 20:20:55 +08:00 committed by Chromeos LUCI
parent 3be45af929
commit efb69c3c0a

View file

@ -159,6 +159,8 @@ pub enum Error {
RegisterIrqfd(base::Error),
#[error("error registering virtual socket device: {0}")]
RegisterVsock(arch::DeviceRegistrationError),
#[error("error reserved pcie config mmio")]
ReservePcieCfgMmio(resources::Error),
#[error("failed to set a hardware breakpoint: {0}")]
SetHwBreakpoint(base::Error),
#[error("failed to set interrupts: {0}")]
@ -230,7 +232,7 @@ const PCIE_CFG_MMIO_START: u64 = FIRST_ADDR_PAST_32BITS - RESERVED_MEM_SIZE - PC
// Reserve memory region for pcie virtual configuration
const PCIE_VCFG_MMIO_SIZE: u64 = PCIE_CFG_MMIO_SIZE;
const END_ADDR_BEFORE_32BITS: u64 = FIRST_ADDR_PAST_32BITS - MEM_32BIT_GAP_SIZE;
const PCI_MMIO_SIZE: u64 = MEM_32BIT_GAP_SIZE - RESERVED_MEM_SIZE - PCIE_CFG_MMIO_SIZE;
const PCI_MMIO_SIZE: u64 = MEM_32BIT_GAP_SIZE - RESERVED_MEM_SIZE;
// Linux (with 4-level paging) has a physical memory limit of 46 bits (64 TiB).
const HIGH_MMIO_MAX_END: u64 = 1u64 << 46;
const KERNEL_64BIT_ENTRY_OFFSET: u64 = 0x200;
@ -469,6 +471,12 @@ impl arch::LinuxArch for X8664arch {
let mut mptable = true;
let mut sci_irq = X86_64_SCI_IRQ;
// punch pcie config mmio from pci low mmio, so that it couldn't be
// allocated to any device.
system_allocator
.reserve_mmio(PCIE_CFG_MMIO_START, PCIE_CFG_MMIO_SIZE)
.map_err(Error::ReservePcieCfgMmio)?;
for sdt in components.acpi_sdts.iter() {
if sdt.is_signature(b"DSDT") || sdt.is_signature(b"APIC") {
noirq = false;