Skip to contentSkip to conversation

x86 PAT changes

GIT PULL New Ingo Molnar 5 participants 15 messages Apr 24, 2008 – Apr 26, 2008

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Linus, please pull the x86-pat git tree from:

git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86-pat.git for-linus

this adds the second (and final) phase of the x86 PAT changes. Due to generic impact (the drivers/char/mem.c and include/asm-generic/iomap.h changes) this is offered as a separate tree.

The new CONFIG_NONPROMISC_DEVMEM defaults to disabled so PAT will be disabled, to stay compatible and to be a bit cautious/gradual.

Thanks,

Ingo

------------------>
Arjan van de Ven (1):
x86: introduce /dev/mem restrictions with a config option

Ingo Molnar (2):
pat: cleanups
/dev/mem: make promisc the default

Venki Pallipadi (1):
devmem: add range_is_allowed() check to mmap of /dev/mem

[email protected] (4):
x86: PAT avoid aliasing in /dev/mem read/write
x86: PAT phys_mem_access_prot_allowed for dev/mem mmap
x86: PAT use reserve free memtype in mmap of /dev/mem
generic: add ioremap_wc() interface wrapper

 arch/x86/Kconfig.debug      |   11 +++
 arch/x86/mm/init_32.c       |   19 +++++
 arch/x86/mm/init_64.c       |   20 +++++
 arch/x86/mm/ioremap.c       |   29 +++++++
 arch/x86/mm/pat.c           |  175 +++++++++++++++++++++++++++++++++++++++----
 drivers/char/mem.c          |  133 +++++++++++++++++++++++++--------
 include/asm-generic/iomap.h |    4 +
 include/asm-x86/io.h        |    8 ++
 include/asm-x86/io_32.h     |    6 --
 include/asm-x86/io_64.h     |    6 --
 include/asm-x86/page.h      |    1 +
 include/asm-x86/pgtable.h   |    9 ++
 12 files changed, 363 insertions(+), 58 deletions(-)
arch/x86/Kconfig.debug +11 -0
index 610aaec..239fd9f 100644
@@ -5,6 +5,17 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
+config NONPROMISC_DEVMEM
+	bool "Disable promiscuous /dev/mem"
+	help
+	  The /dev/mem file by default only allows userspace access to PCI
+	  space and the BIOS code and data regions. This is sufficient for
+	  dosemu and X and all common users of /dev/mem. With this config
+	  option, you allow userspace access to all of memory, including
+	  kernel and userspace memory. Accidental access to this is
+	  obviously disasterous, but specific access can be used by people
+	  debugging the kernel.
+
 config EARLY_PRINTK
 	bool "Early printk" if EMBEDDED
 	default y
arch/x86/mm/init_32.c +19 -0
index 9ec62da..39852d5 100644
@@ -227,6 +227,25 @@ static inline int page_kills_ppro(unsigned long pagenr)
 	return 0;
 }
 
+/*
+ * 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 area
+ * contains bios code and data regions used by X and dosemu and similar apps.
+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+ * mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+	if (pagenr <= 256)
+		return 1;
+	if (!page_is_ram(pagenr))
+		return 1;
+	return 0;
+}
+
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
arch/x86/mm/init_64.c +20 -0
index 1ff7906..49c274e 100644
@@ -664,6 +664,26 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
+/*
+ * 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 area
+ * contains bios code and data regions used by X and dosemu and similar apps.
+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+ * mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+	if (pagenr <= 256)
+		return 1;
+	if (!page_is_ram(pagenr))
+		return 1;
+	return 0;
+}
+
+
 static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
 			 kcore_modules, kcore_vsyscall;
 
arch/x86/mm/ioremap.c +29 -0
index 3a4baf9..caac7d5 100644
@@ -336,6 +336,35 @@ void iounmap(volatile void __iomem *addr)
 }
 EXPORT_SYMBOL(iounmap);
 
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+void *xlate_dev_mem_ptr(unsigned long phys)
+{
+	void *addr;
+	unsigned long start = phys & PAGE_MASK;
+
+	/* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
+	if (page_is_ram(start >> PAGE_SHIFT))
+		return __va(phys);
+
+	addr = (void *)ioremap(start, PAGE_SIZE);
+	if (addr)
+		addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK));
+
+	return addr;
+}
+
+void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
+{
+	if (page_is_ram(phys >> PAGE_SHIFT))
+		return;
+
+	iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
+	return;
+}
+
 #ifdef CONFIG_X86_32
 
 int __initdata early_ioremap_debug;
arch/x86/mm/pat.c +161 -14

244 lines not on this page · raw message

drivers/char/mem.c +101 -32

207 lines not on this page · raw message

include/asm-generic/iomap.h +4 -0
index 67dc84c..76b0cc5 100644
@@ -60,6 +60,10 @@ extern void iowrite32_rep(void __iomem *port, const void *buf, unsigned long cou
 extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
 extern void ioport_unmap(void __iomem *);
 
+#ifndef ARCH_HAS_IOREMAP_WC
+#define ioremap_wc ioremap_nocache
+#endif
+
 /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
 extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
include/asm-x86/io.h +8 -0
index 7b292d3..d5b11f6 100644
@@ -1,3 +1,6 @@
+#ifndef _ASM_X86_IO_H
+#define _ASM_X86_IO_H
+
 #define ARCH_HAS_IOREMAP_WC
 
 #ifdef CONFIG_X86_32
@@ -5,7 +8,12 @@
 #else
 # include "io_64.h"
 #endif
+
+extern void *xlate_dev_mem_ptr(unsigned long phys);
+extern void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
+
 extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
 				unsigned long prot_val);
 extern void __iomem *ioremap_wc(unsigned long offset, unsigned long size);
 
+#endif /* _ASM_X86_IO_H */
include/asm-x86/io_32.h +0 -6
index 509045f..6e73467 100644
@@ -49,12 +49,6 @@
 #include <linux/vmalloc.h>
 
 /*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p)	__va(p)
-
-/*
  * Convert a virtual cached pointer to an uncached pointer
  */
 #define xlate_dev_kmem_ptr(p)	p
include/asm-x86/io_64.h +0 -6
index c2f5eef..0930bed 100644
@@ -308,12 +308,6 @@ extern int iommu_bio_merge;
 #define BIO_VMERGE_BOUNDARY iommu_bio_merge
 
 /*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p)	__va(p)
-
-/*
  * Convert a virtual cached pointer to an uncached pointer
  */
 #define xlate_dev_kmem_ptr(p)	p
include/asm-x86/page.h +1 -0
index 6724a4b..b381f4a 100644
@@ -47,6 +47,7 @@
 #ifndef __ASSEMBLY__
 
 extern int page_is_ram(unsigned long pagenr);
+extern int devmem_is_allowed(unsigned long pagenr);
 
 extern unsigned long max_pfn_mapped;
 
include/asm-x86/pgtable.h +9 -0
index f1d9f4a..1902f0a 100644
@@ -289,6 +289,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 #define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
 
+#ifndef __ASSEMBLY__
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+struct file;
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+                              unsigned long size, pgprot_t vma_prot);
+int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
+                              unsigned long size, pgprot_t *vma_prot);
+#endif
+
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else  /* !CONFIG_PARAVIRT */
#1 lore raw
Quoted 7 lines · Ingo Molnar

Linus, please pull the x86-pat git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86-pat.git for-linus

this adds the second (and final) phase of the x86 PAT changes. Due to generic impact (the drivers/char/mem.c and include/asm-generic/iomap.h changes) this is offered as a separate tree.

So why is PAT dependent on NONPROMISC_DEVMEM here?

It seems pointless and wrong. Somebody might want to have both the full /dev/mem and PAT.

Also, it causes this message for me on one of my machines:

	EXT3-fs: mounted filesystem with ordered data mode.
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	mtrr: no more MTRRs available
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	EXT3 FS on dm-0, internal journal
	...
	eth0: no IPv6 routers present
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xd0000000-0xd0020000
	mtrr: no more MTRRs available
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000

which is a bit annoying. Forgotten debug printk, perhaps?

Linus

#2 lore raw
Quoted 5 lines · Linus Torvalds

So why is PAT dependent on NONPROMISC_DEVMEM here?

It seems pointless and wrong. Somebody might want to have both the full /dev/mem and PAT.

The problem is that that can create cached/uncached aliases, which can cause some processors to lock up (especially AMD is known to have a lot of errata in this area.)

-hpa

#3 lore raw
Quoted 4 lines · H. Peter Anvin

The problem is that that can create cached/uncached aliases, which can cause some processors to lock up (especially AMD is known to have a lot of errata in this area.)

Umm.. I don't think you understand. Right now, NONPROMISC_DEVMEM doesn't just disable mmap() on /dev/mem, it disables totally regular reads and writes too. That seems pretty damn excessive.

If it was just mmap(), I don't think it would matter much. I don't think we traditionally even supported mmap() on real RAM (because the page counting would get confused), and that actually got supported only thanks to VM changes that made it possible.

But read/write has always been supported, and shouldn't cause any cached/uncached aliases!

Linus

#4 lore raw
Quoted 10 lines · Linus Torvalds
Quoted 4 lines · H. Peter Anvin

The problem is that that can create cached/uncached aliases, which can cause some processors to lock up (especially AMD is known to have a lot of errata in this area.)

Umm.. I don't think you understand. Right now, NONPROMISC_DEVMEM doesn't just disable mmap() on /dev/mem, it disables totally regular reads and writes too. That seems pretty damn excessive.

Quoted 7 lines

If it was just mmap(), I don't think it would matter much. I don't think we traditionally even supported mmap() on real RAM (because the page counting would get confused), and that actually got supported only thanks to VM changes that made it possible.

But read/write has always been supported, and shouldn't cause any cached/uncached aliases!

You are right, there should be no architectural need to make PAT dependent on nonpromisc-devmem, and thus the patch below should be safe.

In theory even mmap() of /dev/mem should be safe this way - as all memtypes are properly tracked.

The thinking behind this dependency was three-fold:

- historic: from the days when the PAT patchset didnt do fully correct tracking yet

- practical: that PAT would be utilized in newer distros on newer systems - with older distros on older systems not really wanting (or needing) neither /dev/mem restrictions nor PAT

- paranoia: one less degree of freedom to take into account

Ingo

----------------------->
Subject: x86 PAT: decouple from nonpromisc devmem
From: Ingo Molnar <[email protected]>
Date: Sat Apr 26 10:26:52 CEST 2008

Linus pointed it out that PAT should not depend on NONPROMISC_DEVMEM.

Also make PAT non-default.

---
 arch/x86/Kconfig |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/Kconfig +2 -2
Index: linux-x86.q/arch/x86/Kconfig
===================================================================
@@ -1042,9 +1042,9 @@ config MTRR
 	  See <file:Documentation/mtrr.txt> for more information.
 
 config X86_PAT
-	def_bool y
+	bool
 	prompt "x86 PAT support"
-	depends on MTRR && NONPROMISC_DEVMEM
+	depends on MTRR
 	help
 	  Use PAT attributes to setup page level cache control.
 
#5 lore raw
Quoted 30 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Ingo Molnar
Sent: Saturday, April 26, 2008 1:56 AM
To: Linus Torvalds
Cc: H. Peter Anvin; [email protected]; Andrew Morton; Thomas Gleixner
Subject: Re: [git pull] x86 PAT changes

Quoted 6 lines · Linus Torvalds
Quoted 4 lines · H. Peter Anvin

The problem is that that can create cached/uncached aliases, which can cause some processors to lock up (especially AMD is known to have a lot of errata in this area.)

Quoted 6 lines

Umm.. I don't think you understand. Right now, NONPROMISC_DEVMEM doesn't just disable mmap() on /dev/mem, it disables totally regular reads and writes too. That seems pretty damn excessive.

If it was just mmap(), I don't think it would matter much. I don't think we traditionally even supported mmap() on real RAM

(because the

Quoted 3 lines

page counting would get confused), and that actually got supported only thanks to VM changes that made it possible.

Quoted 7 lines
Quoted 2 lines

But read/write has always been supported, and shouldn't cause any cached/uncached aliases!

You are right, there should be no architectural need to make PAT dependent on nonpromisc-devmem, and thus the patch below should be safe.

Agreed that NONPROMISC_DEVMEM is not really needed for read/write. But, we will still need it for /dev/mem.

The problem with /dev/mem maps of RAM is situation like this:
1) drivers does vmalloc(), followed by set_memory_uc.
2) User does a /dev/mem map of that vmalloced physical address. User will get a UC mapping for /dev/mem.
3) driver changes the memory to set_memory_wb and frees the memory.
4) user mapping for this address is still UC which will lead to aliasing.

Read/write is ok, as they will just use __va for RAM to access and that will always be consistent.

Thanks,
Venki

#6 lore raw
Quoted 3 lines · Venkatesh

Agreed that NONPROMISC_DEVMEM is not really needed for read/write. But, we will still need it for /dev/mem.

If so, just disable it unconditionally for mmap.

As mentioned, that's really just a return to original Linux /dev/mmap
semantics: long ago (well, not _that_ long ago) we never used to be able to mmap() normal kernel memory, because the page counts would get screwed up on pages that weren't marked PG_Reserved.

So the traditional Linux behavior for mmap() on /dev/mem was always to only allow it on memory that either had no "struct page *" backing at all, or that was marked PG_Reserved (ie the ISA hole ay 640k-1M and things like the BIOS tables etc).

Going back to that doesn't sound horrible.

Linus

#7 lore raw
Quoted 14 lines · Linus Torvalds
Quoted 3 lines · Venkatesh

Agreed that NONPROMISC_DEVMEM is not really needed for read/write. But, we will still need it for /dev/mem.

If so, just disable it unconditionally for mmap.

As mentioned, that's really just a return to original Linux /dev/mmap
semantics: long ago (well, not _that_ long ago) we never used to be able to mmap() normal kernel memory, because the page counts would get screwed up on pages that weren't marked PG_Reserved.

Quoted 7 lines

So the traditional Linux behavior for mmap() on /dev/mem was always to only allow it on memory that either had no "struct page *" backing at all, or that was marked PG_Reserved (ie the ISA hole ay 640k-1M and things like the BIOS tables etc).

Going back to that doesn't sound horrible.

OK. Below is the quick to disable /dev/mem mmap of RAM with PAT. This should go along with Ingo's patch that removes PAT dependency on NONPROMISC_DEVMEM. It makes things safer and eliminates aliasing. Still somewhat unclean as the range_is_allowed is duplicated. And also, just compile tested right now.

---
 arch/x86/mm/pat.c |   31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
arch/x86/mm/pat.c +31 -0
Index: linux-2.6/arch/x86/mm/pat.c
===================================================================
@@ -16,6 +16,7 @@
 #include <asm/msr.h>
 #include <asm/tlbflush.h>
 #include <asm/processor.h>
+#include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/pat.h>
 #include <asm/e820.h>
@@ -477,6 +478,33 @@ pgprot_t phys_mem_access_prot(struct fil
 	return vma_prot;
 }
 
+#ifdef CONFIG_NONPROMISC_DEVMEM
+/* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
+static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+{
+	return 1;
+}
+#else
+static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+{
+	u64 from = ((u64)pfn) << PAGE_SHIFT;
+	u64 to = from + size;
+	u64 cursor = from;
+
+	while (cursor < to) {
+		if (!devmem_is_allowed(pfn)) {
+			printk(KERN_INFO
+		"Program %s tried to access /dev/mem between %Lx->%Lx.\n",
+				current->comm, from, to);
+			return 0;
+		}
+		cursor += PAGE_SIZE;
+		pfn++;
+	}
+	return 1;
+}
+#endif /* CONFIG_NONPROMISC_DEVMEM */
+
 int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
 				unsigned long size, pgprot_t *vma_prot)
 {
@@ -485,6 +513,9 @@ int phys_mem_access_prot_allowed(struct 
 	unsigned long ret_flags;
 	int retval;
 
+	if (!range_is_allowed(pfn, size))
+		return 0;
+
 	if (file->f_flags & O_SYNC) {
 		flags = _PAGE_CACHE_UC;
 	}
#8 lore raw

PATCH 1/1 x86, PAT: disable /dev/mem mmap RAM with PAT

Quoted 5 lines · Venki Pallipadi

OK. Below is the quick to disable /dev/mem mmap of RAM with PAT. This should go along with Ingo's patch that removes PAT dependency on NONPROMISC_DEVMEM. It makes things safer and eliminates aliasing. Still somewhat unclean as the range_is_allowed is duplicated. And also, just compile tested right now.

thanks, i've queued up the patch below. I'll do some testing and then send it to Linus.

Ingo

--------------->
Subject: x86, PAT: disable /dev/mem mmap RAM with PAT
From: Venki Pallipadi <[email protected]>
Date: Sat, 26 Apr 2008 11:32:12 -0700

disable /dev/mem mmap of RAM with PAT. It makes things safer and eliminates aliasing. A future improvement would be to avoid the range_is_allowed duplication.

---
 arch/x86/mm/pat.c |   31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
arch/x86/mm/pat.c +31 -0
Index: linux-x86.q/arch/x86/mm/pat.c
===================================================================
@@ -16,6 +16,7 @@
 #include <asm/msr.h>
 #include <asm/tlbflush.h>
 #include <asm/processor.h>
+#include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/pat.h>
 #include <asm/e820.h>
@@ -477,6 +478,33 @@ pgprot_t phys_mem_access_prot(struct fil
 	return vma_prot;
 }
 
+#ifdef CONFIG_NONPROMISC_DEVMEM
+/* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
+static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+{
+	return 1;
+}
+#else
+static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+{
+	u64 from = ((u64)pfn) << PAGE_SHIFT;
+	u64 to = from + size;
+	u64 cursor = from;
+
+	while (cursor < to) {
+		if (!devmem_is_allowed(pfn)) {
+			printk(KERN_INFO
+		"Program %s tried to access /dev/mem between %Lx->%Lx.\n",
+				current->comm, from, to);
+			return 0;
+		}
+		cursor += PAGE_SIZE;
+		pfn++;
+	}
+	return 1;
+}
+#endif /* CONFIG_NONPROMISC_DEVMEM */
+
 int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
 				unsigned long size, pgprot_t *vma_prot)
 {
@@ -485,6 +513,9 @@ int phys_mem_access_prot_allowed(struct 
 	unsigned long ret_flags;
 	int retval;
 
+	if (!range_is_allowed(pfn, size))
+		return 0;
+
 	if (file->f_flags & O_SYNC) {
 		flags = _PAGE_CACHE_UC;
 	}
#9 lore raw
In reply to Linus Torvalds
Quoted 43 lines · Linus Torvalds

Also, it causes this message for me on one of my machines:

	EXT3-fs: mounted filesystem with ordered data mode.
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	mtrr: no more MTRRs available
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	EXT3 FS on dm-0, internal journal
	...
	eth0: no IPv6 routers present
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xd0000000-0xd0020000
	mtrr: no more MTRRs available
	Overlap at 0xd0000000-0xe0000000
	Overlap at 0xe0300000-0xe0400000
	Overlap at 0xe0300000-0xe0380000
Quoted 1 line

which is a bit annoying. Forgotten debug printk, perhaps?

yeah - i already toned it down to KERN_INFO once in commit 28eb559b5 - but it should be pr_debug() instead. The idea in pat.c is to only print out if it's a material condition that the user should know about. I've queued up the patch below.

Ingo

-------->
Subject: x86 PAT: tone down debugging messages
From: Ingo Molnar <[email protected]>
Date: Sat Apr 26 11:40:31 CEST 2008

Linus reported these excessive debug printouts:

Quoted 7 lines
      Overlap at 0xe0300000-0xe0400000
      Overlap at 0xe0300000-0xe0380000
      Overlap at 0xe0300000-0xe0400000
      Overlap at 0xe0300000-0xe0400000
      Overlap at 0xe0300000-0xe0400000
      Overlap at 0xe0300000-0xe0400000
      Overlap at 0xe0300000-0xe0400000

turn that into a pr_debug().

---
 arch/x86/mm/pat.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/mm/pat.c +1 -1
Index: linux-x86.q/arch/x86/mm/pat.c
===================================================================
@@ -334,7 +334,7 @@ int reserve_memtype(u64 start, u64 end, 
 				break;
 			}
 
-			printk("Overlap at 0x%Lx-0x%Lx\n",
+			pr_debug("Overlap at 0x%Lx-0x%Lx\n",
 			       saved_ptr->start, saved_ptr->end);
 			/* No conflict. Go ahead and add this new entry */
 			list_add(&new_entry->nd, saved_ptr->nd.prev);
#10 lore raw
In reply to Ingo Molnar
Quoted 11 lines · Ingo Molnar

Linus, please pull the x86-pat git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86-pat.git for-linus

this adds the second (and final) phase of the x86 PAT changes. Due to generic impact (the drivers/char/mem.c and include/asm-generic/iomap.h changes) this is offered as a separate tree.

The new CONFIG_NONPROMISC_DEVMEM defaults to disabled so PAT will be disabled, to stay compatible and to be a bit cautious/gradual.

Hi Ingo,

When using an 64bit ( didn't got time to test 32bit now ) kernel[1] with PAT enabled , kvm-intel does not work anymore.

When modprobing kvm-intel , kvm is saying VT extension is disable by BIOS which isn't true. When disabling PAT again ( no changes to BIOS ) kvm-intel works again here.

Is that an known problem ?

If you need more infos just let me know.

Gabriel

[1] 2.6.25-05096-gb1721d0-dirty

     with following patches :
     http://lkml.org/lkml/2008/4/26/37
     http://lkml.org/lkml/2008/4/26/24
     http://lkml.org/lkml/2008/4/25/107
#11 lore raw
Quoted 10 lines · Gabriel C

Hi Ingo,

When using an 64bit ( didn't got time to test 32bit now ) kernel[1] with PAT enabled , kvm-intel does not work anymore.

When modprobing kvm-intel , kvm is saying VT extension is disable by BIOS which isn't true. When disabling PAT again ( no changes to BIOS ) kvm-intel works again here.

Is that an known problem ?

no, that side-effect was not known. Cc:-ed more folks.

Quoted 9 lines

If you need more infos just let me know.

Gabriel

[1] 2.6.25-05096-gb1721d0-dirty

     with following patches :
     http://lkml.org/lkml/2008/4/26/37
     http://lkml.org/lkml/2008/4/26/24
     http://lkml.org/lkml/2008/4/25/107

thanks - that should be enough for now. We'll try to reproduce these problems.

A blind guess: maybe it's the CONFIG_NONPROMISC_DEVMEM somehow breaks Qemu. With the patch below you'd be able to disable NONPROMISC_DEVMEM without disabling PAT.

Ingo

arch/x86/Kconfig +2 -2
index 4d350b5..4aa4180 100644
@@ -1049,9 +1049,9 @@ config MTRR
 	  See <file:Documentation/mtrr.txt> for more information.
 
 config X86_PAT
-	def_bool y
+	bool
 	prompt "x86 PAT support"
-	depends on MTRR && NONPROMISC_DEVMEM
+	depends on MTRR
 	help
 	  Use PAT attributes to setup page level cache control.
 
#12 lore raw
Quoted 7 lines · Ingo Molnar
Quoted 5 lines · Gabriel C

Hi Ingo,

When using an 64bit ( didn't got time to test 32bit now ) kernel[1] with PAT enabled , kvm-intel does not work anymore.

Quoted 7 lines
Quoted 5 lines

When modprobing kvm-intel , kvm is saying VT extension is disable by BIOS which isn't true. When disabling PAT again ( no changes to BIOS ) kvm-intel works again here.

Is that an known problem ?

no, that side-effect was not known. Cc:-ed more folks.

It seems like the update triggers some compiler bug.

Setting CC_OPTIMIZE_FOR_SIZE=n fixed that btw.

I don't have the time right now but later on today I will compile gcc43_svn_branch and test again with CC_OPTIMIZE_FOR_SIZE=y and see what I get.

Ingo sorry for the noise.

Gabriel

#13 lore raw
Quoted 18 lines · Gabriel C
Quoted 7 lines · Ingo Molnar
Quoted 5 lines · Gabriel C

Hi Ingo,

When using an 64bit ( didn't got time to test 32bit now ) kernel[1] with PAT enabled , kvm-intel does not work anymore.

Quoted 7 lines
Quoted 5 lines

When modprobing kvm-intel , kvm is saying VT extension is disable by BIOS which isn't true. When disabling PAT again ( no changes to BIOS ) kvm-intel works again here.

Is that an known problem ?

no, that side-effect was not known. Cc:-ed more folks.

It seems like the update triggers some compiler bug.

Quoted 7 lines

Setting CC_OPTIMIZE_FOR_SIZE=n fixed that btw.

I don't have the time right now but later on today I will compile gcc43_svn_branch and test again with CC_OPTIMIZE_FOR_SIZE=y and see what I get.

Ingo sorry for the noise.

no problem and it's not noise even if it turns out to be a compiler problem - we very much want to know about them when they affect the kernel.

Ingo

#14 lore raw
Quoted 10 lines · Ingo Molnar
Quoted 9 lines · Gabriel C

It seems like the update triggers some compiler bug.

Setting CC_OPTIMIZE_FOR_SIZE=n fixed that btw.

I don't have the time right now but later on today I will compile gcc43_svn_branch and test again with CC_OPTIMIZE_FOR_SIZE=y and see what I get.

Quoted 5 lines
Quoted 1 line

Ingo sorry for the noise.

no problem and it's not noise even if it turns out to be a compiler problem - we very much want to know about them when they affect the kernel.

Indeed. Often these kinds of compiler issues are also actually our bugs, where some code generation thing just happened to hide the fact that we did something wrong.

So Gabriel, it would be wondeful if you could try to pinpoint where the problem happens. That said, especially if you are using something like a self-compiled gcc from the current SVN tree, that obviously does make it a *lot* more likely that you are hitting a real compiler bug.

(But even then, if you can pinpoint it, I bet the gcc people would be really happy to hear about it.)

Linus