From: lixianglai <lixianglai(a)loongson.cn>
Config some capabilities for loongarch virt machine such as
PCI multi bus.
Signed-off-by: lixianglai <lixianglai(a)loongson.cn>
---
src/qemu/qemu_capabilities.c | 5 ++++
src/qemu/qemu_domain.c | 28 +++++++++++++++++
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_domain_address.c | 55 ++++++++++++++++++++++++++++++++++
src/qemu/qemu_validate.c | 2 +-
5 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 118d3429c3..eb84c9da7d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2080,6 +2080,11 @@ bool virQEMUCapsHasPCIMultiBus(const virDomainDef *def)
return true;
}
+ /* loongarch64 support PCI-multibus on all machine types
+ * since forever */
+ if (ARCH_IS_LOONGARCH(def->os.arch))
+ return true;
+
return false;
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 00e38950b6..a8f04155a3 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5635,6 +5635,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *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 */
@@ -8924,6 +8929,22 @@ qemuDomainMachineIsPSeries(const char *machine,
}
+static bool
+qemuDomainMachineIsLoongson(const char *machine,
+ const virArch arch)
+{
+ if (!ARCH_IS_LOONGARCH(arch))
+ return false;
+
+ if (STREQ(machine, "virt") ||
+ STRPREFIX(machine, "virt-")) {
+ return true;
+ }
+
+ return false;
+}
+
+
static bool
qemuDomainMachineIsMipsMalta(const char *machine,
const virArch arch)
@@ -9017,6 +9038,13 @@ qemuDomainIsMipsMalta(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 1e56e50672..1bdbb9c549 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -827,6 +827,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 qemuDomainIsMipsMalta(const virDomainDef *def);
bool qemuDomainHasPCIRoot(const virDomainDef *def);
bool qemuDomainHasPCIeRoot(const virDomainDef *def);
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 099778b2a8..2a37853d56 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -2079,6 +2079,56 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDef *def,
}
+static int
+qemuDomainValidateDevicePCISlotsLoongson(virDomainDef *def,
+ virDomainPCIAddressSet *addrs)
+{
+ virPCIDeviceAddress tmp_addr;
+ 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 */
+ virDomainVideoDef *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 -1;
+
+ if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+ if (qemuDomainPCIAddressReserveNextAddr(addrs,
+ &primaryVideo->info) <
0) {
+ return -1;
+ }
+ } else {
+ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) <
0)
+ return -1;
+ primaryVideo->info.addr.pci = tmp_addr;
+ primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
static int
qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def,
virDomainPCIAddressSet *addrs)
@@ -2093,6 +2143,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def,
return -1;
}
+ if (qemuDomainIsLoongson(def) &&
+ qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) {
+ return -1;
+ }
+
return 0;
}
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index e475ad035e..498e76b1e7 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -100,7 +100,7 @@ qemuValidateDomainDefFeatures(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 '%1$s' feature is not supported
for architecture '%2$s' or machine type '%3$s'"),
featureName,
--
2.27.0