Commit 0670afdf authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6: (27 commits)
  [IA64] swiotlb abstraction (e.g. for Xen)
  [IA64] swiotlb cleanup
  [IA64] make swiotlb use bus_to_virt/virt_to_bus
  [IA64] swiotlb bug fixes
  [IA64] Hook up getcpu system call for IA64
  [IA64] clean up sparsemem memory_present call
  [IA64] show_mem() for IA64 sparsemem NUMA
  [IA64] missing exports hwsw_sync_...
  [IA64] virt_to_page() can be called with NULL arg
  [IA64] alignment bug in ldscript
  [IA64] register memory ranges in a consistent manner
  [IA64] Enable SWIOTLB only when needed
  [IA64-SGI] Check for TIO errors on shub2 Altix
  [IA64] remove bogus prototype ia64_esi_init()
  [IA64] Clear IRQ affinity when unregistered
  [IA64] fix ACPI Kconfig issues
  [IA64] Fix NULL-pointer dereference in ia64_machine_kexec()
  [IA64] find thread for user rbs address
  [IA64] use snprintf() on features field of /proc/cpuinfo
  [IA64] enable singlestep on system call
  ...
parents dda2ac15 51099005
...@@ -11,6 +11,8 @@ menu "Processor type and features" ...@@ -11,6 +11,8 @@ menu "Processor type and features"
config IA64 config IA64
bool bool
select PCI if (!IA64_HP_SIM)
select ACPI if (!IA64_HP_SIM)
default y default y
help help
The Itanium Processor Family is Intel's 64-bit successor to The Itanium Processor Family is Intel's 64-bit successor to
...@@ -28,7 +30,6 @@ config MMU ...@@ -28,7 +30,6 @@ config MMU
config SWIOTLB config SWIOTLB
bool bool
default y
config RWSEM_XCHGADD_ALGORITHM config RWSEM_XCHGADD_ALGORITHM
bool bool
...@@ -84,10 +85,9 @@ choice ...@@ -84,10 +85,9 @@ choice
config IA64_GENERIC config IA64_GENERIC
bool "generic" bool "generic"
select ACPI
select PCI
select NUMA select NUMA
select ACPI_NUMA select ACPI_NUMA
select SWIOTLB
help help
This selects the system type of your hardware. A "generic" kernel This selects the system type of your hardware. A "generic" kernel
will run on any supported IA-64 system. However, if you configure will run on any supported IA-64 system. However, if you configure
...@@ -104,6 +104,7 @@ config IA64_GENERIC ...@@ -104,6 +104,7 @@ config IA64_GENERIC
config IA64_DIG config IA64_DIG
bool "DIG-compliant" bool "DIG-compliant"
select SWIOTLB
config IA64_HP_ZX1 config IA64_HP_ZX1
bool "HP-zx1/sx1000" bool "HP-zx1/sx1000"
...@@ -113,6 +114,7 @@ config IA64_HP_ZX1 ...@@ -113,6 +114,7 @@ config IA64_HP_ZX1
config IA64_HP_ZX1_SWIOTLB config IA64_HP_ZX1_SWIOTLB
bool "HP-zx1/sx1000 with software I/O TLB" bool "HP-zx1/sx1000 with software I/O TLB"
select SWIOTLB
help help
Build a kernel that runs on HP zx1 and sx1000 systems even when they Build a kernel that runs on HP zx1 and sx1000 systems even when they
have broken PCI devices which cannot DMA to full 32 bits. Apart have broken PCI devices which cannot DMA to full 32 bits. Apart
...@@ -131,6 +133,7 @@ config IA64_SGI_SN2 ...@@ -131,6 +133,7 @@ config IA64_SGI_SN2
config IA64_HP_SIM config IA64_HP_SIM
bool "Ski-simulator" bool "Ski-simulator"
select SWIOTLB
endchoice endchoice
......
...@@ -192,3 +192,7 @@ EXPORT_SYMBOL(hwsw_unmap_sg); ...@@ -192,3 +192,7 @@ EXPORT_SYMBOL(hwsw_unmap_sg);
EXPORT_SYMBOL(hwsw_dma_supported); EXPORT_SYMBOL(hwsw_dma_supported);
EXPORT_SYMBOL(hwsw_alloc_coherent); EXPORT_SYMBOL(hwsw_alloc_coherent);
EXPORT_SYMBOL(hwsw_free_coherent); EXPORT_SYMBOL(hwsw_free_coherent);
EXPORT_SYMBOL(hwsw_sync_single_for_cpu);
EXPORT_SYMBOL(hwsw_sync_single_for_device);
EXPORT_SYMBOL(hwsw_sync_sg_for_cpu);
EXPORT_SYMBOL(hwsw_sync_sg_for_device);
...@@ -79,6 +79,7 @@ crash_save_this_cpu() ...@@ -79,6 +79,7 @@ crash_save_this_cpu()
final_note(buf); final_note(buf);
} }
#ifdef CONFIG_SMP
static int static int
kdump_wait_cpu_freeze(void) kdump_wait_cpu_freeze(void)
{ {
...@@ -91,6 +92,7 @@ kdump_wait_cpu_freeze(void) ...@@ -91,6 +92,7 @@ kdump_wait_cpu_freeze(void)
} }
return 1; return 1;
} }
#endif
void void
machine_crash_shutdown(struct pt_regs *pt) machine_crash_shutdown(struct pt_regs *pt)
...@@ -116,6 +118,11 @@ machine_crash_shutdown(struct pt_regs *pt) ...@@ -116,6 +118,11 @@ machine_crash_shutdown(struct pt_regs *pt)
static void static void
machine_kdump_on_init(void) machine_kdump_on_init(void)
{ {
if (!ia64_kimage) {
printk(KERN_NOTICE "machine_kdump_on_init(): "
"kdump not configured\n");
return;
}
local_irq_disable(); local_irq_disable();
kexec_disable_iosapic(); kexec_disable_iosapic();
machine_kexec(ia64_kimage); machine_kexec(ia64_kimage);
...@@ -132,11 +139,12 @@ kdump_cpu_freeze(struct unw_frame_info *info, void *arg) ...@@ -132,11 +139,12 @@ kdump_cpu_freeze(struct unw_frame_info *info, void *arg)
atomic_inc(&kdump_cpu_freezed); atomic_inc(&kdump_cpu_freezed);
kdump_status[cpuid] = 1; kdump_status[cpuid] = 1;
mb(); mb();
if (cpuid == 0) { #ifdef CONFIG_HOTPLUG_CPU
for (;;) if (cpuid != 0)
cpu_relax();
} else
ia64_jump_to_sal(&sal_boot_rendez_state[cpuid]); ia64_jump_to_sal(&sal_boot_rendez_state[cpuid]);
#endif
for (;;)
cpu_relax();
} }
static int static int
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/uaccess.h> #include <asm/page.h>
#include <asm/uaccess.h>
/** /**
* copy_oldmem_page - copy one page from "oldmem" * copy_oldmem_page - copy one page from "oldmem"
......
...@@ -380,7 +380,7 @@ efi_get_pal_addr (void) ...@@ -380,7 +380,7 @@ efi_get_pal_addr (void)
#endif #endif
return __va(md->phys_addr); return __va(md->phys_addr);
} }
printk(KERN_WARNING "%s: no PAL-code memory-descriptor found", printk(KERN_WARNING "%s: no PAL-code memory-descriptor found\n",
__FUNCTION__); __FUNCTION__);
return NULL; return NULL;
} }
......
...@@ -1610,5 +1610,7 @@ sys_call_table: ...@@ -1610,5 +1610,7 @@ sys_call_table:
data8 sys_sync_file_range // 1300 data8 sys_sync_file_range // 1300
data8 sys_tee data8 sys_tee
data8 sys_vmsplice data8 sys_vmsplice
data8 sys_ni_syscall // reserved for move_pages
data8 sys_getcpu
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
...@@ -925,6 +925,11 @@ iosapic_unregister_intr (unsigned int gsi) ...@@ -925,6 +925,11 @@ iosapic_unregister_intr (unsigned int gsi)
/* Clear the interrupt controller descriptor */ /* Clear the interrupt controller descriptor */
idesc->chip = &no_irq_type; idesc->chip = &no_irq_type;
#ifdef CONFIG_SMP
/* Clear affinity */
cpus_setall(idesc->affinity);
#endif
/* Clear the interrupt information */ /* Clear the interrupt information */
memset(&iosapic_intr_info[vector], 0, memset(&iosapic_intr_info[vector], 0,
sizeof(struct iosapic_intr_info)); sizeof(struct iosapic_intr_info));
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/efi.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/delay.h> #include <asm/delay.h>
...@@ -68,22 +69,10 @@ void machine_kexec_cleanup(struct kimage *image) ...@@ -68,22 +69,10 @@ void machine_kexec_cleanup(struct kimage *image)
{ {
} }
void machine_shutdown(void)
{
int cpu;
for_each_online_cpu(cpu) {
if (cpu != smp_processor_id())
cpu_down(cpu);
}
kexec_disable_iosapic();
}
/* /*
* Do not allocate memory (or fail in any way) in machine_kexec(). * Do not allocate memory (or fail in any way) in machine_kexec().
* We are past the point of no return, committed to rebooting now. * We are past the point of no return, committed to rebooting now.
*/ */
extern void *efi_get_pal_addr(void);
static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
{ {
struct kimage *image = arg; struct kimage *image = arg;
...@@ -93,6 +82,7 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) ...@@ -93,6 +82,7 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
unsigned long vector; unsigned long vector;
int ii; int ii;
BUG_ON(!image);
if (image->type == KEXEC_TYPE_CRASH) { if (image->type == KEXEC_TYPE_CRASH) {
crash_save_this_cpu(); crash_save_this_cpu();
current->thread.ksp = (__u64)info->sw - 16; current->thread.ksp = (__u64)info->sw - 16;
...@@ -131,6 +121,7 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) ...@@ -131,6 +121,7 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
void machine_kexec(struct kimage *image) void machine_kexec(struct kimage *image)
{ {
BUG_ON(!image);
unw_init_running(ia64_machine_kexec, image); unw_init_running(ia64_machine_kexec, image);
for(;;); for(;;);
} }
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <asm/ia32.h> #include <asm/ia32.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/kdebug.h> #include <asm/kdebug.h>
#include <asm/kexec.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/sal.h> #include <asm/sal.h>
...@@ -803,6 +804,21 @@ cpu_halt (void) ...@@ -803,6 +804,21 @@ cpu_halt (void)
ia64_pal_halt(min_power_state); ia64_pal_halt(min_power_state);
} }
void machine_shutdown(void)
{
#ifdef CONFIG_HOTPLUG_CPU
int cpu;
for_each_online_cpu(cpu) {
if (cpu != smp_processor_id())
cpu_down(cpu);
}
#endif
#ifdef CONFIG_KEXEC
kexec_disable_iosapic();
#endif
}
void void
machine_restart (char *restart_cmd) machine_restart (char *restart_cmd)
{ {
......
...@@ -607,7 +607,7 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr) ...@@ -607,7 +607,7 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr)
*/ */
list_for_each_safe(this, next, &current->children) { list_for_each_safe(this, next, &current->children) {
p = list_entry(this, struct task_struct, sibling); p = list_entry(this, struct task_struct, sibling);
if (p->mm != mm) if (p->tgid != child->tgid)
continue; continue;
if (thread_matches(p, addr)) { if (thread_matches(p, addr)) {
child = p; child = p;
...@@ -1405,6 +1405,7 @@ ptrace_disable (struct task_struct *child) ...@@ -1405,6 +1405,7 @@ ptrace_disable (struct task_struct *child)
struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child)); struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
/* make sure the single step/taken-branch trap bits are not set: */ /* make sure the single step/taken-branch trap bits are not set: */
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
child_psr->ss = 0; child_psr->ss = 0;
child_psr->tb = 0; child_psr->tb = 0;
} }
...@@ -1525,6 +1526,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) ...@@ -1525,6 +1526,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
* Make sure the single step/taken-branch trap bits * Make sure the single step/taken-branch trap bits
* are not set: * are not set:
*/ */
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
ia64_psr(pt)->ss = 0; ia64_psr(pt)->ss = 0;
ia64_psr(pt)->tb = 0; ia64_psr(pt)->tb = 0;
...@@ -1556,6 +1558,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) ...@@ -1556,6 +1558,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
goto out_tsk; goto out_tsk;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
set_tsk_thread_flag(child, TIF_SINGLESTEP);
if (request == PTRACE_SINGLESTEP) { if (request == PTRACE_SINGLESTEP) {
ia64_psr(pt)->ss = 1; ia64_psr(pt)->ss = 1;
} else { } else {
...@@ -1595,13 +1598,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) ...@@ -1595,13 +1598,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
} }
void static void
syscall_trace (void) syscall_trace (void)
{ {
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
if (!(current->ptrace & PT_PTRACED))
return;
/* /*
* The 0x80 provides a way for the tracing parent to * The 0x80 provides a way for the tracing parent to
* distinguish between a syscall stop and SIGTRAP delivery. * distinguish between a syscall stop and SIGTRAP delivery.
...@@ -1664,7 +1663,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, ...@@ -1664,7 +1663,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
audit_syscall_exit(success, result); audit_syscall_exit(success, result);
} }
if (test_thread_flag(TIF_SYSCALL_TRACE) if ((test_thread_flag(TIF_SYSCALL_TRACE)
|| test_thread_flag(TIF_SINGLESTEP))
&& (current->ptrace & PT_PTRACED)) && (current->ptrace & PT_PTRACED))
syscall_trace(); syscall_trace();
} }
...@@ -569,34 +569,31 @@ show_cpuinfo (struct seq_file *m, void *v) ...@@ -569,34 +569,31 @@ show_cpuinfo (struct seq_file *m, void *v)
{ 1UL << 1, "spontaneous deferral"}, { 1UL << 1, "spontaneous deferral"},
{ 1UL << 2, "16-byte atomic ops" } { 1UL << 2, "16-byte atomic ops" }
}; };
char features[128], *cp, sep; char features[128], *cp, *sep;
struct cpuinfo_ia64 *c = v; struct cpuinfo_ia64 *c = v;
unsigned long mask; unsigned long mask;
unsigned long proc_freq; unsigned long proc_freq;
int i; int i, size;
mask = c->features; mask = c->features;
/* build the feature string: */ /* build the feature string: */
memcpy(features, " standard", 10); memcpy(features, "standard", 9);
cp = features; cp = features;
sep = 0; size = sizeof(features);
for (i = 0; i < (int) ARRAY_SIZE(feature_bits); ++i) { sep = "";
for (i = 0; i < ARRAY_SIZE(feature_bits) && size > 1; ++i) {
if (mask & feature_bits[i].mask) { if (mask & feature_bits[i].mask) {
if (sep) cp += snprintf(cp, size, "%s%s", sep,
*cp++ = sep; feature_bits[i].feature_name),
sep = ','; sep = ", ";
*cp++ = ' ';
strcpy(cp, feature_bits[i].feature_name);
cp += strlen(feature_bits[i].feature_name);
mask &= ~feature_bits[i].mask; mask &= ~feature_bits[i].mask;
size = sizeof(features) - (cp - features);
} }
} }
if (mask) { if (mask && size > 1) {
/* print unknown features as a hex value: */ /* print unknown features as a hex value */
if (sep) snprintf(cp, size, "%s0x%lx", sep, mask);
*cp++ = sep;
sprintf(cp, " 0x%lx", mask);
} }
proc_freq = cpufreq_quick_get(cpunum); proc_freq = cpufreq_quick_get(cpunum);
...@@ -612,7 +609,7 @@ show_cpuinfo (struct seq_file *m, void *v) ...@@ -612,7 +609,7 @@ show_cpuinfo (struct seq_file *m, void *v)
"model name : %s\n" "model name : %s\n"
"revision : %u\n" "revision : %u\n"
"archrev : %u\n" "archrev : %u\n"
"features :%s\n" /* don't change this---it _is_ right! */ "features : %s\n"
"cpu number : %lu\n" "cpu number : %lu\n"
"cpu regs : %u\n" "cpu regs : %u\n"
"cpu MHz : %lu.%06lu\n" "cpu MHz : %lu.%06lu\n"
......
...@@ -157,6 +157,7 @@ SECTIONS ...@@ -157,6 +157,7 @@ SECTIONS
} }
#endif #endif
. = ALIGN(8);
__con_initcall_start = .; __con_initcall_start = .;
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET)
{ *(.con_initcall.init) } { *(.con_initcall.init) }
......
...@@ -30,47 +30,69 @@ static unsigned long max_gap; ...@@ -30,47 +30,69 @@ static unsigned long max_gap;
#endif #endif
/** /**
* show_mem - display a memory statistics summary * show_mem - give short summary of memory stats
* *
* Just walks the pages in the system and describes where they're allocated. * Shows a simple page count of reserved and used pages in the system.
* For discontig machines, it does this on a per-pgdat basis.
*/ */
void void show_mem(void)
show_mem (void)
{ {
int i, total = 0, reserved = 0; int i, total_reserved = 0;
int shared = 0, cached = 0; int total_shared = 0, total_cached = 0;
unsigned long total_present = 0;
pg_data_t *pgdat;
printk(KERN_INFO "Mem-info:\n"); printk(KERN_INFO "Mem-info:\n");
show_free_areas(); show_free_areas();
printk(KERN_INFO "Free swap: %6ldkB\n", printk(KERN_INFO "Free swap: %6ldkB\n",
nr_swap_pages<<(PAGE_SHIFT-10)); nr_swap_pages<<(PAGE_SHIFT-10));
i = max_mapnr; printk(KERN_INFO "Node memory in pages:\n");
for (i = 0; i < max_mapnr; i++) { for_each_online_pgdat(pgdat) {
if (!pfn_valid(i)) { unsigned long present;
unsigned long flags;
int shared = 0, cached = 0, reserved = 0;
pgdat_resize_lock(pgdat, &flags);
present = pgdat->node_present_pages;
for(i = 0; i < pgdat->node_spanned_pages; i++) {
struct page *page;
if (pfn_valid(pgdat->node_start_pfn + i))
page = pfn_to_page(pgdat->node_start_pfn + i);
else {
#ifdef CONFIG_VIRTUAL_MEM_MAP #ifdef CONFIG_VIRTUAL_MEM_MAP
if (max_gap < LARGE_GAP) if (max_gap < LARGE_GAP)
continue; continue;
i = vmemmap_find_next_valid_pfn(0, i) - 1;
#endif #endif
continue; i = vmemmap_find_next_valid_pfn(pgdat->node_id,
i) - 1;
continue;
}
if (PageReserved(page))
reserved++;
else if (PageSwapCache(page))
cached++;
else if (page_count(page))
shared += page_count(page)-1;
} }
total++; pgdat_resize_unlock(pgdat, &flags);
if (PageReserved(mem_map+i)) total_present += present;
reserved++; total_reserved += reserved;
else if (PageSwapCache(mem_map+i)) total_cached += cached;
cached++; total_shared += shared;
else if (page_count(mem_map + i)) printk(KERN_INFO "Node %4d: RAM: %11ld, rsvd: %8d, "
shared += page_count(mem_map + i) - 1; "shrd: %10d, swpd: %10d\n", pgdat->node_id,
present, reserved, shared, cached);
} }
printk(KERN_INFO "%d pages of RAM\n", total); printk(KERN_INFO "%ld pages of RAM\n", total_present);
printk(KERN_INFO "%d reserved pages\n", reserved); printk(KERN_INFO "%d reserved pages\n", total_reserved);
printk(KERN_INFO "%d pages shared\n", shared); printk(KERN_INFO "%d pages shared\n", total_shared);
printk(KERN_INFO "%d pages swap cached\n", cached); printk(KERN_INFO "%d pages swap cached\n", total_cached);
printk(KERN_INFO "%ld pages in page table cache\n", printk(KERN_INFO "Total of %ld pages in page table cache\n",
pgtable_quicklist_total_size()); pgtable_quicklist_total_size());
printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
} }
/* physical address where the bootmem map is located */ /* physical address where the bootmem map is located */
unsigned long bootmap_start; unsigned long bootmap_start;
...@@ -177,7 +199,7 @@ find_memory (void) ...@@ -177,7 +199,7 @@ find_memory (void)
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
/* If we are doing a crash dump, we still need to know the real mem /* If we are doing a crash dump, we still need to know the real mem
* size before original memory map is * reset. */ * size before original memory map is reset. */
saved_max_pfn = max_pfn; saved_max_pfn = max_pfn;
#endif #endif
} }
......
...@@ -412,37 +412,6 @@ static void __init memory_less_nodes(void) ...@@ -412,37 +412,6 @@ static void __init memory_less_nodes(void)
return; return;
} }
#ifdef CONFIG_SPARSEMEM
/**
* register_sparse_mem - notify SPARSEMEM that this memory range exists.
* @start: physical start of range
* @end: physical end of range
* @arg: unused
*
* Simply calls SPARSEMEM to register memory section(s).
*/
static int __init register_sparse_mem(unsigned long start, unsigned long end,
void *arg)
{
int nid;
start = __pa(start) >> PAGE_SHIFT;
end = __pa(end) >> PAGE_SHIFT;
nid = early_pfn_to_nid(start);
memory_present(nid, start, end);
return 0;
}
static void __init arch_sparse_init(void)
{
efi_memmap_walk(register_sparse_mem, NULL);
sparse_init();
}
#else
#define arch_sparse_init() do {} while (0)
#endif
/** /**
* find_memory - walk the EFI memory map and setup the bootmem allocator * find_memory - walk the EFI memory map and setup the bootmem allocator
* *
...@@ -473,6 +442,9 @@ void __init find_memory(void) ...@@ -473,6 +442,9 @@ void __init find_memory(void)
node_clear(node, memory_less_mask); node_clear(node, memory_less_mask);
mem_data[node].min_pfn = ~0UL; mem_data[node].min_pfn = ~0UL;
} }
efi_memmap_walk(register_active_ranges, NULL);
/* /*
* Initialize the boot memory maps in reverse order since that's * Initialize the boot memory maps in reverse order since that's
* what the bootmem allocator expects * what the bootmem allocator expects
...@@ -506,6 +478,12 @@ void __init find_memory(void) ...@@ -506,6 +478,12 @@ void __init find_memory(void)
max_pfn = max_low_pfn; max_pfn = max_low_pfn;
find_initrd(); find_initrd();
#ifdef CONFIG_CRASH_DUMP
/* If we are doing a crash dump, we still need to know the real mem
* size before original memory map is reset. */
saved_max_pfn = max_pfn;
#endif
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -654,7 +632,6 @@ static __init int count_node_pages(unsigned long start, unsigned long len, int n ...@@ -654,7 +632,6 @@ static __init int count_node_pages(unsigned long start, unsigned long len, int n
{ {
unsigned long end = start + len; unsigned long end = start + len;
add_active_range(node, start >> PAGE_SHIFT, end >> PAGE_SHIFT);
mem_data[node].num_physpages += len >> PAGE_SHIFT; mem_data[node].num_physpages += len >> PAGE_SHIFT;
if (start <= __pa(MAX_DMA_ADDRESS)) if (start <= __pa(MAX_DMA_ADDRESS))
mem_data[node].num_dma_physpages += mem_data[node].num_dma_physpages +=
...@@ -686,10 +663,11 @@ void __init paging_init(void) ...@@ -686,10 +663,11 @@ void __init paging_init(void)
max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
arch_sparse_init();
efi_memmap_walk(filter_rsvd_memory, count_node_pages); efi_memmap_walk(filter_rsvd_memory, count_node_pages);
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
#ifdef CONFIG_VIRTUAL_MEM_MAP #ifdef CONFIG_VIRTUAL_MEM_MAP
vmalloc_end -= PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * vmalloc_end -= PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) *
sizeof(struct page)); sizeof(struct page));
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/kexec.h>
#include <asm/a.out.h> #include <asm/a.out.h>
#include <asm/dma.h> #include <asm/dma.h>
...@@ -128,6 +129,25 @@ lazy_mmu_prot_update (pte_t pte) ...@@ -128,6 +129,25 @@ lazy_mmu_prot_update (pte_t pte)
set_bit(PG_arch_1, &page->flags); /* mark page as clean */ set_bit(PG_arch_1, &page->flags); /* mark page as clean */
} }
/*
* Since DMA is i-cache coherent, any (complete) pages that were written via
* DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
* flush them when they get mapped into an executable vm-area.
*/
void
dma_mark_clean(void *addr, size_t size)
{
unsigned long pg_addr, end;
pg_addr = PAGE_ALIGN((unsigned long) addr);
end = (unsigned long) addr + size;
while (pg_addr + PAGE_SIZE <= end) {
struct page *page = virt_to_page(pg_addr);
set_bit(PG_arch_1, &page->flags);
pg_addr += PAGE_SIZE;
}
}
inline void inline void
ia64_set_rbs_bot (void) ia64_set_rbs_bot (void)
{ {
...@@ -595,13 +615,27 @@ find_largest_hole (u64 start, u64 end, void *arg) ...@@ -595,13 +615,27 @@ find_largest_hole (u64 start, u64 end, void *arg)
return 0; return 0;
} }
#endif /* CONFIG_VIRTUAL_MEM_MAP */
int __init int __init
register_active_ranges(u64 start, u64 end, void *arg) register_active_ranges(u64 start, u64 end, void *arg)
{ {
add_active_range(0, __pa(start) >> PAGE_SHIFT, __pa(end) >> PAGE_SHIFT); int nid = paddr_to_nid(__pa(start));
if (nid < 0)
nid = 0;
#ifdef CONFIG_KEXEC
if (start > crashk_res.start && start < crashk_res.end)
start = crashk_res.end;
if (end > crashk_res.start && end < crashk_res.end)
end = crashk_res.start;
#endif
if (start < end)
add_active_range(nid, __pa(start) >> PAGE_SHIFT,
__pa(end) >> PAGE_SHIFT);
return 0; return 0;
} }
#endif /* CONFIG_VIRTUAL_MEM_MAP */
static int __init static int __init
count_reserved_pages (u64 start, u64 end, void *arg) count_reserved_pages (u64 start, u64 end, void *arg)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000,2002-2005 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000,2002-2007 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/types.h> #include <linux/types.h>
...@@ -38,12 +38,20 @@ static irqreturn_t hub_eint_handler(int irq, void *arg) ...@@ -38,12 +38,20 @@ static irqreturn_t hub_eint_handler(int irq, void *arg)
(u64) nasid, 0, 0, 0, 0, 0, 0); (u64) nasid, 0, 0, 0, 0, 0, 0);
if ((int)ret_stuff.v0) if ((int)ret_stuff.v0)
panic("hubii_eint_handler(): Fatal TIO Error"); panic("%s: Fatal %s Error", __FUNCTION__,
((nasid & 1) ? "TIO" : "HUBII"));
if (!(nasid & 1)) /* Not a TIO, handle CRB errors */ if (!(nasid & 1)) /* Not a TIO, handle CRB errors */
(void)hubiio_crb_error_handler(hubdev_info); (void)hubiio_crb_error_handler(hubdev_info);
} else } else
bte_error_handler((unsigned long)NODEPDA(nasid_to_cnodeid(nasid))); if (nasid & 1) { /* TIO errors */
SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
(u64) nasid, 0, 0, 0, 0, 0, 0);
if ((int)ret_stuff.v0)
panic("%s: Fatal TIO Error", __FUNCTION__);
} else
bte_error_handler((unsigned long)NODEPDA(nasid_to_cnodeid(nasid)));
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -29,7 +29,7 @@ struct dma_mapping_ops swiotlb_dma_ops = { ...@@ -29,7 +29,7 @@ struct dma_mapping_ops swiotlb_dma_ops = {
.dma_supported = NULL, .dma_supported = NULL,
}; };
void pci_swiotlb_init(void) void __init pci_swiotlb_init(void)
{ {
/* don't initialize swiotlb if iommu=off (no_iommu=1) */ /* don't initialize swiotlb if iommu=off (no_iommu=1) */
if (!iommu_detected && !no_iommu && end_pfn > MAX_DMA32_PFN) if (!iommu_detected && !no_iommu && end_pfn > MAX_DMA32_PFN)
......
...@@ -19,4 +19,6 @@ extern unsigned long MAX_DMA_ADDRESS; ...@@ -19,4 +19,6 @@ extern unsigned long MAX_DMA_ADDRESS;
#define free_dma(x) #define free_dma(x)
void dma_mark_clean(void *addr, size_t size);
#endif /* _ASM_IA64_DMA_H */ #endif /* _ASM_IA64_DMA_H */
...@@ -19,7 +19,6 @@ enum esi_proc_type { ...@@ -19,7 +19,6 @@ enum esi_proc_type {
ESI_PROC_REENTRANT /* MP-safe and reentrant */ ESI_PROC_REENTRANT /* MP-safe and reentrant */
}; };
extern int ia64_esi_init (void);
extern struct ia64_sal_retval esi_call_phys (void *, u64 *); extern struct ia64_sal_retval esi_call_phys (void *, u64 *);
extern int ia64_esi_call(efi_guid_t, struct ia64_sal_retval *, extern int ia64_esi_call(efi_guid_t, struct ia64_sal_retval *,
enum esi_proc_type, enum esi_proc_type,
......
...@@ -51,12 +51,13 @@ extern void efi_memmap_init(unsigned long *, unsigned long *); ...@@ -51,12 +51,13 @@ extern void efi_memmap_init(unsigned long *, unsigned long *);
#define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */ #define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
extern int register_active_ranges(u64 start, u64 end, void *arg);
#ifdef CONFIG_VIRTUAL_MEM_MAP #ifdef CONFIG_VIRTUAL_MEM_MAP
# define LARGE_GAP 0x40000000 /* Use virtual mem map if hole is > than this */ # define LARGE_GAP 0x40000000 /* Use virtual mem map if hole is > than this */
extern unsigned long vmalloc_end; extern unsigned long vmalloc_end;
extern struct page *vmem_map; extern struct page *vmem_map;
extern int find_largest_hole (u64 start, u64 end, void *arg); extern int find_largest_hole (u64 start, u64 end, void *arg);
extern int register_active_ranges (u64 start, u64 end, void *arg);
extern int create_mem_map_page_table (u64 start, u64 end, void *arg); extern int create_mem_map_page_table (u64 start, u64 end, void *arg);
extern int vmemmap_find_next_valid_pfn(int, int); extern int vmemmap_find_next_valid_pfn(int, int);
#else #else
......
...@@ -137,7 +137,8 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte) ...@@ -137,7 +137,8 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
static inline struct page *pte_alloc_one(struct mm_struct *mm, static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long addr) unsigned long addr)
{ {
return virt_to_page(pgtable_quicklist_alloc()); void *pg = pgtable_quicklist_alloc();
return pg ? virt_to_page(pg) : NULL;
} }
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
......
#ifndef _ASM_SWIOTLB_H
#define _ASM_SWIOTLB_H 1
#include <asm/machvec.h>
#define SWIOTLB_ARCH_NEED_LATE_INIT
#define SWIOTLB_ARCH_NEED_ALLOC
#endif /* _ASM_SWIOTLB_H */
...@@ -84,6 +84,7 @@ struct thread_info { ...@@ -84,6 +84,7 @@ struct thread_info {
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SYSCALL_TRACE 3 /* syscall trace active */ #define TIF_SYSCALL_TRACE 3 /* syscall trace active */
#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */
#define TIF_SINGLESTEP 5 /* restore singlestep on return to user mode */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 #define TIF_MEMDIE 17
#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */ #define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
...@@ -92,7 +93,8 @@ struct thread_info { ...@@ -92,7 +93,8 @@ struct thread_info {
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
......
...@@ -291,11 +291,13 @@ ...@@ -291,11 +291,13 @@
#define __NR_sync_file_range 1300 #define __NR_sync_file_range 1300
#define __NR_tee 1301 #define __NR_tee 1301
#define __NR_vmsplice 1302 #define __NR_vmsplice 1302
/* 1303 reserved for move_pages */
#define __NR_getcpu 1304
#ifdef __KERNEL__ #ifdef __KERNEL__
#define NR_syscalls 279 /* length of syscall table */ #define NR_syscalls 281 /* length of syscall table */
#define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGACTION
......
#ifndef _ASM_SWIOTLB_H #ifndef _ASM_SWIOTLB_H
#define _ASM_SWTIOLB_H 1 #define _ASM_SWIOTLB_H 1
#include <asm/dma-mapping.h> #include <asm/dma-mapping.h>
...@@ -45,6 +44,7 @@ extern void swiotlb_init(void); ...@@ -45,6 +44,7 @@ extern void swiotlb_init(void);
extern int swiotlb_force; extern int swiotlb_force;
#ifdef CONFIG_SWIOTLB #ifdef CONFIG_SWIOTLB
#define SWIOTLB_ARCH_NEED_ALLOC
extern int swiotlb; extern int swiotlb;
#else #else
#define swiotlb 0 #define swiotlb 0
...@@ -52,4 +52,6 @@ extern int swiotlb; ...@@ -52,4 +52,6 @@ extern int swiotlb;
extern void pci_swiotlb_init(void); extern void pci_swiotlb_init(void);
#endif /* _ASM_SWTIOLB_H */ static inline void dma_mark_clean(void *addr, size_t size) {}
#endif /* _ASM_SWIOTLB_H */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment