From owner-dev-commits-src-all@freebsd.org Tue Feb 2 08:49:03 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 6436C52A34B; Tue, 2 Feb 2021 08:49:03 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DVJQ70kZmz4fVD; Tue, 2 Feb 2021 08:49:03 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id BDF9D3278; Tue, 2 Feb 2021 08:49:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1128n2BI066010; Tue, 2 Feb 2021 08:49:02 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1128n2DU066009; Tue, 2 Feb 2021 08:49:02 GMT (envelope-from git) Date: Tue, 2 Feb 2021 08:49:02 GMT Message-Id: <202102020849.1128n2DU066009@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Roger Pau Monné Subject: git: 5ea878684f6c - main - bhyve/ioapic: improve the tracking of IRR bit MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: royger X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5ea878684f6cfff4ad05186346ff3a4828d980ca Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Feb 2021 08:49:03 -0000 The branch main has been updated by royger: URL: https://cgit.FreeBSD.org/src/commit/?id=5ea878684f6cfff4ad05186346ff3a4828d980ca commit 5ea878684f6cfff4ad05186346ff3a4828d980ca Author: Roger Pau Monné AuthorDate: 2021-01-19 11:52:28 +0000 Commit: Roger Pau Monné CommitDate: 2021-02-02 08:47:00 +0000 bhyve/ioapic: improve the tracking of IRR bit One common method of EOI'ing an interrupt at the IO-APIC level is to switch the pin to edge triggering mode and then back into level mode. That would cause the IRR bit to be cleared and thus further interrupts to be injected. FreeBSD does indeed use that method if the IO-APIC EOI register is not supported. The bhyve IO-APIC emulation code didn't clear the IRR bit when doing that switch, and was also missing acknowledging the IRR state when trying to inject an interrupt in vioapic_send_intr. Reviewed by: grehan Differential revision: https://reviews.freebsd.org/D28238 --- sys/amd64/vmm/io/vioapic.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/sys/amd64/vmm/io/vioapic.c b/sys/amd64/vmm/io/vioapic.c index 941f7c7364bc..639c1b07eb08 100644 --- a/sys/amd64/vmm/io/vioapic.c +++ b/sys/amd64/vmm/io/vioapic.c @@ -122,8 +122,14 @@ vioapic_send_intr(struct vioapic *vioapic, int pin) phys = ((low & IOART_DESTMOD) == IOART_DESTPHY); delmode = low & IOART_DELMOD; level = low & IOART_TRGRLVL ? true : false; - if (level) + if (level) { + if ((low & IOART_REM_IRR) != 0) { + VIOAPIC_CTR1(vioapic, "ioapic pin%d: irr pending", + pin); + return; + } vioapic->rtbl[pin].reg |= IOART_REM_IRR; + } vector = low & IOART_INTVEC; dest = high >> APIC_ID_SHIFT; @@ -342,6 +348,16 @@ vioapic_write(struct vioapic *vioapic, int vcpuid, uint32_t addr, uint32_t data) vioapic->rtbl[pin].reg &= ~mask64 | RTBL_RO_BITS; vioapic->rtbl[pin].reg |= data64 & ~RTBL_RO_BITS; + /* + * Switching from level to edge triggering will clear the IRR + * bit. This is what FreeBSD will do in order to EOI an + * interrupt when the IO-APIC doesn't support targeted EOI (see + * _ioapic_eoi_source). + */ + if ((vioapic->rtbl[pin].reg & IOART_TRGRMOD) == IOART_TRGREDG && + (vioapic->rtbl[pin].reg & IOART_REM_IRR) != 0) + vioapic->rtbl[pin].reg &= ~IOART_REM_IRR; + VIOAPIC_CTR2(vioapic, "ioapic pin%d: redir table entry %#lx", pin, vioapic->rtbl[pin].reg); @@ -363,12 +379,10 @@ vioapic_write(struct vioapic *vioapic, int vcpuid, uint32_t addr, uint32_t data) /* * Generate an interrupt if the following conditions are met: - * - previous interrupt has been EOIed * - pin trigger mode is level * - pin level is asserted */ - if ((vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0 && - (vioapic->rtbl[pin].reg & IOART_TRGRMOD) == IOART_TRGRLVL && + if ((vioapic->rtbl[pin].reg & IOART_TRGRMOD) == IOART_TRGRLVL && (vioapic->rtbl[pin].acnt > 0)) { VIOAPIC_CTR2(vioapic, "ioapic pin%d: asserted at rtbl " "write, acnt %d", pin, vioapic->rtbl[pin].acnt);