mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] x86/mm/ident_map: Use gbpages only where full GB page should be mapped.
@ 2023-10-31 19:50 Steve Wahl
  2023-11-02 16:02 ` Dave Hansen
  0 siblings, 1 reply; 4+ messages in thread
From: Steve Wahl @ 2023-10-31 19:50 UTC (permalink / raw)
  To: Steve Wahl, rja_direct, Dave Hansen, Andy Lutomirski,
	Peter Zijlstra, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	x86, H. Peter Anvin, linux-kernel

Instead of using gbpages for all memory regions, use them only when
map creation requests include the full GB page of space; descend to
using smaller 2M pages when only portions of a GB page are requested.

When gbpages are used exclusively to create identity maps, large
ranges of addresses not actually requested can be included in the
resulting table.  On UV systems, this ends up including regions that
will cause hardware to halt the system if accessed (these are marked
"reserved" by BIOS).  Even though code does not actually make
references to these addresses, including them in an active map allows
processor speculation into this region, which is enough to trigger the
system halt.

The kernel option "nogbpages" will disallow use of gbpages entirely
and avoid this problem, but uses a lot of extra memory for page tables
that are not really needed.

Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
---

Please ignore previous send with internal message.  Thanks.

 arch/x86/mm/ident_map.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c
index 968d7005f4a7..b63a1ffcfe9f 100644
--- a/arch/x86/mm/ident_map.c
+++ b/arch/x86/mm/ident_map.c
@@ -31,18 +31,26 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page,
 		if (next > end)
 			next = end;
 
-		if (info->direct_gbpages) {
+		/*
+		 * if gbpages allowed, this entry not yet present, and
+		 * the full gbpage range is requested (both ends are
+		 * correctly aligned), create a gbpage.
+		 */
+		if (info->direct_gbpages
+		    && !pud_present(*pud)
+		    && !(addr & ~PUD_MASK)
+		    && !(next & ~PUD_MASK)) {
 			pud_t pudval;
 
-			if (pud_present(*pud))
-				continue;
-
-			addr &= PUD_MASK;
 			pudval = __pud((addr - info->offset) | info->page_flag);
 			set_pud(pud, pudval);
 			continue;
 		}
 
+		/* if this is already a gbpage, this portion is already mapped */
+		if (pud_large(*pud))
+			continue;
+
 		if (pud_present(*pud)) {
 			pmd = pmd_offset(pud, 0);
 			ident_pmd_init(info, pmd, addr, next);
-- 
2.26.2


^ permalink raw reply	[flat|nested] 4+ messages in thread
* [PATCH] x86/mm/ident_map: Use gbpages only where full GB page should be mapped.
@ 2023-10-31 19:46 Steve Wahl
  0 siblings, 0 replies; 4+ messages in thread
From: Steve Wahl @ 2023-10-31 19:46 UTC (permalink / raw)
  To: Steve Wahl, rja_direct, Dave Hansen, Andy Lutomirski,
	Peter Zijlstra, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	x86, H. Peter Anvin, linux-kernel

[HPE only, 3rd version.  Nobody noticed that I had typoed "x68"
instead of "x86" in the subject line!  Glad I caught it.  But mostly,
incorporated Uwe's and Dimitri's suggestions.  Need to test with the
change to make sure it still works, though.]

Instead of using gbpages for all memory regions, use them only when
map creation requests include the full GB page of space; descend to
using smaller 2M pages when only portions of a GB page are requested.

When gbpages are used exclusively to create identity maps, large
ranges of addresses not actually requested can be included in the
resulting table.  On UV systems, this ends up including regions that
will cause hardware to halt the system if accessed (these are marked
"reserved" by BIOS).  Even though code does not actually make
references to these addresses, including them in an active map allows
processor speculation into this region, which is enough to trigger the
system halt.

The kernel option "nogbpages" will disallow use of gbpages entirely
and avoid this problem, but uses a lot of extra memory for page tables
that are not really needed.

Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
---
 arch/x86/mm/ident_map.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c
index 968d7005f4a7..b63a1ffcfe9f 100644
--- a/arch/x86/mm/ident_map.c
+++ b/arch/x86/mm/ident_map.c
@@ -31,18 +31,26 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page,
 		if (next > end)
 			next = end;
 
-		if (info->direct_gbpages) {
+		/*
+		 * if gbpages allowed, this entry not yet present, and
+		 * the full gbpage range is requested (both ends are
+		 * correctly aligned), create a gbpage.
+		 */
+		if (info->direct_gbpages
+		    && !pud_present(*pud)
+		    && !(addr & ~PUD_MASK)
+		    && !(next & ~PUD_MASK)) {
 			pud_t pudval;
 
-			if (pud_present(*pud))
-				continue;
-
-			addr &= PUD_MASK;
 			pudval = __pud((addr - info->offset) | info->page_flag);
 			set_pud(pud, pudval);
 			continue;
 		}
 
+		/* if this is already a gbpage, this portion is already mapped */
+		if (pud_large(*pud))
+			continue;
+
 		if (pud_present(*pud)) {
 			pmd = pmd_offset(pud, 0);
 			ident_pmd_init(info, pmd, addr, next);
-- 
2.26.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-11-03 16:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-31 19:50 [PATCH] x86/mm/ident_map: Use gbpages only where full GB page should be mapped Steve Wahl
2023-11-02 16:02 ` Dave Hansen
2023-11-03 16:13   ` Steve Wahl
  -- strict thread matches above, loose matches on Subject: below --
2023-10-31 19:46 Steve Wahl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®