hv: vPCI: fix large bar base update
The current code would write 'BAR address & size_maks' into PCIe virtual BAR before updating the virtual BAR's base address when guest writing a PCIe device's BAR. If the size of a PCIe device's BAR is larger than 4G, the low 32 bits size_mask for this 64 bits BAR is zero. When ACRN updating the virtual BAR's base address, the low 32 bits sizing information would be lost. This patch saves whether a BAR writing is sizing or not before updating the virtual BAR's base address. Tracked-On: #8267 Signed-off-by: Fei Li <fei1.li@intel.com>
This commit is contained in:
parent
5a452e5e32
commit
ab4e19d0be
|
@ -111,13 +111,13 @@ static void pci_vdev_update_vbar_base(struct pci_vdev *vdev, uint32_t idx)
|
||||||
vbar = &vdev->vbars[idx];
|
vbar = &vdev->vbars[idx];
|
||||||
offset = pci_bar_offset(idx);
|
offset = pci_bar_offset(idx);
|
||||||
lo = pci_vdev_read_vcfg(vdev, offset, 4U);
|
lo = pci_vdev_read_vcfg(vdev, offset, 4U);
|
||||||
if ((!is_pci_reserved_bar(vbar)) && (lo != (vbar->mask | vbar->bar_type.bits))) {
|
if ((!is_pci_reserved_bar(vbar)) && !vbar->sizing) {
|
||||||
base = lo & vbar->mask;
|
base = lo & vbar->mask;
|
||||||
|
|
||||||
if (is_pci_mem64lo_bar(vbar)) {
|
if (is_pci_mem64lo_bar(vbar)) {
|
||||||
vbar = &vdev->vbars[idx + 1U];
|
vbar = &vdev->vbars[idx + 1U];
|
||||||
|
if (!vbar->sizing) {
|
||||||
hi = pci_vdev_read_vcfg(vdev, (offset + 4U), 4U);
|
hi = pci_vdev_read_vcfg(vdev, (offset + 4U), 4U);
|
||||||
if (hi != vbar->mask) {
|
|
||||||
base |= ((uint64_t)hi << 32U);
|
base |= ((uint64_t)hi << 32U);
|
||||||
} else {
|
} else {
|
||||||
base = 0UL;
|
base = 0UL;
|
||||||
|
@ -199,6 +199,7 @@ void pci_vdev_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||||
uint32_t update_idx = idx;
|
uint32_t update_idx = idx;
|
||||||
|
|
||||||
vbar = &vdev->vbars[idx];
|
vbar = &vdev->vbars[idx];
|
||||||
|
vbar->sizing = (val == ~0U);
|
||||||
bar = val & vbar->mask;
|
bar = val & vbar->mask;
|
||||||
if (vbar->is_mem64hi) {
|
if (vbar->is_mem64hi) {
|
||||||
update_idx -= 1U;
|
update_idx -= 1U;
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
struct pci_vbar {
|
struct pci_vbar {
|
||||||
bool is_mem64hi; /* this is to indicate the high part of 64 bits MMIO bar */
|
bool is_mem64hi; /* this is to indicate the high part of 64 bits MMIO bar */
|
||||||
|
bool sizing; /* this is to indicate the guest is sizing this BAR */
|
||||||
uint64_t size; /* BAR size */
|
uint64_t size; /* BAR size */
|
||||||
uint64_t base_gpa; /* BAR guest physical address */
|
uint64_t base_gpa; /* BAR guest physical address */
|
||||||
uint64_t base_hpa; /* BAR host physical address */
|
uint64_t base_hpa; /* BAR host physical address */
|
||||||
|
|
Loading…
Reference in New Issue