[libvirt] [PATCH] qemu: Introduce 16550A serial console model

Andrea Bolognani abologna at redhat.com
Mon Aug 27 12:10:18 UTC 2018


None of the existing models is suitable for use with
RISC-V virt guests, and we don't want information about
the serial console to be missing from the XML.

The name is based on comments in qemu/hw/riscv/virt.c:

  RISC-V machine with 16550a UART and VirtIO MMIO

and in qemu/hw/char/serial.c:

  QEMU 16550A UART emulation

along with the output of dmesg in the guest:

  Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
  10000000.uart: ttyS0 at MMIO 0x10000000 (irq = 13,
    base_baud= 230400) is a 16550A

Signed-off-by: Andrea Bolognani <abologna at redhat.com>
---
CC'ing Rich mostly so that he can double-check the name
choice is sensible.

 docs/formatdomain.html.in                 | 12 +++++-----
 docs/schemas/domaincommon.rng             |  1 +
 src/conf/domain_conf.c                    |  1 +
 src/conf/domain_conf.h                    |  1 +
 src/qemu/qemu_command.c                   | 12 ++++++++++
 src/qemu/qemu_domain.c                    | 27 ++++++++++++++++-------
 tests/qemuxml2xmloutdata/riscv64-virt.xml |  4 +++-
 7 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0cbf570a13..eb619a1656 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -7011,7 +7011,8 @@ qemu-kvm -net nic,model=? /dev/null
       is available) and <code>pci-serial</code> (usable whenever PCI support
       is available); <span class="since">since 3.10.0</span>,
       <code>spapr-vio-serial</code> (usable with ppc64/pseries guests),
-      <code>system-serial</code> (usable with aarch64/virt guests) and
+      <code>system-serial</code> (usable with aarch64/virt and,
+      <span class="since">since 4.7.0</span>, riscv/virt guests) and
       <code>sclp-serial</code> (usable with s390 and s390x guests) are
       available as well.
     </p>
@@ -7025,10 +7026,11 @@ qemu-kvm -net nic,model=? /dev/null
       target type); <code>pci-serial</code>
       (usable with the <code>pci-serial</code> target type);
       <code>spapr-vty</code> (usable with the <code>spapr-vio-serial</code>
-      target type); <code>pl011</code> (usable with the
-      <code>system-serial</code> target type); <code>sclpconsole</code> and
-      <code>sclplmconsole</code> (usable with the <code>sclp-serial</code>
-      target type).
+      target type); <code>pl011</code> and,
+      <span class="since">since 4.7.0</span>, <code>16550a</code> (usable
+      with the <code>system-serial</code> target type);
+      <code>sclpconsole</code> and <code>sclplmconsole</code> (usable with
+      the <code>sclp-serial</code> target type).
     </p>
 
     <p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f176538195..3796eb4b5e 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3733,6 +3733,7 @@
           <value>pci-serial</value>
           <value>spapr-vty</value>
           <value>pl011</value>
+          <value>16550a</value>
           <value>sclpconsole</value>
           <value>sclplmconsole</value>
         </choice>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index bde9fef914..8af59bb4bb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -493,6 +493,7 @@ VIR_ENUM_IMPL(virDomainChrSerialTargetModel,
               "pl011",
               "sclpconsole",
               "sclplmconsole",
+              "16550a",
 );
 
 VIR_ENUM_IMPL(virDomainChrDevice, VIR_DOMAIN_CHR_DEVICE_TYPE_LAST,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index c0ad072db5..8a3673361a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1133,6 +1133,7 @@ typedef enum {
     VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011,
     VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE,
     VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE,
+    VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A,
 
     VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST
 } virDomainChrSerialTargetModel;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fd9e58fd5d..f63e35444e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9149,6 +9149,7 @@ qemuChrSerialTargetModelToCaps(virDomainChrSerialTargetModel targetModel)
         return QEMU_CAPS_DEVICE_SCLPLMCONSOLE;
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011:
         return QEMU_CAPS_DEVICE_PL011;
+    case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A:
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE:
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST:
         break;
@@ -9189,6 +9190,16 @@ qemuChrIsPlatformDevice(const virDomainDef *def,
         }
     }
 
+    if (ARCH_IS_RISCV(def->os.arch)) {
+
+        /* 16550a (used by riscv/virt guests) is a platform device */
+        if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
+            chr->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM &&
+            chr->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A) {
+            return true;
+        }
+    }
+
     /* If we got all the way here and we're still stuck with the default
      * target type for a serial device, it means we have no clue what kind of
      * device we're talking about and we must treat it as a platform device. */
@@ -10579,6 +10590,7 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
         break;
 
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011:
+    case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A:
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE:
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST:
         /* Except from _LAST, which is just a guard value and will never
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 886e3fbb72..1cc4cefbd1 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4183,6 +4183,7 @@ qemuDomainChrSerialTargetModelToTargetType(int targetModel)
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY:
         return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO;
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011:
+    case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A:
         return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM;
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE:
     case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE:
@@ -4248,6 +4249,7 @@ qemuDomainChrTargetDefValidate(const virDomainChrDef *chr)
         case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011:
         case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE:
         case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE:
+        case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A:
 
             expected = qemuDomainChrSerialTargetModelToTargetType(chr->targetModel);
 
@@ -4298,18 +4300,23 @@ qemuDomainChrDefValidate(const virDomainChrDef *dev,
     if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
         bool isCompatible = true;
 
+        if (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM) {
+            if (dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011 &&
+                !qemuDomainIsARMVirt(def)) {
+                isCompatible = false;
+            }
+            if (dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A &&
+                !qemuDomainIsRISCVVirt(def)) {
+                isCompatible = false;
+            }
+        }
+
         if (!qemuDomainIsPSeries(def) &&
             (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO ||
              dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY)) {
             isCompatible = false;
         }
 
-        if (!qemuDomainIsARMVirt(def) &&
-            (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM ||
-             dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011)) {
-            isCompatible = false;
-        }
-
         if (!ARCH_IS_S390(def->os.arch) &&
             (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP ||
              dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE ||
@@ -6129,7 +6136,7 @@ qemuDomainChrDefPostParse(virDomainChrDefPtr chr,
             chr->targetType = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA;
         } else if (qemuDomainIsPSeries(def)) {
             chr->targetType = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO;
-        } else if (qemuDomainIsARMVirt(def)) {
+        } else if (qemuDomainIsARMVirt(def) || qemuDomainIsRISCVVirt(def)) {
             chr->targetType = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM;
         } else if (ARCH_IS_S390(def->os.arch)) {
             chr->targetType = VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP;
@@ -6153,7 +6160,11 @@ qemuDomainChrDefPostParse(virDomainChrDefPtr chr,
             chr->targetModel = VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY;
             break;
         case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM:
-            chr->targetModel = VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011;
+            if (qemuDomainIsARMVirt(def)) {
+                chr->targetModel = VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011;
+            } else if (qemuDomainIsRISCVVirt(def)) {
+                chr->targetModel = VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A;
+            }
             break;
         case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP:
             chr->targetModel = VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE;
diff --git a/tests/qemuxml2xmloutdata/riscv64-virt.xml b/tests/qemuxml2xmloutdata/riscv64-virt.xml
index 822a59a604..daf9ca4978 100644
--- a/tests/qemuxml2xmloutdata/riscv64-virt.xml
+++ b/tests/qemuxml2xmloutdata/riscv64-virt.xml
@@ -24,7 +24,9 @@
     </disk>
     <controller type='usb' index='0'/>
     <serial type='pty'>
-      <target port='0'/>
+      <target type='system-serial' port='0'>
+        <model name='16550a'/>
+      </target>
     </serial>
     <console type='pty'>
       <target type='serial' port='0'/>
-- 
2.17.1




More information about the libvir-list mailing list