* [PATCH] vfio-pci: add Ascend devices passthrough quirks
@ 2020-10-29 11:40 Binfeng Wu
2020-10-30 3:07 ` Alex Williamson
0 siblings, 1 reply; 2+ messages in thread
From: Binfeng Wu @ 2020-10-29 11:40 UTC (permalink / raw)
To: alex.williamson; +Cc: xieyingtai, qemu-devel, Binfeng Wu
Ascend is a series of SoC processors developed by Huawei. Ascend310/910
are highly efficient, flexible, and programmable AI processors in this
series and support device passthrough via vfio-pci. Ascends device
xloader update is only allowed in host, because update triggered by vm
users may affect other users when Ascend devices passthrough to vm.
Set a bar quirk is an effective method to keep vm users from updating
xloader. In this patch, two bar quirks were proposed to cover
Ascend310/910 respectively.
Signed-off-by: Binfeng Wu <wubinfeng@huawei.com>
---
hw/vfio/pci-quirks.c | 104 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 57150913b7..291a45d3ab 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1202,6 +1202,108 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
return 0;
}
+#define PCI_VENDOR_ID_HUAWEI 0x19e5
+#define PCI_DEVICE_ID_ASCEND910 0xd801
+#define PCI_DEVICE_ID_ASCEND310 0xd100
+#define ASCEND910_XLOADER_SIZE 4
+#define ASCEND910_XLOADER_OFFSET 0x80400
+#define ASCEND310_XLOADER_SIZE 4
+#define ASCEND310_XLOADER_OFFSET 0x400
+
+typedef struct VFIOAscendBarQuirk {
+ struct VFIOPCIDevice *vdev;
+ pcibus_t offset;
+ uint8_t bar;
+ MemoryRegion *mem;
+} VFIOAscendBarQuirk;
+
+static uint64_t vfio_ascend_quirk_read(void *opaque,
+ hwaddr addr, unsigned size)
+{
+ VFIOAscendBarQuirk *quirk = opaque;
+ VFIOPCIDevice *vdev = quirk->vdev;
+
+ return vfio_region_read(&vdev->bars[quirk->bar].region,
+ addr + quirk->offset, size);
+}
+
+static void vfio_ascend_quirk_write(void *opaque, hwaddr addr,
+ uint64_t data, unsigned size)
+{
+}
+
+static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = {
+ .read = vfio_ascend_quirk_read,
+ .write = vfio_ascend_quirk_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void vfio_probe_ascend_bar0_quirk(VFIOPCIDevice *vdev, int nr)
+{
+ VFIOQuirk *quirk;
+ VFIOAscendBarQuirk *bar0_quirk;
+
+ if (!vfio_pci_is(vdev, PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ASCEND910) ||
+ nr != 0) {
+ return;
+ }
+
+ quirk = g_malloc0(sizeof(*quirk));
+ quirk->nr_mem = 1;
+ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem);
+ bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem);
+ bar0_quirk[0].vdev = vdev;
+ bar0_quirk[0].offset = ASCEND910_XLOADER_OFFSET;
+ bar0_quirk[0].bar = nr;
+
+ /*
+ * intercept w/r to the xloader-updating register,
+ * so the vm can't enable xloader-updating
+ */
+ memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
+ &vfio_ascend_intercept_regs_quirk,
+ &bar0_quirk[0],
+ "vfio-ascend-bar0-intercept-regs-quirk",
+ ASCEND910_XLOADER_SIZE);
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
+ bar0_quirk[0].offset,
+ &quirk->mem[0], 1);
+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
+}
+
+static void vfio_probe_ascend_bar4_quirk(VFIOPCIDevice *vdev, int nr)
+{
+ VFIOQuirk *quirk;
+ VFIOAscendBarQuirk *bar4_quirk;
+
+ if (!vfio_pci_is(vdev, PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ASCEND310) ||
+ nr != 4) {
+ return;
+ }
+
+ quirk = g_malloc0(sizeof(*quirk));
+ quirk->nr_mem = 1;
+ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem);
+ bar4_quirk = quirk->data = g_new0(typeof(*bar4_quirk), quirk->nr_mem);
+ bar4_quirk[0].vdev = vdev;
+ bar4_quirk[0].offset = ASCEND310_XLOADER_OFFSET;
+ bar4_quirk[0].bar = nr;
+
+ /*
+ * intercept w/r to the xloader-updating register,
+ * so the vm can't enable xloader-updating
+ */
+ memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
+ &vfio_ascend_intercept_regs_quirk,
+ &bar4_quirk[0],
+ "vfio-ascend-bar4-intercept-regs-quirk",
+ ASCEND310_XLOADER_SIZE);
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
+ bar4_quirk[0].offset,
+ &quirk->mem[0], 1);
+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
+}
+
/*
* Common quirk probe entry points.
*/
@@ -1251,6 +1353,8 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
vfio_probe_nvidia_bar5_quirk(vdev, nr);
vfio_probe_nvidia_bar0_quirk(vdev, nr);
vfio_probe_rtl8168_bar2_quirk(vdev, nr);
+ vfio_probe_ascend_bar0_quirk(vdev, nr);
+ vfio_probe_ascend_bar4_quirk(vdev, nr);
#ifdef CONFIG_VFIO_IGD
vfio_probe_igd_bar4_quirk(vdev, nr);
#endif
--
2.26.2.windows.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] vfio-pci: add Ascend devices passthrough quirks
2020-10-29 11:40 [PATCH] vfio-pci: add Ascend devices passthrough quirks Binfeng Wu
@ 2020-10-30 3:07 ` Alex Williamson
0 siblings, 0 replies; 2+ messages in thread
From: Alex Williamson @ 2020-10-30 3:07 UTC (permalink / raw)
To: Binfeng Wu; +Cc: xieyingtai, qemu-devel
On Thu, 29 Oct 2020 19:40:48 +0800
Binfeng Wu <wubinfeng@huawei.com> wrote:
> Ascend is a series of SoC processors developed by Huawei. Ascend310/910
> are highly efficient, flexible, and programmable AI processors in this
> series and support device passthrough via vfio-pci. Ascends device
> xloader update is only allowed in host, because update triggered by vm
> users may affect other users when Ascend devices passthrough to vm.
> Set a bar quirk is an effective method to keep vm users from updating
> xloader. In this patch, two bar quirks were proposed to cover
> Ascend310/910 respectively.
If you're trying to say that userspace, not just a VM, should not be
able to update this feature, then is QEMU the right place to implement
this quirk versus device specific protection within the host kernel?
Thanks,
Alex
> Signed-off-by: Binfeng Wu <wubinfeng@huawei.com>
> ---
> hw/vfio/pci-quirks.c | 104 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 104 insertions(+)
>
> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
> index 57150913b7..291a45d3ab 100644
> --- a/hw/vfio/pci-quirks.c
> +++ b/hw/vfio/pci-quirks.c
> @@ -1202,6 +1202,108 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
> return 0;
> }
>
> +#define PCI_VENDOR_ID_HUAWEI 0x19e5
> +#define PCI_DEVICE_ID_ASCEND910 0xd801
> +#define PCI_DEVICE_ID_ASCEND310 0xd100
> +#define ASCEND910_XLOADER_SIZE 4
> +#define ASCEND910_XLOADER_OFFSET 0x80400
> +#define ASCEND310_XLOADER_SIZE 4
> +#define ASCEND310_XLOADER_OFFSET 0x400
> +
> +typedef struct VFIOAscendBarQuirk {
> + struct VFIOPCIDevice *vdev;
> + pcibus_t offset;
> + uint8_t bar;
> + MemoryRegion *mem;
> +} VFIOAscendBarQuirk;
> +
> +static uint64_t vfio_ascend_quirk_read(void *opaque,
> + hwaddr addr, unsigned size)
> +{
> + VFIOAscendBarQuirk *quirk = opaque;
> + VFIOPCIDevice *vdev = quirk->vdev;
> +
> + return vfio_region_read(&vdev->bars[quirk->bar].region,
> + addr + quirk->offset, size);
> +}
> +
> +static void vfio_ascend_quirk_write(void *opaque, hwaddr addr,
> + uint64_t data, unsigned size)
> +{
> +}
> +
> +static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = {
> + .read = vfio_ascend_quirk_read,
> + .write = vfio_ascend_quirk_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static void vfio_probe_ascend_bar0_quirk(VFIOPCIDevice *vdev, int nr)
> +{
> + VFIOQuirk *quirk;
> + VFIOAscendBarQuirk *bar0_quirk;
> +
> + if (!vfio_pci_is(vdev, PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ASCEND910) ||
> + nr != 0) {
> + return;
> + }
> +
> + quirk = g_malloc0(sizeof(*quirk));
> + quirk->nr_mem = 1;
> + quirk->mem = g_new0(MemoryRegion, quirk->nr_mem);
> + bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem);
> + bar0_quirk[0].vdev = vdev;
> + bar0_quirk[0].offset = ASCEND910_XLOADER_OFFSET;
> + bar0_quirk[0].bar = nr;
> +
> + /*
> + * intercept w/r to the xloader-updating register,
> + * so the vm can't enable xloader-updating
> + */
> + memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
> + &vfio_ascend_intercept_regs_quirk,
> + &bar0_quirk[0],
> + "vfio-ascend-bar0-intercept-regs-quirk",
> + ASCEND910_XLOADER_SIZE);
> + memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
> + bar0_quirk[0].offset,
> + &quirk->mem[0], 1);
> + QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
> +}
> +
> +static void vfio_probe_ascend_bar4_quirk(VFIOPCIDevice *vdev, int nr)
> +{
> + VFIOQuirk *quirk;
> + VFIOAscendBarQuirk *bar4_quirk;
> +
> + if (!vfio_pci_is(vdev, PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ASCEND310) ||
> + nr != 4) {
> + return;
> + }
> +
> + quirk = g_malloc0(sizeof(*quirk));
> + quirk->nr_mem = 1;
> + quirk->mem = g_new0(MemoryRegion, quirk->nr_mem);
> + bar4_quirk = quirk->data = g_new0(typeof(*bar4_quirk), quirk->nr_mem);
> + bar4_quirk[0].vdev = vdev;
> + bar4_quirk[0].offset = ASCEND310_XLOADER_OFFSET;
> + bar4_quirk[0].bar = nr;
> +
> + /*
> + * intercept w/r to the xloader-updating register,
> + * so the vm can't enable xloader-updating
> + */
> + memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
> + &vfio_ascend_intercept_regs_quirk,
> + &bar4_quirk[0],
> + "vfio-ascend-bar4-intercept-regs-quirk",
> + ASCEND310_XLOADER_SIZE);
> + memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
> + bar4_quirk[0].offset,
> + &quirk->mem[0], 1);
> + QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
> +}
> +
> /*
> * Common quirk probe entry points.
> */
> @@ -1251,6 +1353,8 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
> vfio_probe_nvidia_bar5_quirk(vdev, nr);
> vfio_probe_nvidia_bar0_quirk(vdev, nr);
> vfio_probe_rtl8168_bar2_quirk(vdev, nr);
> + vfio_probe_ascend_bar0_quirk(vdev, nr);
> + vfio_probe_ascend_bar4_quirk(vdev, nr);
> #ifdef CONFIG_VFIO_IGD
> vfio_probe_igd_bar4_quirk(vdev, nr);
> #endif
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-10-30 3:08 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-29 11:40 [PATCH] vfio-pci: add Ascend devices passthrough quirks Binfeng Wu
2020-10-30 3:07 ` Alex Williamson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).