mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 20:53:46 +00:00
hv: vpci: move vBAR base setting into pci_vdev_write_bar
Updating vBAR base when setting vBAR configuration sapce. Tracked-On: #3475 Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
5fdb6cc0ac
commit
5aa92b85ea
@ -49,7 +49,6 @@ static void vdev_pt_unmap_mem_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
ept_del_mr(vm, (uint64_t *)(vm->arch_vm.nworld_eptp),
|
||||
vbar->base, /* GPA (old vbar) */
|
||||
vbar->size);
|
||||
vbar->base = 0UL;
|
||||
}
|
||||
|
||||
is_msix_table_bar = (has_msix_cap(vdev) && (idx == vdev->msix.table_bar));
|
||||
@ -89,30 +88,16 @@ static void vdev_pt_map_mem_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
{
|
||||
bool is_msix_table_bar;
|
||||
struct pci_bar *vbar;
|
||||
uint64_t vbar_base;
|
||||
struct acrn_vm *vm = vdev->vpci->vm;
|
||||
|
||||
vbar = &vdev->bar[idx];
|
||||
|
||||
vbar_base = pci_vdev_get_bar_base(vdev, idx);
|
||||
if (vbar_base != 0UL) {
|
||||
if (ept_is_mr_valid(vm, vbar_base, vbar->size)) {
|
||||
uint64_t hpa = gpa2hpa(vdev->vpci->vm, vbar_base);
|
||||
uint64_t pbar_base = vbar->base_hpa; /* pbar (hpa) */
|
||||
|
||||
if (hpa != pbar_base) {
|
||||
ept_add_mr(vm, (uint64_t *)(vm->arch_vm.nworld_eptp),
|
||||
pbar_base, /* HPA (pbar) */
|
||||
vbar_base, /* GPA (new vbar) */
|
||||
vbar->size,
|
||||
EPT_WR | EPT_RD | EPT_UNCACHED);
|
||||
}
|
||||
/* Remember the previously mapped MMIO vbar */
|
||||
vbar->base = vbar_base;
|
||||
} else {
|
||||
pr_fatal("%s, %x:%x.%x set invalid bar[%d] address: 0x%lx\n", __func__,
|
||||
vdev->bdf.bits.b, vdev->bdf.bits.d, vdev->bdf.bits.f, idx, vbar_base);
|
||||
}
|
||||
if (vbar->base != 0UL) {
|
||||
ept_add_mr(vm, (uint64_t *)(vm->arch_vm.nworld_eptp),
|
||||
vbar->base_hpa, /* HPA (pbar) */
|
||||
vbar->base, /* GPA (new vbar) */
|
||||
vbar->size,
|
||||
EPT_WR | EPT_RD | EPT_UNCACHED);
|
||||
}
|
||||
|
||||
is_msix_table_bar = (has_msix_cap(vdev) && (idx == vdev->msix.table_bar));
|
||||
@ -145,11 +130,8 @@ static void vdev_pt_allow_io_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
/* For SOS, all port IO access is allowed by default, so skip SOS here */
|
||||
if (!is_sos_vm(vdev->vpci->vm)) {
|
||||
struct pci_bar *vbar = &vdev->bar[idx];
|
||||
uint64_t vbar_base = pci_vdev_get_bar_base(vdev, idx); /* vbar (gpa) */
|
||||
if (vbar_base != 0UL) {
|
||||
allow_guest_pio_access(vdev->vpci->vm, (uint16_t)vbar_base, (uint32_t)(vbar->size));
|
||||
/* Remember the previously allowed IO vbar base */
|
||||
vbar->base = vbar_base;
|
||||
if (vbar->base != 0UL) {
|
||||
allow_guest_pio_access(vdev->vpci->vm, (uint16_t)vbar->base, (uint32_t)(vbar->size));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,7 +149,6 @@ static void vdev_pt_deny_io_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
struct pci_bar *vbar = &vdev->bar[idx];
|
||||
if (vbar->base != 0UL) {
|
||||
deny_guest_pio_access(vdev->vpci->vm, (uint16_t)(vbar->base), (uint32_t)(vbar->size));
|
||||
vbar->base = 0UL;
|
||||
}
|
||||
|
||||
}
|
||||
@ -190,6 +171,7 @@ void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||
vdev_pt_allow_io_vbar(vdev, update_idx);
|
||||
} else {
|
||||
pci_vdev_write_cfg_u32(vdev, offset, val);
|
||||
vdev->bar[update_idx].base = 0UL;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -199,7 +181,7 @@ void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||
|
||||
default:
|
||||
if (vbar->type == PCIBAR_MEM64HI) {
|
||||
update_idx = idx - 1U;
|
||||
update_idx -= 1U;
|
||||
}
|
||||
vdev_pt_unmap_mem_vbar(vdev, update_idx);
|
||||
if (val != ~0U) {
|
||||
@ -207,6 +189,7 @@ void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||
vdev_pt_map_mem_vbar(vdev, update_idx);
|
||||
} else {
|
||||
pci_vdev_write_cfg_u32(vdev, offset, val);
|
||||
vdev->bar[update_idx].base = 0UL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -280,7 +263,6 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
||||
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
||||
lo = (uint32_t)vdev->pci_dev_config->vbar_base[idx];
|
||||
}
|
||||
pci_vdev_write_bar(vdev, idx, lo);
|
||||
|
||||
if (type == PCIBAR_MEM64) {
|
||||
idx++;
|
||||
@ -300,12 +282,14 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
||||
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
||||
hi = (uint32_t)(vdev->pci_dev_config->vbar_base[idx - 1U] >> 32U);
|
||||
}
|
||||
pci_vdev_write_bar(vdev, idx - 1U, lo);
|
||||
pci_vdev_write_bar(vdev, idx, hi);
|
||||
} else {
|
||||
vbar->size = vbar->size & ~(vbar->size - 1UL);
|
||||
if (type == PCIBAR_MEM32) {
|
||||
vbar->size = round_page_up(vbar->size);
|
||||
}
|
||||
pci_vdev_write_bar(vdev, idx, lo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#include <vm.h>
|
||||
#include "vpci_priv.h"
|
||||
#include <ept.h>
|
||||
#include <logmsg.h>
|
||||
|
||||
/**
|
||||
* @pre vdev != NULL
|
||||
@ -105,24 +107,13 @@ uint32_t pci_vdev_read_bar(const struct pci_vdev *vdev, uint32_t idx)
|
||||
return bar;
|
||||
}
|
||||
|
||||
void pci_vdev_write_bar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||
static void pci_vdev_update_bar_base(struct pci_vdev *vdev, uint32_t idx)
|
||||
{
|
||||
struct pci_bar *vbar;
|
||||
uint32_t bar, offset;
|
||||
|
||||
vbar = &vdev->bar[idx];
|
||||
bar = val & vbar->mask;
|
||||
bar |= vbar->fixed;
|
||||
offset = pci_bar_offset(idx);
|
||||
pci_vdev_write_cfg_u32(vdev, offset, bar);
|
||||
}
|
||||
|
||||
uint64_t pci_vdev_get_bar_base(const struct pci_vdev *vdev, uint32_t idx)
|
||||
{
|
||||
const struct pci_bar *vbar;
|
||||
enum pci_bar_type type;
|
||||
uint64_t base = 0UL;
|
||||
uint32_t lo, hi, offset;
|
||||
struct acrn_vm *vm = vdev->vpci->vm;
|
||||
|
||||
vbar = &vdev->bar[idx];
|
||||
offset = pci_bar_offset(idx);
|
||||
@ -146,5 +137,31 @@ uint64_t pci_vdev_get_bar_base(const struct pci_vdev *vdev, uint32_t idx)
|
||||
}
|
||||
}
|
||||
|
||||
return base;
|
||||
if ((base != 0UL) && !ept_is_mr_valid(vm, base, vdev->bar[idx].size)) {
|
||||
pr_fatal("%s, %x:%x.%x set invalid bar[%d] base: 0x%lx, size: 0x%lx\n", __func__,
|
||||
vdev->bdf.bits.b, vdev->bdf.bits.d, vdev->bdf.bits.f, idx, base, vdev->bar[idx].size);
|
||||
/* If guest set a invalid GPA, ignore it temporarily */
|
||||
base = 0UL;
|
||||
}
|
||||
|
||||
vdev->bar[idx].base = base;
|
||||
}
|
||||
|
||||
void pci_vdev_write_bar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||
{
|
||||
struct pci_bar *vbar;
|
||||
uint32_t bar, offset;
|
||||
uint32_t update_idx = idx;
|
||||
|
||||
vbar = &vdev->bar[idx];
|
||||
bar = val & vbar->mask;
|
||||
bar |= vbar->fixed;
|
||||
offset = pci_bar_offset(idx);
|
||||
pci_vdev_write_cfg_u32(vdev, offset, bar);
|
||||
|
||||
if (vbar->type == PCIBAR_MEM64HI) {
|
||||
update_idx -= 1U;
|
||||
}
|
||||
|
||||
pci_vdev_update_bar_base(vdev, update_idx);
|
||||
}
|
||||
|
@ -146,5 +146,4 @@ struct pci_vdev *pci_find_vdev(struct acrn_vpci *vpci, union pci_bdf vbdf);
|
||||
|
||||
uint32_t pci_vdev_read_bar(const struct pci_vdev *vdev, uint32_t idx);
|
||||
void pci_vdev_write_bar(struct pci_vdev *vdev, uint32_t idx, uint32_t val);
|
||||
uint64_t pci_vdev_get_bar_base(const struct pci_vdev *vdev, uint32_t idx);
|
||||
#endif /* VPCI_PRIV_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user