From: dmukhin@xen.org
To: xen-devel@lists.xenproject.org
Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech,
jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com,
roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com
Subject: [PATCH v7 16/16] emul/ns16x50: implement IRQ emulation via vIOAPIC
Date: Mon, 8 Sep 2025 14:11:49 -0700 [thread overview]
Message-ID: <20250908211149.279143-17-dmukhin@ford.com> (raw)
In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com>
From: Denis Mukhin <dmukhin@ford.com>
PVH domains use vIOAPIC, not vPIC and NS16550 emulates ISA IRQs which cannot
be asserted on vIOAPIC.
{map,unmap}_domain_pirq_emuirq() infrastructure is modified by adding new
type of interrupt resources 'IRQ_EMU' which means 'emulated device IRQ'
(similarly to IRQ_MSI_EMU).
This is necessary to for IOAPIC emulation code to skip IRQ->PIRQ mapping
(vioapic_hwdom_map_gsi()) when guest OS unmasks vIOAPIC pin corresponding to
virtual device's IRQ.
Also, hvm_gsi_eoi() is modified to trigger assertion in hvm_gsi_deassert()
path for ISA IRQs.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes since v6:
- n/a
---
xen/arch/x86/hvm/vioapic.c | 10 ++++++++++
xen/arch/x86/include/asm/irq.h | 6 ++++++
xen/common/emul/vuart/ns16x50.c | 28 ++++++++++++++++++++++++++--
xen/drivers/passthrough/x86/hvm.c | 11 ++++++++++-
4 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 7c725f9e471f..6314874b64f7 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -177,6 +177,16 @@ static int vioapic_hwdom_map_gsi(unsigned int gsi, unsigned int trig,
ASSERT(is_hardware_domain(currd));
+ /*
+ * Interrupt is claimed by one of the platform virtual devices (e.g.
+ * NS16550); do nothing.
+ */
+ write_lock(&currd->event_lock);
+ ret = is_domain_emuirq_claimed(currd, gsi);
+ write_unlock(&currd->event_lock);
+ if ( ret )
+ return 0;
+
/* Interrupt has been unmasked, bind it now. */
ret = mp_register_gsi(gsi, trig, pol);
if ( ret == -EEXIST )
diff --git a/xen/arch/x86/include/asm/irq.h b/xen/arch/x86/include/asm/irq.h
index 8bffec3bbfee..bdbe700274e9 100644
--- a/xen/arch/x86/include/asm/irq.h
+++ b/xen/arch/x86/include/asm/irq.h
@@ -168,6 +168,11 @@ void free_domain_pirqs(struct domain *d);
int map_domain_emuirq_pirq(struct domain *d, int pirq, int emuirq);
int unmap_domain_pirq_emuirq(struct domain *d, int pirq);
+#define domain_emuirq_claim(d, irq) map_domain_emuirq_pirq(d, irq, IRQ_EMU)
+#define domain_emuirq_unclaim(d, irq) unmap_domain_pirq_emuirq(d, irq)
+#define is_domain_emuirq_claimed(d, irq) \
+ (domain_pirq_to_emuirq(d, irq) != IRQ_UNBOUND)
+
/* Evacuate interrupts assigned to CPUs not present in the CPU online map. */
void fixup_irqs(void);
void fixup_eoi(void);
@@ -221,6 +226,7 @@ void cleanup_domain_irq_mapping(struct domain *d);
#define IRQ_UNBOUND (-1)
#define IRQ_PT (-2)
#define IRQ_MSI_EMU (-3)
+#define IRQ_EMU (-4)
bool cpu_has_pending_apic_eoi(void);
diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index 6bd58ba5540b..081d2639aa7a 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -299,7 +299,7 @@ static void ns16x50_irq_assert(const struct vuart_ns16x50 *vdev)
if ( has_vpic(d) )
vector = hvm_isa_irq_assert(d, info->irq, vioapic_get_vector);
else if ( has_vioapic(d) )
- /* TODO */
+ vector = hvm_ioapic_assert(d, info->irq, false);
else
ASSERT_UNREACHABLE();
@@ -314,7 +314,7 @@ static void ns16x50_irq_deassert(const struct vuart_ns16x50 *vdev)
if ( has_vpic(d) )
hvm_isa_irq_deassert(d, info->irq);
else if ( has_vioapic(d) )
- /* TODO */
+ hvm_ioapic_deassert(d, info->irq);
else
ASSERT_UNREACHABLE();
@@ -806,6 +806,17 @@ static int ns16x50_init(void *arg)
return rc;
}
+ /* Claim virtual IRQ */
+ write_lock(&d->event_lock);
+ rc = domain_emuirq_claim(d, info->irq);
+ write_unlock(&d->event_lock);
+ if ( rc )
+ {
+ ns16x50_err(info, "virtual IRQ#%d: cannot claim: %d\n",
+ info->irq, rc);
+ return rc;
+ }
+
/* NB: report 115200 baud rate. */
vdev->regs[NS16X50_REGS_NUM + UART_DLL] = divisor & UINT8_MAX;
vdev->regs[NS16X50_REGS_NUM + UART_DLM] = (divisor >> 8) & UINT8_MAX;
@@ -822,9 +833,22 @@ static int ns16x50_init(void *arg)
static void cf_check ns16x50_deinit(void *arg)
{
struct vuart_ns16x50 *vdev = arg;
+ const struct vuart_info *info;
+ struct domain *d;
+ int rc;
ASSERT(vdev);
+ d = vdev->owner;
+ info = vdev->info;
+
+ write_lock(&d->event_lock);
+ rc = domain_emuirq_unclaim(d, info->irq);
+ write_unlock(&d->event_lock);
+ if ( rc )
+ ns16x50_err(vdev, "virtual IRQ#%d: cannot unclaim: %d\n",
+ info->irq, rc);
+
spin_lock(&vdev->lock);
ns16x50_fifo_tx_flush(vdev);
spin_unlock(&vdev->lock);
diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x86/hvm.c
index a2ca7e0e570c..20641194561f 100644
--- a/xen/drivers/passthrough/x86/hvm.c
+++ b/xen/drivers/passthrough/x86/hvm.c
@@ -922,7 +922,16 @@ static void __hvm_dpci_eoi(struct domain *d,
static void hvm_gsi_eoi(struct domain *d, unsigned int gsi)
{
- struct pirq *pirq = pirq_info(d, gsi);
+ struct pirq *pirq;
+
+ /* Check if GSI is claimed by one of the virtual devices. */
+ if ( is_domain_emuirq_claimed(d, gsi) )
+ {
+ hvm_gsi_deassert(d, gsi);
+ return;
+ }
+
+ pirq = pirq_info(d, gsi);
/* Check if GSI is actually mapped. */
if ( !pirq_dpci(pirq) )
--
2.51.0
prev parent reply other threads:[~2025-09-08 21:12 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-08 21:11 [PATCH v7 00/16] x86: introduce NS16550-compatible UART emulator dmukhin
2025-09-08 21:11 ` [PATCH v7 01/16] emul/vuart: introduce framework for UART emulators dmukhin
2025-09-10 7:57 ` Mykola Kvach
2025-09-13 18:09 ` dmukhin
2025-09-08 21:11 ` [PATCH v7 02/16] xen/8250-uart: update definitions dmukhin
2025-09-09 10:05 ` Jan Beulich
2025-09-09 19:42 ` dmukhin
2025-09-10 8:39 ` Mykola Kvach
2025-09-13 17:50 ` dmukhin
2025-09-08 21:11 ` [PATCH v7 03/16] emul/ns16x50: implement emulator stub dmukhin
2025-09-10 10:05 ` Mykola Kvach
2025-09-13 17:29 ` dmukhin
2025-11-14 5:19 ` dmukhin
2025-09-15 10:16 ` Mykola Kvach
2025-11-14 5:28 ` dmukhin
2025-09-08 21:11 ` [PATCH v7 04/16] emul/ns16x50: implement DLL/DLM registers dmukhin
2025-09-10 10:16 ` Mykola Kvach
2025-09-08 21:11 ` [PATCH v7 05/16] emul/ns16x50: implement SCR register dmukhin
2025-09-12 7:23 ` Mykola Kvach
2025-09-08 21:11 ` [PATCH v7 06/16] emul/ns16x50: implement IER/IIR registers dmukhin
2025-09-15 6:00 ` Mykola Kvach
2025-09-08 21:11 ` [PATCH v7 07/16] emul/ns16x50: implement LCR/LSR registers dmukhin
2025-09-15 6:00 ` Mykola Kvach
2025-09-08 21:11 ` [PATCH v7 08/16] emul/ns16x50: implement MCR/MSR registers dmukhin
2025-09-15 6:00 ` Mykola Kvach
2025-09-15 14:49 ` Jan Beulich
2025-09-16 8:00 ` Mykola Kvach
2025-09-16 14:13 ` Jan Beulich
2025-09-08 21:11 ` [PATCH v7 09/16] emul/ns16x50: implement RBR register dmukhin
2025-11-18 6:00 ` Mykola Kvach
2025-09-08 21:11 ` [PATCH v7 10/16] emul/ns16x50: implement THR register dmukhin
2025-11-18 6:00 ` Mykola Kvach
2026-05-14 23:23 ` dmukhin
2025-09-08 21:11 ` [PATCH v7 11/16] emul/ns16x50: implement FCR register (write-only) dmukhin
2025-11-18 6:00 ` Mykola Kvach
2025-09-08 21:11 ` [PATCH v7 12/16] emul/ns16550: implement dump_state() hook dmukhin
2025-11-18 6:00 ` Mykola Kvach
2026-05-14 23:35 ` dmukhin
2025-09-08 21:11 ` [PATCH v7 13/16] emul/ns16x50: add Kconfig options dmukhin
2025-11-18 6:00 ` Mykola Kvach
2025-09-08 21:11 ` [PATCH v7 14/16] x86/domain: enable per-domain I/O port bitmaps dmukhin
2025-11-18 6:00 ` Mykola Kvach
2026-05-14 23:52 ` dmukhin
2025-09-08 21:11 ` [PATCH v7 15/16] xen/domain: allocate d->irq_caps before arch-specific initialization dmukhin
2025-11-18 6:00 ` Mykola Kvach
2025-09-08 21:11 ` dmukhin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250908211149.279143-17-dmukhin@ford.com \
--to=dmukhin@xen.org \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=dmukhin@ford.com \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=michal.orzel@amd.com \
--cc=roger.pau@citrix.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.