remove pci_device_lock in pci.c

-- remove unnecessary lock in pci_mmcfg_read_cfg and
   pci_mmcfg_write_cfg since the mmio operation is atomic
   if the offest is aligned with 1/2/4 bytes.
-- move pci_is_valid_access to pci.h

Tracked-On: #4958
Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
This commit is contained in:
Mingqiang Chi 2020-06-18 13:17:22 +08:00 committed by wenlingz
parent d808031a04
commit 0bd6555cab
3 changed files with 31 additions and 25 deletions

View File

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

View File

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

View File

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