git: 0340fb032881 - main - vmm: Skip TMR rebuilds for edge-to-edge IOAPIC writes

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 02 Nov 2026 16:27:16 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=0340fb03288166091a8cdf694f5fed20e4c4f9ac

commit 0340fb03288166091a8cdf694f5fed20e4c4f9ac
Author:     Hayzam Sherif <hayzam@gmail.com>
AuthorDate: 2026-11-02 16:21:36 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-11-02 16:26:57 +0000

    vmm: Skip TMR rebuilds for edge-to-edge IOAPIC writes
    
    IOAPIC redirection-table writes rendezvous all active vCPUs to
    rebuild their vlapic trigger-mode registers when fields other than
    mask or polarity change. Retargeting an edge-triggered pin incurs
    this cost even though it does not contribute to the TMR.
    
    vioapic_update_tmr() rebuilds the TMR from level-triggered entries
    only. Skip the rendezvous when the modified entry is edge-triggered
    both before and after the write. Check the old and new trigger modes
    so that edge-to-level and level-to-edge transitions still rebuild
    the TMR. Retain the existing all-vCPU rebuild path, mask/polarity
    exclusions and remote-IRR handling.
    
    Reported by:    Wanpeng Qian <wanpengqian@gmail.com>
    Reviewed by:    Wanpeng Qian <wanpengqian@gmail.com>, markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D60721
---
 sys/amd64/vmm/io/vioapic.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/sys/amd64/vmm/io/vioapic.c b/sys/amd64/vmm/io/vioapic.c
index a3956785d049..e48f8ba66bcf 100644
--- a/sys/amd64/vmm/io/vioapic.c
+++ b/sys/amd64/vmm/io/vioapic.c
@@ -370,12 +370,14 @@ vioapic_write(struct vioapic *vioapic, struct vcpu *vcpu, uint32_t addr,
 		    pin, vioapic->rtbl[pin].reg);
 
 		/*
-		 * If any fields in the redirection table entry (except mask
-		 * or polarity) have changed then rendezvous all the vcpus
-		 * to update their vlapic trigger-mode registers.
+		 * Only level-triggered pins contribute to the TMR. If fields
+		 * other than mask or polarity changed and the pin was or is
+		 * level-triggered, rendezvous all the vcpus to update their
+		 * vlapic trigger-mode registers.
 		 */
 		changed = last ^ vioapic->rtbl[pin].reg;
-		if (changed & ~(IOART_INTMASK | IOART_INTPOL)) {
+		if ((changed & ~(IOART_INTMASK | IOART_INTPOL)) != 0 &&
+		    ((last | vioapic->rtbl[pin].reg) & IOART_TRGRLVL) != 0) {
 			VIOAPIC_CTR1(vioapic, "ioapic pin%d: recalculate "
 			    "vlapic trigger-mode register", pin);
 			VIOAPIC_UNLOCK(vioapic);