x86_64: Change each pci device's vcfg mmio size from 4k to 8k

Extend pci device's vcfg mmio size frome 4k to 8k, the first page is
trapped by crosvm, the second page is share memory between guest and
crosvm, so that guest could read/write it directly without vm exit.

BUG=b:194391459
TEST=check vcfg mmio size for each pci device

Change-Id: If5ac75b4dc8a829cabce4370e7592f23600e4ef8
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3813136
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Victor Ding <victording@chromium.org>
Tested-by: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
Xiong Zhang 2022-06-15 10:21:54 +08:00 committed by crosvm LUCI
parent 60711c2bac
commit 7f7b8ef3b0
2 changed files with 10 additions and 5 deletions

View file

@ -464,13 +464,17 @@ impl BusDevice for PciConfigMmio {
}
}
/// Inspired by PCI configuration space, CrosVM provides 1024 dword virtual registers (4KiB in
/// Inspired by PCI configuration space, CrosVM provides 2048 dword virtual registers (8KiB in
/// total) for each PCI device. The guest can use these registers to exchange device-specific
/// information with CrosVM.
/// information with CrosVM. The first 4kB is trapped by crosvm and crosm supply these
/// register's emulation. The second 4KB is mapped into guest directly as shared memory, so
/// when guest access this 4KB, vm exit doesn't happen.
/// All these virtual registers from all PCI devices locate in a contiguous memory region.
/// The base address of this memory region is provided by an IntObj named VCFG in the ACPI DSDT.
/// Bit 12 is used to select the first trapped page or the second directly mapped page
/// The offset of each register is calculated in the same way as PCIe ECAM;
/// i.e. offset = (bus << 20) | (device << 15) | (function << 12) | (register_index << 2)
/// i.e. offset = (bus << 21) | (device << 16) | (function << 13) | (page_select << 12) |
/// (register_index << 2)
pub struct PciVirtualConfigMmio {
/// PCI root bridge.
pci_root: Arc<Mutex<PciRoot>>,

View file

@ -640,7 +640,7 @@ impl arch::LinuxArch for X8664arch {
.insert(pcie_cfg_mmio, pcie_cfg_mmio_range.start, pcie_cfg_mmio_len)
.unwrap();
let pcie_vcfg_mmio = Arc::new(Mutex::new(PciVirtualConfigMmio::new(pci.clone(), 12)));
let pcie_vcfg_mmio = Arc::new(Mutex::new(PciVirtualConfigMmio::new(pci.clone(), 13)));
let pcie_vcfg_range = Self::get_pcie_vcfg_mmio_range(&mem, &pcie_cfg_mmio_range);
mmio_bus
.insert(
@ -1467,7 +1467,8 @@ impl X8664arch {
// Put PCIe VCFG region at a 2MB boundary after physical memory or 4gb, whichever is greater.
let ram_end_round_2mb = (mem.end_addr().offset() + 2 * MB - 1) / (2 * MB) * (2 * MB);
let start = std::cmp::max(ram_end_round_2mb, 4 * GB);
let end = start + pcie_cfg_mmio.len().unwrap() - 1;
// Each pci device's ECAM size is 4kb and its vcfg size is 8kb
let end = start + pcie_cfg_mmio.len().unwrap() * 2 - 1;
AddressRange { start, end }
}