diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/Kconfig | 9 | ||||
-rw-r--r-- | arch/ia64/kernel/gate.lds.S | 135 | ||||
-rw-r--r-- | arch/ia64/kernel/kprobes.c | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/ia64/kernel/smpboot.c | 18 | ||||
-rw-r--r-- | arch/ia64/kernel/uncached.c | 4 | ||||
-rw-r--r-- | arch/ia64/mm/discontig.c | 8 | ||||
-rw-r--r-- | arch/ia64/mm/fault.c | 2 | ||||
-rw-r--r-- | arch/ia64/mm/hugetlbpage.c | 4 | ||||
-rw-r--r-- | arch/ia64/mm/init.c | 20 |
10 files changed, 128 insertions, 86 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 2e6310b8eab7..59b91ac861ac 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -54,6 +54,11 @@ config ARCH_HAS_ILOG2_U64 | |||
54 | bool | 54 | bool |
55 | default n | 55 | default n |
56 | 56 | ||
57 | config HUGETLB_PAGE_SIZE_VARIABLE | ||
58 | bool | ||
59 | depends on HUGETLB_PAGE | ||
60 | default y | ||
61 | |||
57 | config GENERIC_FIND_NEXT_BIT | 62 | config GENERIC_FIND_NEXT_BIT |
58 | bool | 63 | bool |
59 | default y | 64 | default y |
@@ -300,6 +305,9 @@ config HOTPLUG_CPU | |||
300 | config ARCH_ENABLE_MEMORY_HOTPLUG | 305 | config ARCH_ENABLE_MEMORY_HOTPLUG |
301 | def_bool y | 306 | def_bool y |
302 | 307 | ||
308 | config ARCH_ENABLE_MEMORY_HOTREMOVE | ||
309 | def_bool y | ||
310 | |||
303 | config SCHED_SMT | 311 | config SCHED_SMT |
304 | bool "SMT scheduler support" | 312 | bool "SMT scheduler support" |
305 | depends on SMP | 313 | depends on SMP |
@@ -348,6 +356,7 @@ config ARCH_FLATMEM_ENABLE | |||
348 | config ARCH_SPARSEMEM_ENABLE | 356 | config ARCH_SPARSEMEM_ENABLE |
349 | def_bool y | 357 | def_bool y |
350 | depends on ARCH_DISCONTIGMEM_ENABLE | 358 | depends on ARCH_DISCONTIGMEM_ENABLE |
359 | select SPARSEMEM_VMEMMAP_ENABLE | ||
351 | 360 | ||
352 | config ARCH_DISCONTIGMEM_DEFAULT | 361 | config ARCH_DISCONTIGMEM_DEFAULT |
353 | def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) | 362 | def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) |
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S index 6d198339bf85..44817d97ab43 100644 --- a/arch/ia64/kernel/gate.lds.S +++ b/arch/ia64/kernel/gate.lds.S | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Linker script for gate DSO. The gate pages are an ELF shared object prelinked to its | 2 | * Linker script for gate DSO. The gate pages are an ELF shared object |
3 | * virtual address, with only one read-only segment and one execute-only segment (both fit | 3 | * prelinked to its virtual address, with only one read-only segment and |
4 | * in one page). This script controls its layout. | 4 | * one execute-only segment (both fit in one page). This script controls |
5 | * its layout. | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | 8 | ||
@@ -9,72 +10,80 @@ | |||
9 | 10 | ||
10 | SECTIONS | 11 | SECTIONS |
11 | { | 12 | { |
12 | . = GATE_ADDR + SIZEOF_HEADERS; | 13 | . = GATE_ADDR + SIZEOF_HEADERS; |
13 | 14 | ||
14 | .hash : { *(.hash) } :readable | 15 | .hash : { *(.hash) } :readable |
15 | .gnu.hash : { *(.gnu.hash) } | 16 | .gnu.hash : { *(.gnu.hash) } |
16 | .dynsym : { *(.dynsym) } | 17 | .dynsym : { *(.dynsym) } |
17 | .dynstr : { *(.dynstr) } | 18 | .dynstr : { *(.dynstr) } |
18 | .gnu.version : { *(.gnu.version) } | 19 | .gnu.version : { *(.gnu.version) } |
19 | .gnu.version_d : { *(.gnu.version_d) } | 20 | .gnu.version_d : { *(.gnu.version_d) } |
20 | .gnu.version_r : { *(.gnu.version_r) } | 21 | .gnu.version_r : { *(.gnu.version_r) } |
21 | .dynamic : { *(.dynamic) } :readable :dynamic | 22 | |
22 | 23 | .dynamic : { *(.dynamic) } :readable :dynamic | |
23 | /* | 24 | |
24 | * This linker script is used both with -r and with -shared. For the layouts to match, | 25 | /* |
25 | * we need to skip more than enough space for the dynamic symbol table et al. If this | 26 | * This linker script is used both with -r and with -shared. For |
26 | * amount is insufficient, ld -shared will barf. Just increase it here. | 27 | * the layouts to match, we need to skip more than enough space for |
27 | */ | 28 | * the dynamic symbol table et al. If this amount is insufficient, |
28 | . = GATE_ADDR + 0x500; | 29 | * ld -shared will barf. Just increase it here. |
29 | 30 | */ | |
30 | .data.patch : { | 31 | . = GATE_ADDR + 0x500; |
31 | __start_gate_mckinley_e9_patchlist = .; | 32 | |
32 | *(.data.patch.mckinley_e9) | 33 | .data.patch : { |
33 | __end_gate_mckinley_e9_patchlist = .; | 34 | __start_gate_mckinley_e9_patchlist = .; |
34 | 35 | *(.data.patch.mckinley_e9) | |
35 | __start_gate_vtop_patchlist = .; | 36 | __end_gate_mckinley_e9_patchlist = .; |
36 | *(.data.patch.vtop) | 37 | |
37 | __end_gate_vtop_patchlist = .; | 38 | __start_gate_vtop_patchlist = .; |
38 | 39 | *(.data.patch.vtop) | |
39 | __start_gate_fsyscall_patchlist = .; | 40 | __end_gate_vtop_patchlist = .; |
40 | *(.data.patch.fsyscall_table) | 41 | |
41 | __end_gate_fsyscall_patchlist = .; | 42 | __start_gate_fsyscall_patchlist = .; |
42 | 43 | *(.data.patch.fsyscall_table) | |
43 | __start_gate_brl_fsys_bubble_down_patchlist = .; | 44 | __end_gate_fsyscall_patchlist = .; |
44 | *(.data.patch.brl_fsys_bubble_down) | 45 | |
45 | __end_gate_brl_fsys_bubble_down_patchlist = .; | 46 | __start_gate_brl_fsys_bubble_down_patchlist = .; |
46 | } :readable | 47 | *(.data.patch.brl_fsys_bubble_down) |
47 | .IA_64.unwind_info : { *(.IA_64.unwind_info*) } | 48 | __end_gate_brl_fsys_bubble_down_patchlist = .; |
48 | .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind | 49 | } :readable |
50 | |||
51 | .IA_64.unwind_info : { *(.IA_64.unwind_info*) } | ||
52 | .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind | ||
49 | #ifdef HAVE_BUGGY_SEGREL | 53 | #ifdef HAVE_BUGGY_SEGREL |
50 | .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable | 54 | .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable |
51 | #else | 55 | #else |
52 | . = ALIGN (PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1)); | 56 | . = ALIGN(PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1)); |
53 | .text : { *(.text) *(.text.*) } :epc | 57 | .text : { *(.text) *(.text.*) } :epc |
54 | #endif | 58 | #endif |
55 | 59 | ||
56 | /DISCARD/ : { | 60 | /DISCARD/ : { |
57 | *(.got.plt) *(.got) | 61 | *(.got.plt) *(.got) |
58 | *(.data .data.* .gnu.linkonce.d.*) | 62 | *(.data .data.* .gnu.linkonce.d.*) |
59 | *(.dynbss) | 63 | *(.dynbss) |
60 | *(.bss .bss.* .gnu.linkonce.b.*) | 64 | *(.bss .bss.* .gnu.linkonce.b.*) |
61 | *(__ex_table) | 65 | *(__ex_table) |
62 | *(__mca_table) | 66 | *(__mca_table) |
63 | } | 67 | } |
64 | } | 68 | } |
65 | 69 | ||
66 | /* | 70 | /* |
71 | * ld does not recognize this name token; use the constant. | ||
72 | */ | ||
73 | #define PT_IA_64_UNWIND 0x70000001 | ||
74 | |||
75 | /* | ||
67 | * We must supply the ELF program headers explicitly to get just one | 76 | * We must supply the ELF program headers explicitly to get just one |
68 | * PT_LOAD segment, and set the flags explicitly to make segments read-only. | 77 | * PT_LOAD segment, and set the flags explicitly to make segments read-only. |
69 | */ | 78 | */ |
70 | PHDRS | 79 | PHDRS |
71 | { | 80 | { |
72 | readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */ | 81 | readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */ |
73 | #ifndef HAVE_BUGGY_SEGREL | 82 | #ifndef HAVE_BUGGY_SEGREL |
74 | epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */ | 83 | epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */ |
75 | #endif | 84 | #endif |
76 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 85 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
77 | unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */ | 86 | unwind PT_IA_64_UNWIND; |
78 | } | 87 | } |
79 | 88 | ||
80 | /* | 89 | /* |
@@ -82,14 +91,14 @@ PHDRS | |||
82 | */ | 91 | */ |
83 | VERSION | 92 | VERSION |
84 | { | 93 | { |
85 | LINUX_2.5 { | 94 | LINUX_2.5 { |
86 | global: | 95 | global: |
87 | __kernel_syscall_via_break; | 96 | __kernel_syscall_via_break; |
88 | __kernel_syscall_via_epc; | 97 | __kernel_syscall_via_epc; |
89 | __kernel_sigtramp; | 98 | __kernel_sigtramp; |
90 | 99 | ||
91 | local: *; | 100 | local: *; |
92 | }; | 101 | }; |
93 | } | 102 | } |
94 | 103 | ||
95 | /* The ELF entry point can be used to set the AT_SYSINFO value. */ | 104 | /* The ELF entry point can be used to set the AT_SYSINFO value. */ |
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 5dc98b5abcfb..5fd65d8302c8 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
@@ -40,6 +40,8 @@ extern void jprobe_inst_return(void); | |||
40 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | 40 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
41 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | 41 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
42 | 42 | ||
43 | struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; | ||
44 | |||
43 | enum instruction_type {A, I, M, F, B, L, X, u}; | 45 | enum instruction_type {A, I, M, F, B, L, X, u}; |
44 | static enum instruction_type bundle_encoding[32][3] = { | 46 | static enum instruction_type bundle_encoding[32][3] = { |
45 | { M, I, I }, /* 00 */ | 47 | { M, I, I }, /* 00 */ |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 9e392a30d197..777c8d8bd5e7 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -528,10 +528,6 @@ setup_arch (char **cmdline_p) | |||
528 | 528 | ||
529 | #ifdef CONFIG_SMP | 529 | #ifdef CONFIG_SMP |
530 | cpu_physical_id(0) = hard_smp_processor_id(); | 530 | cpu_physical_id(0) = hard_smp_processor_id(); |
531 | |||
532 | cpu_set(0, cpu_sibling_map[0]); | ||
533 | cpu_set(0, cpu_core_map[0]); | ||
534 | |||
535 | check_for_logical_procs(); | 531 | check_for_logical_procs(); |
536 | if (smp_num_cpucores > 1) | 532 | if (smp_num_cpucores > 1) |
537 | printk(KERN_INFO | 533 | printk(KERN_INFO |
@@ -873,6 +869,14 @@ cpu_init (void) | |||
873 | void *cpu_data; | 869 | void *cpu_data; |
874 | 870 | ||
875 | cpu_data = per_cpu_init(); | 871 | cpu_data = per_cpu_init(); |
872 | /* | ||
873 | * insert boot cpu into sibling and core mapes | ||
874 | * (must be done after per_cpu area is setup) | ||
875 | */ | ||
876 | if (smp_processor_id() == 0) { | ||
877 | cpu_set(0, per_cpu(cpu_sibling_map, 0)); | ||
878 | cpu_set(0, cpu_core_map[0]); | ||
879 | } | ||
876 | 880 | ||
877 | /* | 881 | /* |
878 | * We set ar.k3 so that assembly code in MCA handler can compute | 882 | * We set ar.k3 so that assembly code in MCA handler can compute |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 308772f7cddc..c57dbce25c12 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -138,7 +138,9 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE; | |||
138 | EXPORT_SYMBOL(cpu_possible_map); | 138 | EXPORT_SYMBOL(cpu_possible_map); |
139 | 139 | ||
140 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | 140 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; |
141 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | 141 | DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map); |
142 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); | ||
143 | |||
142 | int smp_num_siblings = 1; | 144 | int smp_num_siblings = 1; |
143 | int smp_num_cpucores = 1; | 145 | int smp_num_cpucores = 1; |
144 | 146 | ||
@@ -650,12 +652,12 @@ clear_cpu_sibling_map(int cpu) | |||
650 | { | 652 | { |
651 | int i; | 653 | int i; |
652 | 654 | ||
653 | for_each_cpu_mask(i, cpu_sibling_map[cpu]) | 655 | for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) |
654 | cpu_clear(cpu, cpu_sibling_map[i]); | 656 | cpu_clear(cpu, per_cpu(cpu_sibling_map, i)); |
655 | for_each_cpu_mask(i, cpu_core_map[cpu]) | 657 | for_each_cpu_mask(i, cpu_core_map[cpu]) |
656 | cpu_clear(cpu, cpu_core_map[i]); | 658 | cpu_clear(cpu, cpu_core_map[i]); |
657 | 659 | ||
658 | cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE; | 660 | per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE; |
659 | } | 661 | } |
660 | 662 | ||
661 | static void | 663 | static void |
@@ -666,7 +668,7 @@ remove_siblinginfo(int cpu) | |||
666 | if (cpu_data(cpu)->threads_per_core == 1 && | 668 | if (cpu_data(cpu)->threads_per_core == 1 && |
667 | cpu_data(cpu)->cores_per_socket == 1) { | 669 | cpu_data(cpu)->cores_per_socket == 1) { |
668 | cpu_clear(cpu, cpu_core_map[cpu]); | 670 | cpu_clear(cpu, cpu_core_map[cpu]); |
669 | cpu_clear(cpu, cpu_sibling_map[cpu]); | 671 | cpu_clear(cpu, per_cpu(cpu_sibling_map, cpu)); |
670 | return; | 672 | return; |
671 | } | 673 | } |
672 | 674 | ||
@@ -807,8 +809,8 @@ set_cpu_sibling_map(int cpu) | |||
807 | cpu_set(i, cpu_core_map[cpu]); | 809 | cpu_set(i, cpu_core_map[cpu]); |
808 | cpu_set(cpu, cpu_core_map[i]); | 810 | cpu_set(cpu, cpu_core_map[i]); |
809 | if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) { | 811 | if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) { |
810 | cpu_set(i, cpu_sibling_map[cpu]); | 812 | cpu_set(i, per_cpu(cpu_sibling_map, cpu)); |
811 | cpu_set(cpu, cpu_sibling_map[i]); | 813 | cpu_set(cpu, per_cpu(cpu_sibling_map, i)); |
812 | } | 814 | } |
813 | } | 815 | } |
814 | } | 816 | } |
@@ -839,7 +841,7 @@ __cpu_up (unsigned int cpu) | |||
839 | 841 | ||
840 | if (cpu_data(cpu)->threads_per_core == 1 && | 842 | if (cpu_data(cpu)->threads_per_core == 1 && |
841 | cpu_data(cpu)->cores_per_socket == 1) { | 843 | cpu_data(cpu)->cores_per_socket == 1) { |
842 | cpu_set(cpu, cpu_sibling_map[cpu]); | 844 | cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); |
843 | cpu_set(cpu, cpu_core_map[cpu]); | 845 | cpu_set(cpu, cpu_core_map[cpu]); |
844 | return 0; | 846 | return 0; |
845 | } | 847 | } |
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index c58e933694d5..a7be4f203420 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c | |||
@@ -196,7 +196,7 @@ unsigned long uncached_alloc_page(int starting_nid) | |||
196 | nid = starting_nid; | 196 | nid = starting_nid; |
197 | 197 | ||
198 | do { | 198 | do { |
199 | if (!node_online(nid)) | 199 | if (!node_state(nid, N_HIGH_MEMORY)) |
200 | continue; | 200 | continue; |
201 | uc_pool = &uncached_pools[nid]; | 201 | uc_pool = &uncached_pools[nid]; |
202 | if (uc_pool->pool == NULL) | 202 | if (uc_pool->pool == NULL) |
@@ -268,7 +268,7 @@ static int __init uncached_init(void) | |||
268 | { | 268 | { |
269 | int nid; | 269 | int nid; |
270 | 270 | ||
271 | for_each_online_node(nid) { | 271 | for_each_node_state(nid, N_ONLINE) { |
272 | uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid); | 272 | uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid); |
273 | mutex_init(&uncached_pools[nid].add_chunk_mutex); | 273 | mutex_init(&uncached_pools[nid].add_chunk_mutex); |
274 | } | 274 | } |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 0d34585058c8..5628067a74d2 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -715,3 +715,11 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) | |||
715 | scatter_node_data(); | 715 | scatter_node_data(); |
716 | } | 716 | } |
717 | #endif | 717 | #endif |
718 | |||
719 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | ||
720 | int __meminit vmemmap_populate(struct page *start_page, | ||
721 | unsigned long size, int node) | ||
722 | { | ||
723 | return vmemmap_populate_basepages(start_page, size, node); | ||
724 | } | ||
725 | #endif | ||
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 9150ffaff9e8..32f26253c4e8 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c | |||
@@ -281,6 +281,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re | |||
281 | } | 281 | } |
282 | printk(KERN_CRIT "VM: killing process %s\n", current->comm); | 282 | printk(KERN_CRIT "VM: killing process %s\n", current->comm); |
283 | if (user_mode(regs)) | 283 | if (user_mode(regs)) |
284 | do_exit(SIGKILL); | 284 | do_group_exit(SIGKILL); |
285 | goto no_context; | 285 | goto no_context; |
286 | } | 286 | } |
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index a9ff685aea25..d3ce8f3bcaa6 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c | |||
@@ -194,6 +194,6 @@ static int __init hugetlb_setup_sz(char *str) | |||
194 | * override here with new page shift. | 194 | * override here with new page shift. |
195 | */ | 195 | */ |
196 | ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2); | 196 | ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2); |
197 | return 1; | 197 | return 0; |
198 | } | 198 | } |
199 | __setup("hugepagesz=", hugetlb_setup_sz); | 199 | early_param("hugepagesz", hugetlb_setup_sz); |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index c14abefabafa..3e10152abbf0 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -54,15 +54,12 @@ struct page *zero_page_memmap_ptr; /* map entry for zero page */ | |||
54 | EXPORT_SYMBOL(zero_page_memmap_ptr); | 54 | EXPORT_SYMBOL(zero_page_memmap_ptr); |
55 | 55 | ||
56 | void | 56 | void |
57 | lazy_mmu_prot_update (pte_t pte) | 57 | __ia64_sync_icache_dcache (pte_t pte) |
58 | { | 58 | { |
59 | unsigned long addr; | 59 | unsigned long addr; |
60 | struct page *page; | 60 | struct page *page; |
61 | unsigned long order; | 61 | unsigned long order; |
62 | 62 | ||
63 | if (!pte_exec(pte)) | ||
64 | return; /* not an executable page... */ | ||
65 | |||
66 | page = pte_page(pte); | 63 | page = pte_page(pte); |
67 | addr = (unsigned long) page_address(page); | 64 | addr = (unsigned long) page_address(page); |
68 | 65 | ||
@@ -721,10 +718,21 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
721 | 718 | ||
722 | return ret; | 719 | return ret; |
723 | } | 720 | } |
724 | 721 | #ifdef CONFIG_MEMORY_HOTREMOVE | |
725 | int remove_memory(u64 start, u64 size) | 722 | int remove_memory(u64 start, u64 size) |
726 | { | 723 | { |
727 | return -EINVAL; | 724 | unsigned long start_pfn, end_pfn; |
725 | unsigned long timeout = 120 * HZ; | ||
726 | int ret; | ||
727 | start_pfn = start >> PAGE_SHIFT; | ||
728 | end_pfn = start_pfn + (size >> PAGE_SHIFT); | ||
729 | ret = offline_pages(start_pfn, end_pfn, timeout); | ||
730 | if (ret) | ||
731 | goto out; | ||
732 | /* we can free mem_map at this point */ | ||
733 | out: | ||
734 | return ret; | ||
728 | } | 735 | } |
729 | EXPORT_SYMBOL_GPL(remove_memory); | 736 | EXPORT_SYMBOL_GPL(remove_memory); |
737 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | ||
730 | #endif | 738 | #endif |