diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/Kconfig | 6 | ||||
-rw-r--r-- | arch/x86_64/kernel/entry.S | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/i8259.c | 6 | ||||
-rw-r--r-- | arch/x86_64/kernel/io_apic.c | 25 | ||||
-rw-r--r-- | arch/x86_64/kernel/irq.c | 18 | ||||
-rw-r--r-- | arch/x86_64/kernel/mce.c | 4 | ||||
-rw-r--r-- | arch/x86_64/kernel/nmi.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/smp.c | 4 | ||||
-rw-r--r-- | arch/x86_64/kernel/smpboot.c | 8 | ||||
-rw-r--r-- | arch/x86_64/mm/init.c | 73 |
10 files changed, 92 insertions, 56 deletions
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index ccc4a7fb97a3..e856804c447f 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -370,6 +370,8 @@ config HOTPLUG_CPU | |||
370 | can be controlled through /sys/devices/system/cpu/cpu#. | 370 | can be controlled through /sys/devices/system/cpu/cpu#. |
371 | Say N if you want to disable CPU hotplug. | 371 | Say N if you want to disable CPU hotplug. |
372 | 372 | ||
373 | config ARCH_ENABLE_MEMORY_HOTPLUG | ||
374 | def_bool y | ||
373 | 375 | ||
374 | config HPET_TIMER | 376 | config HPET_TIMER |
375 | bool | 377 | bool |
@@ -459,10 +461,10 @@ config KEXEC | |||
459 | help | 461 | help |
460 | kexec is a system call that implements the ability to shutdown your | 462 | kexec is a system call that implements the ability to shutdown your |
461 | current kernel, and to start another kernel. It is like a reboot | 463 | current kernel, and to start another kernel. It is like a reboot |
462 | but it is indepedent of the system firmware. And like a reboot | 464 | but it is independent of the system firmware. And like a reboot |
463 | you can start any kernel with it, not just Linux. | 465 | you can start any kernel with it, not just Linux. |
464 | 466 | ||
465 | The name comes from the similiarity to the exec system call. | 467 | The name comes from the similarity to the exec system call. |
466 | 468 | ||
467 | It is an ongoing process to be certain the hardware in a machine | 469 | It is an ongoing process to be certain the hardware in a machine |
468 | is properly shutdown, so do not be surprised if this code does not | 470 | is properly shutdown, so do not be surprised if this code does not |
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 7290e72b9a34..22cac4487b57 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -588,7 +588,7 @@ END(common_interrupt) | |||
588 | */ | 588 | */ |
589 | .macro apicinterrupt num,func | 589 | .macro apicinterrupt num,func |
590 | INTR_FRAME | 590 | INTR_FRAME |
591 | pushq $\num-256 | 591 | pushq $~(\num) |
592 | CFI_ADJUST_CFA_OFFSET 8 | 592 | CFI_ADJUST_CFA_OFFSET 8 |
593 | interrupt \func | 593 | interrupt \func |
594 | jmp ret_from_intr | 594 | jmp ret_from_intr |
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 86b2c1e197aa..3dd1659427dc 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c | |||
@@ -235,7 +235,7 @@ void make_8259A_irq(unsigned int irq) | |||
235 | { | 235 | { |
236 | disable_irq_nosync(irq); | 236 | disable_irq_nosync(irq); |
237 | io_apic_irqs &= ~(1<<irq); | 237 | io_apic_irqs &= ~(1<<irq); |
238 | irq_desc[irq].handler = &i8259A_irq_type; | 238 | irq_desc[irq].chip = &i8259A_irq_type; |
239 | enable_irq(irq); | 239 | enable_irq(irq); |
240 | } | 240 | } |
241 | 241 | ||
@@ -468,12 +468,12 @@ void __init init_ISA_irqs (void) | |||
468 | /* | 468 | /* |
469 | * 16 old-style INTA-cycle interrupts: | 469 | * 16 old-style INTA-cycle interrupts: |
470 | */ | 470 | */ |
471 | irq_desc[i].handler = &i8259A_irq_type; | 471 | irq_desc[i].chip = &i8259A_irq_type; |
472 | } else { | 472 | } else { |
473 | /* | 473 | /* |
474 | * 'high' PCI IRQs filled in on demand | 474 | * 'high' PCI IRQs filled in on demand |
475 | */ | 475 | */ |
476 | irq_desc[i].handler = &no_irq_type; | 476 | irq_desc[i].chip = &no_irq_type; |
477 | } | 477 | } |
478 | } | 478 | } |
479 | } | 479 | } |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index c768d8a036d0..401b687fef21 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -876,15 +876,17 @@ static struct hw_interrupt_type ioapic_edge_type; | |||
876 | #define IOAPIC_EDGE 0 | 876 | #define IOAPIC_EDGE 0 |
877 | #define IOAPIC_LEVEL 1 | 877 | #define IOAPIC_LEVEL 1 |
878 | 878 | ||
879 | static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) | 879 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) |
880 | { | 880 | { |
881 | unsigned idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | 881 | unsigned idx; |
882 | |||
883 | idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | ||
882 | 884 | ||
883 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 885 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
884 | trigger == IOAPIC_LEVEL) | 886 | trigger == IOAPIC_LEVEL) |
885 | irq_desc[idx].handler = &ioapic_level_type; | 887 | irq_desc[idx].chip = &ioapic_level_type; |
886 | else | 888 | else |
887 | irq_desc[idx].handler = &ioapic_edge_type; | 889 | irq_desc[idx].chip = &ioapic_edge_type; |
888 | set_intr_gate(vector, interrupt[idx]); | 890 | set_intr_gate(vector, interrupt[idx]); |
889 | } | 891 | } |
890 | 892 | ||
@@ -986,7 +988,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in | |||
986 | * The timer IRQ doesn't have to know that behind the | 988 | * The timer IRQ doesn't have to know that behind the |
987 | * scene we have a 8259A-master in AEOI mode ... | 989 | * scene we have a 8259A-master in AEOI mode ... |
988 | */ | 990 | */ |
989 | irq_desc[0].handler = &ioapic_edge_type; | 991 | irq_desc[0].chip = &ioapic_edge_type; |
990 | 992 | ||
991 | /* | 993 | /* |
992 | * Add it to the IO-APIC irq-routing table: | 994 | * Add it to the IO-APIC irq-routing table: |
@@ -1616,6 +1618,13 @@ static void set_ioapic_affinity_vector (unsigned int vector, | |||
1616 | #endif // CONFIG_SMP | 1618 | #endif // CONFIG_SMP |
1617 | #endif // CONFIG_PCI_MSI | 1619 | #endif // CONFIG_PCI_MSI |
1618 | 1620 | ||
1621 | static int ioapic_retrigger(unsigned int irq) | ||
1622 | { | ||
1623 | send_IPI_self(IO_APIC_VECTOR(irq)); | ||
1624 | |||
1625 | return 1; | ||
1626 | } | ||
1627 | |||
1619 | /* | 1628 | /* |
1620 | * Level and edge triggered IO-APIC interrupts need different handling, | 1629 | * Level and edge triggered IO-APIC interrupts need different handling, |
1621 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be | 1630 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be |
@@ -1636,6 +1645,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = { | |||
1636 | #ifdef CONFIG_SMP | 1645 | #ifdef CONFIG_SMP |
1637 | .set_affinity = set_ioapic_affinity, | 1646 | .set_affinity = set_ioapic_affinity, |
1638 | #endif | 1647 | #endif |
1648 | .retrigger = ioapic_retrigger, | ||
1639 | }; | 1649 | }; |
1640 | 1650 | ||
1641 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { | 1651 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { |
@@ -1649,6 +1659,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = { | |||
1649 | #ifdef CONFIG_SMP | 1659 | #ifdef CONFIG_SMP |
1650 | .set_affinity = set_ioapic_affinity, | 1660 | .set_affinity = set_ioapic_affinity, |
1651 | #endif | 1661 | #endif |
1662 | .retrigger = ioapic_retrigger, | ||
1652 | }; | 1663 | }; |
1653 | 1664 | ||
1654 | static inline void init_IO_APIC_traps(void) | 1665 | static inline void init_IO_APIC_traps(void) |
@@ -1683,7 +1694,7 @@ static inline void init_IO_APIC_traps(void) | |||
1683 | make_8259A_irq(irq); | 1694 | make_8259A_irq(irq); |
1684 | else | 1695 | else |
1685 | /* Strange. Oh, well.. */ | 1696 | /* Strange. Oh, well.. */ |
1686 | irq_desc[irq].handler = &no_irq_type; | 1697 | irq_desc[irq].chip = &no_irq_type; |
1687 | } | 1698 | } |
1688 | } | 1699 | } |
1689 | } | 1700 | } |
@@ -1900,7 +1911,7 @@ static inline void check_timer(void) | |||
1900 | apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 1911 | apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
1901 | 1912 | ||
1902 | disable_8259A_irq(0); | 1913 | disable_8259A_irq(0); |
1903 | irq_desc[0].handler = &lapic_irq_type; | 1914 | irq_desc[0].chip = &lapic_irq_type; |
1904 | apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 1915 | apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
1905 | enable_8259A_irq(0); | 1916 | enable_8259A_irq(0); |
1906 | 1917 | ||
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index 59518d4d4358..a1f1df5f7bfc 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
@@ -79,7 +79,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
79 | for_each_online_cpu(j) | 79 | for_each_online_cpu(j) |
80 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 80 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
81 | #endif | 81 | #endif |
82 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 82 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
83 | 83 | ||
84 | seq_printf(p, " %s", action->name); | 84 | seq_printf(p, " %s", action->name); |
85 | for (action=action->next; action; action = action->next) | 85 | for (action=action->next; action; action = action->next) |
@@ -115,8 +115,14 @@ skip: | |||
115 | */ | 115 | */ |
116 | asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | 116 | asmlinkage unsigned int do_IRQ(struct pt_regs *regs) |
117 | { | 117 | { |
118 | /* high bits used in ret_from_ code */ | 118 | /* high bit used in ret_from_ code */ |
119 | unsigned irq = regs->orig_rax & 0xff; | 119 | unsigned irq = ~regs->orig_rax; |
120 | |||
121 | if (unlikely(irq >= NR_IRQS)) { | ||
122 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", | ||
123 | __FUNCTION__, irq); | ||
124 | BUG(); | ||
125 | } | ||
120 | 126 | ||
121 | exit_idle(); | 127 | exit_idle(); |
122 | irq_enter(); | 128 | irq_enter(); |
@@ -140,13 +146,13 @@ void fixup_irqs(cpumask_t map) | |||
140 | if (irq == 2) | 146 | if (irq == 2) |
141 | continue; | 147 | continue; |
142 | 148 | ||
143 | cpus_and(mask, irq_affinity[irq], map); | 149 | cpus_and(mask, irq_desc[irq].affinity, map); |
144 | if (any_online_cpu(mask) == NR_CPUS) { | 150 | if (any_online_cpu(mask) == NR_CPUS) { |
145 | printk("Breaking affinity for irq %i\n", irq); | 151 | printk("Breaking affinity for irq %i\n", irq); |
146 | mask = map; | 152 | mask = map; |
147 | } | 153 | } |
148 | if (irq_desc[irq].handler->set_affinity) | 154 | if (irq_desc[irq].chip->set_affinity) |
149 | irq_desc[irq].handler->set_affinity(irq, mask); | 155 | irq_desc[irq].chip->set_affinity(irq, mask); |
150 | else if (irq_desc[irq].action && !(warned++)) | 156 | else if (irq_desc[irq].action && !(warned++)) |
151 | printk("Cannot set affinity for irq %i\n", irq); | 157 | printk("Cannot set affinity for irq %i\n", irq); |
152 | } | 158 | } |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index acd5816b1a6f..88845674c661 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -629,7 +629,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) | |||
629 | #endif | 629 | #endif |
630 | 630 | ||
631 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ | 631 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ |
632 | static int | 632 | static __cpuinit int |
633 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 633 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
634 | { | 634 | { |
635 | unsigned int cpu = (unsigned long)hcpu; | 635 | unsigned int cpu = (unsigned long)hcpu; |
@@ -647,7 +647,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
647 | return NOTIFY_OK; | 647 | return NOTIFY_OK; |
648 | } | 648 | } |
649 | 649 | ||
650 | static struct notifier_block mce_cpu_notifier = { | 650 | static struct notifier_block __cpuinitdata mce_cpu_notifier = { |
651 | .notifier_call = mce_cpu_callback, | 651 | .notifier_call = mce_cpu_callback, |
652 | }; | 652 | }; |
653 | 653 | ||
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 399489c93132..0ef9cf2bc45e 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -607,11 +607,13 @@ void set_nmi_callback(nmi_callback_t callback) | |||
607 | vmalloc_sync_all(); | 607 | vmalloc_sync_all(); |
608 | rcu_assign_pointer(nmi_callback, callback); | 608 | rcu_assign_pointer(nmi_callback, callback); |
609 | } | 609 | } |
610 | EXPORT_SYMBOL_GPL(set_nmi_callback); | ||
610 | 611 | ||
611 | void unset_nmi_callback(void) | 612 | void unset_nmi_callback(void) |
612 | { | 613 | { |
613 | nmi_callback = dummy_nmi_callback; | 614 | nmi_callback = dummy_nmi_callback; |
614 | } | 615 | } |
616 | EXPORT_SYMBOL_GPL(unset_nmi_callback); | ||
615 | 617 | ||
616 | #ifdef CONFIG_SYSCTL | 618 | #ifdef CONFIG_SYSCTL |
617 | 619 | ||
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index acee4bc3f6fa..5a1c0a3bf872 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c | |||
@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) | |||
135 | 135 | ||
136 | cpu = smp_processor_id(); | 136 | cpu = smp_processor_id(); |
137 | /* | 137 | /* |
138 | * orig_rax contains the interrupt vector - 256. | 138 | * orig_rax contains the negated interrupt vector. |
139 | * Use that to determine where the sender put the data. | 139 | * Use that to determine where the sender put the data. |
140 | */ | 140 | */ |
141 | sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START; | 141 | sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; |
142 | f = &per_cpu(flush_state, sender); | 142 | f = &per_cpu(flush_state, sender); |
143 | 143 | ||
144 | if (!cpu_isset(cpu, f->flush_cpumask)) | 144 | if (!cpu_isset(cpu, f->flush_cpumask)) |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 4e9755179ecf..540c0ccbcccc 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -455,10 +455,12 @@ cpumask_t cpu_coregroup_map(int cpu) | |||
455 | struct cpuinfo_x86 *c = cpu_data + cpu; | 455 | struct cpuinfo_x86 *c = cpu_data + cpu; |
456 | /* | 456 | /* |
457 | * For perf, we return last level cache shared map. | 457 | * For perf, we return last level cache shared map. |
458 | * TBD: when power saving sched policy is added, we will return | 458 | * And for power savings, we return cpu_core_map |
459 | * cpu_core_map when power saving policy is enabled | ||
460 | */ | 459 | */ |
461 | return c->llc_shared_map; | 460 | if (sched_mc_power_savings || sched_smt_power_savings) |
461 | return cpu_core_map[cpu]; | ||
462 | else | ||
463 | return c->llc_shared_map; | ||
462 | } | 464 | } |
463 | 465 | ||
464 | /* representing cpus for which sibling maps can be computed */ | 466 | /* representing cpus for which sibling maps can be computed */ |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 02add1d1dfa8..95bd232ff0cf 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/proc_fs.h> | 24 | #include <linux/proc_fs.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/poison.h> | ||
26 | #include <linux/dma-mapping.h> | 27 | #include <linux/dma-mapping.h> |
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
28 | #include <linux/memory_hotplug.h> | 29 | #include <linux/memory_hotplug.h> |
@@ -506,8 +507,6 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) | |||
506 | /* | 507 | /* |
507 | * Memory hotplug specific functions | 508 | * Memory hotplug specific functions |
508 | */ | 509 | */ |
509 | #if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||
510 | |||
511 | void online_page(struct page *page) | 510 | void online_page(struct page *page) |
512 | { | 511 | { |
513 | ClearPageReserved(page); | 512 | ClearPageReserved(page); |
@@ -517,31 +516,17 @@ void online_page(struct page *page) | |||
517 | num_physpages++; | 516 | num_physpages++; |
518 | } | 517 | } |
519 | 518 | ||
520 | #ifndef CONFIG_MEMORY_HOTPLUG | 519 | #ifdef CONFIG_MEMORY_HOTPLUG |
521 | /* | 520 | /* |
522 | * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, | 521 | * XXX: memory_add_physaddr_to_nid() is to find node id from physical address |
523 | * just online the pages. | 522 | * via probe interface of sysfs. If acpi notifies hot-add event, then it |
523 | * can tell node id by searching dsdt. But, probe interface doesn't have | ||
524 | * node id. So, return 0 as node id at this time. | ||
524 | */ | 525 | */ |
525 | int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | 526 | #ifdef CONFIG_NUMA |
527 | int memory_add_physaddr_to_nid(u64 start) | ||
526 | { | 528 | { |
527 | int err = -EIO; | 529 | return 0; |
528 | unsigned long pfn; | ||
529 | unsigned long total = 0, mem = 0; | ||
530 | for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { | ||
531 | if (pfn_valid(pfn)) { | ||
532 | online_page(pfn_to_page(pfn)); | ||
533 | err = 0; | ||
534 | mem++; | ||
535 | } | ||
536 | total++; | ||
537 | } | ||
538 | if (!err) { | ||
539 | z->spanned_pages += total; | ||
540 | z->present_pages += mem; | ||
541 | z->zone_pgdat->node_spanned_pages += total; | ||
542 | z->zone_pgdat->node_present_pages += mem; | ||
543 | } | ||
544 | return err; | ||
545 | } | 530 | } |
546 | #endif | 531 | #endif |
547 | 532 | ||
@@ -549,9 +534,9 @@ int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | |||
549 | * Memory is added always to NORMAL zone. This means you will never get | 534 | * Memory is added always to NORMAL zone. This means you will never get |
550 | * additional DMA/DMA32 memory. | 535 | * additional DMA/DMA32 memory. |
551 | */ | 536 | */ |
552 | int add_memory(u64 start, u64 size) | 537 | int arch_add_memory(int nid, u64 start, u64 size) |
553 | { | 538 | { |
554 | struct pglist_data *pgdat = NODE_DATA(0); | 539 | struct pglist_data *pgdat = NODE_DATA(nid); |
555 | struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; | 540 | struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; |
556 | unsigned long start_pfn = start >> PAGE_SHIFT; | 541 | unsigned long start_pfn = start >> PAGE_SHIFT; |
557 | unsigned long nr_pages = size >> PAGE_SHIFT; | 542 | unsigned long nr_pages = size >> PAGE_SHIFT; |
@@ -568,7 +553,7 @@ error: | |||
568 | printk("%s: Problem encountered in __add_pages!\n", __func__); | 553 | printk("%s: Problem encountered in __add_pages!\n", __func__); |
569 | return ret; | 554 | return ret; |
570 | } | 555 | } |
571 | EXPORT_SYMBOL_GPL(add_memory); | 556 | EXPORT_SYMBOL_GPL(arch_add_memory); |
572 | 557 | ||
573 | int remove_memory(u64 start, u64 size) | 558 | int remove_memory(u64 start, u64 size) |
574 | { | 559 | { |
@@ -576,7 +561,33 @@ int remove_memory(u64 start, u64 size) | |||
576 | } | 561 | } |
577 | EXPORT_SYMBOL_GPL(remove_memory); | 562 | EXPORT_SYMBOL_GPL(remove_memory); |
578 | 563 | ||
579 | #endif | 564 | #else /* CONFIG_MEMORY_HOTPLUG */ |
565 | /* | ||
566 | * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, | ||
567 | * just online the pages. | ||
568 | */ | ||
569 | int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | ||
570 | { | ||
571 | int err = -EIO; | ||
572 | unsigned long pfn; | ||
573 | unsigned long total = 0, mem = 0; | ||
574 | for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { | ||
575 | if (pfn_valid(pfn)) { | ||
576 | online_page(pfn_to_page(pfn)); | ||
577 | err = 0; | ||
578 | mem++; | ||
579 | } | ||
580 | total++; | ||
581 | } | ||
582 | if (!err) { | ||
583 | z->spanned_pages += total; | ||
584 | z->present_pages += mem; | ||
585 | z->zone_pgdat->node_spanned_pages += total; | ||
586 | z->zone_pgdat->node_present_pages += mem; | ||
587 | } | ||
588 | return err; | ||
589 | } | ||
590 | #endif /* CONFIG_MEMORY_HOTPLUG */ | ||
580 | 591 | ||
581 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, | 592 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, |
582 | kcore_vsyscall; | 593 | kcore_vsyscall; |
@@ -650,7 +661,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
650 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | 661 | for (addr = begin; addr < end; addr += PAGE_SIZE) { |
651 | ClearPageReserved(virt_to_page(addr)); | 662 | ClearPageReserved(virt_to_page(addr)); |
652 | init_page_count(virt_to_page(addr)); | 663 | init_page_count(virt_to_page(addr)); |
653 | memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); | 664 | memset((void *)(addr & ~(PAGE_SIZE-1)), |
665 | POISON_FREE_INITMEM, PAGE_SIZE); | ||
654 | free_page(addr); | 666 | free_page(addr); |
655 | totalram_pages++; | 667 | totalram_pages++; |
656 | } | 668 | } |
@@ -658,7 +670,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
658 | 670 | ||
659 | void free_initmem(void) | 671 | void free_initmem(void) |
660 | { | 672 | { |
661 | memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); | 673 | memset(__initdata_begin, POISON_FREE_INITDATA, |
674 | __initdata_end - __initdata_begin); | ||
662 | free_init_pages("unused kernel memory", | 675 | free_init_pages("unused kernel memory", |
663 | (unsigned long)(&__init_begin), | 676 | (unsigned long)(&__init_begin), |
664 | (unsigned long)(&__init_end)); | 677 | (unsigned long)(&__init_end)); |