From nobody Mon Jun 8 04:19:36 2026 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B1653932E9 for ; Thu, 4 Jun 2026 16:59:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780592378; cv=none; b=i5kxm6gLj2I4Jat4o9tvUS00IrMIvJ+8dytdZjzVfuH9bVpKVHAOuEeUutHzE3Rrn4mOxKGRt7ImXHVH+XkXw3CHxQLKSL6DHpMloLI4Zr91jThjFmvC1UXoIxBlZEjGrAboFVtGwHwEU6yCxv3AMHO2awlF+0y7SIiGkp6E3+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780592378; c=relaxed/simple; bh=yUtTpJHdzEWbgTjsiuCj893qdVCNtyL0l8/2vu8sS4E=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=GaGx83Tskw3KXuSy0WR40lDmacj8mHblH08kR6LsSj65MwQDa+dTHWZkGhgvonhQ0fZaEGJ+eKUPXGN1GF5+KEe92ZajEQKZHI+cwdzOn8Hx9ReqcXg0/Sbq7FqvPh3SsQfQj6qBW+aCbPR4UKWKrIbN/pxvNtvp8F2NYMxYa08= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l3azZzTf; arc=none smtp.client-ip=209.85.221.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l3azZzTf" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-45eedcdaeaaso654450f8f.3 for ; Thu, 04 Jun 2026 09:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780592376; x=1781197176; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=5pGoeEOr9RRtwxMbbZF4kryR7MSLvpeOOpDT4EcPNUk=; b=l3azZzTf4EZCVX985MITEzwnHVrxpYoDZ+7GeOT75J6Yl7pzlRp9z8FUksGklfxSfO FbyEgSyOH78cyvMnipX1G3pn16hEUjqzmp4K6lQ6+zxb4N3jp23zpFsE1dencmxyCm/V jlLMQ/efXxRDXqhKS3khhnx02Oe4IqWSOFe9Oh5sWnQ0lnY0oOUFaX7qShd4hd9Ua/8/ /nACZ9JrUUSq5exUxtua1rkY09rzwdoVhnEyoKR46+KxmEM3CsSPfsH+U4oA8mttTjnf 4eh8J+T6uf3wTdxC8XE5fCV/PjNLBrTuM1dobmKR8diC3jADYl0Ihh2aLSkYC4k9tt6r e/CA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780592376; x=1781197176; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=5pGoeEOr9RRtwxMbbZF4kryR7MSLvpeOOpDT4EcPNUk=; b=Syfdh/KsPQ3MCyNtMacPMEJBBWglehRJvPuHsL7KJ0CU9sRmj3znKcgDrIKS2hjIEw AuasVEv0FjIqa/4jDIGiwLuoC8nUEc3pDuRQfYK8rvYNo5OA00wc3GZ3foPi3QezYq1w XDDT4Ps4GlCAraHf7Md92NoLEYYtzoERfK15zQub2240LmqNsOTiMEW+WjZJNYCUsIU2 fyvKTvHFGhzpBT6ItYneITXrihhDZ/nvSnA8vkSHaSzyJAR07cEs9KUMwsJkg75EOL+n MKBfgnQbm7rl56ct+1ZyUCUotXrjjwbiKYepCzcoK/eL4Rz+yhqNjx6usBfLVbIYICJZ rZFg== X-Forwarded-Encrypted: i=1; AFNElJ+wBq1I+lw8E1luVdopbNyiyBvqwdQyHCDywulIncSG8KuqcMwEidARoLOr7LrxU9dw+T6Kr1hk6etunGU=@vger.kernel.org X-Gm-Message-State: AOJu0YyneQAH+s19oM0T8RpAzkkPYdn+hj8c/dNkqYlXzHep+AWRWlQn WecY7OZ73w+3eXEHs84YlhIG2zV5IjyxXpIia0+Xfwnlf19iVExf1O9q X-Gm-Gg: Acq92OE8Vb4Zvi9O64ebcLk4yUeGJWGD7R9ZjgfjchcLHVjkLSUIyaQkd3+lV7wh7f+ i/j1Yn0hh1aj/NTzFp7h+k1kn75/wP9u3RJClat84mo0fYwiqaezGvEtODJtFabqEeSsgEnhJBD 8VTNEnGxtKV5RVJfIugDossL9LktfkxDO6QRONCwI3V1sfkdGUywPNC2V9a05xDgG2kjdMhPFw/ b/xpp5OYsd2fiKOidQpDCPjQ4Foef0vBRCyTGLEMNh2DZhywjRHiX4k+txl0BELwQfPgHjLGhf7 KS996TtfU0z/W7BPzneAQM6OgxfRviKtxjoV0P4AiGnFpsAhPueyDHEZxoNlCTVUxAkK8pc+i8t JmtjTOWCgqFTHf7LTkK2x/6pEycgksGX041XC97/Wtt3AHkPSEv7sdlipvenhLGAzBn8yaZGnw5 EYfGY+Fz7TjkTyuT4ULQTdE58uVW9Jn9VYX+bZnf5JmpqFTVfq9bgzfnfvehMUjtSvcb0= X-Received: by 2002:adf:ef0a:0:b0:43d:7c1b:b8c7 with SMTP id ffacd0b85a97d-4602183267cmr11729522f8f.21.1780592375658; Thu, 04 Jun 2026 09:59:35 -0700 (PDT) Received: from localhost.localdomain ([5.165.242.139]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f34413csm17376308f8f.21.2026.06.04.09.59.33 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Thu, 04 Jun 2026 09:59:35 -0700 (PDT) From: Anton Leontev To: netdev@vger.kernel.org Cc: linux-hyperv@vger.kernel.org, haiyangz@microsoft.com, kys@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, kuba@kernel.org, pabeni@redhat.com, edumazet@google.com, davem@davemloft.net, stable@vger.kernel.org, linux-kernel@vger.kernel.org, Anton Leontev Subject: [PATCH net v3] hv_netvsc: use kmap_local_page in netvsc_copy_to_send_buf Date: Thu, 4 Jun 2026 19:59:38 +0300 Message-ID: <20260604165938.32033-1-leontyevantony@gmail.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" netvsc_copy_to_send_buf() copies page buffer entries into the VMBus send buffer using phys_to_virt() on the entry PFN. Entries for the RNDIS header and the skb linear data come from kmalloc'd memory and are always in the kernel direct map, but entries for skb fragments reference page cache or user pages, which on 32-bit x86 with CONFIG_HIGHMEM=3Dy can live above the LOWMEM boundary. For such a page phys_to_virt() returns an address outside the direct map and the subsequent memcpy() faults on the transmit softirq path, which is fatal. Map the pages with kmap_local_page() instead, handling two properties of the page buffer entries: - pb[i].pfn is a Hyper-V PFN at HV_HYP_PAGE_SIZE (4K) granularity, not a native PFN. Reconstruct the physical address first and derive the native page from it, so the mapping stays correct where PAGE_SIZE > HV_HYP_PAGE_SIZE (e.g. arm64 with 64K pages). - Since commit 41a6328b2c55 ("hv_netvsc: Preserve contiguous PFN grouping in the page buffer array"), an entry describes a full physically contiguous fragment and pb[i].len can exceed PAGE_SIZE, while kmap_local_page() maps a single page. Copy page by page, splitting at native page boundaries. The copy path only handles packets smaller than the send section size (6144 bytes by default); larger packets take the cp_partial path where only the RNDIS header is copied. So entries here are bounded by the section size and a copy is split at most once on 4K-page systems. On !CONFIG_HIGHMEM configs kmap_local_page() folds to page_address() and no mapping work is added. Fixes: c25aaf814a63 ("hyperv: Enable sendbuf mechanism on the send path") Cc: stable@vger.kernel.org Signed-off-by: Anton Leontev --- v3: - Copy page by page: since 41a6328b2c55 a pb entry describes a full contiguous fragment and pb[i].len can exceed PAGE_SIZE, while kmap_local_page() maps a single page. Split copies at native page boundaries. v2: - Derive the native page and in-page offset from the physical address instead of passing the Hyper-V 4K PFN to pfn_to_page(), correct where PAGE_SIZE > 4K (e.g. arm64 64K pages). I do not have a 32-bit HIGHMEM Hyper-V setup to exercise this path; testing help from the Hyper-V folks would be much appreciated. drivers/net/hyperv/netvsc.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 59e95341f9b1..4d319c50955e 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -965,12 +966,22 @@ static void netvsc_copy_to_send_buf(struct netvsc_dev= ice *net_device, } =20 for (i =3D 0; i < page_count; i++) { - char *src =3D phys_to_virt(pb[i].pfn << HV_HYP_PAGE_SHIFT); - u32 offset =3D pb[i].offset; + phys_addr_t paddr =3D (pb[i].pfn << HV_HYP_PAGE_SHIFT) + + pb[i].offset; u32 len =3D pb[i].len; =20 - memcpy(dest, (src + offset), len); - dest +=3D len; + while (len) { + struct page *page =3D phys_to_page(paddr); + u32 off =3D offset_in_page(paddr); + u32 chunk =3D min_t(u32, len, PAGE_SIZE - off); + char *src =3D kmap_local_page(page); + + memcpy(dest, src + off, chunk); + kunmap_local(src); + dest +=3D chunk; + paddr +=3D chunk; + len -=3D chunk; + } } =20 if (padding) --=20 2.43.0