mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 21:19:35 +00:00
HV: Fix VPCI bugs found in integration testing for partition mode
Tracked-On: #1126 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com>
This commit is contained in:
parent
308910ebf7
commit
36c4a27abc
@ -115,7 +115,9 @@ static int vdev_hostbridge_cfgwrite(struct pci_vdev *vdev, uint32_t offset,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_vdev_write_cfg(vdev, offset, bytes, val);
|
if (!pci_bar_access(offset)) {
|
||||||
|
pci_vdev_write_cfg(vdev, offset, bytes, val);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
#define PCIR_VENDOR 0x00U
|
#define PCIR_VENDOR 0x00U
|
||||||
#define PCIR_DEVICE 0x02U
|
#define PCIR_DEVICE 0x02U
|
||||||
#define PCIR_COMMAND 0x04U
|
#define PCIR_COMMAND 0x04U
|
||||||
#define PCIM_CMD_MEMEN 0x0002U
|
|
||||||
#define PCIR_REVID 0x08U
|
#define PCIR_REVID 0x08U
|
||||||
#define PCIR_SUBCLASS 0x0AU
|
#define PCIR_SUBCLASS 0x0AU
|
||||||
#define PCIR_CLASS 0x0BU
|
#define PCIR_CLASS 0x0BU
|
||||||
|
@ -131,6 +131,7 @@ static int vdev_pt_init(struct pci_vdev *vdev)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct vm *vm = vdev->vpci->vm;
|
struct vm *vm = vdev->vpci->vm;
|
||||||
|
uint16_t pci_command;
|
||||||
|
|
||||||
ret = vdev_pt_init_validate(vdev);
|
ret = vdev_pt_init_validate(vdev);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -150,6 +151,11 @@ static int vdev_pt_init(struct pci_vdev *vdev)
|
|||||||
ret = assign_iommu_device(vm->iommu, vdev->pdev.bdf.bits.b,
|
ret = assign_iommu_device(vm->iommu, vdev->pdev.bdf.bits.b,
|
||||||
(uint8_t)(vdev->pdev.bdf.value & 0xFFU));
|
(uint8_t)(vdev->pdev.bdf.value & 0xFFU));
|
||||||
|
|
||||||
|
pci_command = pci_pdev_read_cfg(&vdev->pdev, PCIR_COMMAND, 2U);
|
||||||
|
/* Disable INTX */
|
||||||
|
pci_command |= 0x400U;
|
||||||
|
pci_pdev_write_cfg(&vdev->pdev, PCIR_COMMAND, 2U, pci_command);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,44 +218,47 @@ static int vdev_pt_remap_bar(struct pci_vdev *vdev, uint32_t idx,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t memen(struct pci_vdev *vdev)
|
|
||||||
{
|
|
||||||
return pci_pdev_read_cfg(&vdev->pdev, PCIR_COMMAND, 2U)
|
|
||||||
& PCIM_CMD_MEMEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vdev_pt_cfgwrite_bar(struct pci_vdev *vdev, uint32_t offset,
|
static void vdev_pt_cfgwrite_bar(struct pci_vdev *vdev, uint32_t offset,
|
||||||
uint32_t bytes, uint32_t new_bar_uos)
|
uint32_t bytes, uint32_t new_bar_uos)
|
||||||
{
|
{
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
uint32_t new_bar, mask;
|
uint32_t new_bar, mask;
|
||||||
bool bar_update_normal = 1;
|
bool bar_update_normal;
|
||||||
bool do_map;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((bytes != 4U) || ((offset & 0x3U) != 0U)) {
|
if ((bytes != 4U) || ((offset & 0x3U) != 0U)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_bar = 0U;
|
||||||
idx = (offset - pci_bar_offset(0U)) >> 2U;
|
idx = (offset - pci_bar_offset(0U)) >> 2U;
|
||||||
mask = ~(vdev->bar[idx].size - 1U);
|
mask = ~(vdev->bar[idx].size - 1U);
|
||||||
bar_update_normal = (new_bar_uos != (uint32_t)~0U);
|
|
||||||
new_bar = new_bar_uos & mask;
|
|
||||||
|
|
||||||
if (pci_bar_base(new_bar) == vdev->bar[idx].base) {
|
switch (vdev->bar[idx].type) {
|
||||||
return;
|
case PCIBAR_NONE:
|
||||||
}
|
vdev->bar[idx].base = 0UL;
|
||||||
|
break;
|
||||||
|
|
||||||
do_map = (memen(vdev)) && bar_update_normal;
|
case PCIBAR_MEM32:
|
||||||
if (do_map) {
|
bar_update_normal = (new_bar_uos != (uint32_t)~0U);
|
||||||
error = vdev_pt_remap_bar(vdev, idx, pci_bar_base(new_bar));
|
new_bar = new_bar_uos & mask;
|
||||||
if (error != 0) {
|
if (bar_update_normal) {
|
||||||
pr_err("vdev_pt_remap_bar failed: %d", idx);
|
error = vdev_pt_remap_bar(vdev, idx,
|
||||||
|
pci_bar_base(new_bar));
|
||||||
|
if (error != 0) {
|
||||||
|
pr_err("vdev_pt_remap_bar failed: %d", idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
vdev->bar[idx].base = pci_bar_base(new_bar);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pr_err("Unknown bar type, idx=%d", idx);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_vdev_write_cfg_u32(vdev, offset, new_bar);
|
pci_vdev_write_cfg_u32(vdev, offset, new_bar);
|
||||||
vdev->bar[idx].base = pci_bar_base(new_bar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vdev_pt_cfgwrite(struct pci_vdev *vdev, uint32_t offset,
|
static int vdev_pt_cfgwrite(struct pci_vdev *vdev, uint32_t offset,
|
||||||
|
Loading…
Reference in New Issue
Block a user