mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-05 15:06:58 +00:00
HV: enable bar emulation for sos
For sos, its vbar base address is set to pbar base address (vbar gpa = pbar hpa) For pre-launched VMs, vbar base address is pre-assigned in vm_config Rename vdev_pt_remap_msix_table_bar to vdev_pt_remap_msix_table_vbar and make it a static function Remove unused function prototye vdev_pt_remap_msix_table_bar() in vpci_priv.h Tracked-On: #3241 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
af163d579f
commit
4be09f24f3
@ -127,14 +127,12 @@ static uint64_t get_pbar_base(const struct pci_pdev *pdev, uint32_t idx)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vdev != NULL
|
* @pre vdev != NULL
|
||||||
* @pre vdev->vpci != NULL
|
|
||||||
* @pre vdev->vpci->vm != NULL
|
|
||||||
*/
|
*/
|
||||||
int32_t vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val)
|
int32_t vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val)
|
||||||
{
|
{
|
||||||
int32_t ret = -ENODEV;
|
int32_t ret = -ENODEV;
|
||||||
|
|
||||||
if (is_prelaunched_vm(vdev->vpci->vm) && is_bar_offset(vdev->nr_bars, offset)) {
|
if (is_bar_offset(vdev->nr_bars, offset)) {
|
||||||
*val = pci_vdev_read_cfg(vdev, offset, bytes);
|
*val = pci_vdev_read_cfg(vdev, offset, bytes);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
@ -149,7 +147,7 @@ int32_t vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t
|
|||||||
* @pre vdev->pdev != NULL
|
* @pre vdev->pdev != NULL
|
||||||
* @pre vdev->pdev->msix.table_bar < vdev->nr_bars
|
* @pre vdev->pdev->msix.table_bar < vdev->nr_bars
|
||||||
*/
|
*/
|
||||||
void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev)
|
static void vdev_pt_remap_msix_table_vbar(struct pci_vdev *vdev)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct pci_msix *msix = &vdev->msix;
|
struct pci_msix *msix = &vdev->msix;
|
||||||
@ -315,7 +313,7 @@ static void vdev_pt_remap_mem_vbar(struct pci_vdev *vdev, uint32_t idx)
|
|||||||
is_msix_table_bar = (has_msix_cap(vdev) && (idx == vdev->msix.table_bar));
|
is_msix_table_bar = (has_msix_cap(vdev) && (idx == vdev->msix.table_bar));
|
||||||
|
|
||||||
if (is_msix_table_bar) {
|
if (is_msix_table_bar) {
|
||||||
vdev_pt_remap_msix_table_bar(vdev);
|
vdev_pt_remap_msix_table_vbar(vdev);
|
||||||
} else {
|
} else {
|
||||||
vdev_pt_remap_generic_mem_vbar(vdev, idx);
|
vdev_pt_remap_generic_mem_vbar(vdev, idx);
|
||||||
}
|
}
|
||||||
@ -403,17 +401,14 @@ static void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t offset, uint32_t
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vdev != NULL
|
* @pre vdev != NULL
|
||||||
* @pre vdev->vpci != NULL
|
|
||||||
* @pre vdev->vpci->vm != NULL
|
|
||||||
* bar write access must be 4 bytes and offset must also be 4 bytes aligned, it will be dropped otherwise
|
* bar write access must be 4 bytes and offset must also be 4 bytes aligned, it will be dropped otherwise
|
||||||
*/
|
*/
|
||||||
int32_t vdev_pt_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val)
|
int32_t vdev_pt_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val)
|
||||||
{
|
{
|
||||||
int32_t ret = -ENODEV;
|
int32_t ret = -ENODEV;
|
||||||
|
|
||||||
/* bar write access must be 4 bytes and offset must also be 4 bytes aligned */
|
/* bar write access must be 4 bytes and offset must also be 4 bytes aligned*/
|
||||||
if (is_prelaunched_vm(vdev->vpci->vm) && is_bar_offset(vdev->nr_bars, offset)
|
if (is_bar_offset(vdev->nr_bars, offset) && (bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
||||||
&& (bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
|
||||||
vdev_pt_write_vbar(vdev, offset, val);
|
vdev_pt_write_vbar(vdev, offset, val);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
@ -457,50 +452,60 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
|||||||
|
|
||||||
ASSERT(vdev->nr_bars > 0U, "vdev->nr_bars should be greater than 0!");
|
ASSERT(vdev->nr_bars > 0U, "vdev->nr_bars should be greater than 0!");
|
||||||
|
|
||||||
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
for (idx = 0U; idx < vdev->nr_bars; idx++) {
|
||||||
for (idx = 0U; idx < vdev->nr_bars; idx++) {
|
pbar = &vdev->pdev->bar[idx];
|
||||||
pbar = &vdev->pdev->bar[idx];
|
vbar = &vdev->bar[idx];
|
||||||
vbar = &vdev->bar[idx];
|
|
||||||
|
|
||||||
vbar->size = 0UL;
|
vbar->size = 0UL;
|
||||||
vbar->reg.value = pbar->reg.value;
|
vbar->reg.value = pbar->reg.value;
|
||||||
vbar->is_64bit_high = pbar->is_64bit_high;
|
vbar->is_64bit_high = pbar->is_64bit_high;
|
||||||
|
|
||||||
if (pbar->is_64bit_high) {
|
if (pbar->is_64bit_high) {
|
||||||
ASSERT(idx > 0U, "idx for upper 32-bit of the 64-bit bar should be greater than 0!");
|
ASSERT(idx > 0U, "idx for upper 32-bit of the 64-bit bar should be greater than 0!");
|
||||||
|
|
||||||
if (idx > 0U) {
|
if (is_sos_vm(vdev->vpci->vm)) {
|
||||||
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
/* For SOS: vbar base (GPA) = pbar base (HPA) */
|
||||||
vbar_base = vdev->ptdev_config->vbar_base[idx - 1U];
|
vbar_base = get_pbar_base(vdev->pdev, idx);
|
||||||
/* Write the upper 32-bit of a 64-bit bar */
|
} else if (idx > 0U) {
|
||||||
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)(vbar_base >> 32U));
|
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
||||||
}
|
vbar_base = vdev->ptdev_config->vbar_base[idx - 1U];
|
||||||
} else {
|
} else {
|
||||||
enum pci_bar_type type = pci_get_bar_type(pbar->reg.value);
|
vbar_base = 0UL;
|
||||||
|
}
|
||||||
|
/* Write the upper 32-bit of a 64-bit bar */
|
||||||
|
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)(vbar_base >> 32U));
|
||||||
|
} else {
|
||||||
|
enum pci_bar_type type = pci_get_bar_type(pbar->reg.value);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PCIBAR_MEM32:
|
case PCIBAR_MEM32:
|
||||||
case PCIBAR_MEM64:
|
case PCIBAR_MEM64:
|
||||||
/**
|
/**
|
||||||
* If vbar->base is 0 (unassigned), Linux kernel will reprogram the vbar on
|
* If vbar->base is 0 (unassigned), Linux kernel will reprogram the vbar on
|
||||||
* its bar size boundary, so in order to ensure the MMIO vbar allocated by guest
|
* its bar size boundary, so in order to ensure the MMIO vbar allocated by guest
|
||||||
* is 4k aligned, set its size to be 4K aligned.
|
* is 4k aligned, set its size to be 4K aligned.
|
||||||
*/
|
*/
|
||||||
vbar->size = round_page_up(pbar->size);
|
vbar->size = round_page_up(pbar->size);
|
||||||
|
|
||||||
|
if (is_sos_vm(vdev->vpci->vm)) {
|
||||||
|
/* For SOS: vbar base (GPA) = pbar base (HPA) */
|
||||||
|
vbar_base = get_pbar_base(vdev->pdev, idx);
|
||||||
|
} else {
|
||||||
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
||||||
vbar_base = vdev->ptdev_config->vbar_base[idx];
|
vbar_base = vdev->ptdev_config->vbar_base[idx];
|
||||||
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)vbar_base);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
vbar->reg.value = 0x0U;
|
|
||||||
vbar->size = 0UL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)vbar_base);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vbar->reg.value = 0x0U;
|
||||||
|
vbar->size = 0UL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
||||||
pci_command = (uint16_t)pci_pdev_read_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U);
|
pci_command = (uint16_t)pci_pdev_read_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U);
|
||||||
|
|
||||||
/* Disable INTX */
|
/* Disable INTX */
|
||||||
|
@ -436,10 +436,6 @@ static void init_vdev_for_pdev(struct pci_pdev *pdev, const struct acrn_vm *vm)
|
|||||||
*/
|
*/
|
||||||
init_vdev_pt(vdev);
|
init_vdev_pt(vdev);
|
||||||
|
|
||||||
if (has_msix_cap(vdev)) {
|
|
||||||
vdev_pt_remap_msix_table_bar(vdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For pre-launched VM, the host bridge is fully virtualized and it does not have a physical
|
* For pre-launched VM, the host bridge is fully virtualized and it does not have a physical
|
||||||
* host bridge counterpart.
|
* host bridge counterpart.
|
||||||
|
@ -116,7 +116,6 @@ int32_t vmsi_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, u
|
|||||||
void deinit_vmsi(const struct pci_vdev *vdev);
|
void deinit_vmsi(const struct pci_vdev *vdev);
|
||||||
|
|
||||||
void init_vmsix(struct pci_vdev *vdev);
|
void init_vmsix(struct pci_vdev *vdev);
|
||||||
void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev);
|
|
||||||
int32_t vmsix_table_mmio_access_handler(struct io_request *io_req, void *handler_private_data);
|
int32_t vmsix_table_mmio_access_handler(struct io_request *io_req, void *handler_private_data);
|
||||||
int32_t vmsix_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val);
|
int32_t vmsix_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val);
|
||||||
int32_t vmsix_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val);
|
int32_t vmsix_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val);
|
||||||
|
Loading…
Reference in New Issue
Block a user