From nobody Mon Nov 02 21:07:11 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4jJPR84T8Pz6yXmC for ; Mon, 02 Nov 2026 21:07:16 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jJPR832phz4tfP for ; Mon, 02 Nov 2026 21:07:16 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793653636; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=evETeDrn/4pfzpTaZ1gYK920pChduaWPcqHMAW0PTYY=; b=UoeZy89NDtT1nHETEc5PJvlNqSUIdaFgQ2W1NqPJJTv1ek1JCNoIBVdPAI6Z/w9b92FhZw jcAjfMH9RyueQSIFSfdg5NsxA0r5/ErDjDQdbEYwHZIVtykE1KECmiW/T2r6gAOHciYGQC EIB0OXyQO6zbqz5ijE9+tNZlp6Zh7jZRMejlgx16wARCohgHbeX/X5vPKrZ1Mp+gKZy+37 13Ix2ygrrCKuuY6YCfy5cQGnAruzJCaw4sL9agCZM8GZ0qUFt7sOfjdsQklLWY6cz7MoIz TmAAXmTLEQY+3OST7tMoAZe7Sk7cJmOWAWKnka+VvEDKgpNp5pJiVqxFODvsDA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793653636; b=qXjDWK55Gwikrx/Es90oU+kB4P2teMnl8eQ02S4dkn6uBoKB0uzviGfA1JIjc+qSoP26/k K1hYxanhL6eIIhzJiixSSbQkwrOy1ub6appYoMiro0vuCZG4IXKwKB/Rqjyfo7chbPfIMM 3fPieY395vrdvF+FHDFfv9p40h0rf8h0+epnXElzoXGLHZKe+muC5WfyYGmPQfjE/7lh9i V6tUCSsoYfSdoA6YHogUQ3a4qHQGF3uLtVWSwpQcCCmjKgiXyzDzhy1aGzcFzTLMevEOiS beKk9IJTXcttDqvSLdI8AGHcXSD+RsmWAda8M6DSlh+mAfYDWL9Ut7GWhIT9yg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793653636; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=evETeDrn/4pfzpTaZ1gYK920pChduaWPcqHMAW0PTYY=; b=D6M2Gbi7z0/yC0Z5OLi0ZVwJjKU6d8RkaEwZeZngfQwM5AD6QlwS4v9vaud2QuX0hRSptn Fhgnt8U27lr04AkuzqBPgvQ4NAvK6vZOCsHpSfmiNJy+bobf3gMwPAIPU3bmg7nsAt21ov 7qtTg0yLT/3vd5mGkeOseyBDbnosFeujtjMBMWePemi4wNAwK2GEdBa4QnIAhC+nZT3KXu l/Z2X/hYvb4Wn4W9/g3NztHrzr5r55i8sPjnYLgiQ6x4iI43XOZoiGW1sGCZzDNZr7Tz7/ 8COJduoLyrsugwjd+1Krgb1NXsURHmdx8LNxoaVZSfaGkUq36gPeQ+voGJApwA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4jJPR82Pxcz12cf for ; Mon, 02 Nov 2026 21:07:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3f2ac by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 02 Nov 2026 21:07:11 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Doongar Singh From: Ruslan Bukin Subject: git: ada1f577cc29 - main - bhyve/riscv: correctly handle empty masks and broadcast in SBI IPI/RFNC List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: Commit messages for the main branch of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: br X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ada1f577cc291336cbb69782075dbbf9fe746872 Auto-Submitted: auto-generated Date: Mon, 02 Nov 2026 21:07:11 +0000 Message-Id: <6ae8fb7f.3f2ac.6d484a47@gitrepo.freebsd.org> The branch main has been updated by br: URL: https://cgit.FreeBSD.org/src/commit/?id=ada1f577cc291336cbb69782075dbbf9fe746872 commit ada1f577cc291336cbb69782075dbbf9fe746872 Author: Doongar Singh AuthorDate: 2026-11-02 20:58:53 +0000 Commit: Ruslan Bukin CommitDate: 2026-11-02 21:05:46 +0000 bhyve/riscv: correctly handle empty masks and broadcast in SBI IPI/RFNC Bhyve treats an empty cpu set as an error which triggers MPASS panic in the guest. As per the SBI spec, empty masks should return SBI_SUCCESS, and a base of -1UL specifies a broadcast to all harts. Fix both in vmm_sbi.c, clear a1 on return, and skip the SBI ecall in sbi_ipi_pic_ipi_send() if the mask is empty. Also add a NULL check in riscv_send_ipi(). Signed-off-by: Doongar Singh Reviewed by: br Differential Revision: https://reviews.freebsd.org/D61126 --- sys/riscv/riscv/sbi_ipi.c | 2 ++ sys/riscv/vmm/vmm_riscv.c | 2 ++ sys/riscv/vmm/vmm_sbi.c | 71 ++++++++++++++++++++++++++++------------------- 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/sys/riscv/riscv/sbi_ipi.c b/sys/riscv/riscv/sbi_ipi.c index fac5c0c39b99..af1df948880b 100644 --- a/sys/riscv/riscv/sbi_ipi.c +++ b/sys/riscv/riscv/sbi_ipi.c @@ -74,6 +74,8 @@ sbi_ipi_pic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus, mask |= (1ul << pc->pc_hart); } } + if (mask == 0) + return; sbi_send_ipi(&mask); } diff --git a/sys/riscv/vmm/vmm_riscv.c b/sys/riscv/vmm/vmm_riscv.c index fe2ca5c07789..3798ab8b0ec8 100644 --- a/sys/riscv/vmm/vmm_riscv.c +++ b/sys/riscv/vmm/vmm_riscv.c @@ -548,6 +548,8 @@ riscv_send_ipi(struct hyp *hyp, cpuset_t *cpus) if (!CPU_ISSET(i, cpus)) continue; hypctx = hyp->ctx[i]; + if (hypctx == NULL) + continue; atomic_set_32(&hypctx->ipi_pending, 1); vcpu_notify_event(vm_vcpu(vm, i)); } diff --git a/sys/riscv/vmm/vmm_sbi.c b/sys/riscv/vmm/vmm_sbi.c index c1e6022097e3..85e336847916 100644 --- a/sys/riscv/vmm/vmm_sbi.c +++ b/sys/riscv/vmm/vmm_sbi.c @@ -52,7 +52,7 @@ vmm_sbi_handle_rfnc(struct vcpu *vcpu, struct hypctx *hypctx) struct hyp *hyp; uint16_t maxcpus; cpuset_t cpus; - int i; + u_int i; func_id = hypctx->guest_regs.hyp_a[6]; hart_mask = hypctx->guest_regs.hyp_a[0]; @@ -83,27 +83,29 @@ vmm_sbi_handle_rfnc(struct vcpu *vcpu, struct hypctx *hypctx) hyp = hypctx->hyp; active_cpus = vm_active_cpus(hyp->vm); maxcpus = vm_get_maxcpus(hyp->vm); - for (i = 0; i < maxcpus; i++) { - vcpu = vm_vcpu(hyp->vm, i); - if (vcpu == NULL) - continue; - if (hart_mask_base != -1UL) { - if (i < hart_mask_base) - continue; - if (!(hart_mask & (1UL << (i - hart_mask_base)))) - continue; - } - /* - * If either hart_mask_base or at least one hartid from - * hart_mask is not valid, then return error. - */ - if (!CPU_ISSET(i, &active_cpus)) + + if (hart_mask_base == (uint64_t)-1) { + CPU_COPY(&active_cpus, &cpus); + } else { + if (hart_mask == 0) + return (SBI_SUCCESS); + if (hart_mask_base >= maxcpus) return (SBI_ERR_INVALID_PARAM); - CPU_SET(i, &cpus); + + while (hart_mask != 0) { + i = ffsl(hart_mask) - 1; + hart_mask &= ~(1UL << i); + + if (hart_mask_base + i >= maxcpus) + return (SBI_ERR_INVALID_PARAM); + if (!CPU_ISSET(hart_mask_base + i, &active_cpus)) + return (SBI_ERR_INVALID_PARAM); + CPU_SET(hart_mask_base + i, &cpus); + } } if (CPU_EMPTY(&cpus)) - return (SBI_ERR_INVALID_PARAM); + return (SBI_SUCCESS); vmm_fence_add(hyp->vm, &cpus, &fence); @@ -138,9 +140,9 @@ vmm_sbi_handle_ipi(struct vcpu *vcpu, struct hypctx *hypctx) uint64_t hart_mask; uint64_t hart_mask_base; uint64_t func_id; + uint16_t maxcpus; cpuset_t cpus; - int hart_id; - int bit; + u_int i; func_id = hypctx->guest_regs.hyp_a[6]; hart_mask = hypctx->guest_regs.hyp_a[0]; @@ -151,18 +153,30 @@ vmm_sbi_handle_ipi(struct vcpu *vcpu, struct hypctx *hypctx) hyp = hypctx->hyp; active_cpus = vm_active_cpus(hyp->vm); + maxcpus = vm_get_maxcpus(hyp->vm); CPU_ZERO(&cpus); switch (func_id) { case SBI_IPI_SEND_IPI: - while ((bit = ffs(hart_mask))) { - hart_id = (bit - 1); - hart_mask &= ~(1u << hart_id); - if (hart_mask_base != -1) - hart_id += hart_mask_base; - if (!CPU_ISSET(hart_id, &active_cpus)) + if (hart_mask_base == (uint64_t)-1) { + CPU_COPY(&active_cpus, &cpus); + } else { + if (hart_mask == 0) + return (SBI_SUCCESS); + if (hart_mask_base >= maxcpus) return (SBI_ERR_INVALID_PARAM); - CPU_SET(hart_id, &cpus); + + while (hart_mask != 0) { + i = ffsl(hart_mask) - 1; + hart_mask &= ~(1UL << i); + + if (hart_mask_base + i >= maxcpus) + return (SBI_ERR_INVALID_PARAM); + if (!CPU_ISSET(hart_mask_base + i, + &active_cpus)) + return (SBI_ERR_INVALID_PARAM); + CPU_SET(hart_mask_base + i, &cpus); + } } break; default: @@ -171,7 +185,7 @@ vmm_sbi_handle_ipi(struct vcpu *vcpu, struct hypctx *hypctx) } if (CPU_EMPTY(&cpus)) - return (SBI_ERR_INVALID_PARAM); + return (SBI_SUCCESS); riscv_send_ipi(hyp, &cpus); @@ -214,6 +228,7 @@ vmm_sbi_ecall(struct vcpu *vcpu) } hypctx->guest_regs.hyp_a[0] = error; + hypctx->guest_regs.hyp_a[1] = 0; /* Request is handled in kernel mode. */ return (true);