Patches contributed by Eötvös Lorand University
commit 886b5b73d71e4027d7dc6c14f5f7ab102201ea6b
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Feb 25 11:03:44 2009 +0100
tracing: remove /debug/tracing/latency_trace
Impact: remove old debug/tracing API
/debug/tracing/latency_trace is an old legacy format we kept from
the old latency tracer. Remove the file for now. If there's any
useful bit missing then we'll propagate any useful output bits into
the /debug/tracing/trace output.
Reported-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e1f3b99a2e52..11ba100f9a9e 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2938,11 +2938,6 @@ static __init int tracer_init_debugfs(void)
if (!entry)
pr_warning("Could not create debugfs 'tracing_cpumask' entry\n");
- entry = debugfs_create_file("latency_trace", 0444, d_tracer,
- &global_trace, &tracing_lt_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'latency_trace' entry\n");
-
entry = debugfs_create_file("trace", 0444, d_tracer,
&global_trace, &tracing_fops);
if (!entry)
commit 95108fa34a83ffd97e0af959e4b28d7c62008781
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Feb 25 08:22:20 2009 +0100
x86: usercopy: check for total size when deciding non-temporal cutoff
Impact: make more types of copies non-temporal
This change makes the following simple fix:
30d697f: x86: fix performance regression in write() syscall
A bit more sophisticated: we check the 'total' number of bytes
written to decide whether to copy in a cached or a non-temporal
way.
This will for example cause the tail (modulo 4096 bytes) chunk
of a large write() to be non-temporal too - not just the page-sized
chunks.
Cc: Salman Qazi <sqazi@google.com>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index a748253db0c9..dcaa0404cf7b 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -198,7 +198,7 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src,
* non-temporal stores here. Smaller writes get handled
* via regular __copy_from_user():
*/
- if (likely(size >= PAGE_SIZE))
+ if (likely(total >= PAGE_SIZE))
return __copy_user_nocache(dst, src, size, 1);
else
return __copy_from_user(dst, src, size);
@@ -207,7 +207,7 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src,
static inline int __copy_from_user_inatomic_nocache(void *dst,
const void __user *src, unsigned size, unsigned total)
{
- if (likely(size >= PAGE_SIZE))
+ if (likely(total >= PAGE_SIZE))
return __copy_user_nocache(dst, src, size, 0);
else
return __copy_from_user_inatomic(dst, src, size);
commit 3255aa2eb636a508fc82a73fabbb8aaf2ff23c0f
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Feb 25 08:21:52 2009 +0100
x86, mm: pass in 'total' to __copy_from_user_*nocache()
Impact: cleanup, enable future change
Add a 'total bytes copied' parameter to __copy_from_user_*nocache(),
and update all the callsites.
The parameter is not used yet - architecture code can use it to
more intelligently decide whether the copy should be cached or
non-temporal.
Cc: Salman Qazi <sqazi@google.com>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index 5e06259e90e5..a0ba61386972 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
@@ -157,7 +157,7 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
}
static __always_inline unsigned long __copy_from_user_nocache(void *to,
- const void __user *from, unsigned long n)
+ const void __user *from, unsigned long n, unsigned long total)
{
might_fault();
if (__builtin_constant_p(n)) {
@@ -180,7 +180,7 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to,
static __always_inline unsigned long
__copy_from_user_inatomic_nocache(void *to, const void __user *from,
- unsigned long n)
+ unsigned long n, unsigned long total)
{
return __copy_from_user_ll_nocache_nozero(to, from, n);
}
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index 987a2c10fe20..a748253db0c9 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -189,7 +189,7 @@ extern long __copy_user_nocache(void *dst, const void __user *src,
unsigned size, int zerorest);
static inline int __copy_from_user_nocache(void *dst, const void __user *src,
- unsigned size)
+ unsigned size, unsigned long total)
{
might_sleep();
/*
@@ -205,8 +205,7 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src,
}
static inline int __copy_from_user_inatomic_nocache(void *dst,
- const void __user *src,
- unsigned size)
+ const void __user *src, unsigned size, unsigned total)
{
if (likely(size >= PAGE_SIZE))
return __copy_user_nocache(dst, src, size, 0);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 818576654092..6b209db8370d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -215,7 +215,7 @@ fast_user_write(struct io_mapping *mapping,
vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base);
unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset,
- user_data, length);
+ user_data, length, length);
io_mapping_unmap_atomic(vaddr_atomic);
if (unwritten)
return -EFAULT;
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 6b58367d145e..6f3c603b0d67 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -41,13 +41,13 @@ static inline void pagefault_enable(void)
#ifndef ARCH_HAS_NOCACHE_UACCESS
static inline unsigned long __copy_from_user_inatomic_nocache(void *to,
- const void __user *from, unsigned long n)
+ const void __user *from, unsigned long n, unsigned long total)
{
return __copy_from_user_inatomic(to, from, n);
}
static inline unsigned long __copy_from_user_nocache(void *to,
- const void __user *from, unsigned long n)
+ const void __user *from, unsigned long n, unsigned long total)
{
return __copy_from_user(to, from, n);
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 23acefe51808..60fd56772cc6 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1816,14 +1816,14 @@ EXPORT_SYMBOL(file_remove_suid);
static size_t __iovec_copy_from_user_inatomic(char *vaddr,
const struct iovec *iov, size_t base, size_t bytes)
{
- size_t copied = 0, left = 0;
+ size_t copied = 0, left = 0, total = bytes;
while (bytes) {
char __user *buf = iov->iov_base + base;
int copy = min(bytes, iov->iov_len - base);
base = 0;
- left = __copy_from_user_inatomic_nocache(vaddr, buf, copy);
+ left = __copy_from_user_inatomic_nocache(vaddr, buf, copy, total);
copied += copy;
bytes -= copy;
vaddr += copy;
@@ -1851,8 +1851,9 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
if (likely(i->nr_segs == 1)) {
int left;
char __user *buf = i->iov->iov_base + i->iov_offset;
+
left = __copy_from_user_inatomic_nocache(kaddr + offset,
- buf, bytes);
+ buf, bytes, bytes);
copied = bytes - left;
} else {
copied = __iovec_copy_from_user_inatomic(kaddr + offset,
@@ -1880,7 +1881,8 @@ size_t iov_iter_copy_from_user(struct page *page,
if (likely(i->nr_segs == 1)) {
int left;
char __user *buf = i->iov->iov_base + i->iov_offset;
- left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
+
+ left = __copy_from_user_nocache(kaddr + offset, buf, bytes, bytes);
copied = bytes - left;
} else {
copied = __iovec_copy_from_user_inatomic(kaddr + offset,
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 0c04615651b7..bf54f8a2cf1d 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -354,7 +354,7 @@ __xip_file_write(struct file *filp, const char __user *buf,
break;
copied = bytes -
- __copy_from_user_nocache(xip_mem + offset, buf, bytes);
+ __copy_from_user_nocache(xip_mem + offset, buf, bytes, bytes);
if (likely(copied > 0)) {
status = copied;
commit 2d542cf34264ac92e9e7ac55c0b096b066d569d2
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Feb 25 08:40:09 2009 +0100
tracing/hw-branch-tracing: convert bts-tracer mutex to a spinlock
Impact: fix CPU hotplug lockup
bts_hotcpu_handler() is called with irqs disabled, so using mutex_lock()
is a no-no.
All the BTS codepaths here are atomic (they do not schedule), so using
a spinlock is the right solution.
Cc: Markus Metzger <markus.t.metzger@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
index 3335e807144b..7bfdf4c2347f 100644
--- a/kernel/trace/trace_hw_branches.c
+++ b/kernel/trace/trace_hw_branches.c
@@ -3,17 +3,15 @@
*
* Copyright (C) 2008-2009 Intel Corporation.
* Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009
- *
*/
-
-#include <linux/module.h>
-#include <linux/fs.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
#include <linux/debugfs.h>
#include <linux/ftrace.h>
-#include <linux/kallsyms.h>
-#include <linux/mutex.h>
+#include <linux/module.h>
#include <linux/cpu.h>
#include <linux/smp.h>
+#include <linux/fs.h>
#include <asm/ds.h>
@@ -23,16 +21,17 @@
#define SIZEOF_BTS (1 << 13)
-/* The tracer mutex protects the below per-cpu tracer array.
- It needs to be held to:
- - start tracing on all cpus
- - stop tracing on all cpus
- - start tracing on a single hotplug cpu
- - stop tracing on a single hotplug cpu
- - read the trace from all cpus
- - read the trace from a single cpu
-*/
-static DEFINE_MUTEX(bts_tracer_mutex);
+/*
+ * The tracer lock protects the below per-cpu tracer array.
+ * It needs to be held to:
+ * - start tracing on all cpus
+ * - stop tracing on all cpus
+ * - start tracing on a single hotplug cpu
+ * - stop tracing on a single hotplug cpu
+ * - read the trace from all cpus
+ * - read the trace from a single cpu
+ */
+static DEFINE_SPINLOCK(bts_tracer_lock);
static DEFINE_PER_CPU(struct bts_tracer *, tracer);
static DEFINE_PER_CPU(unsigned char[SIZEOF_BTS], buffer);
@@ -47,7 +46,7 @@ static struct trace_array *hw_branch_trace __read_mostly;
* Start tracing on the current cpu.
* The argument is ignored.
*
- * pre: bts_tracer_mutex must be locked.
+ * pre: bts_tracer_lock must be locked.
*/
static void bts_trace_start_cpu(void *arg)
{
@@ -66,19 +65,19 @@ static void bts_trace_start_cpu(void *arg)
static void bts_trace_start(struct trace_array *tr)
{
- mutex_lock(&bts_tracer_mutex);
+ spin_lock(&bts_tracer_lock);
on_each_cpu(bts_trace_start_cpu, NULL, 1);
trace_hw_branches_enabled = 1;
- mutex_unlock(&bts_tracer_mutex);
+ spin_unlock(&bts_tracer_lock);
}
/*
* Stop tracing on the current cpu.
* The argument is ignored.
*
- * pre: bts_tracer_mutex must be locked.
+ * pre: bts_tracer_lock must be locked.
*/
static void bts_trace_stop_cpu(void *arg)
{
@@ -90,12 +89,12 @@ static void bts_trace_stop_cpu(void *arg)
static void bts_trace_stop(struct trace_array *tr)
{
- mutex_lock(&bts_tracer_mutex);
+ spin_lock(&bts_tracer_lock);
trace_hw_branches_enabled = 0;
on_each_cpu(bts_trace_stop_cpu, NULL, 1);
- mutex_unlock(&bts_tracer_mutex);
+ spin_unlock(&bts_tracer_lock);
}
static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
@@ -103,7 +102,7 @@ static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
{
unsigned int cpu = (unsigned long)hcpu;
- mutex_lock(&bts_tracer_mutex);
+ spin_lock(&bts_tracer_lock);
if (!trace_hw_branches_enabled)
goto out;
@@ -119,7 +118,7 @@ static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
}
out:
- mutex_unlock(&bts_tracer_mutex);
+ spin_unlock(&bts_tracer_lock);
return NOTIFY_DONE;
}
@@ -225,7 +224,7 @@ static void trace_bts_at(const struct bts_trace *trace, void *at)
/*
* Collect the trace on the current cpu and write it into the ftrace buffer.
*
- * pre: bts_tracer_mutex must be locked
+ * pre: bts_tracer_lock must be locked
*/
static void trace_bts_cpu(void *arg)
{
@@ -261,11 +260,11 @@ static void trace_bts_cpu(void *arg)
static void trace_bts_prepare(struct trace_iterator *iter)
{
- mutex_lock(&bts_tracer_mutex);
+ spin_lock(&bts_tracer_lock);
on_each_cpu(trace_bts_cpu, iter->tr, 1);
- mutex_unlock(&bts_tracer_mutex);
+ spin_unlock(&bts_tracer_lock);
}
static void trace_bts_close(struct trace_iterator *iter)
@@ -275,11 +274,11 @@ static void trace_bts_close(struct trace_iterator *iter)
void trace_hw_branch_oops(void)
{
- mutex_lock(&bts_tracer_mutex);
+ spin_lock(&bts_tracer_lock);
trace_bts_cpu(hw_branch_trace);
- mutex_unlock(&bts_tracer_mutex);
+ spin_unlock(&bts_tracer_lock);
}
struct tracer bts_tracer __read_mostly =
commit 95f66b3770d6d0755b4a2d818c237574ffd74e4c
Merge: 46cb27f5169d 9f331119a4f9
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Feb 25 08:27:46 2009 +0100
Merge branch 'x86/asm' into x86/mm
commit 0edcf8d6926f4038443dbc24e319530177ca0353
Merge: 87b203079ed9 40150d37be7f
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Feb 24 21:52:45 2009 +0100
Merge branch 'tj-percpu' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc into core/percpu
Conflicts:
arch/x86/include/asm/pgtable.h
diff --cc arch/x86/include/asm/pgtable.h
index 1c097a3a6669,46312eb0d682..d0812e155f1d
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@@ -288,195 -388,84 +288,197 @@@ static inline int is_new_memtype_allowe
return 1;
}
-#ifndef __ASSEMBLY__
-/* Indicate that x86 has its own track and untrack pfn vma functions */
-#define __HAVE_PFNMAP_TRACKING
-
-#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
-
-/* Install a pte for a particular vaddr in kernel space. */
-void set_pte_vaddr(unsigned long vaddr, pte_t pte);
+ pmd_t *populate_extra_pmd(unsigned long vaddr);
+ pte_t *populate_extra_pte(unsigned long vaddr);
+#endif /* __ASSEMBLY__ */
#ifdef CONFIG_X86_32
-extern void native_pagetable_setup_start(pgd_t *base);
-extern void native_pagetable_setup_done(pgd_t *base);
+# include "pgtable_32.h"
#else
-static inline void native_pagetable_setup_start(pgd_t *base) {}
-static inline void native_pagetable_setup_done(pgd_t *base) {}
+# include "pgtable_64.h"
#endif
-struct seq_file;
-extern void arch_report_meminfo(struct seq_file *m);
+#ifndef __ASSEMBLY__
+#include <linux/mm_types.h>
-#ifdef CONFIG_PARAVIRT
-#include <asm/paravirt.h>
-#else /* !CONFIG_PARAVIRT */
-#define set_pte(ptep, pte) native_set_pte(ptep, pte)
-#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte)
+static inline int pte_none(pte_t pte)
+{
+ return !pte.pte;
+}
-#define set_pte_present(mm, addr, ptep, pte) \
- native_set_pte_present(mm, addr, ptep, pte)
-#define set_pte_atomic(ptep, pte) \
- native_set_pte_atomic(ptep, pte)
+#define __HAVE_ARCH_PTE_SAME
+static inline int pte_same(pte_t a, pte_t b)
+{
+ return a.pte == b.pte;
+}
-#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd)
+static inline int pte_present(pte_t a)
+{
+ return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
+}
-#ifndef __PAGETABLE_PUD_FOLDED
-#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd)
-#define pgd_clear(pgd) native_pgd_clear(pgd)
-#endif
+static inline int pmd_present(pmd_t pmd)
+{
+ return pmd_flags(pmd) & _PAGE_PRESENT;
+}
-#ifndef set_pud
-# define set_pud(pudp, pud) native_set_pud(pudp, pud)
-#endif
+static inline int pmd_none(pmd_t pmd)
+{
+ /* Only check low word on 32-bit platforms, since it might be
+ out of sync with upper half. */
+ return (unsigned long)native_pmd_val(pmd) == 0;
+}
-#ifndef __PAGETABLE_PMD_FOLDED
-#define pud_clear(pud) native_pud_clear(pud)
-#endif
+static inline unsigned long pmd_page_vaddr(pmd_t pmd)
+{
+ return (unsigned long)__va(pmd_val(pmd) & PTE_PFN_MASK);
+}
-#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep)
-#define pmd_clear(pmd) native_pmd_clear(pmd)
+/*
+ * Currently stuck as a macro due to indirect forward reference to
+ * linux/mmzone.h's __section_mem_map_addr() definition:
+ */
+#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
-#define pte_update(mm, addr, ptep) do { } while (0)
-#define pte_update_defer(mm, addr, ptep) do { } while (0)
+/*
+ * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+ *
+ * this macro returns the index of the entry in the pmd page which would
+ * control the given virtual address
+ */
+static inline unsigned pmd_index(unsigned long address)
+{
+ return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+}
-static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * (Currently stuck as a macro because of indirect forward reference
+ * to linux/mm.h:page_to_nid())
+ */
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this function returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+static inline unsigned pte_index(unsigned long address)
{
- native_pagetable_setup_start(base);
+ return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
}
-static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
+static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
{
- native_pagetable_setup_done(base);
+ return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address);
}
-#endif /* CONFIG_PARAVIRT */
-#endif /* __ASSEMBLY__ */
+static inline int pmd_bad(pmd_t pmd)
+{
+ return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;
+}
-#ifdef CONFIG_X86_32
-# include "pgtable_32.h"
+static inline unsigned long pages_to_mb(unsigned long npg)
+{
+ return npg >> (20 - PAGE_SHIFT);
+}
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#if PAGETABLE_LEVELS > 2
+static inline int pud_none(pud_t pud)
+{
+ return native_pud_val(pud) == 0;
+}
+
+static inline int pud_present(pud_t pud)
+{
+ return pud_flags(pud) & _PAGE_PRESENT;
+}
+
+static inline unsigned long pud_page_vaddr(pud_t pud)
+{
+ return (unsigned long)__va((unsigned long)pud_val(pud) & PTE_PFN_MASK);
+}
+
+/*
+ * Currently stuck as a macro due to indirect forward reference to
+ * linux/mmzone.h's __section_mem_map_addr() definition:
+ */
+#define pud_page(pud) pfn_to_page(pud_val(pud) >> PAGE_SHIFT)
+
+/* Find an entry in the second-level page table.. */
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+{
+ return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
+}
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+ return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
+}
+
+static inline int pud_large(pud_t pud)
+{
+ return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
+ (_PAGE_PSE | _PAGE_PRESENT);
+}
+
+static inline int pud_bad(pud_t pud)
+{
+ return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
+}
#else
-# include "pgtable_64.h"
-#endif
+static inline int pud_large(pud_t pud)
+{
+ return 0;
+}
+#endif /* PAGETABLE_LEVELS > 2 */
+
+#if PAGETABLE_LEVELS > 3
+static inline int pgd_present(pgd_t pgd)
+{
+ return pgd_flags(pgd) & _PAGE_PRESENT;
+}
+
+static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+{
+ return (unsigned long)__va((unsigned long)pgd_val(pgd) & PTE_PFN_MASK);
+}
+
+/*
+ * Currently stuck as a macro due to indirect forward reference to
+ * linux/mmzone.h's __section_mem_map_addr() definition:
+ */
+#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
+
+/* to find an entry in a page-table-directory. */
+static inline unsigned pud_index(unsigned long address)
+{
+ return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
+}
+
+static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
+{
+ return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address);
+}
+
+static inline int pgd_bad(pgd_t pgd)
+{
+ return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
+}
+
+static inline int pgd_none(pgd_t pgd)
+{
+ return !native_pgd_val(pgd);
+}
+#endif /* PAGETABLE_LEVELS > 3 */
+
+#endif /* __ASSEMBLY__ */
/*
* the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
commit 87b203079ed949de52f0d92aeae20e5e0116c12f
Merge: 58105ef18571 a852cbfaaf81
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Feb 24 21:52:27 2009 +0100
Merge branch 'x86/core' into core/percpu
commit a852cbfaaf8122827602027b1614971cfd832304
Merge: 0d3a9cf5ab04 ecda06289f82 9f331119a4f9 bda3a89745d7 b319eed0aa0a a967bb3fbe64 954a8b8162ec
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Feb 24 21:50:43 2009 +0100
Merge branches 'x86/acpi', 'x86/apic', 'x86/asm', 'x86/cleanups', 'x86/mm', 'x86/signal' and 'x86/urgent'; commit 'v2.6.29-rc6' into x86/core
diff --cc Makefile
index 681c1d23b4d4,96628d0b48d2,b280cfcf1efe,96628d0b48d2,96628d0b48d2,96628d0b48d2,df6ce3e80090..27fb890a2bff
--- a/Makefile
+++ b/Makefile
@@@@@@@@ -1,7 -1,7 -1,7 -1,7 -1,7 -1,7 -1,7 +1,7 @@@@@@@@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
- EXTRAVERSION = -rc4
----- EXTRAVERSION = -rc5
++++++ EXTRAVERSION = -rc6
NAME = Erotic Pickled Herring
# *DOCUMENTATION*
diff --cc arch/x86/kernel/traps.c
index 98c2d055284b,c8c0a7e530be,acb8c0585ab9,2df927b5003f,acb8c0585ab9,acb8c0585ab9,a9e7548e1790..c05430ac1b44
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@@@@@@@ -59,10 -59,9 -59,9 -59,9 -59,9 -59,9 -59,10 +59,9 @@@@@@@@
#ifdef CONFIG_X86_64
#include <asm/pgalloc.h>
#include <asm/proto.h>
- -#include <asm/pda.h>
#else
#include <asm/processor-flags.h>
- -----#include <asm/arch_hooks.h>
+ +++++#include <asm/setup.h>
#include <asm/traps.h>
#include "cpu/mcheck/mce.h"
@@@@@@@@ -906,16 -913,20 -913,20 -913,20 -913,20 -913,20 -914,19 +913,20 @@@@@@@@ void math_emulate(struct math_emu_info
}
#endif /* CONFIG_MATH_EMULATION */
-dotraplinkage void __kprobes do_device_not_available(struct pt_regs regs)
+dotraplinkage void __kprobes
- do_device_not_available(struct pt_regs *regs, long error)
+ +do_device_not_available(struct pt_regs *regs, long error_code)
{
#ifdef CONFIG_X86_32
if (read_cr0() & X86_CR0_EM) {
+ struct math_emu_info info = { };
+
- conditional_sti(®s);
+ conditional_sti(regs);
- math_emulate(0);
+
- info.regs = ®s;
+ + info.regs = regs;
+ math_emulate(&info);
} else {
math_state_restore(); /* interrupts still off */
- conditional_sti(®s);
+ conditional_sti(regs);
}
#else
math_state_restore();
diff --cc arch/x86/kernel/vmiclock_32.c
index c4c1f9e09402,49b4cd6707f9,a4791ef412d1,b77ad5789af9,9cd28c04952a,9cd28c04952a,e5b088fffa40..33a788d5879c
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@@@@@@@ -286,7 -286,9 -286,7 -287,8 -287,9 -287,9 -287,9 +286,8 @@@@@@@@ static struct clocksource clocksource_v
static cycle_t read_real_cycles(void)
{
- - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
+ + cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
- --- return ret >= clocksource_vmi.cycle_last ?
- --- ret : clocksource_vmi.cycle_last;
+++ +++ return max(ret, clocksource_vmi.cycle_last);
}
static struct clocksource clocksource_vmi = {
commit a7f4463e0300b5135c0f0caf7c34a0529405f986
Merge: c478f8786973 20f4d6c3a2a2
Author: Ingo Molnar <mingo@elte.hu>
Date: Tue Feb 24 18:22:39 2009 +0100
Merge branch 'tracing/ftrace'; commit 'v2.6.29-rc6' into tracing/core
commit 8e6dafd6c741cd4679b4de3c5d9698851e4fa59c
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Feb 23 00:34:39 2009 +0100
x86: refactor x86_quirks support
Impact: cleanup
Make x86_quirks support more transparent. The highlevel
methods are now named:
extern void x86_quirk_pre_intr_init(void);
extern void x86_quirk_intr_init(void);
extern void x86_quirk_trap_init(void);
extern void x86_quirk_pre_time_init(void);
extern void x86_quirk_time_init(void);
This makes it clear that if some platform extension has to
do something here that it is considered ... weird, and is
discouraged.
Also remove arch_hooks.h and move it into setup.h (and other
header files where appropriate).
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/include/asm/arch_hooks.h b/arch/x86/include/asm/arch_hooks.h
deleted file mode 100644
index 54248172be14..000000000000
--- a/arch/x86/include/asm/arch_hooks.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _ASM_X86_ARCH_HOOKS_H
-#define _ASM_X86_ARCH_HOOKS_H
-
-#include <linux/interrupt.h>
-
-/*
- * linux/include/asm/arch_hooks.h
- *
- * define the architecture specific hooks
- */
-
-/* these aren't arch hooks, they are generic routines
- * that can be used by the hooks */
-extern void init_ISA_irqs(void);
-extern irqreturn_t timer_interrupt(int irq, void *dev_id);
-
-/* these are the defined hooks */
-extern void pre_intr_init_hook(void);
-extern void intr_init_hook(void);
-
-extern void trap_init_hook(void);
-
-extern void pre_time_init_hook(void);
-extern void time_init_hook(void);
-
-#endif /* _ASM_X86_ARCH_HOOKS_H */
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index 58d7091eeb1f..1a99e6c092af 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -60,4 +60,8 @@ extern struct irq_chip i8259A_chip;
extern void mask_8259A(void);
extern void unmask_8259A(void);
+#ifdef CONFIG_X86_32
+extern void init_ISA_irqs(void);
+#endif
+
#endif /* _ASM_X86_I8259_H */
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 8029369cd6f4..66801cb72f69 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -13,6 +13,7 @@
struct mpc_cpu;
struct mpc_bus;
struct mpc_oemtable;
+
struct x86_quirks {
int (*arch_pre_time_init)(void);
int (*arch_time_init)(void);
@@ -33,6 +34,14 @@ struct x86_quirks {
int (*update_apic)(void);
};
+extern void x86_quirk_pre_intr_init(void);
+extern void x86_quirk_intr_init(void);
+
+extern void x86_quirk_trap_init(void);
+
+extern void x86_quirk_pre_time_init(void);
+extern void x86_quirk_time_init(void);
+
#endif /* __ASSEMBLY__ */
#ifdef __i386__
diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h
index 2bb6a835c453..a81195eaa2b3 100644
--- a/arch/x86/include/asm/timer.h
+++ b/arch/x86/include/asm/timer.h
@@ -3,6 +3,7 @@
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/percpu.h>
+#include <linux/interrupt.h>
#define TICK_SIZE (tick_nsec / 1000)
@@ -12,6 +13,7 @@ unsigned long native_calibrate_tsc(void);
#ifdef CONFIG_X86_32
extern int timer_ack;
extern int recalibrate_cpu_khz(void);
+extern irqreturn_t timer_interrupt(int irq, void *dev_id);
#endif /* CONFIG_X86_32 */
extern int no_timer_check;
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index c6bd7710585d..f9cecdfd05c5 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -34,7 +34,6 @@
#include <linux/smp.h>
#include <linux/mm.h>
-#include <asm/arch_hooks.h>
#include <asm/pgalloc.h>
#include <asm/atomic.h>
#include <asm/mpspec.h>
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index c9ec90742e9f..3a730fa574bb 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/acpi.h>
-#include <asm/arch_hooks.h>
#include <asm/e820.h>
#include <asm/setup.h>
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 11d5093eb281..df89102bef80 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -22,7 +22,6 @@
#include <asm/pgtable.h>
#include <asm/desc.h>
#include <asm/apic.h>
-#include <asm/arch_hooks.h>
#include <asm/i8259.h>
/*
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c
index bf629cadec1a..50b8c3a3006c 100644
--- a/arch/x86/kernel/irqinit_32.c
+++ b/arch/x86/kernel/irqinit_32.c
@@ -18,7 +18,7 @@
#include <asm/pgtable.h>
#include <asm/desc.h>
#include <asm/apic.h>
-#include <asm/arch_hooks.h>
+#include <asm/setup.h>
#include <asm/i8259.h>
#include <asm/traps.h>
@@ -127,8 +127,8 @@ void __init native_init_IRQ(void)
{
int i;
- /* all the set up before the call gates are initialised */
- pre_intr_init_hook();
+ /* Execute any quirks before the call gates are initialised: */
+ x86_quirk_pre_intr_init();
/*
* Cover the whole vector space, no vector can escape
@@ -188,10 +188,11 @@ void __init native_init_IRQ(void)
if (!acpi_ioapic)
setup_irq(2, &irq2);
- /* setup after call gates are initialised (usually add in
- * the architecture specific gates)
+ /*
+ * Call quirks after call gates are initialised (usually add in
+ * the architecture specific gates):
*/
- intr_init_hook();
+ x86_quirk_intr_init();
/*
* External FPU? Set up irq13 if so, for
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 652fce6d2cce..137f2e8132df 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -19,7 +19,6 @@
#include <linux/clocksource.h>
#include <linux/kvm_para.h>
#include <asm/pvclock.h>
-#include <asm/arch_hooks.h>
#include <asm/msr.h>
#include <asm/apic.h>
#include <linux/percpu.h>
diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c
index f74eef52ab55..845d80ce1ef1 100644
--- a/arch/x86/kernel/mca_32.c
+++ b/arch/x86/kernel/mca_32.c
@@ -51,7 +51,6 @@
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <linux/init.h>
-#include <asm/arch_hooks.h>
static unsigned char which_scsi;
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 6dc4dca255e4..63dd358d8ee1 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -28,7 +28,6 @@
#include <asm/paravirt.h>
#include <asm/desc.h>
#include <asm/setup.h>
-#include <asm/arch_hooks.h>
#include <asm/pgtable.h>
#include <asm/time.h>
#include <asm/pgalloc.h>
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d4de1e4c2045..5b85759e7972 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -74,8 +74,9 @@
#include <asm/e820.h>
#include <asm/mpspec.h>
#include <asm/setup.h>
-#include <asm/arch_hooks.h>
#include <asm/efi.h>
+#include <asm/timer.h>
+#include <asm/i8259.h>
#include <asm/sections.h>
#include <asm/dmi.h>
#include <asm/io_apic.h>
@@ -987,7 +988,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_X86_32
/**
- * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
+ * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
*
* Description:
* Perform any necessary interrupt initialisation prior to setting up
@@ -995,7 +996,7 @@ void __init setup_arch(char **cmdline_p)
* interrupts should be initialised here if the machine emulates a PC
* in any way.
**/
-void __init pre_intr_init_hook(void)
+void __init x86_quirk_pre_intr_init(void)
{
if (x86_quirks->arch_pre_intr_init) {
if (x86_quirks->arch_pre_intr_init())
@@ -1005,7 +1006,7 @@ void __init pre_intr_init_hook(void)
}
/**
- * intr_init_hook - post gate setup interrupt initialisation
+ * x86_quirk_intr_init - post gate setup interrupt initialisation
*
* Description:
* Fill in any interrupts that may have been left out by the general
@@ -1013,7 +1014,7 @@ void __init pre_intr_init_hook(void)
* than the devices on the I/O bus (like APIC interrupts in intel MP
* systems) are started here.
**/
-void __init intr_init_hook(void)
+void __init x86_quirk_intr_init(void)
{
if (x86_quirks->arch_intr_init) {
if (x86_quirks->arch_intr_init())
@@ -1022,13 +1023,13 @@ void __init intr_init_hook(void)
}
/**
- * trap_init_hook - initialise system specific traps
+ * x86_quirk_trap_init - initialise system specific traps
*
* Description:
* Called as the final act of trap_init(). Used in VISWS to initialise
* the various board specific APIC traps.
**/
-void __init trap_init_hook(void)
+void __init x86_quirk_trap_init(void)
{
if (x86_quirks->arch_trap_init) {
if (x86_quirks->arch_trap_init())
@@ -1044,23 +1045,23 @@ static struct irqaction irq0 = {
};
/**
- * pre_time_init_hook - do any specific initialisations before.
+ * x86_quirk_pre_time_init - do any specific initialisations before.
*
**/
-void __init pre_time_init_hook(void)
+void __init x86_quirk_pre_time_init(void)
{
if (x86_quirks->arch_pre_time_init)
x86_quirks->arch_pre_time_init();
}
/**
- * time_init_hook - do any specific initialisations for the system timer.
+ * x86_quirk_time_init - do any specific initialisations for the system timer.
*
* Description:
* Must plug the system timer interrupt source at HZ into the IRQ listed
* in irq_vectors.h:TIMER_IRQ
**/
-void __init time_init_hook(void)
+void __init x86_quirk_time_init(void)
{
if (x86_quirks->arch_time_init) {
/*
diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
index 764c74e871f2..5c5d87f0b2e1 100644
--- a/arch/x86/kernel/time_32.c
+++ b/arch/x86/kernel/time_32.c
@@ -33,7 +33,7 @@
#include <linux/time.h>
#include <linux/mca.h>
-#include <asm/arch_hooks.h>
+#include <asm/setup.h>
#include <asm/hpet.h>
#include <asm/time.h>
#include <asm/timer.h>
@@ -118,7 +118,7 @@ void __init hpet_time_init(void)
{
if (!hpet_enable())
setup_pit_timer();
- time_init_hook();
+ x86_quirk_time_init();
}
/*
@@ -131,7 +131,7 @@ void __init hpet_time_init(void)
*/
void __init time_init(void)
{
- pre_time_init_hook();
+ x86_quirk_pre_time_init();
tsc_init();
late_time_init = choose_time_init();
}
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index acb8c0585ab9..c8c0a7e530be 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -61,7 +61,7 @@
#include <asm/proto.h>
#else
#include <asm/processor-flags.h>
-#include <asm/arch_hooks.h>
+#include <asm/setup.h>
#include <asm/traps.h>
#include "cpu/mcheck/mce.h"
@@ -1026,6 +1026,6 @@ void __init trap_init(void)
cpu_init();
#ifdef CONFIG_X86_32
- trap_init_hook();
+ x86_quirk_trap_init();
#endif
}
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index 34199d30ff46..191a876e9e87 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -24,7 +24,6 @@
#include <asm/visws/cobalt.h>
#include <asm/visws/piix4.h>
-#include <asm/arch_hooks.h>
#include <asm/io_apic.h>
#include <asm/fixmap.h>
#include <asm/reboot.h>
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index 8c48b4650599..49b4cd6707f9 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -28,7 +28,6 @@
#include <asm/vmi.h>
#include <asm/vmi_time.h>
-#include <asm/arch_hooks.h>
#include <asm/apicdef.h>
#include <asm/apic.h>
#include <asm/timer.h>