mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-05 13:42:07 +00:00
HV: add support for PIO bar emulation
For PIO bar emulation, initially or when guest reprograms the PIO bar, allow guest access for the specified bar base address (pio port) and sized by calling vev_pt_allow_io_vbar For PIO bar emulation, just set the initial vbar base address equal to pbar base address. For example, if the pbar base address is 0x2000, then set the initial vbar base address also to 0x2000 Tracked-On: #3241 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
4be09f24f3
commit
148e747349
@ -30,6 +30,7 @@
|
||||
#include <errno.h>
|
||||
#include <ept.h>
|
||||
#include <mmu.h>
|
||||
#include <vmx.h>
|
||||
#include <logmsg.h>
|
||||
#include "vpci_priv.h"
|
||||
|
||||
@ -319,6 +320,33 @@ static void vdev_pt_remap_mem_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allow IO bar access
|
||||
* @pre vdev != NULL
|
||||
* @pre vdev->vpci != NULL
|
||||
* @pre vdev->vpci->vm != NULL
|
||||
*/
|
||||
static void vdev_pt_allow_io_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
{
|
||||
struct pci_bar *vbar;
|
||||
uint64_t vbar_base = get_vbar_base(vdev, idx); /* vbar (gpa) */
|
||||
|
||||
vbar = &vdev->bar[idx];
|
||||
|
||||
/* For SOS, all port IO access is allowed by default, so skip SOS here */
|
||||
if ((vdev->bar_base_mapped[idx] != vbar_base) && !is_sos_vm(vdev->vpci->vm)) {
|
||||
if (vdev->bar_base_mapped[idx] != 0UL) {
|
||||
deny_guest_pio_access(vdev->vpci->vm, (uint16_t)(vdev->bar_base_mapped[idx]),
|
||||
(uint32_t)(vbar->size));
|
||||
}
|
||||
|
||||
allow_guest_pio_access(vdev->vpci->vm, (uint16_t)vbar_base, (uint32_t)(vbar->size));
|
||||
|
||||
/* Remember the previously allowed IO vbar base */
|
||||
vdev->bar_base_mapped[idx] = vbar_base;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the base address portion of the vbar base address register (32-bit)
|
||||
* base: bar value with flags portion masked off
|
||||
@ -375,6 +403,15 @@ static void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t offset, uint32_t
|
||||
enum pci_bar_type type = pci_get_bar_type(vbar->reg.value);
|
||||
|
||||
switch (type) {
|
||||
case PCIBAR_IO_SPACE:
|
||||
base = git_size_masked_bar_base(vbar->size, (uint64_t)val) & 0xffffUL;
|
||||
set_vbar_base(vbar, (uint32_t)base);
|
||||
|
||||
if (bar_update_normal) {
|
||||
vdev_pt_allow_io_vbar(vdev, idx);
|
||||
}
|
||||
break;
|
||||
|
||||
case PCIBAR_MEM32:
|
||||
base = git_size_masked_bar_base(vbar->size, (uint64_t)val);
|
||||
set_vbar_base(vbar, (uint32_t)base);
|
||||
@ -497,9 +534,13 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
||||
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)vbar_base);
|
||||
break;
|
||||
|
||||
case PCIBAR_IO_SPACE:
|
||||
vbar->size = pbar->size;
|
||||
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)get_pbar_base(vdev->pdev, idx));
|
||||
break;
|
||||
|
||||
default:
|
||||
vbar->reg.value = 0x0U;
|
||||
vbar->size = 0UL;
|
||||
/* Nothing to do in this case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user