From 4b7f6284eaa3e3b15360e25848fc68b37ee6c768 Mon Sep 17 00:00:00 2001 From: zhaotianrui Date: Wed, 11 Jan 2023 11:56:03 -0500 Subject: [PATCH 3/4] Config some capabilities for loongarch virt machine Config some capabilities for loongarch virt machine such as PCI multi bus and the path of loongarch uefi binary. Signed-off-by: zhaotianrui --- src/qemu/qemu.conf | 3 +- src/qemu/qemu_capabilities.c | 4 ++ src/qemu/qemu_conf.c | 3 +- src/qemu/qemu_domain.c | 31 ++++++++++- src/qemu/qemu_domain.h | 1 + src/qemu/qemu_domain_address.c | 86 ++++++++++++++++++++++++++++++ src/qemu/test_libvirtd_qemu.aug.in | 1 + 7 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index abdbf07fec..3856087248 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -771,7 +771,8 @@ # "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd", # "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.fd", # "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd", -# "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd" +# "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd", +# "/usr/share/qemu/loongarch_bios.bin:/usr/share/qemu/loongarch_vars.bin" #] # The backend to use for handling stdout/stderr output from diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 0c3eb148b2..21b477cd4d 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1983,6 +1983,10 @@ bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps, * since forever */ if (ARCH_IS_SW64(def->os.arch)) return true; + /* loongarch64 support PCI-multibus on all machine types + * since forever */ + if (ARCH_IS_LOONGARCH(def->os.arch)) + return true; if (def->os.arch == VIR_ARCH_PPC || ARCH_IS_PPC64(def->os.arch)) { diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 28319a1baf..3253875d6e 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -98,7 +98,8 @@ qemuDriverUnlock(virQEMUDriverPtr driver) "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd:" \ "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.fd:" \ "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd:" \ - "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd" + "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd:" \ + "/usr/share/qemu/loongarch_bios.bin:/usr/share/qemu/loongarch_vars.bin" #endif diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 37dac3694b..152c8615d5 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5186,7 +5186,7 @@ qemuDomainDefValidateFeatures(const virDomainDef *def, switch ((virDomainFeature) i) { case VIR_DOMAIN_FEATURE_IOAPIC: if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) { - if (!ARCH_IS_X86(def->os.arch)) { + if (!ARCH_IS_X86(def->os.arch) && !ARCH_IS_LOONGARCH(def->os.arch)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("The '%s' feature is not supported for " "architecture '%s' or machine type '%s'"), @@ -9089,6 +9089,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDefPtr cont, cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; + } else if (ARCH_IS_LOONGARCH(def->os.arch)) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; + else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; } } /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ @@ -12985,6 +12990,20 @@ qemuDomainMachineIsPSeries(const char *machine, return false; } +static bool +qemuDomainMachineIsLoongson(const char *machine, + const virArch arch) +{ + if (!ARCH_IS_LOONGARCH(arch)) + return false; + + if (STREQ(machine, "loongson7a") || + STRPREFIX(machine, "loongson7a-")) { + return true; + } + + return false; +} /* You should normally avoid this function and use * qemuDomainHasBuiltinIDE() instead. */ @@ -12996,7 +13015,8 @@ qemuDomainMachineHasBuiltinIDE(const char *machine, STREQ(machine, "malta") || STREQ(machine, "sun4u") || STREQ(machine, "core3") || - STREQ(machine, "g3beige"); + STREQ(machine, "g3beige") || + STREQ(machine, "loongson7a"); } @@ -13066,6 +13086,13 @@ qemuDomainIsPSeries(const virDomainDef *def) } +bool +qemuDomainIsLoongson(const virDomainDef *def) +{ + return qemuDomainMachineIsLoongson(def->os.machine, def->os.arch); +} + + bool qemuDomainHasPCIRoot(const virDomainDef *def) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 7603724ccd..368fc4030f 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -999,6 +999,7 @@ bool qemuDomainIsS390CCW(const virDomainDef *def); bool qemuDomainIsARMVirt(const virDomainDef *def); bool qemuDomainIsRISCVVirt(const virDomainDef *def); bool qemuDomainIsPSeries(const virDomainDef *def); +bool qemuDomainIsLoongson(const virDomainDef *def); bool qemuDomainHasPCIRoot(const virDomainDef *def); bool qemuDomainHasPCIeRoot(const virDomainDef *def); bool qemuDomainHasBuiltinIDE(const virDomainDef *def); diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index ab6bce19f4..7f48773832 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2078,6 +2078,87 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, return 0; } +static int +qemuDomainValidateDevicePCISlotsLoongson(virDomainDefPtr def, + virQEMUCapsPtr qemuCaps, + virDomainPCIAddressSetPtr addrs) +{ + int ret = -1; + virPCIDeviceAddress tmp_addr; + bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); + g_autofree char *addrStr = NULL; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + + if (addrs->nbuses) { + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 1; + /* pci-ohci at 00:01.0 */ + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) + return -1; + } + + if (def->nvideos > 0 && + def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE && + def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_RAMFB) { + /* reserve slot 2 for vga device */ + virDomainVideoDefPtr primaryVideo = def->videos[0]; + + if (virDeviceInfoPCIAddressIsWanted(&primaryVideo->info)) { + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 2; + + if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr))) + return -1; + if (!virDomainPCIAddressValidate(addrs, &tmp_addr, + addrStr, flags, true)) + return ret; + + if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { + if (qemuDeviceVideoUsable) { + if (qemuDomainPCIAddressReserveNextAddr(addrs, + &primaryVideo->info) < 0) { + return ret; + } + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("PCI address 0:0:2.0 is in use, " + "QEMU needs it for primary video")); + return ret; + } + } else { + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) + return ret; + primaryVideo->info.addr.pci = tmp_addr; + primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + } + } else if (!qemuDeviceVideoUsable) { + if (primaryVideo->info.addr.pci.domain != 0 || + primaryVideo->info.addr.pci.bus != 0 || + primaryVideo->info.addr.pci.slot != 2 || + primaryVideo->info.addr.pci.function != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Primary video card must have PCI address 0:0:2.0")); + return ret; + } + /* If TYPE == PCI, then qemuDomainCollectPCIAddress() function + * has already reserved the address, so we must skip */ + } + } else if (addrs->nbuses && !qemuDeviceVideoUsable) { + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 2; + + if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { + VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a video" + " device will not be possible without manual" + " intervention"); + } else if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) { + return ret; + } + } + + ret = 0; + return ret; +} static int qemuDomainValidateDevicePCISlotsChipsets(virDomainDefPtr def, @@ -2094,6 +2175,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDefPtr def, return -1; } + if (qemuDomainIsLoongson(def) && + qemuDomainValidateDevicePCISlotsLoongson(def, qemuCaps, addrs) < 0) { + return -1; + } + return 0; } diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index 19da591aae..caa06a45cb 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -95,6 +95,7 @@ module Test_libvirtd_qemu = { "2" = "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.fd" } { "3" = "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd" } { "4" = "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd" } + { "5" = "/usr/share/qemu/loongarch_bios.bin:/usr/share/qemu/loongarch_vars.bin" } } { "stdio_handler" = "logd" } { "gluster_debug_level" = "9" } -- 2.25.1