hv: inject #GP if guest tries to reprogram pass-thru dev PIO bar

In current design, when pass-thru dev,
for the PIO bar, need to ensure the guest PIO start address
equals to host PIO start address.

But malicious guest may reprogram the PIO bar,
then hv will pass-thru the reprogramed PIO address to guest.
This isn't safe behavior.
When guest tries to reprogram pass-thru dev PIO bar,
inject #GP to guest directly.

Tracked-On: #6508

Signed-off-by: Liu,Junming <junming.liu@intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
This commit is contained in:
Liu,Junming 2021-09-23 16:59:50 +00:00 committed by wenlingz
parent 4105ca2cb4
commit 545c006a33

View File

@ -30,6 +30,7 @@
#include <asm/guest/vm.h>
#include "vpci_priv.h"
#include <asm/guest/ept.h>
#include <asm/guest/virq.h>
#include <logmsg.h>
#include <hash.h>
@ -132,8 +133,26 @@ static void pci_vdev_update_vbar_base(struct pci_vdev *vdev, uint32_t idx)
}
}
if ( (base != 0UL) && (!is_pci_io_bar(vbar))) {
if ((!is_pci_mem_bar_base_valid(vpci2vm(vdev->vpci), base)) || (!mem_aligned_check(base, vdev->vbars[idx].size))) {
if (base != 0UL) {
if (is_pci_io_bar(vbar)) {
/*
* ACRN-DM and acrn-config should ensure the identical mapping of PIO bar of pass-thru devs.
* Currently, we don't support the reprogram of PIO bar of pass-thru devs,
* If guest tries to reprogram, hv will inject #GP to guest.
*/
if ((vdev->pdev != NULL) && ((lo & PCI_BASE_ADDRESS_IO_MASK) != vbar->base_hpa)) {
struct acrn_vcpu *vcpu = vcpu_from_pid(vpci2vm(vdev->vpci), get_pcpu_id());
if (vcpu != NULL) {
vcpu_inject_gp(vcpu, 0U);
}
pr_err("%s, PCI:%02x:%02x.%x PIO BAR%d couldn't be reprogramed, "
"the valid value is 0x%lx, but the actual value is 0x%lx",
__func__, vdev->bdf.bits.b, vdev->bdf.bits.d, vdev->bdf.bits.f, idx,
vdev->vbars[idx].base_hpa, lo & PCI_BASE_ADDRESS_IO_MASK);
base = 0UL;
}
} else if ((!is_pci_mem_bar_base_valid(vpci2vm(vdev->vpci), base))
|| (!mem_aligned_check(base, vdev->vbars[idx].size))) {
res = (base < (1UL << 32UL)) ? &(vdev->vpci->res32): &(vdev->vpci->res64);
/* VM tries to reprogram vbar address out of pci mmio bar window, it can be caused by:
* 1. For SOS, <board>.xml is misaligned with the actual native platform, and we get wrong mmio window.