Patches contributed by Eötvös Lorand University
commit 9df84993cb3d71669894654ab257f01f6e4ed48e
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Feb 4 16:48:09 2008 +0100
x86: cpa, cleanups
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 42ca3d8effad..029fb07b3f03 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -16,6 +16,9 @@
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
+/*
+ * The current flushing context - we pass it instead of 5 arguments:
+ */
struct cpa_data {
unsigned long vaddr;
pgprot_t mask_set;
@@ -206,6 +209,7 @@ pte_t *lookup_address(unsigned long address, int *level)
if (pgd_none(*pgd))
return NULL;
+
pud = pud_offset(pgd, address);
if (pud_none(*pud))
return NULL;
@@ -223,9 +227,13 @@ pte_t *lookup_address(unsigned long address, int *level)
return (pte_t *)pmd;
*level = PG_LEVEL_4K;
+
return pte_offset_kernel(pmd, address);
}
+/*
+ * Set the new pmd in all the pgds we know about:
+ */
static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
{
/* change init_mm */
@@ -248,8 +256,9 @@ static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
#endif
}
-static int try_preserve_large_page(pte_t *kpte, unsigned long address,
- struct cpa_data *cpa)
+static int
+try_preserve_large_page(pte_t *kpte, unsigned long address,
+ struct cpa_data *cpa)
{
unsigned long nextpage_addr, numpages, pmask, psize, flags;
pte_t new_pte, old_pte, *tmp;
@@ -341,17 +350,18 @@ static int try_preserve_large_page(pte_t *kpte, unsigned long address,
out_unlock:
spin_unlock_irqrestore(&pgd_lock, flags);
+
return res;
}
static int split_large_page(pte_t *kpte, unsigned long address)
{
- pgprot_t ref_prot;
- gfp_t gfp_flags = GFP_KERNEL;
unsigned long flags, addr, pfn, pfninc = 1;
+ gfp_t gfp_flags = GFP_KERNEL;
+ unsigned int i, level;
pte_t *pbase, *tmp;
+ pgprot_t ref_prot;
struct page *base;
- unsigned int i, level;
#ifdef CONFIG_DEBUG_PAGEALLOC
gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
@@ -505,7 +515,6 @@ static int __change_page_attr(unsigned long address, struct cpa_data *cpa)
*
* Modules and drivers should use the set_memory_* APIs instead.
*/
-
static int change_page_attr_addr(struct cpa_data *cpa)
{
int err;
commit 6ce9fc17d913ae51f8434d2826f306347820b07d
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Feb 4 16:48:08 2008 +0100
x86: remove cpa warning
this race is legit and can happen on SMP systems.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 72880993af89..0b029c97174e 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -356,10 +356,8 @@ static int split_large_page(pte_t *kpte, unsigned long address)
* up for us already:
*/
tmp = lookup_address(address, &level);
- if (tmp != kpte) {
- WARN_ON_ONCE(1);
+ if (tmp != kpte)
goto out_unlock;
- }
address = __pa(address);
addr = address & PMD_PAGE_MASK;
commit 34508f66b69ff1708192654f631eb8f1d4c52005
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Feb 4 16:48:07 2008 +0100
x86: AMD Athlon X2 hard hang fix
An Athlon 64 X2 test system showed hard hangs shortly after marking
the kernel text read-only, if we tried to preserve largepages and
changed the PSE entry from RW to RO. The pagetable code itself is
correct, it's the CPU that locked up hard (and not even the NMI
watchdog could punch through that hard hang).
So be conservative and always do splitups - like we did in the past.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 40b7ac58e671..3810f7a83b1d 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -243,6 +243,17 @@ static int try_preserve_large_page(pte_t *kpte, unsigned long address,
pgprot_t old_prot, new_prot;
int level, res = CPA_SPLIT;
+ /*
+ * An Athlon 64 X2 showed hard hangs if we tried to preserve
+ * largepages and changed the PSE entry from RW to RO.
+ *
+ * As AMD CPUs have a long series of erratas in this area,
+ * (and none of the known ones seem to explain this hang),
+ * disable this code until the hang can be debugged:
+ */
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ return res;
+
spin_lock_irqsave(&pgd_lock, flags);
/*
* Check for races, another CPU might have split this page
commit 262d5ee27271703a0396d63649430f43f3b5deb3
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Feb 4 16:47:54 2008 +0100
x86: VMI fix
Jeff Chua bisected down a vmware guest boot breakage (hang) to
this paravirt change:
commit 8d947344c47a40626730bb80d136d8daac9f2060
Author: Glauber de Oliveira Costa <gcosta@redhat.com>
Date: Wed Jan 30 13:31:12 2008 +0100
x86: change write_idt_entry signature
fix the off-by-one indexing bug ...
Bisected-by: Jeff Chua <jeff.chua.linux@gmail.com>
Tested-by: Jeff Chua <jeff.chua.linux@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 4525bc2c2e19..12affe1f9bce 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -220,21 +220,21 @@ static void vmi_set_tr(void)
static void vmi_write_idt_entry(gate_desc *dt, int entry, const gate_desc *g)
{
u32 *idt_entry = (u32 *)g;
- vmi_ops.write_idt_entry(dt, entry, idt_entry[0], idt_entry[2]);
+ vmi_ops.write_idt_entry(dt, entry, idt_entry[0], idt_entry[1]);
}
static void vmi_write_gdt_entry(struct desc_struct *dt, int entry,
const void *desc, int type)
{
u32 *gdt_entry = (u32 *)desc;
- vmi_ops.write_gdt_entry(dt, entry, gdt_entry[0], gdt_entry[2]);
+ vmi_ops.write_gdt_entry(dt, entry, gdt_entry[0], gdt_entry[1]);
}
static void vmi_write_ldt_entry(struct desc_struct *dt, int entry,
const void *desc)
{
u32 *ldt_entry = (u32 *)desc;
- vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[2]);
+ vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
}
static void vmi_load_sp0(struct tss_struct *tss,
commit 38cb47ba0187c481aa949d3bbf149e014e8cacda
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Feb 4 16:47:54 2008 +0100
x86: relax RAM check in ioremap()
Kevin Winchester reported the loss of direct rendering, due to:
[ 0.588184] agpgart: Detected AGP bridge 0
[ 0.588184] agpgart: unable to get memory for graphics translation table.
[ 0.588184] agpgart: agp_backend_initialize() failed.
[ 0.588207] agpgart-amd64: probe of 0000:00:00.0 failed with error -12
and bisected it down to:
commit 266b9f8727976769e2ed2dad77ac9295f37e321e
Author: Thomas Gleixner <tglx@linutronix.de>
Date: Wed Jan 30 13:34:06 2008 +0100
x86: fix ioremap RAM check
this check was too strict and caused an ioremap() failure.
the problem is due to the somewhat unclean way of how the GART code
reserves a memory range for its aperture, and how it utilizes it
later on.
Allow RAM pages to be ioremap()-ed too, as long as they are reserved.
Bisected-by: Kevin Winchester <kjwinchester@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Tested-by: Kevin Winchester <kjwinchester@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index c004d94608fd..1a88d1572a77 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -116,7 +116,7 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
{
void __iomem *addr;
struct vm_struct *area;
- unsigned long offset, last_addr;
+ unsigned long pfn, offset, last_addr;
pgprot_t prot;
/* Don't allow wraparound or zero size */
@@ -133,9 +133,10 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
- for (offset = phys_addr >> PAGE_SHIFT; offset < max_pfn_mapped &&
- (offset << PAGE_SHIFT) < last_addr; offset++) {
- if (page_is_ram(offset))
+ for (pfn = phys_addr >> PAGE_SHIFT; pfn < max_pfn_mapped &&
+ (pfn << PAGE_SHIFT) < last_addr; pfn++) {
+ if (page_is_ram(pfn) && pfn_valid(pfn) &&
+ !PageReserved(pfn_to_page(pfn)))
return NULL;
}
commit aa6299926950c8dfe2fea638276cad6def092bc9
Author: Ingo Molnar <mingo@elte.hu>
Date: Fri Feb 1 23:45:18 2008 +0100
x86: fix bootup crash in native_read_tsc()
fix bootup crash in native_read_tsc() that was reported on an Athlon-XP
and bisected. The correct feature boundary for X86_FEATURE_MFENCE_RDTSC
is not XMM but XMM2.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 06fa159232fd..693e353999cd 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -304,7 +304,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
if (c->x86 < 6)
clear_bit(X86_FEATURE_MCE, c->x86_capability);
- if (cpu_has_xmm)
+ if (cpu_has_xmm2)
set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
}
commit c4772d99300a9fc13c86aaa370e630c5973664f6
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Jan 31 22:45:23 2008 +0100
debug: turn ignore_loglevel into an early param
i was debugging early crashes and wondered where all the printks
went. The reason: ignore_loglevel_setup() was not called yet ...
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/kernel/printk.c b/kernel/printk.c
index 58bbec684119..29ae1e99cde0 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -455,10 +455,10 @@ static int __init ignore_loglevel_setup(char *str)
ignore_loglevel = 1;
printk(KERN_INFO "debug: ignoring loglevel setting.\n");
- return 1;
+ return 0;
}
-__setup("ignore_loglevel", ignore_loglevel_setup);
+early_param("ignore_loglevel", ignore_loglevel_setup);
/*
* Write out chars from start to end - 1 inclusive
commit 62152d0ea7012382cd814c7b361b4ef2029f26e6
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Jan 31 22:05:48 2008 +0100
asm-generic/tlb.h: build fix
bring back the avr32, blackfin, sh, sparc architectures into working order,
by reverting the effects of this change that came in via the x86 tree:
commit a5a19c63f4e55e32dc0bc3d936d7f94793d8b380
Author: Jeremy Fitzhardinge <jeremy@goop.org>
Date: Wed Jan 30 13:33:39 2008 +0100
x86: demacro asm-x86/pgalloc_32.h
Sorry about that!
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 6ce9f3ab928d..75f2bfab614f 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -15,6 +15,7 @@
#include <linux/swap.h>
#include <linux/quicklist.h>
+#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
/*
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 2c3ce4c69b25..4f3838adbb30 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -6,7 +6,6 @@
#include <linux/mmzone.h>
#include <linux/list.h>
#include <linux/sched.h>
-#include <linux/pagemap.h>
#include <asm/atomic.h>
#include <asm/page.h>
commit 5aa0508508e7cd62bec6e3933b86fce03d2e8502
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Jan 31 22:05:48 2008 +0100
x86: uninline __pte_free_tlb() and __pmd_free_tlb()
this also removes an include file dependency.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index 2ae5999a795a..cb3aa470249b 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -376,3 +376,26 @@ void check_pgt_cache(void)
{
quicklist_trim(0, pgd_dtor, 25, 16);
}
+
+void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
+{
+ paravirt_release_pt(page_to_pfn(pte));
+ tlb_remove_page(tlb, pte);
+}
+
+#ifdef CONFIG_X86_PAE
+
+void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+{
+ /* This is called just after the pmd has been detached from
+ the pgd, which requires a full tlb flush to be recognized
+ by the CPU. Rather than incurring multiple tlb flushes
+ while the address space is being pulled down, make the tlb
+ gathering machinery do a full flush when we're done. */
+ tlb->fullmm = 1;
+
+ paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
+ tlb_remove_page(tlb, virt_to_page(pmd));
+}
+
+#endif
diff --git a/include/asm-x86/pgalloc_32.h b/include/asm-x86/pgalloc_32.h
index 10c2b452e64c..7641e7b5d931 100644
--- a/include/asm-x86/pgalloc_32.h
+++ b/include/asm-x86/pgalloc_32.h
@@ -3,6 +3,7 @@
#include <linux/threads.h>
#include <linux/mm.h> /* for struct page */
+#include <linux/pagemap.h>
#include <asm/tlb.h>
#include <asm-generic/tlb.h>
@@ -51,11 +52,7 @@ static inline void pte_free(struct page *pte)
}
-static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
-{
- paravirt_release_pt(page_to_pfn(pte));
- tlb_remove_page(tlb, pte);
-}
+extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte);
#ifdef CONFIG_X86_PAE
/*
@@ -72,18 +69,7 @@ static inline void pmd_free(pmd_t *pmd)
free_page((unsigned long)pmd);
}
-static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
-{
- /* This is called just after the pmd has been detached from
- the pgd, which requires a full tlb flush to be recognized
- by the CPU. Rather than incurring multiple tlb flushes
- while the address space is being pulled down, make the tlb
- gathering machinery do a full flush when we're done. */
- tlb->fullmm = 1;
-
- paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
- tlb_remove_page(tlb, virt_to_page(pmd));
-}
+extern void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd);
static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
{
commit 9b1fffddc80949fb4aa93fdcc57544bc2108ced3
Author: Ingo Molnar <mingo@elte.hu>
Date: Fri Nov 16 15:20:28 2007 +0100
[ALSA] snd hda suspend latency: shorten codec read
not sleeping for every codec read/write but doing a short udelay and
a conditional reschedule has cut suspend+resume latency by about 1
second on my T60.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 38c591649147..41edf85db38b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -561,7 +561,8 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
}
if (!chip->rirb.cmds)
return chip->rirb.res; /* the last value */
- schedule_timeout_uninterruptible(1);
+ udelay(10);
+ cond_resched();
} while (time_after_eq(timeout, jiffies));
if (chip->msi) {