From nobody Wed Jun 17 01:52:04 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 055D7282F02 for ; Tue, 21 Apr 2026 15:19:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776784753; cv=none; b=DpB8HmZ/zbyFW/FlXMa3uRYw9VU0DN/EWudiEOozjIG6n4ZujSCFx53EWgffR2hAMZRP/WPm2lSiDooGAfYH9iSY2lwMWzjDLwPKv0WdKZTF4E+CXwkqunmy6vRN9caMttWuHmRxlDswLzit0lA2RGeX8rCl69NiqT1ViSXP+aA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776784753; c=relaxed/simple; bh=1ZqaNoijCpm0pXLFelB+paXGVnf2yv9Z9gFEyv3TJCM=; h=Subject:To:Cc:From:Date:Message-Id; b=dUMgnhYyDJMkFFtUC+4Mn+JcKEfG/vkgLWzKwacrqCh8B1cmpHk5ow8yro5SQPYjENH0pSEd2KwC891V+RQXQynL4aH7pqlXjHBlGChSk0sehDeVs3S6NkluU3mcB19Lwbw0I+TfxrmBwiLFmszJ+D7XNlIwMtHlblxHNoQhWu8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=A1/nLRIa; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="A1/nLRIa" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1776784752; x=1808320752; h=subject:to:cc:from:date:message-id; bh=1ZqaNoijCpm0pXLFelB+paXGVnf2yv9Z9gFEyv3TJCM=; b=A1/nLRIaCvzqtA8cv5g0fRia/yCH90Krufg5TfzQep0TEc/JdwblDfSX mNcNAOO2NhXXHMw3hWohADmv2SFpBSKhywAIFOVkXBAwRbW6lcjbRAT9O WVrW8QKFTYhjJPKqDHDaNDQa+9RiHENUWDvRWIEPuQPU/6u922Yr9H1f/ VnM3Wktg3N7/Kp0LazSBIRGhLVc6qNHTFN1XFVuB+6riuATEKzFOh0d2C Pcs5CypoGwgI/HbxkBkd6+Gv0vQ/pNCwVaGJtQraYEDSPYT8g9vaAjZdQ +lSgbvHbiSvHBirpINz/Aj+R01lrFZqRkhEz11m3Q1zdZFHTMG5D7tbv/ A==; X-CSE-ConnectionGUID: P4rnBOiZSqagxId8a+aZUw== X-CSE-MsgGUID: iWFLIJmVR8KZ3FNcHaDVnA== X-IronPort-AV: E=McAfee;i="6800,10657,11763"; a="81586638" X-IronPort-AV: E=Sophos;i="6.23,191,1770624000"; d="scan'208";a="81586638" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Apr 2026 08:19:11 -0700 X-CSE-ConnectionGUID: x9gNivtqRMG1UIph5TZxuQ== X-CSE-MsgGUID: 1gjTNwojQFOviyH+nccglQ== X-ExtLoop1: 1 Received: from davehans-spike.ostc.intel.com (HELO localhost.localdomain) ([10.165.164.11]) by fmviesa003.fm.intel.com with ESMTP; 21 Apr 2026 08:19:11 -0700 Subject: [PATCH] x86/mm: Revert INVLPGB optimization for set_memory code To: linux-kernel@vger.kernel.org Cc: Dave Hansen , Andy Lutomirski , Borislav Petkov , Cui Ling , Hellstrom Thomas , Ingo Molnar , Peter Zijlstra , Rik van Riel , Thomas Gleixner , x86@kernel.org, Yu-cheng Yu From: Dave Hansen Date: Tue, 21 Apr 2026 08:19:09 -0700 Message-Id: <20260421151909.6B3281C6@davehans-spike.ostc.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Dave Hansen tl;dr: Revert an INVLPGB optimization that did not properly handle discontiguous virtual addresses. Full story: I got a report from some graphics (i915) folks that bisected a regression in their test suite to 86e6815b316e ("x86/mm: Change cpa_flush() to call flush_kernel_range() directly"). There was a bit of flip-flopping on the exact bisect, but the code here does seem wrong to me. The i915 folks were calling set_pages_array_wc(), so using the CPA_PAGES_ARRAY mode. Basically, the 'struct cpa_data' can wrap up all kinds of page table changes. Some of these are virtually contiguous, but some are very much not which is one reason why there are ->vaddr and ->pages arrays. 86e6815b316e made the mistake of assuming that the virtual addresses in the cpa_data are always contiguous. It got things right when neither CPA_ARRAY/CPA_PAGES_ARRAY is used, but theoretically wrong when either of those is used. In the i915 case, it probably failed to flush some WB TLB entries and install WC ones, leaving some data in the caches and not flushing it out to where the device could see it. That eventually caused graphics problems. Revert the INVLPGB optimization. It can be reintroduced later, but it will need to be a bit careful about the array modes. Signed-off-by: Dave Hansen Reported-by: Cui, Ling Cc: Yu-cheng Yu Cc: Rik van Riel Cc: Hellstrom, Thomas Cc: Andy Lutomirski Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: x86@kernel.org Reviewed-by: Rick Edgecombe Reviewed-by: Thomas Hellstr=C3=B6m --- b/arch/x86/mm/pat/set_memory.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff -puN arch/x86/mm/pat/set_memory.c~revert-86e6815b316ec0ea8 arch/x86/mm= /pat/set_memory.c --- a/arch/x86/mm/pat/set_memory.c~revert-86e6815b316ec0ea8 2026-04-21 06:5= 6:29.208686362 -0700 +++ b/arch/x86/mm/pat/set_memory.c 2026-04-21 06:57:54.946011984 -0700 @@ -399,6 +399,15 @@ static void cpa_flush_all(unsigned long on_each_cpu(__cpa_flush_all, (void *) cache, 1); } =20 +static void __cpa_flush_tlb(void *data) +{ + struct cpa_data *cpa =3D data; + unsigned int i; + + for (i =3D 0; i < cpa->numpages; i++) + flush_tlb_one_kernel(fix_addr(__cpa_addr(cpa, i))); +} + static int collapse_large_pages(unsigned long addr, struct list_head *pgta= bles); =20 static void cpa_collapse_large_pages(struct cpa_data *cpa) @@ -435,7 +444,6 @@ static void cpa_collapse_large_pages(str =20 static void cpa_flush(struct cpa_data *cpa, int cache) { - unsigned long start, end; unsigned int i; =20 BUG_ON(irqs_disabled() && !early_boot_irqs_disabled); @@ -445,12 +453,10 @@ static void cpa_flush(struct cpa_data *c goto collapse_large_pages; } =20 - start =3D fix_addr(__cpa_addr(cpa, 0)); - end =3D start + cpa->numpages * PAGE_SIZE; - if (cpa->force_flush_all) - end =3D TLB_FLUSH_ALL; - - flush_tlb_kernel_range(start, end); + if (cpa->force_flush_all || cpa->numpages > tlb_single_page_flush_ceiling) + flush_tlb_all(); + else + on_each_cpu(__cpa_flush_tlb, cpa, 1); =20 if (!cache) goto collapse_large_pages; _