aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2020-11-24 23:18:52 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2020-11-24 23:18:52 +0000
commit1925586e03bed086b78fda5d8d758912aea7ecc7 (patch)
tree8724060974d53d8848ede2155765b07a3e804c53 /sys
parent5f9740e3998a8a2bd0466e57cc4cce61abe1343c (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/include/vmm_dev.h3
-rw-r--r--sys/amd64/vmm/io/ppt.c23
-rw-r--r--sys/amd64/vmm/io/ppt.h1
-rw-r--r--sys/amd64/vmm/vmm_dev.c5
4 files changed, 32 insertions, 0 deletions
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
index 28ecd339bf864..e4204e759bf62 100644
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -301,6 +301,7 @@ enum {
IOCNUM_MAP_PPTDEV_MMIO = 42,
IOCNUM_PPTDEV_MSI = 43,
IOCNUM_PPTDEV_MSIX = 44,
+ IOCNUM_PPTDEV_DISABLE_MSIX = 45,
/* statistics */
IOCNUM_VM_STATS = 50,
@@ -413,6 +414,8 @@ enum {
_IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi)
#define VM_PPTDEV_MSIX \
_IOW('v', IOCNUM_PPTDEV_MSIX, struct vm_pptdev_msix)
+#define VM_PPTDEV_DISABLE_MSIX \
+ _IOW('v', IOCNUM_PPTDEV_DISABLE_MSIX, struct vm_pptdev)
#define VM_INJECT_NMI \
_IOW('v', IOCNUM_INJECT_NMI, struct vm_nmi)
#define VM_STATS \
diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c
index 547a14e6464e0..476dfcd91a07d 100644
--- a/sys/amd64/vmm/io/ppt.c
+++ b/sys/amd64/vmm/io/ppt.c
@@ -518,6 +518,10 @@ ppt_setup_msi(struct vm *vm, int vcpu, int bus, int slot, int func,
if (ppt->vm != vm) /* Make sure we own this device */
return (EBUSY);
+ /* Reject attempts to enable MSI while MSI-X is active. */
+ if (ppt->msix.num_msgs != 0 && numvec != 0)
+ return (EBUSY);
+
/* Free any allocated resources */
ppt_teardown_msi(ppt);
@@ -607,6 +611,10 @@ ppt_setup_msix(struct vm *vm, int vcpu, int bus, int slot, int func,
if (ppt->vm != vm) /* Make sure we own this device */
return (EBUSY);
+ /* Reject attempts to enable MSI-X while MSI is active. */
+ if (ppt->msi.num_msgs != 0)
+ return (EBUSY);
+
dinfo = device_get_ivars(ppt->dev);
if (!dinfo)
return (ENXIO);
@@ -700,3 +708,18 @@ ppt_setup_msix(struct vm *vm, int vcpu, int bus, int slot, int func,
return (0);
}
+
+int
+ppt_disable_msix(struct vm *vm, int bus, int slot, int func)
+{
+ struct pptdev *ppt;
+
+ ppt = ppt_find(bus, slot, func);
+ if (ppt == NULL)
+ return (ENOENT);
+ if (ppt->vm != vm) /* Make sure we own this device */
+ return (EBUSY);
+
+ ppt_teardown_msix(ppt);
+ return (0);
+}
diff --git a/sys/amd64/vmm/io/ppt.h b/sys/amd64/vmm/io/ppt.h
index df84130311675..223afb343e8c3 100644
--- a/sys/amd64/vmm/io/ppt.h
+++ b/sys/amd64/vmm/io/ppt.h
@@ -38,6 +38,7 @@ int ppt_setup_msi(struct vm *vm, int vcpu, int bus, int slot, int func,
uint64_t addr, uint64_t msg, int numvec);
int ppt_setup_msix(struct vm *vm, int vcpu, int bus, int slot, int func,
int idx, uint64_t addr, uint64_t msg, uint32_t vector_control);
+int ppt_disable_msix(struct vm *vm, int bus, int slot, int func);
int ppt_assigned_devices(struct vm *vm);
bool ppt_is_mmio(struct vm *vm, vm_paddr_t gpa);
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index eafe35bed56c4..da8c051016ecd 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -514,6 +514,11 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
pptmsix->addr, pptmsix->msg,
pptmsix->vector_control);
break;
+ case VM_PPTDEV_DISABLE_MSIX:
+ pptdev = (struct vm_pptdev *)data;
+ error = ppt_disable_msix(sc->vm, pptdev->bus, pptdev->slot,
+ pptdev->func);
+ break;
case VM_MAP_PPTDEV_MMIO:
pptmmio = (struct vm_pptdev_mmio *)data;
error = ppt_map_mmio(sc->vm, pptmmio->bus, pptmmio->slot,