diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index c21a216b4..1c2ec5432 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -100,21 +100,6 @@ static bool vpci_pio_cfgaddr_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t return ret; } -static inline bool vpci_is_valid_access_offset(uint32_t offset, uint32_t bytes) -{ - return ((offset & (bytes - 1U)) == 0U); -} - -static inline bool vpci_is_valid_access_byte(uint32_t bytes) -{ - return ((bytes == 1U) || (bytes == 2U) || (bytes == 4U)); -} - -static inline bool vpci_is_valid_access(uint32_t offset, uint32_t bytes) -{ - return (vpci_is_valid_access_byte(bytes) && vpci_is_valid_access_offset(offset, bytes)); -} - /** * @pre vcpu != NULL * @pre vcpu->vm != NULL @@ -138,7 +123,7 @@ static bool vpci_pio_cfgdata_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t cfg_addr.value = atomic_readandclear32(&vpci->addr.value); if (cfg_addr.bits.enable != 0U) { - if (vpci_is_valid_access(cfg_addr.bits.reg_num + offset, bytes)) { + if (pci_is_valid_access(cfg_addr.bits.reg_num + offset, bytes)) { bdf.value = cfg_addr.bits.bdf; ret = vpci_read_cfg(vpci, bdf, cfg_addr.bits.reg_num + offset, bytes, &val); } @@ -169,7 +154,7 @@ static bool vpci_pio_cfgdata_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t cfg_addr.value = atomic_readandclear32(&vpci->addr.value); if (cfg_addr.bits.enable != 0U) { - if (vpci_is_valid_access(cfg_addr.bits.reg_num + offset, bytes)) { + if (pci_is_valid_access(cfg_addr.bits.reg_num + offset, bytes)) { bdf.value = cfg_addr.bits.bdf; ret = vpci_write_cfg(vpci, bdf, cfg_addr.bits.reg_num + offset, bytes, val); } diff --git a/hypervisor/hw/pci.c b/hypervisor/hw/pci.c index 8dbe40416..7b009ecff 100644 --- a/hypervisor/hw/pci.c +++ b/hypervisor/hw/pci.c @@ -49,7 +49,6 @@ #define PDEV_HLIST_HASHBITS 6U #define PDEV_HLIST_HASHSIZE (1U << PDEV_HLIST_HASHBITS) -static spinlock_t pci_device_lock; static uint32_t num_pci_pdev; static struct pci_pdev pci_pdevs[CONFIG_MAX_PCI_DEV_NUM]; static struct hlist_head pdevs_hlist_heads[PDEV_HLIST_HASHSIZE]; @@ -144,19 +143,28 @@ static const struct pci_cfg_ops pci_pio_cfg_ops = { /* * @pre offset < 0x1000U + * @pre pci_mmcfg_base 4K-byte alignment */ static inline uint32_t mmcfg_off_to_address(union pci_bdf bdf, uint32_t offset) { return (uint32_t)pci_mmcfg_base + (((uint32_t)bdf.value << 12U) | offset); } +/* + * @pre bytes == 1U || bytes == 2U || bytes == 4U + * @pre offset 1-byte alignment if byte == 1U + * 2-byte alignment if byte == 2U + * 4-byte alignment if byte == 4U + */ static uint32_t pci_mmcfg_read_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes) { uint32_t addr = mmcfg_off_to_address(bdf, offset); void *hva = hpa2hva(addr); uint32_t val; - spinlock_obtain(&pci_device_lock); + + ASSERT(pci_is_valid_access(offset, bytes), "the offset should be aligned with 2/4 byte\n"); + switch (bytes) { case 1U: val = (uint32_t)mmio_read8(hva); @@ -168,20 +176,22 @@ static uint32_t pci_mmcfg_read_cfg(union pci_bdf bdf, uint32_t offset, uint32_t val = mmio_read32(hva); break; } - spinlock_release(&pci_device_lock); return val; } /* * @pre bytes == 1U || bytes == 2U || bytes == 4U + * @pre offset 1-byte alignment if byte == 1U + * 2-byte alignment if byte == 2U + * 4-byte alignment if byte == 4U */ static void pci_mmcfg_write_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes, uint32_t val) { uint32_t addr = mmcfg_off_to_address(bdf, offset); void *hva = hpa2hva(addr); - spinlock_obtain(&pci_device_lock); + ASSERT(pci_is_valid_access(offset, bytes), "the offset should be aligned with 2/4 byte\n"); switch (bytes) { case 1U: mmio_write8((uint8_t)val, hva); @@ -193,7 +203,6 @@ static void pci_mmcfg_write_cfg(union pci_bdf bdf, uint32_t offset, uint32_t byt mmio_write32(val, hva); break; } - spinlock_release(&pci_device_lock); } static const struct pci_cfg_ops pci_mmcfg_cfg_ops = { @@ -616,9 +625,6 @@ void init_pci_pdev_list(void) uint16_t bus; bool was_visited = false; - /* explicitly init the lock before using it */ - spinlock_init(&pci_device_lock); - pci_parse_iommu_devscopes(&bdfs_from_drhds, &drhd_idx_pci_all); /* TODO: iterate over list of PCI Host Bridges found in ACPI namespace */ diff --git a/hypervisor/include/hw/pci.h b/hypervisor/include/hw/pci.h index 2efc2d569..a79b73f8b 100644 --- a/hypervisor/include/hw/pci.h +++ b/hypervisor/include/hw/pci.h @@ -361,6 +361,21 @@ static inline bool is_pci_cfg_multifunction(uint8_t header_type) return ((header_type & PCIM_MFDEV) == PCIM_MFDEV); } +static inline bool pci_is_valid_access_offset(uint32_t offset, uint32_t bytes) +{ + return ((offset & (bytes - 1U)) == 0U); +} + +static inline bool pci_is_valid_access_byte(uint32_t bytes) +{ + return ((bytes == 1U) || (bytes == 2U) || (bytes == 4U)); +} + +static inline bool pci_is_valid_access(uint32_t offset, uint32_t bytes) +{ + return (pci_is_valid_access_byte(bytes) && pci_is_valid_access_offset(offset, bytes)); +} + bool is_plat_hidden_pdev(union pci_bdf bdf); bool pdev_need_bar_restore(const struct pci_pdev *pdev); void pdev_restore_bar(const struct pci_pdev *pdev);