From nobody Fri Oct 09 22:13:46 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 4j1h2z1Jbtz6w9Nd for ; Fri, 09 Oct 2026 22:13:47 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j1h2z0pj9z4P8V for ; Fri, 09 Oct 2026 22:13:47 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791584027; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=wFQLzmM3MCDyYtCQPKwcI/ds4zkx1ceqPLRYwa3B9SI=; b=Soaf8gnMhK7YdXE2zwenf1cVqYEP4nc5CJODj6tITrK4LCaYN1ecyYglPofA4UOdJahyaC cxPD/D+S/Izcg+sfxlKsMBVjfaxoJzOKNTjQwdyg7phvccIlEEC0YzZtDKVQYd7MS3drQu oHMOyGvXda+D9vkHfZrlDgeddw09DfzEOuwc9QSQ/UUBEuR3yBRYdbknGxb5Ks8IHZZ5W1 Q3/S+uaOMnQ/s/PlzJnlkUESwvCWPKt3CyH2oTEFEC4IXQhADPN+dcX5d4HprG0FkmW8SY Tc3/hKUuvRUHQUErwcbQv+wKpmaup64I5W5rt7cGnVCjIRHu38JpjDkMHsiljw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791584027; b=FRAYAVkncjiMKSKVKkp6WzUHnnbIoh8GCSjWfxR+rtQ+lH3p9kisQfVrsDU6edd7vSbGfT AZ2RcJyiTfvC0IVqOPvfSnfVUglzuYuqJ5lddGyO9GwgHan3eVMiDe0m9MC8ewD6icqOMt ic4blTDWGzz87Dzg8UuAEh33O+sm/B1PYjviGDQ/GEMx2fXSmYAyTXzYst4TZnQJIp0cCY TLEQVeLVedEa0aexOsXJSqQQeGvX7m1MYfUPw0CyWxMQVt4Hi7QvoIbb+DCUCiWEni3tRZ zEhiUbJ++VPzCE5LvAOQQotBBQy6OAUi2iocXomhFc0/sHYD/rvQt2cntITiJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791584027; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=wFQLzmM3MCDyYtCQPKwcI/ds4zkx1ceqPLRYwa3B9SI=; b=UX6kx/EvL6xMd1liJy9zdY67C4pLXlmgIihHRmaFNhtf7pfP+ctC5TVF/i6ecY9MQb34/v rd88DR0EYgWEyFAxFzIPYym31C+gz6tw/hJFnyFMqZ7ukWJyeXLAmfNKwmkuWVE1TMbpu5 +xZ6hQnHOoqh7PKNoxqYqkXPl/rLfjj/kuypE3esQmeJVpekcUCgNa7tOyiin0j994zFVV LTLxWBnHLspzIiq7Hcp6hYeOixMPPdlPtKgH+JqsbzRH8ly15lOArPW3nK/ZpdB7db30cf ah8u9NBzuAO8WwnksLegxpxJp1YS5pkwcUyT/sN/3laRx6bRPG3YSgzo1vkaTA== 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 4j1h2y70PRzSjg for ; Fri, 09 Oct 2026 22:13:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3e7fc by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 09 Oct 2026 22:13:46 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: ShengYi Hung Subject: git: 5b1f1fd62435 - main - hyperv: Fix single page invalidation path 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: 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: aokblast X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5b1f1fd624352840cd9666447ff9cdebeaf910d4 Auto-Submitted: auto-generated Date: Fri, 09 Oct 2026 22:13:46 +0000 Message-Id: <6ac9671a.3e7fc.58e302e0@gitrepo.freebsd.org> The branch main has been updated by aokblast: URL: https://cgit.FreeBSD.org/src/commit/?id=5b1f1fd624352840cd9666447ff9cdebeaf910d4 commit 5b1f1fd624352840cd9666447ff9cdebeaf910d4 Author: ShengYi Hung AuthorDate: 2026-10-05 19:58:06 +0000 Commit: ShengYi Hung CommitDate: 2026-10-09 22:13:31 +0000 hyperv: Fix single page invalidation path A single page invalidation sets addr2 == 0. In the original code, it falsely flush the whole address in non global pmap. However, the kernel pmap are all PG_G, which means a single page flush will always be staled and thus become invalid. As a result, we set parameter based on their op in a new helper function instead of relying on args. This affects only on AMD platform as Intel has their PTI implementation. PR: 291577 Tested by: franco@opnsense.org MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D60380 --- sys/dev/hyperv/vmbus/hyperv_mmu.c | 82 ++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/sys/dev/hyperv/vmbus/hyperv_mmu.c b/sys/dev/hyperv/vmbus/hyperv_mmu.c index 8e982974161c..0a75a5b070b6 100644 --- a/sys/dev/hyperv/vmbus/hyperv_mmu.c +++ b/sys/dev/hyperv/vmbus/hyperv_mmu.c @@ -83,6 +83,39 @@ static inline int fill_gva_list(uint64_t gva_list[], return gva_n; } +static void +hv_tlb_flush_params(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, + enum invl_op_codes op, uint64_t *addr_space, uint64_t *flags, + vm_offset_t *start, vm_offset_t *end) +{ + switch (op) { + case INVL_OP_TLB: + case INVL_OP_TLB_PCID: + case INVL_OP_TLB_INVPCID_PTI: + case INVL_OP_TLB_INVPCID: + *start = *end = 0; + break; + case INVL_OP_PG: + case INVL_OP_PG_INVPCID: + case INVL_OP_PG_PCID: + *start = addr1; + *end = addr1 + PAGE_SIZE; + break; + default: + *start = addr1; + *end = addr2; + break; + } + if (pmap == kernel_pmap || *end == 0) { + *addr_space = 0; + *flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES; + } else { + *addr_space = pmap->pm_cr3 & ~CR3_PCID_MASK; + *flags = 0; + } + if (*end == 0 && pmap != kernel_pmap) + *flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY; +} inline int hv_cpumask_to_vpset(struct hv_vpset *vpset, const cpuset_t *cpus, struct vmbus_softc * sc) @@ -135,7 +168,7 @@ hv_vm_tlb_flush(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, int cpu, vcpu; int max_gvas, gva_n; uint64_t status = 0; - uint64_t cr3; + vm_offset_t start, end; /* * Hyper-V doesn't handle the invalidating cache. Let system handle it. @@ -178,18 +211,9 @@ hv_vm_tlb_flush(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, ("hv_tlb_flush: interrupts disabled")); critical_enter(); flush->processor_mask = 0; - cr3 = pmap->pm_cr3; - - if (op == INVL_OP_TLB || op == INVL_OP_TLB_INVPCID || - op == INVL_OP_TLB_INVPCID_PTI || op == INVL_OP_TLB_PCID) { - flush->address_space = 0; - flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES; - } else { - flush->address_space = cr3; - flush->address_space &= ~CR3_PCID_MASK; - flush->flags = 0; - } + hv_tlb_flush_params(pmap, addr1, addr2, op, &flush->address_space, + &flush->flags, &start, &end); if(CPU_CMP(&mask, &all_cpus) == 0) { flush->flags |= HV_FLUSH_ALL_PROCESSORS; } else { @@ -207,19 +231,14 @@ hv_vm_tlb_flush(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, goto native; } max_gvas = (PAGE_SIZE - sizeof(*flush)) / sizeof(flush->gva_list[0]); - if (addr2 == 0) { - flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY; - status = hypercall_do_md(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE, - (uint64_t)flush, (uint64_t)NULL); - } else if ((addr2 && (addr2 -addr1)/HV_TLB_FLUSH_UNIT) > max_gvas) { + if (end == 0 || (end - start) / HV_TLB_FLUSH_UNIT > max_gvas) { status = hypercall_do_md(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE, (uint64_t)flush, (uint64_t)NULL); } else { - gva_n = fill_gva_list(flush->gva_list, addr1, addr2); + gva_n = fill_gva_list(flush->gva_list, start, end); status = hv_do_rep_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST, gva_n, 0, (uint64_t)flush, (uint64_t)NULL); - } if(status) goto native; @@ -256,22 +275,13 @@ hv_flush_tlb_others_ex(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, return EINVAL; flush = *VMBUS_PCPU_PTR(sc, cpu_mem, curcpu); uint64_t status = 0; - uint64_t cr3; + vm_offset_t start, end; if (!(hyperv_recommends & HYPERV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) return EINVAL; - cr3 = pmap->pm_cr3; - if (op == INVL_OP_TLB) { - flush->address_space = 0; - flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES; - } else { - - flush->address_space = cr3; - flush->address_space &= ~CR3_PCID_MASK; - flush->flags = 0; - } - + hv_tlb_flush_params(pmap, addr1, addr2, op, &flush->address_space, + &flush->flags, &start, &end); flush->hv_vp_set.valid_bank_mask = 0; flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K; @@ -287,19 +297,13 @@ hv_flush_tlb_others_ex(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, sizeof(flush->hv_vp_set.bank_contents[0])) / sizeof(flush->hv_vp_set.bank_contents[0]); - if (addr2 == 0) { - flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY; - status = hv_do_rep_hypercall( - HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX, - 0, nr_bank, (uint64_t)flush, (uint64_t)NULL); - } else if (addr2 && - ((addr2 - addr1)/HV_TLB_FLUSH_UNIT) > max_gvas) { + if (end == 0 || ((end - start) / HV_TLB_FLUSH_UNIT) > max_gvas) { status = hv_do_rep_hypercall( HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX, 0, nr_bank, (uint64_t)flush, (uint64_t)NULL); } else { gva_n = fill_gva_list(&flush->hv_vp_set.bank_contents[nr_bank], - addr1, addr2); + start, end); status = hv_do_rep_hypercall( HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX, gva_n, nr_bank, (uint64_t)flush, (uint64_t)NULL);