Skip to content

Commit 0ddab1d

Browse files
Toshi Kanitorvalds
authored andcommitted
lib/ioremap.c: add huge I/O map capability interfaces
Add ioremap_pud_enabled() and ioremap_pmd_enabled(), which return 1 when I/O mappings with pud/pmd are enabled on the kernel. ioremap_huge_init() calls arch_ioremap_pud_supported() and arch_ioremap_pmd_supported() to initialize the capabilities at boot-time. A new kernel option "nohugeiomap" is also added, so that user can disable the huge I/O map capabilities when necessary. Signed-off-by: Toshi Kani <toshi.kani@hp.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Robert Elliott <Elliott@hp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 0f616be commit 0ddab1d

File tree

5 files changed

+52
-0
lines changed

5 files changed

+52
-0
lines changed

Documentation/kernel-parameters.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,6 +2323,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
23232323
register save and restore. The kernel will only save
23242324
legacy floating-point registers on task switch.
23252325

2326+
nohugeiomap [KNL,x86] Disable kernel huge I/O mappings.
2327+
23262328
noxsave [BUGS=X86] Disables x86 extended register state save
23272329
and restore using xsave. The kernel will fallback to
23282330
enabling legacy floating-point and sse state.

arch/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,9 @@ config HAVE_IRQ_TIME_ACCOUNTING
446446
config HAVE_ARCH_TRANSPARENT_HUGEPAGE
447447
bool
448448

449+
config HAVE_ARCH_HUGE_VMAP
450+
bool
451+
449452
config HAVE_ARCH_SOFT_DIRTY
450453
bool
451454

include/linux/io.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ static inline int ioremap_page_range(unsigned long addr, unsigned long end,
3838
}
3939
#endif
4040

41+
#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
42+
void __init ioremap_huge_init(void);
43+
int arch_ioremap_pud_supported(void);
44+
int arch_ioremap_pmd_supported(void);
45+
#else
46+
static inline void ioremap_huge_init(void) { }
47+
#endif
48+
4149
/*
4250
* Managed iomap interface
4351
*/

init/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#include <linux/list.h>
8181
#include <linux/integrity.h>
8282
#include <linux/proc_ns.h>
83+
#include <linux/io.h>
8384

8485
#include <asm/io.h>
8586
#include <asm/bugs.h>
@@ -484,6 +485,7 @@ static void __init mm_init(void)
484485
percpu_init_late();
485486
pgtable_init();
486487
vmalloc_init();
488+
ioremap_huge_init();
487489
}
488490

489491
asmlinkage __visible void __init start_kernel(void)

lib/ioremap.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,43 @@
1313
#include <asm/cacheflush.h>
1414
#include <asm/pgtable.h>
1515

16+
#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
17+
int __read_mostly ioremap_pud_capable;
18+
int __read_mostly ioremap_pmd_capable;
19+
int __read_mostly ioremap_huge_disabled;
20+
21+
static int __init set_nohugeiomap(char *str)
22+
{
23+
ioremap_huge_disabled = 1;
24+
return 0;
25+
}
26+
early_param("nohugeiomap", set_nohugeiomap);
27+
28+
void __init ioremap_huge_init(void)
29+
{
30+
if (!ioremap_huge_disabled) {
31+
if (arch_ioremap_pud_supported())
32+
ioremap_pud_capable = 1;
33+
if (arch_ioremap_pmd_supported())
34+
ioremap_pmd_capable = 1;
35+
}
36+
}
37+
38+
static inline int ioremap_pud_enabled(void)
39+
{
40+
return ioremap_pud_capable;
41+
}
42+
43+
static inline int ioremap_pmd_enabled(void)
44+
{
45+
return ioremap_pmd_capable;
46+
}
47+
48+
#else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */
49+
static inline int ioremap_pud_enabled(void) { return 0; }
50+
static inline int ioremap_pmd_enabled(void) { return 0; }
51+
#endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */
52+
1653
static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
1754
unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
1855
{

0 commit comments

Comments
 (0)