[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250520152030.1499670-3-arnd@kernel.org>
Date: Tue, 20 May 2025 17:20:30 +0200
From: Arnd Bergmann <arnd@...nel.org>
To: Dave Hansen <dave.hansen@...ux.intel.com>,
Dan Williams <dan.j.williams@...el.com>
Cc: Andy Lutomirski <luto@...nel.org>,
Peter Zijlstra <peterz@...radead.org>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>,
Borislav Petkov <bp@...en8.de>,
x86@...nel.org,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Nikolay Borisov <nik.borisov@...e.com>,
linux-kernel@...r.kernel.org,
Arnd Bergmann <arnd@...db.de>
Subject: [PATCH 3/3] [RFC] x86/devmem: remove low 1MB hack for x86-64
From: Arnd Bergmann <arnd@...db.de>
Traditionally, both reading and mapping anything in the low 1MB area is
allowed on x86, through a series of ugly hacks. In combination with
features such as memory encryption, this keeps causing trouble and
requires building additional hacks on top.
Chances are that this is only really used for 32-bit machines, as the
usual users of this were dosemu, svgalib or ancient XFree86 versions,
none of which should be used on 64-bit kernels any more.
Remove both the custom devmem_is_allowed() and the custom
xlate_dev_mem_ptr() on 64-bit kernels, and use the normal implementation
based on phys_to_virt() instead for read/write access on the linear
map.
As a result, this makes x86-64 behave more like the other architecture
on /dev/mem, allowing read/write access only on actual system RAM and
only when CONFIG_STRICT_DEVMEM is disabled, while mmap() can be use
on MMIO pages with the normal restrictions.
Signed-off-by: Arnd Bergmann <arnd@...db.de>
---
Unlike the other two patches in this series, this one is expected to
change the behavior on x86-64 kernels, which has the risk of
regressions, but seems worthwhile to me.
Are there any reasons left for keeping these hacks?
---
arch/x86/Kconfig | 3 ++-
arch/x86/include/asm/io.h | 3 ++-
arch/x86/mm/init.c | 4 +++-
arch/x86/mm/ioremap.c | 2 ++
4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 47a3cd5ffc4f..635328b57e35 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -85,7 +85,7 @@ config X86
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
- select ARCH_HAS_DEVMEM_IS_ALLOWED
+ select ARCH_HAS_DEVMEM_IS_ALLOWED if !X86_64
select ARCH_HAS_DMA_OPS if GART_IOMMU || XEN
select ARCH_HAS_EARLY_DEBUG if KGDB
select ARCH_HAS_ELF_RANDOMIZE
@@ -180,6 +180,7 @@ config X86
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_RESERVATION_MODE
select GENERIC_IRQ_SHOW
+ select GENERIC_LIB_DEVMEM_IS_ALLOWED if X86_64
select GENERIC_PENDING_IRQ if SMP
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 367d45755f85..c1ecca34f28d 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -285,11 +285,12 @@ BUILDIO(l, u32)
#define outsw outsw
#define outsl outsl
+#ifdef CONFIG_X86_32
extern void *xlate_dev_mem_ptr(phys_addr_t phys);
extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
-
#define xlate_dev_mem_ptr xlate_dev_mem_ptr
#define unxlate_dev_mem_ptr unxlate_dev_mem_ptr
+#endif
extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
enum page_cache_mode pcm);
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index aa56d9ac0b8f..16d0f242f0de 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -856,11 +856,12 @@ void __init poking_init(void)
pte_unmap_unlock(ptep, ptl);
}
+#ifdef CONFIG_X86_32
/*
* devmem_is_allowed() checks to see if /dev/mem access to a certain address
* is valid. The argument is a physical page number.
*
- * On x86, access has to be given to the first megabyte of RAM because that
+ * On x86-32, access has to be given to the first megabyte of RAM because that
* area traditionally contains BIOS code and data regions used by X, dosemu,
* and similar apps. Since they map the entire memory range, the whole range
* must be allowed (for mapping), but any areas that would otherwise be
@@ -897,6 +898,7 @@ int devmem_is_allowed(unsigned long pagenr)
return 1;
}
+#endif
void free_init_pages(const char *what, unsigned long begin, unsigned long end)
{
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 11b4ea7d7fa5..1e51d1c245bf 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -509,6 +509,7 @@ void *arch_memremap_wb(phys_addr_t phys_addr, size_t size, unsigned long flags)
return (void __force *)ioremap_encrypted(phys_addr, size);
}
+#ifdef CONFIG_X86_32
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
@@ -533,6 +534,7 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
{
memunmap((void *)((unsigned long)addr & PAGE_MASK));
}
+#endif
#ifdef CONFIG_AMD_MEM_ENCRYPT
/*
--
2.39.5
Powered by blists - more mailing lists