mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-13 12:59:45 +00:00
hv: vpci: handle the quirk part for pass through pci device cfg access in dm
There're some PCI devices need special handler for vendor-specical feature or capability CFG access. The Intel GPU is one of them. In order to keep the ACRN-HV clean, we want to throw the qurik part of PCI CFG asccess to DM to handle. To achieve this, we implement per-device policy base on whether it needs quirk handler for a VM: each device could configure as "quirk pass through device" or not. For a "quirk pass through device", we will handle the general part in HV and the quirk part in DM. For a non "quirk pass through device", we will handle all the part in HV. Tracked-On: #4371 Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
@@ -123,6 +123,28 @@ read_config(struct pci_device *phys_dev, long reg, int width)
|
||||
return temp;
|
||||
}
|
||||
|
||||
static int
|
||||
write_config(struct pci_device *phys_dev, long reg, int width, uint32_t data)
|
||||
{
|
||||
int temp = -1;
|
||||
|
||||
switch (width) {
|
||||
case 1:
|
||||
temp = pci_device_cfg_write_u8(phys_dev, data, reg);
|
||||
break;
|
||||
case 2:
|
||||
temp = pci_device_cfg_write_u16(phys_dev, data, reg);
|
||||
break;
|
||||
case 4:
|
||||
temp = pci_device_cfg_write_u32(phys_dev, data, reg);
|
||||
break;
|
||||
default:
|
||||
warnx("%s: invalid reg width", __func__);
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
static int
|
||||
cfginit_cap(struct vmctx *ctx, struct passthru_dev *ptdev)
|
||||
{
|
||||
@@ -515,8 +537,10 @@ passthru_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
||||
/* initialize the EPT mapping for passthrough GPU opregion */
|
||||
vm_map_ptdev_mmio(ctx, 0, 2, 0, GPU_OPREGION_GPA, GPU_OPREGION_SIZE, opregion_start_hpa);
|
||||
|
||||
pcidev.rsvd2[0] = GPU_GSM_GPA | (gsm_phys & ~PCIM_BDSM_GSM_MASK) ;
|
||||
pcidev.rsvd2[1] = GPU_OPREGION_GPA | (opregion_phys & ~PCIM_ASLS_OPREGION_MASK);
|
||||
pci_set_cfgdata32(dev, PCIR_BDSM, GPU_GSM_GPA | (gsm_phys & ~PCIM_BDSM_GSM_MASK));
|
||||
pci_set_cfgdata32(dev, PCIR_ASLS_CTL, GPU_OPREGION_GPA | (opregion_phys & ~PCIM_ASLS_OPREGION_MASK));
|
||||
|
||||
pcidev.type = QUIRK_PTDEV;
|
||||
}
|
||||
|
||||
pcidev.virt_bdf = PCI_BDF(dev->bus, dev->slot, dev->func);
|
||||
@@ -628,13 +652,27 @@ static int
|
||||
passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
|
||||
int coff, int bytes, uint32_t *rv)
|
||||
{
|
||||
return ~0;
|
||||
struct passthru_dev *ptdev = dev->arg;
|
||||
|
||||
if ((PCI_BDF(dev->bus, dev->slot, dev->func) == PCI_BDF_GPU) &&
|
||||
((coff == PCIR_BDSM) || (coff == PCIR_ASLS_CTL)))
|
||||
*rv = pci_get_cfgdata32(dev, coff);
|
||||
else
|
||||
*rv = read_config(ptdev->phys_dev, coff, bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
|
||||
int coff, int bytes, uint32_t val)
|
||||
{
|
||||
struct passthru_dev *ptdev = dev->arg;
|
||||
|
||||
if (!((PCI_BDF(dev->bus, dev->slot, dev->func) == PCI_BDF_GPU) &&
|
||||
((coff == PCIR_BDSM) || (coff == PCIR_ASLS_CTL))))
|
||||
write_config(ptdev->phys_dev, coff, bytes, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -154,8 +154,9 @@ struct vm_memmap {
|
||||
*
|
||||
*/
|
||||
struct acrn_assign_pcidev {
|
||||
/** reversed for externed compatibility */
|
||||
uint32_t rsvd1;
|
||||
#define QUIRK_PTDEV (1 << 0) /* We will only handle general part in HV, others in DM */
|
||||
/** the type of the the pass-through PCI device */
|
||||
uint32_t type;
|
||||
|
||||
/** virtual BDF# of the pass-through PCI device */
|
||||
uint16_t virt_bdf;
|
||||
|
Reference in New Issue
Block a user