不同的操作系统修改QEMU的操作步骤不同,可直接参考表1直接跳转到对应的内容。
虚拟机操作系统 |
参考步骤 |
---|---|
openEuler 22.03 LTS x86 openEuler 20.03 LTS BC Linux 8.2 BC Linux 21.10 CULinux 3.0 Kylin V10 Arm Kylin V10 SP2 Kylin V10 SP3 UOS V20(1050e) UOS V20(1050u2e) |
|
CentOS 7.5(5.10.0) Tlinux3.1 |
|
Ubuntu 20.04 Ubuntu 22.04 veLinux 1.1 veLinux 1.1(5.10.200) |
|
veLinux 1.2 Debian10.8 Debian10.13 Debian11.8 |
|
Debian10(veLinux 1.3) |
yum install spice-server spice-server-devel -y
显示如下,表示安装成功。
Complete!
virsh version
Compiled against library: libvirt 7.0.0 Using library: libvirt 7.0.0 Using API: QEMU 7.0.0 Running hypervisor: QEMU 4.1.0
chmod +x ./qemu-4.1.0.tar.xz
tar -xf ./qemu-4.1.0.tar.xz
cd qemu-4.1.0/
增加如下加粗字体标注的代码并保存:
… #include "hw/nvram/fw_cfg.h" #include "pci.h" #include "trace.h" // ascend-patch begin #define PCI_VENDOR_ID_HUAWEI 0x19e5 #define PCI_DEVICE_ID_ASCEND910 0xd801 #define PCI_DEVICE_ID_ASCEND910_A2 0xd802 #define PCI_DEVICE_ID_ASCEND310P 0xd500 #define PCI_DEVICE_ID_ASCEND310B 0xd105 #define PCI_DEVICE_ID_ASCEND310 0xd100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN 0x100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX 0x10f #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN 0x110 #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX 0x11f #define ASCEND910_XLOADER_SIZE 4 #define ASCEND910_XLOADER_OFFSET 0x80400 #define ASCEND910_A2_XLOADER_SIZE 4 #define ASCEND910_A2_XLOADER_OFFSET 0x18208430 #define ASCEND310P_2P_BASE (128 * 1024 * 1024) #define ASCEND310P_1P_DEVNUM 1 #define ASCEND310P_2P_DEVNUM 2 #define ASCEND310P_XLOADER_SIZE 4 #define ASCEND310P_XLOADER_OFFSET 0x100430 #define ASCEND310B_XLOADER_SIZE 4 #define ASCEND310B_XLOADER_OFFSET 0x4430 #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; qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", addr + quirk->offset, size); 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) { VFIOAscendBarQuirk *quirk = opaque; qemu_log("modifying RO region is not allowed! addr=0x%" HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", addr + quirk->offset, data, 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_ascend910_a2_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND910_A2) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND910_A2_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend910_a2-bar2-intercept-regs-quirk", ASCEND910_A2_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar0_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || vdev->device_id != PCI_DEVICE_ID_ASCEND910) { 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-ascend910-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_ascend310p_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; int sub_device_id; int devnum = 0; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310P) { return; } sub_device_id = pci_get_word(vdev->pdev.config + PCI_SUBSYSTEM_ID); if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX) { devnum = ASCEND310P_1P_DEVNUM; } else if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX) { devnum = ASCEND310P_2P_DEVNUM; } if (devnum != ASCEND310P_1P_DEVNUM && devnum != ASCEND310P_2P_DEVNUM) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = devnum; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310P_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310p-bar2-1p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); if (devnum == ASCEND310P_2P_DEVNUM) { bar2_quirk[1].vdev = vdev; bar2_quirk[1].offset = (ASCEND310P_2P_BASE + ASCEND310P_XLOADER_OFFSET); bar2_quirk[1].bar = nr; memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_ascend_intercept_regs_quirk, &bar2_quirk[1], "vfio-ascend310p-bar2-2p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[1].offset, &quirk->mem[1], 1); } QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310b_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310B) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310B_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310b-bar2-intercept-regs-quirk", ASCEND310B_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar4_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || vdev->device_id != PCI_DEVICE_ID_ASCEND310) { 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-ascend310-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); } // ascend-patch end …
void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
{
vfio_probe_ati_bar4_quirk(vdev, nr);
vfio_probe_ati_bar2_quirk(vdev, nr);
vfio_probe_nvidia_bar5_quirk(vdev, nr);
vfio_probe_nvidia_bar0_quirk(vdev, nr);
// ascend-patch begin
vfio_probe_ascend910_a2_bar2_quirk(vdev, nr);
vfio_probe_ascend910_bar0_quirk(vdev, nr);
vfio_probe_ascend310p_bar2_quirk(vdev, nr);
vfio_probe_ascend310b_bar2_quirk(vdev, nr);
vfio_probe_ascend310_bar4_quirk(vdev, nr);
// ascend-patch end
vfio_probe_rtl8168_bar2_quirk(vdev, nr);
vfio_probe_igd_bar4_quirk(vdev, nr);
}…
执行如下命令,修改配置文件“./linux-user/syscall.c”的TARGET_NR_stime函数。
vi ./linux-user/syscall.c
#ifdef TARGET_NR_stime /* not on alpha */ case TARGET_NR_stime: { time_t host_time; if (get_user_sal(host_time, argl)) return -TARGET_EFAULT; struct timespec res; res.tv_sec = host_time; return get_errno(clock_settime(CLOCK_REALTIME, &res)); } #endif
vi ./configure
修改如下加粗字体的参数取值为“yes”并保存。
qom_cast_debug="yes" trace_backends="log" trace_file="trace" spice="yes" rbd="" smartcard="" libusb="" usb_redir="" opengl="" opengl_dmabuf="no" cpuid_h="no" avx2_opt=""
./configure --enable-kvm
make -j 64
make install
不同的OS回显信息不同,具体回显信息请以实际环境为准。
Redirecting to /bin/systemctl restart libvirtd.service
sudo systemctl disable apparmor
Compiled against library: libvirt 6.0.0 Using library: libvirt 6.0.0 Using API: QEMU 6.0.0 Running hypervisor: QEMU 4.1.0
yum install spice-server spice-server-devel -y
对于Tlinux3.1:还需执行yum install -y python3 perl
显示如下,表示安装成功。
Complete!
virsh version
Compiled against library: libvirt 7.0.0 Using library: libvirt 7.0.0 Using API: QEMU 7.0.0 Running hypervisor: QEMU 4.1.0
chmod +x ./qemu-5.2.0.tar.xz
tar -xf ./qemu-5.2.0.tar.xz
cd qemu-5.2.0/
增加如下加粗字体标注的代码并保存:
… #include "hw/nvram/fw_cfg.h" #include "pci.h" #include "trace.h" // ascend-patch begin #define PCI_VENDOR_ID_HUAWEI 0x19e5 #define PCI_DEVICE_ID_ASCEND910 0xd801 #define PCI_DEVICE_ID_ASCEND910_A2 0xd802 #define PCI_DEVICE_ID_ASCEND310P 0xd500 #define PCI_DEVICE_ID_ASCEND310B 0xd105 #define PCI_DEVICE_ID_ASCEND310 0xd100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN 0x100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX 0x10f #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN 0x110 #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX 0x11f #define ASCEND910_XLOADER_SIZE 4 #define ASCEND910_XLOADER_OFFSET 0x80400 #define ASCEND910_A2_XLOADER_SIZE 4 #define ASCEND910_A2_XLOADER_OFFSET 0x18208430 #define ASCEND310P_2P_BASE (128 * 1024 * 1024) #define ASCEND310P_1P_DEVNUM 1 #define ASCEND310P_2P_DEVNUM 2 #define ASCEND310P_XLOADER_SIZE 4 #define ASCEND310P_XLOADER_OFFSET 0x100430 #define ASCEND310B_XLOADER_SIZE 4 #define ASCEND310B_XLOADER_OFFSET 0x4430 #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; qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", addr + quirk->offset, size); 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) { VFIOAscendBarQuirk *quirk = opaque; qemu_log("modifying RO region is not allowed! addr=0x%" HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", addr + quirk->offset, data, 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_ascend910_a2_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND910_A2) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND910_A2_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend910_a2-bar2-intercept-regs-quirk", ASCEND910_A2_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar0_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || vdev->device_id != PCI_DEVICE_ID_ASCEND910) { 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-ascend910-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_ascend310p_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; int sub_device_id; int devnum = 0; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310P) { return; } sub_device_id = pci_get_word(vdev->pdev.config + PCI_SUBSYSTEM_ID); if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX) { devnum = ASCEND310P_1P_DEVNUM; } else if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX) { devnum = ASCEND310P_2P_DEVNUM; } if (devnum != ASCEND310P_1P_DEVNUM && devnum != ASCEND310P_2P_DEVNUM) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = devnum; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310P_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310p-bar2-1p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); if (devnum == ASCEND310P_2P_DEVNUM) { bar2_quirk[1].vdev = vdev; bar2_quirk[1].offset = (ASCEND310P_2P_BASE + ASCEND310P_XLOADER_OFFSET); bar2_quirk[1].bar = nr; memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_ascend_intercept_regs_quirk, &bar2_quirk[1], "vfio-ascend310p-bar2-2p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[1].offset, &quirk->mem[1], 1); } QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310b_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310B) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310B_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310b-bar2-intercept-regs-quirk", ASCEND310B_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar4_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || vdev->device_id != PCI_DEVICE_ID_ASCEND310) { 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-ascend310-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); } // ascend-patch end …
void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
{
vfio_probe_ati_bar4_quirk(vdev, nr);
vfio_probe_ati_bar2_quirk(vdev, nr);
vfio_probe_nvidia_bar5_quirk(vdev, nr);
vfio_probe_nvidia_bar0_quirk(vdev, nr);
// ascend-patch begin
vfio_probe_ascend910_a2_bar2_quirk(vdev, nr);
vfio_probe_ascend910_bar0_quirk(vdev, nr);
vfio_probe_ascend310p_bar2_quirk(vdev, nr);
vfio_probe_ascend310b_bar2_quirk(vdev, nr);
vfio_probe_ascend310_bar4_quirk(vdev, nr);
// ascend-patch end
vfio_probe_rtl8168_bar2_quirk(vdev, nr);
vfio_probe_igd_bar4_quirk(vdev, nr);
}…
#ifdef TARGET_NR_stime /* not on alpha */ case TARGET_NR_stime: { time_t host_time; if (get_user_sal(host_time, argl)) return -TARGET_EFAULT; struct timespec res; res.tv_sec = host_time; return get_errno(clock_settime(CLOCK_REALTIME, &res)); } #endif
增加如下加粗字体标注的内容并保存。
static void x86_cpu_realizefn(DeviceState *dev, Error **errp) { … if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { if (accel_uses_host_cpuid()) { uint32_t host_phys_bits = x86_host_phys_bits(); static bool warned; cpu->host_phys_bits = true; … } else { … } … }
vi ./linux-user/strace.c
增加如下加粗字体内容并保存。
#include "qemu/osdep.h" #include <sys/ipc.h> #include <sys/msg.h> #include <sys/sem.h> #include <sys/shm.h> #include <sys/select.h> #include <sys/mount.h> #include <arpa/inet.h> #include <netinet/tcp.h> #include <linux/if_packet.h> #include <linux/netlink.h> #include <linux/falloc.h> #include <sched.h> #include "qemu.h"
vi ./configure
修改如下加粗字体的参数取值为“yes”并保存。
qom_cast_debug="yes" trace_backends="log" trace_file="trace" spice="yes" rbd="" smartcard="" libusb="" usb_redir="" opengl="" opengl_dmabuf="no" cpuid_h="no" avx2_opt=""
yum install -y ninja-build libffi-devel unzip
显示如下,表示安装成功。
Complete!
./configure --enable-kvm
make -j 64
make install
不同的OS回显信息不同,具体回显信息请以实际环境为准。
Redirecting to /bin/systemctl restart libvirtd.service
sudo systemctl disable apparmor
Compiled against library: libvirt 6.0.0 Using library: libvirt 6.0.0 Using API: QEMU 6.0.0 Running hypervisor: QEMU 5.2.0
apt-get install -y ninja-build gcc pkg-config build-essential zlib1g-dev libglib2.0-dev libmount-dev libpixman-1-dev
apt-get install -y libusbredirhost-dev libusbredirhost1 libusbredirparser-dev libusbredirparser1 usbredirserver
apt-get install libspice-server-dev libspice-server1
Reading package lists... DoneBuilding dependency treeReading state information... Donelibspice-server1 is already the newest version (0.14.2-4ubuntu3.1).libspice-server1 set to manually installed.The following NEW packages will be installed: libspice-protocol-dev libspice-server-dev0 upgraded, 2 newly installed, 0 to remove and 263 not upgraded.Need to get 31.8 kB of archives.After this operation, 198 kB of additional disk space will be used.Get:1 http://ports.ubuntu.com/ubuntu-ports focal/main arm64 libspice-protocol-dev all 0.14.0-0ubuntu1 [21.5 kB]Get:2 http://ports.ubuntu.com/ubuntu-ports focal-updates/main arm64 libspice-server-dev arm64 0.14.2-4ubuntu3.1 [10.3 kB]Fetched 31.8 kB in 8s (3,903 B/s)Selecting previously unselected package libspice-protocol-dev.(Reading database ... 97326 files and directories currently installed.)Preparing to unpack .../libspice-protocol-dev_0.14.0-0ubuntu1_all.deb ...
virsh version
Compiled against library: libvirt 7.0.0 Using library: libvirt 7.0.0 Using API: QEMU 7.0.0 Running hypervisor: QEMU 4.1.0
对于Atlas 200T A2 Box16 异构子框,建议下载5.2.0版本的QEMU源码包。
chmod +x ./qemu-4.1.0.tar.xz
tar -xf ./qemu-4.1.0.tar.xz
cd qemu-4.1.0/
增加如下加粗字体标注的代码并保存:
… #include "hw/nvram/fw_cfg.h" #include "pci.h" #include "trace.h" // ascend-patch begin #define PCI_VENDOR_ID_HUAWEI 0x19e5 #define PCI_DEVICE_ID_ASCEND910 0xd801 #define PCI_DEVICE_ID_ASCEND910_A2 0xd802 #define PCI_DEVICE_ID_ASCEND310P 0xd500 #define PCI_DEVICE_ID_ASCEND310B 0xd105 #define PCI_DEVICE_ID_ASCEND310 0xd100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN 0x100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX 0x10f #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN 0x110 #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX 0x11f #define ASCEND910_XLOADER_SIZE 4 #define ASCEND910_XLOADER_OFFSET 0x80400 #define ASCEND910_A2_XLOADER_SIZE 4 #define ASCEND910_A2_XLOADER_OFFSET 0x18208430 #define ASCEND310P_2P_BASE (128 * 1024 * 1024) #define ASCEND310P_1P_DEVNUM 1 #define ASCEND310P_2P_DEVNUM 2 #define ASCEND310P_XLOADER_SIZE 4 #define ASCEND310P_XLOADER_OFFSET 0x100430 #define ASCEND310B_XLOADER_SIZE 4 #define ASCEND310B_XLOADER_OFFSET 0x4430 #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; qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", addr + quirk->offset, size); 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) { VFIOAscendBarQuirk *quirk = opaque; qemu_log("modifying RO region is not allowed! addr=0x%" HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", addr + quirk->offset, data, 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_ascend910_a2_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND910_A2) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND910_A2_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend910_a2-bar2-intercept-regs-quirk", ASCEND910_A2_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar0_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || vdev->device_id != PCI_DEVICE_ID_ASCEND910) { 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-ascend910-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_ascend310p_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; int sub_device_id; int devnum = 0; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310P) { return; } sub_device_id = pci_get_word(vdev->pdev.config + PCI_SUBSYSTEM_ID); if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX) { devnum = ASCEND310P_1P_DEVNUM; } else if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX) { devnum = ASCEND310P_2P_DEVNUM; } if (devnum != ASCEND310P_1P_DEVNUM && devnum != ASCEND310P_2P_DEVNUM) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = devnum; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310P_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310p-bar2-1p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); if (devnum == ASCEND310P_2P_DEVNUM) { bar2_quirk[1].vdev = vdev; bar2_quirk[1].offset = (ASCEND310P_2P_BASE + ASCEND310P_XLOADER_OFFSET); bar2_quirk[1].bar = nr; memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_ascend_intercept_regs_quirk, &bar2_quirk[1], "vfio-ascend310p-bar2-2p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[1].offset, &quirk->mem[1], 1); } QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310b_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310B) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310B_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310b-bar2-intercept-regs-quirk", ASCEND310B_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar4_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || vdev->device_id != PCI_DEVICE_ID_ASCEND310) { 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-ascend310-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); } // ascend-patch end …
void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
{
vfio_probe_ati_bar4_quirk(vdev, nr);
vfio_probe_ati_bar2_quirk(vdev, nr);
vfio_probe_nvidia_bar5_quirk(vdev, nr);
vfio_probe_nvidia_bar0_quirk(vdev, nr);
// ascend-patch begin
vfio_probe_ascend910_a2_bar2_quirk(vdev, nr);
vfio_probe_ascend910_bar0_quirk(vdev, nr);
vfio_probe_ascend310p_bar2_quirk(vdev, nr);
vfio_probe_ascend310b_bar2_quirk(vdev, nr);
vfio_probe_ascend310_bar4_quirk(vdev, nr);
// ascend-patch end
vfio_probe_rtl8168_bar2_quirk(vdev, nr);
vfio_probe_igd_bar4_quirk(vdev, nr);
}…
对于Atlas 800 训练服务器(型号:9000)/Atlas 800 训练服务器(型号:9010),请跳过此步骤。
vi ./linux-user/syscall.c
#ifdef TARGET_NR_stime /* not on alpha */ case TARGET_NR_stime: { time_t host_time; if (get_user_sal(host_time, argl)) return -TARGET_EFAULT; struct timespec res; res.tv_sec = host_time; return get_errno(clock_settime(CLOCK_REALTIME, &res)); } #endif
vi ./target/i386/cpu.c
增加如下加粗字体内容并保存。
static void x86_cpu_realizefn(DeviceState *dev, Error **errp) { … if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { if (accel_uses_host_cpuid()) { uint32_t host_phys_bits = x86_host_phys_bits(); static bool warned; cpu->host_phys_bits = true; … } else { … } … }
vi ./configure
修改如下加粗字体的参数取值为“yes”并保存。
qom_cast_debug="yes" trace_backends="log" trace_file="trace" spice="yes" rbd="" smartcard="" libusb="" usb_redir="" opengl="" opengl_dmabuf="no" cpuid_h="no" avx2_opt=""
./configure --enable-kvm
make -j 64
make install
不同的OS回显信息不同,具体回显信息请以实际环境为准。
Redirecting to /bin/systemctl restart libvirtd.service
sudo systemctl disable apparmor
Compiled against library: libvirt 6.0.0 Using library: libvirt 6.0.0 Using API: QEMU 6.0.0 Running hypervisor: QEMU 4.1.0
apt install -y make gcc pkg-config build-essential zlib1g-dev libglib2.0-dev libmount-dev libpixman-1-dev --allow-unauthenticated
apt install -y libusbredirhost1 libusbredirparser1
apt install libspice-server1 ninja*
Reading package lists... Done Building dependency tree... Done Reading state information... Done libspice-server1 is already the newest version (0.14.3-2.1). 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
virsh version
Compiled against library: libvirt 7.0.0 Using library: libvirt 7.0.0 Using API: QEMU 7.0.0 Running hypervisor: QEMU 4.1.0
chmod +x ./qemu-4.1.0.tar.xz
tar -xf ./qemu-4.1.0.tar.xz
cd qemu-4.1.0/
增加如下加粗字体标注的代码并保存:
… #include "hw/nvram/fw_cfg.h" #include "pci.h" #include "trace.h" // ascend-patch begin #define PCI_VENDOR_ID_HUAWEI 0x19e5 #define PCI_DEVICE_ID_ASCEND910 0xd801 #define PCI_DEVICE_ID_ASCEND910_A2 0xd802 #define PCI_DEVICE_ID_ASCEND310P 0xd500 #define PCI_DEVICE_ID_ASCEND310B 0xd105 #define PCI_DEVICE_ID_ASCEND310 0xd100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN 0x100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX 0x10f #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN 0x110 #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX 0x11f #define ASCEND910_XLOADER_SIZE 4 #define ASCEND910_XLOADER_OFFSET 0x80400 #define ASCEND910_A2_XLOADER_SIZE 4 #define ASCEND910_A2_XLOADER_OFFSET 0x18208430 #define ASCEND310P_2P_BASE (128 * 1024 * 1024) #define ASCEND310P_1P_DEVNUM 1 #define ASCEND310P_2P_DEVNUM 2 #define ASCEND310P_XLOADER_SIZE 4 #define ASCEND310P_XLOADER_OFFSET 0x100430 #define ASCEND310B_XLOADER_SIZE 4 #define ASCEND310B_XLOADER_OFFSET 0x4430 #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; qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", addr + quirk->offset, size); 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) { VFIOAscendBarQuirk *quirk = opaque; qemu_log("modifying RO region is not allowed! addr=0x%" HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", addr + quirk->offset, data, 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_ascend910_a2_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND910_A2) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND910_A2_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend910_a2-bar2-intercept-regs-quirk", ASCEND910_A2_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar0_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || vdev->device_id != PCI_DEVICE_ID_ASCEND910) { 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-ascend910-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_ascend310p_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; int sub_device_id; int devnum = 0; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310P) { return; } sub_device_id = pci_get_word(vdev->pdev.config + PCI_SUBSYSTEM_ID); if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX) { devnum = ASCEND310P_1P_DEVNUM; } else if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX) { devnum = ASCEND310P_2P_DEVNUM; } if (devnum != ASCEND310P_1P_DEVNUM && devnum != ASCEND310P_2P_DEVNUM) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = devnum; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310P_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310p-bar2-1p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); if (devnum == ASCEND310P_2P_DEVNUM) { bar2_quirk[1].vdev = vdev; bar2_quirk[1].offset = (ASCEND310P_2P_BASE + ASCEND310P_XLOADER_OFFSET); bar2_quirk[1].bar = nr; memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_ascend_intercept_regs_quirk, &bar2_quirk[1], "vfio-ascend310p-bar2-2p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[1].offset, &quirk->mem[1], 1); } QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310b_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310B) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310B_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310b-bar2-intercept-regs-quirk", ASCEND310B_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar4_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || vdev->device_id != PCI_DEVICE_ID_ASCEND310) { 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-ascend310-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); } // ascend-patch end …
void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
{
vfio_probe_ati_bar4_quirk(vdev, nr);
vfio_probe_ati_bar2_quirk(vdev, nr);
vfio_probe_nvidia_bar5_quirk(vdev, nr);
vfio_probe_nvidia_bar0_quirk(vdev, nr);
// ascend-patch begin
vfio_probe_ascend910_a2_bar2_quirk(vdev, nr);
vfio_probe_ascend910_bar0_quirk(vdev, nr);
vfio_probe_ascend310p_bar2_quirk(vdev, nr);
vfio_probe_ascend310b_bar2_quirk(vdev, nr);
vfio_probe_ascend310_bar4_quirk(vdev, nr);
// ascend-patch end
vfio_probe_rtl8168_bar2_quirk(vdev, nr);
vfio_probe_igd_bar4_quirk(vdev, nr);
}…
#ifdef TARGET_NR_stime /* not on alpha */ case TARGET_NR_stime: { time_t host_time; if (get_user_sal(host_time, argl)) return -TARGET_EFAULT; struct timespec res; res.tv_sec = host_time; return get_errno(clock_settime(CLOCK_REALTIME, &res)); } #endif
./configure --enable-kvm
make -j 64
make install
不同的OS回显信息不同,具体回显信息请以实际环境为准。
Redirecting to /bin/systemctl restart libvirtd.service
sudo systemctl disable apparmor
不同的OS回显信息不同,具体回显信息请以实际环境为准。
Synchronizing state of apparmor.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install disable apparmor Removed /etc/systemd/system/sysinit.target.wants/apparmor.service
若系统环境为Debian10.13/veLinux 1.2系统,可跳过此步骤。
Compiled against library: libvirt 6.0.0 Using library: libvirt 6.0.0 Using API: QEMU 6.0.0 Running hypervisor: QEMU 4.1.0
apt install -y make gcc pkg-config build-essential zlib1g-dev libglib2.0-dev libmount-dev libpixman-1-dev --allow-unauthenticated
apt install -y libusbredirhost1 libusbredirparser1
Reading package lists... Done Building dependency tree... Done Reading state information... Done libspice-server1 is already the newest version (0.14.3-2.1). 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
virsh version
Compiled against library: libvirt 7.0.0 Using library: libvirt 7.0.0 Using API: QEMU 7.0.0 Running hypervisor: QEMU 4.1.0
chmod +x ./qemu-8.1.0.tar.xz
tar -xf ./qemu-8.1.0.tar.xz
cd qemu-8.1.0/
增加如下加粗字体标注的代码并保存:
… #include "hw/nvram/fw_cfg.h" #include "pci.h" #include "trace.h" // ascend-patch begin #define PCI_VENDOR_ID_HUAWEI 0x19e5 #define PCI_DEVICE_ID_ASCEND910 0xd801 #define PCI_DEVICE_ID_ASCEND910_A2 0xd802 #define PCI_DEVICE_ID_ASCEND910_A3 0xd803 #define PCI_DEVICE_ID_ASCEND310P 0xd500 #define PCI_DEVICE_ID_ASCEND310B 0xd105 #define PCI_DEVICE_ID_ASCEND310 0xd100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN 0x100 #define PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX 0x10f #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN 0x110 #define PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX 0x11f #define ASCEND910_XLOADER_SIZE 4 #define ASCEND910_XLOADER_OFFSET 0x80400 #define ASCEND910_A2_XLOADER_SIZE 4 #define ASCEND910_A2_XLOADER_OFFSET 0x18208430 #define ASCEND910_A3_XLOADER_SIZE 4 #define ASCEND910_A3_XLOADER_OFFSET 0x18208430 #define ASCEND910_A3_FEATURE_SIZE 4 #define ASCEND910_A3_FEATURE_OFFSET 0x182085f8 #define ASCEND310P_2P_BASE (128 * 1024 * 1024) #define ASCEND310P_1P_DEVNUM 1 #define ASCEND310P_2P_DEVNUM 2 #define ASCEND310P_XLOADER_SIZE 4 #define ASCEND310P_XLOADER_OFFSET 0x100430 #define ASCEND310B_XLOADER_SIZE 4 #define ASCEND310B_XLOADER_OFFSET 0x4430 #define ASCEND310_XLOADER_SIZE 4 #define ASCEND310_XLOADER_OFFSET 0x400 enum { VFIO_ASCEND_TYPE_ERR = 0, VFIO_ASCEND_TYPE_XLOADER = 1, VFIO_ASCEND_TYPE_FEATURE = 2, }; enum { QIURK_READ_SIZE_1_BYTE = 1, QIURK_READ_SIZE_2_BYTE = 2, QIURK_READ_SIZE_4_BYTE = 4, }; typedef struct VFIOAscendBarQuirk { struct VFIOPCIDevice *vdev; pcibus_t offset; unsigned int flags; /* for normal NC */ int type; /* XLOADER or FEATURE or etc. */ uint8_t bar; MemoryRegion *mem; } VFIOAscendBarQuirk; static uint64_t vfio_ascend_quirk_read(void *opaque, hwaddr addr, unsigned size) { uint64_t value, off_value; const unsigned byte_size = 8; unsigned start = addr * byte_size, length_size = size * byte_size; VFIOAscendBarQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", addr + quirk->offset, size); switch (quirk->type) { case VFIO_ASCEND_TYPE_XLOADER: value = vfio_region_read(&vdev->bars[quirk->bar].region, addr + quirk->offset, size); break; case VFIO_ASCEND_TYPE_FEATURE: switch (size) { case QIURK_READ_SIZE_1_BYTE: case QIURK_READ_SIZE_2_BYTE: case QIURK_READ_SIZE_4_BYTE: off_value = ((uint64_t)quirk->flags >> start) & ((1UL << length_size) - 1); return le64_to_cpu(off_value); default: qemu_log("Ascend quirk unsupported read size, %d bytes\n", size); return 0; } default: qemu_log("read RO region error type! addr=0x%" HWADDR_PRIx ", size=%d\n", addr + quirk->offset, size); return 0; } return value; } static void vfio_ascend_quirk_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { VFIOAscendBarQuirk *quirk = opaque; qemu_log("modifying RO region is not allowed! addr=0x%" HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", addr + quirk->offset, data, size); } static unsigned int vfio_ascend_get_region_flags(VFIOPCIDevice *vdev, int nr) { int ret = 0; unsigned int flags; VFIODevice *vbasedev = &vdev->vbasedev; struct vfio_region_info *reg_info; ret = vfio_get_region_info(vbasedev, nr, ®_info); if (ret != 0) { qemu_log("Ascend failed to get region %d info\n", nr); return 0; } flags = reg_info->flags; g_free(reg_info); return flags; } static unsigned int vfio_ascend_get_all_regions_flags(VFIOPCIDevice *vdev) { int i = 0; unsigned int flag = 0, flags = 0; for (i = VFIO_PCI_BAR0_REGION_INDEX; i < VFIO_PCI_ROM_REGION_INDEX; i++) { flag = vfio_ascend_get_region_flags(vdev, i); if (flag & VFIO_REGION_INFO_FLAG_NORMAL_NC) { flags |= (1 << i); } } return flags; } static void vfio_ascend_set_bar_quirk_array(VFIOAscendBarQuirk *bar_quirk, VFIOPCIDevice *vdev, int index, pcibus_t offset, unsigned int flags, int type, uint8_t bar) { bar_quirk[index].vdev = vdev; bar_quirk[index].offset = offset; bar_quirk[index].flags = flags; bar_quirk[index].type = type; bar_quirk[index].bar = bar; } 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_ascend910_a2_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND910_A2) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND910_A2_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend910_a2-bar2-intercept-regs-quirk", ASCEND910_A2_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend910_a3_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; const int quirk_region_num = 2; /* XLOADER and FEATURE */ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND910_A3) { return; } quirk = vfio_quirk_alloc(quirk_region_num); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); vfio_ascend_set_bar_quirk_array(bar2_quirk, vdev, 0, ASCEND910_A3_XLOADER_OFFSET, 0, VFIO_ASCEND_TYPE_XLOADER, 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, &bar2_quirk[0], "vfio-ascend910_a3-bar2-intercept-regs-quirk", ASCEND910_A3_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); /* 910_A3 FEATURE */ vfio_ascend_set_bar_quirk_array(bar2_quirk, vdev, 1, ASCEND910_A3_FEATURE_OFFSET, vfio_ascend_get_all_regions_flags(vdev), VFIO_ASCEND_TYPE_FEATURE, nr); memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_ascend_intercept_regs_quirk, &bar2_quirk[1], "vfio-ascend910_a3-bar2-feature-regs-quirk", ASCEND910_A3_FEATURE_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[1].offset, &quirk->mem[1], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar0_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || vdev->device_id != PCI_DEVICE_ID_ASCEND910) { 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-ascend910-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_ascend310p_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; int sub_device_id; int devnum = 0; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310P) { return; } sub_device_id = pci_get_word(vdev->pdev.config + PCI_SUBSYSTEM_ID); if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_1P_MAX) { devnum = ASCEND310P_1P_DEVNUM; } else if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MIN && sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND310P_2P_MAX) { devnum = ASCEND310P_2P_DEVNUM; } if (devnum != ASCEND310P_1P_DEVNUM && devnum != ASCEND310P_2P_DEVNUM) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = devnum; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310P_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310p-bar2-1p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); if (devnum == ASCEND310P_2P_DEVNUM) { bar2_quirk[1].vdev = vdev; bar2_quirk[1].offset = (ASCEND310P_2P_BASE + ASCEND310P_XLOADER_OFFSET); bar2_quirk[1].bar = nr; memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_ascend_intercept_regs_quirk, &bar2_quirk[1], "vfio-ascend310p-bar2-2p-intercept-regs-quirk", ASCEND310P_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[1].offset, &quirk->mem[1], 1); } QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310b_bar2_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar2_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || vdev->device_id != PCI_DEVICE_ID_ASCEND310B) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->nr_mem = 1; quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); bar2_quirk[0].vdev = vdev; bar2_quirk[0].offset = ASCEND310B_XLOADER_OFFSET; bar2_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, &bar2_quirk[0], "vfio-ascend310b-bar2-intercept-regs-quirk", ASCEND310B_XLOADER_SIZE); memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, bar2_quirk[0].offset, &quirk->mem[0], 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); } static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOAscendBarQuirk *bar4_quirk; if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || vdev->device_id != PCI_DEVICE_ID_ASCEND310) { 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-ascend310-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); } // ascend-patch end …
void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
{
vfio_probe_ati_bar4_quirk(vdev, nr);
vfio_probe_ati_bar2_quirk(vdev, nr);
vfio_probe_nvidia_bar5_quirk(vdev, nr);
vfio_probe_nvidia_bar0_quirk(vdev, nr);
// ascend-patch begin
vfio_probe_ascend910_a2_bar2_quirk(vdev, nr);
vfio_probe_ascend910_a3_bar2_quirk(vdev, nr);
vfio_probe_ascend910_bar0_quirk(vdev, nr);
vfio_probe_ascend310p_bar2_quirk(vdev, nr);
vfio_probe_ascend310b_bar2_quirk(vdev, nr);
vfio_probe_ascend310_bar4_quirk(vdev, nr);
// ascend-patch end
#ifdef CONFIG_VFIO_IGD
vfio_probe_igd_bar4_quirk(vdev, nr);
#endif
}…
vi ./linux-headers/linux/vfio.h
增加如下加粗字体标注的代码并保存。
struct vfio_region_info { __u32 argsz; __u32 flags; #define VFIO_REGION_INFO_FLAG_READ (1 << 0) /* Region supports read */ #define VFIO_REGION_INFO_FLAG_WRITE (1 << 1) /* Region supports write */ #define VFIO_REGION_INFO_FLAG_MMAP (1 << 2) /* Region supports mmap */ #define VFIO_REGION_INFO_FLAG_CAPS (1 << 3) /* Info supports caps */ #define VFIO_REGION_INFO_FLAG_NORMAL_NC (1 << 4) /* Region supports normal NC */ __u32 index; /* Region index */ __u32 cap_offset; /* Offset within info struct of first cap */ __u64 size; /* Region size (bytes) */ __u64 offset; /* Region offset from start of device fd */ };
修改extended_memmap数组定义,加粗字体由512修改至2048后保存。
static MemMapEntry extended_memmap[] = { /* Additional 64 MB redist region (can contain up to 512 redistributors) */ [VIRT_HIGH_GIC_REDIST2] = { 0x0, 64 * MiB }, [VIRT_HIGH_PCIE_ECAM] = { 0x0, 256 * MiB }, /* Second PCIe window */ [VIRT_HIGH_PCIE_MMIO] = { 0x0, 2048 * GiB },
./configure --enable-kvm --enable-numa
make -j 64
make install
修改虚拟机msix中断个数,如下加粗字体标注的内容。
#max_processes = 0 max_files = 8192