diff mbox series

[v3,22/24] x86/hvm: enable NS16550-compatible UART emulator

Message ID 20250103-vuart-ns8250-v3-v1-22-c5d36b31d66c@ford.com (mailing list archive)
State New
Headers show
Series x86: introduce NS16550-compatible UART emulator | expand

Commit Message

Denis Mukhin via B4 Relay Jan. 4, 2025, 1:58 a.m. UTC
From: Denis Mukhin <dmukhin@ford.com>

Introduce new emulation flag for virtual UART on x86 and plumb it through
domain creation code so NS16550 emulator is enabled properly.

Virtual UART facility is enabled for HVM domains only. Enabling it for PVH
domains requires some work, as vPIC is not enabled in PVH.

Also, since feature is currently for debugging only, vUART facility is
controlled build-time only and globally for all HVM domains.

The toolstack cannot configure virtual UART yet.

Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
In PVH case, vUART asserts on vpic_irq_positive_edge() call while firing a
virtual IRQ to the guest OS:
[[
...
Assertion 'has_vpic(d)' failed at arch/x86/hvm/vpic.c:525
(XEN) [   28.984923] ----[ Xen-4.20-unstable  x86_64  debug=y  Not tainted ]----
(XEN) [   28.984925] CPU:    3
(XEN) [   28.984926] RIP:    e008:[<ffff82d0402d201a>] vpic_irq_positive_edge+0x98/0xc0
...
]]
---
---
 tools/ocaml/libs/xc/xenctrl.ml    |  1 +
 tools/ocaml/libs/xc/xenctrl.mli   |  1 +
 xen/arch/x86/domain.c             | 10 ++++++++++
 xen/arch/x86/include/asm/domain.h |  5 +++--
 xen/include/public/virtdev.h      |  6 ++++--
 5 files changed, 19 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
index 2690f9a92316b812ad3d3ff0e1c36823070adb4a..647239b3e55e88b00eb8e9773a5267894cbbae54 100644
--- a/tools/ocaml/libs/xc/xenctrl.ml
+++ b/tools/ocaml/libs/xc/xenctrl.ml
@@ -47,6 +47,7 @@  type x86_arch_emulation_flags =
   | X86_EMU_PIT
   | X86_EMU_USE_PIRQ
   | X86_EMU_VPCI
+  | X86_EMU_VUART
 
 type x86_arch_misc_flags =
   | X86_MSR_RELAXED
diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli
index febbe1f6ae3f10c5abe45eaa3c06a8a67d9ba268..4f5f64c786e83e8a0c3dd3cdb0460f7095de4a62 100644
--- a/tools/ocaml/libs/xc/xenctrl.mli
+++ b/tools/ocaml/libs/xc/xenctrl.mli
@@ -41,6 +41,7 @@  type x86_arch_emulation_flags =
   | X86_EMU_PIT
   | X86_EMU_USE_PIRQ
   | X86_EMU_VPCI
+  | X86_EMU_VUART
 
 type x86_arch_misc_flags =
   | X86_MSR_RELAXED
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 9669886ac95cbee27c9eb72b16386705b470e7b1..c1b15ddf664269ba63d0bcd8a974491a4ab3524f 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -752,6 +752,10 @@  static bool emulation_flags_ok(const struct domain *d, uint32_t emflags)
         if ( is_hardware_domain(d) &&
              emflags != (X86_EMU_VPCI | X86_EMU_LAPIC | X86_EMU_IOAPIC) )
             return false;
+
+        /* FIXME: remove once virtual UART is configurable via xl */
+        emflags &= ~XEN_X86_EMU_VUART;
+
         if ( !is_hardware_domain(d) &&
              xen_emflags_allowable(emflags) != XEN_X86_EMU_BASELINE &&
              emflags != X86_EMU_LAPIC )
@@ -804,6 +808,12 @@  int arch_domain_create(struct domain *d,
 
     emflags = config->arch.emulation_flags;
 
+    /* FIXME: enable virtual UART for all HVMs; must be configurable via xl */
+    if ( IS_ENABLED(CONFIG_HAS_VUART) && is_hvm_domain(d) )
+        emflags |= XEN_X86_EMU_VUART;
+    else
+        emflags &= ~XEN_X86_EMU_VUART;
+
     if ( is_hardware_domain(d) && is_pv_domain(d) )
         emflags |= XEN_X86_EMU_PIT;
 
diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h
index 2532616bca015d0aad9abc35e14948937ab39b8f..53d14881d94f888e72f7443159c1c278d15d05cb 100644
--- a/xen/arch/x86/include/asm/domain.h
+++ b/xen/arch/x86/include/asm/domain.h
@@ -485,7 +485,8 @@  struct arch_domain
 #define X86_EMU_VPCI     0
 #endif
 
-#define X86_EMU_PIT     XEN_X86_EMU_PIT
+#define X86_EMU_PIT      XEN_X86_EMU_PIT
+#define X86_EMU_VUART    XEN_X86_EMU_VUART
 
 /* This must match XEN_X86_EMU_ALL in xen.h */
 #define X86_EMU_ALL             (X86_EMU_LAPIC | X86_EMU_HPET |         \
@@ -493,7 +494,7 @@  struct arch_domain
                                  X86_EMU_IOAPIC | X86_EMU_PIC |         \
                                  X86_EMU_VGA | X86_EMU_IOMMU |          \
                                  X86_EMU_PIT | X86_EMU_USE_PIRQ |       \
-                                 X86_EMU_VPCI)
+                                 X86_EMU_VPCI | X86_EMU_VUART)
 
 #define has_vlapic(d)      (!!((d)->arch.emulation_flags & X86_EMU_LAPIC))
 #define has_vhpet(d)       (!!((d)->arch.emulation_flags & X86_EMU_HPET))
diff --git a/xen/include/public/virtdev.h b/xen/include/public/virtdev.h
index 36931e0d679cedadd4212f34142d7c3f00cd3389..bcc71b519310e58d6094fadded14a3e0ee6bfd7e 100644
--- a/xen/include/public/virtdev.h
+++ b/xen/include/public/virtdev.h
@@ -32,17 +32,19 @@  enum {
 #define XEN_X86_EMU_PIT             VIRTDEV_PIT
 #define XEN_X86_EMU_USE_PIRQ        VIRTDEV_PIRQ
 #define XEN_X86_EMU_VPCI            VIRTDEV_PCI
+#define XEN_X86_EMU_VUART           VIRTDEV_UART
 
 #define XEN_X86_EMU_ALL             (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET |  \
                                      XEN_X86_EMU_PM | XEN_X86_EMU_RTC |      \
                                      XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |  \
                                      XEN_X86_EMU_VGA | XEN_X86_EMU_IOMMU |   \
                                      XEN_X86_EMU_PIT | XEN_X86_EMU_USE_PIRQ |\
-                                     XEN_X86_EMU_VPCI)
+                                     XEN_X86_EMU_VPCI | XEN_X86_EMU_VUART)
 
 /* PIRQ (HVM) feature is user-selectable (libxl). */
 #define XEN_X86_EMU_OPTIONAL        (XEN_X86_EMU_VPCI | \
-                                     XEN_X86_EMU_USE_PIRQ)
+                                     XEN_X86_EMU_USE_PIRQ | \
+                                     XEN_X86_EMU_VUART)
 
 #define XEN_X86_EMU_BASELINE        xen_emflags_allowable(XEN_X86_EMU_ALL)