aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts13
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca5s.dts13
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca9.dts9
-rw-r--r--arch/arm/mach-prima2/irq.c6
-rw-r--r--arch/arm/mach-tegra/flowctrl.c4
-rw-r--r--arch/arm/mach-vexpress/v2m.c2
-rw-r--r--arch/arm/mm/fault.c4
-rw-r--r--arch/arm/mm/mmu.c3
-rw-r--r--arch/arm/vfp/vfpmodule.c24
-rw-r--r--arch/frv/include/asm/processor.h4
-rw-r--r--arch/mn10300/kernel/smp.c9
-rw-r--r--arch/parisc/include/asm/prefetch.h7
-rw-r--r--arch/parisc/kernel/entry.S4
-rw-r--r--arch/parisc/kernel/pacache.S38
-rw-r--r--arch/parisc/kernel/smp.c8
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h7
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_host.c13
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c1
-rw-r--r--arch/powerpc/kvm/book3s_segment.S42
-rw-r--r--arch/tile/Kconfig1
-rw-r--r--arch/tile/include/asm/thread_info.h9
-rw-r--r--arch/tile/kernel/compat_signal.c12
-rw-r--r--arch/tile/kernel/intvec_32.S41
-rw-r--r--arch/tile/kernel/intvec_64.S38
-rw-r--r--arch/tile/kernel/process.c7
-rw-r--r--arch/x86/Makefile3
-rw-r--r--arch/x86/boot/compressed/Makefile9
-rw-r--r--arch/x86/include/asm/kvm_para.h3
-rw-r--r--arch/x86/kernel/acpi/boot.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c14
-rw-r--r--arch/x86/kernel/microcode_intel.c14
-rw-r--r--arch/x86/tools/.gitignore1
-rw-r--r--arch/x86/tools/Makefile4
-rw-r--r--arch/x86/tools/relocs.c (renamed from arch/x86/boot/compressed/relocs.c)242
34 files changed, 424 insertions, 187 deletions
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index 941b161ab78c..7e1091d91af8 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -73,7 +73,10 @@
73 #address-cells = <0>; 73 #address-cells = <0>;
74 interrupt-controller; 74 interrupt-controller;
75 reg = <0x2c001000 0x1000>, 75 reg = <0x2c001000 0x1000>,
76 <0x2c002000 0x100>; 76 <0x2c002000 0x1000>,
77 <0x2c004000 0x2000>,
78 <0x2c006000 0x2000>;
79 interrupts = <1 9 0xf04>;
77 }; 80 };
78 81
79 memory-controller@7ffd0000 { 82 memory-controller@7ffd0000 {
@@ -93,6 +96,14 @@
93 <0 91 4>; 96 <0 91 4>;
94 }; 97 };
95 98
99 timer {
100 compatible = "arm,armv7-timer";
101 interrupts = <1 13 0xf08>,
102 <1 14 0xf08>,
103 <1 11 0xf08>,
104 <1 10 0xf08>;
105 };
106
96 pmu { 107 pmu {
97 compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu"; 108 compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
98 interrupts = <0 68 4>, 109 interrupts = <0 68 4>,
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index 6905e66d4748..18917a0f8604 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -77,13 +77,18 @@
77 77
78 timer@2c000600 { 78 timer@2c000600 {
79 compatible = "arm,cortex-a5-twd-timer"; 79 compatible = "arm,cortex-a5-twd-timer";
80 reg = <0x2c000600 0x38>; 80 reg = <0x2c000600 0x20>;
81 interrupts = <1 2 0x304>, 81 interrupts = <1 13 0x304>;
82 <1 3 0x304>; 82 };
83
84 watchdog@2c000620 {
85 compatible = "arm,cortex-a5-twd-wdt";
86 reg = <0x2c000620 0x20>;
87 interrupts = <1 14 0x304>;
83 }; 88 };
84 89
85 gic: interrupt-controller@2c001000 { 90 gic: interrupt-controller@2c001000 {
86 compatible = "arm,corex-a5-gic", "arm,cortex-a9-gic"; 91 compatible = "arm,cortex-a5-gic", "arm,cortex-a9-gic";
87 #interrupt-cells = <3>; 92 #interrupt-cells = <3>;
88 #address-cells = <0>; 93 #address-cells = <0>;
89 interrupt-controller; 94 interrupt-controller;
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index da778693be54..3f0c736d31d6 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -105,8 +105,13 @@
105 timer@1e000600 { 105 timer@1e000600 {
106 compatible = "arm,cortex-a9-twd-timer"; 106 compatible = "arm,cortex-a9-twd-timer";
107 reg = <0x1e000600 0x20>; 107 reg = <0x1e000600 0x20>;
108 interrupts = <1 2 0xf04>, 108 interrupts = <1 13 0xf04>;
109 <1 3 0xf04>; 109 };
110
111 watchdog@1e000620 {
112 compatible = "arm,cortex-a9-twd-wdt";
113 reg = <0x1e000620 0x20>;
114 interrupts = <1 14 0xf04>;
110 }; 115 };
111 116
112 gic: interrupt-controller@1e001000 { 117 gic: interrupt-controller@1e001000 {
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
index 37c2de9b6f26..a7b9415d30f8 100644
--- a/arch/arm/mach-prima2/irq.c
+++ b/arch/arm/mach-prima2/irq.c
@@ -42,7 +42,8 @@ sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
42static __init void sirfsoc_irq_init(void) 42static __init void sirfsoc_irq_init(void)
43{ 43{
44 sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32); 44 sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32);
45 sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, SIRFSOC_INTENAL_IRQ_END - 32); 45 sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32,
46 SIRFSOC_INTENAL_IRQ_END + 1 - 32);
46 47
47 writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0); 48 writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0);
48 writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1); 49 writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1);
@@ -68,7 +69,8 @@ void __init sirfsoc_of_irq_init(void)
68 if (!sirfsoc_intc_base) 69 if (!sirfsoc_intc_base)
69 panic("unable to map intc cpu registers\n"); 70 panic("unable to map intc cpu registers\n");
70 71
71 irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL); 72 irq_domain_add_legacy(np, SIRFSOC_INTENAL_IRQ_END + 1, 0, 0,
73 &irq_domain_simple_ops, NULL);
72 74
73 of_node_put(np); 75 of_node_put(np);
74 76
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index fef66a7486ed..f07488e0bd32 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -53,10 +53,10 @@ static void flowctrl_update(u8 offset, u32 value)
53 53
54void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value) 54void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value)
55{ 55{
56 return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value); 56 return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value);
57} 57}
58 58
59void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value) 59void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value)
60{ 60{
61 return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value); 61 return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value);
62} 62}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 47cdcca5a7e7..e769ab612627 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -14,7 +14,6 @@
14#include <linux/ata_platform.h> 14#include <linux/ata_platform.h>
15#include <linux/smsc911x.h> 15#include <linux/smsc911x.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/device.h>
18#include <linux/usb/isp1760.h> 17#include <linux/usb/isp1760.h>
19#include <linux/clkdev.h> 18#include <linux/clkdev.h>
20#include <linux/mtd/physmap.h> 19#include <linux/mtd/physmap.h>
@@ -29,7 +28,6 @@
29#include <asm/hardware/gic.h> 28#include <asm/hardware/gic.h>
30#include <asm/hardware/timer-sp.h> 29#include <asm/hardware/timer-sp.h>
31#include <asm/hardware/sp810.h> 30#include <asm/hardware/sp810.h>
32#include <asm/hardware/gic.h>
33 31
34#include <mach/ct-ca9x4.h> 32#include <mach/ct-ca9x4.h>
35#include <mach/motherboard.h> 33#include <mach/motherboard.h>
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index f07467533365..5bb48356d217 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -247,7 +247,9 @@ good_area:
247 return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); 247 return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
248 248
249check_stack: 249check_stack:
250 if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) 250 /* Don't allow expansion below FIRST_USER_ADDRESS */
251 if (vma->vm_flags & VM_GROWSDOWN &&
252 addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr))
251 goto good_area; 253 goto good_area;
252out: 254out:
253 return fault; 255 return fault;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 2c7cf2f9c837..aa78de8bfdd3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -489,7 +489,8 @@ static void __init build_mem_type_table(void)
489 */ 489 */
490 for (i = 0; i < ARRAY_SIZE(mem_types); i++) { 490 for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
491 mem_types[i].prot_pte |= PTE_EXT_AF; 491 mem_types[i].prot_pte |= PTE_EXT_AF;
492 mem_types[i].prot_sect |= PMD_SECT_AF; 492 if (mem_types[i].prot_sect)
493 mem_types[i].prot_sect |= PMD_SECT_AF;
493 } 494 }
494 kern_pgprot |= PTE_EXT_AF; 495 kern_pgprot |= PTE_EXT_AF;
495 vecs_pgprot |= PTE_EXT_AF; 496 vecs_pgprot |= PTE_EXT_AF;
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index bc683b8219b5..b0197b2c857d 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -11,6 +11,7 @@
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/cpu.h> 12#include <linux/cpu.h>
13#include <linux/cpu_pm.h> 13#include <linux/cpu_pm.h>
14#include <linux/hardirq.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/notifier.h> 16#include <linux/notifier.h>
16#include <linux/signal.h> 17#include <linux/signal.h>
@@ -432,7 +433,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
432 433
433static void vfp_enable(void *unused) 434static void vfp_enable(void *unused)
434{ 435{
435 u32 access = get_copro_access(); 436 u32 access;
437
438 BUG_ON(preemptible());
439 access = get_copro_access();
436 440
437 /* 441 /*
438 * Enable full access to VFP (cp10 and cp11) 442 * Enable full access to VFP (cp10 and cp11)
@@ -573,12 +577,6 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
573 * entry. 577 * entry.
574 */ 578 */
575 hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); 579 hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK);
576
577 /*
578 * Disable VFP in the hwstate so that we can detect if it gets
579 * used.
580 */
581 hwstate->fpexc &= ~FPEXC_EN;
582 return 0; 580 return 0;
583} 581}
584 582
@@ -591,12 +589,8 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
591 unsigned long fpexc; 589 unsigned long fpexc;
592 int err = 0; 590 int err = 0;
593 591
594 /* 592 /* Disable VFP to avoid corrupting the new thread state. */
595 * If VFP has been used, then disable it to avoid corrupting 593 vfp_flush_hwstate(thread);
596 * the new thread state.
597 */
598 if (hwstate->fpexc & FPEXC_EN)
599 vfp_flush_hwstate(thread);
600 594
601 /* 595 /*
602 * Copy the floating point registers. There can be unused 596 * Copy the floating point registers. There can be unused
@@ -657,7 +651,7 @@ static int __init vfp_init(void)
657 unsigned int cpu_arch = cpu_architecture(); 651 unsigned int cpu_arch = cpu_architecture();
658 652
659 if (cpu_arch >= CPU_ARCH_ARMv6) 653 if (cpu_arch >= CPU_ARCH_ARMv6)
660 vfp_enable(NULL); 654 on_each_cpu(vfp_enable, NULL, 1);
661 655
662 /* 656 /*
663 * First check that there is a VFP that we can use. 657 * First check that there is a VFP that we can use.
@@ -678,8 +672,6 @@ static int __init vfp_init(void)
678 } else { 672 } else {
679 hotcpu_notifier(vfp_hotplug, 0); 673 hotcpu_notifier(vfp_hotplug, 0);
680 674
681 smp_call_function(vfp_enable, NULL, 1);
682
683 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ 675 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
684 printk("implementor %02x architecture %d part %02x variant %x rev %x\n", 676 printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
685 (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, 677 (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h
index 81c2e271d620..9b1a92b73f60 100644
--- a/arch/frv/include/asm/processor.h
+++ b/arch/frv/include/asm/processor.h
@@ -135,10 +135,6 @@ unsigned long get_wchan(struct task_struct *p);
135#define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) 135#define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc)
136#define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp) 136#define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp)
137 137
138/* Allocation and freeing of basic task resources. */
139extern struct task_struct *alloc_task_struct_node(int node);
140extern void free_task_struct(struct task_struct *p);
141
142#define cpu_relax() barrier() 138#define cpu_relax() barrier()
143 139
144/* data cache prefetch */ 140/* data cache prefetch */
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
index 910dddf65e44..9cd69ad6aa02 100644
--- a/arch/mn10300/kernel/smp.c
+++ b/arch/mn10300/kernel/smp.c
@@ -24,6 +24,7 @@
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/profile.h> 25#include <linux/profile.h>
26#include <linux/smp.h> 26#include <linux/smp.h>
27#include <linux/cpu.h>
27#include <asm/tlbflush.h> 28#include <asm/tlbflush.h>
28#include <asm/bitops.h> 29#include <asm/bitops.h>
29#include <asm/processor.h> 30#include <asm/processor.h>
@@ -38,7 +39,6 @@
38#include "internal.h" 39#include "internal.h"
39 40
40#ifdef CONFIG_HOTPLUG_CPU 41#ifdef CONFIG_HOTPLUG_CPU
41#include <linux/cpu.h>
42#include <asm/cacheflush.h> 42#include <asm/cacheflush.h>
43 43
44static unsigned long sleep_mode[NR_CPUS]; 44static unsigned long sleep_mode[NR_CPUS];
@@ -874,10 +874,13 @@ static void __init smp_online(void)
874 874
875 cpu = smp_processor_id(); 875 cpu = smp_processor_id();
876 876
877 local_irq_enable(); 877 notify_cpu_starting(cpu);
878 878
879 ipi_call_lock();
879 set_cpu_online(cpu, true); 880 set_cpu_online(cpu, true);
880 smp_wmb(); 881 ipi_call_unlock();
882
883 local_irq_enable();
881} 884}
882 885
883/** 886/**
diff --git a/arch/parisc/include/asm/prefetch.h b/arch/parisc/include/asm/prefetch.h
index c5edc60c059f..1ee7c82672c1 100644
--- a/arch/parisc/include/asm/prefetch.h
+++ b/arch/parisc/include/asm/prefetch.h
@@ -21,7 +21,12 @@
21#define ARCH_HAS_PREFETCH 21#define ARCH_HAS_PREFETCH
22static inline void prefetch(const void *addr) 22static inline void prefetch(const void *addr)
23{ 23{
24 __asm__("ldw 0(%0), %%r0" : : "r" (addr)); 24 __asm__(
25#ifndef CONFIG_PA20
26 /* Need to avoid prefetch of NULL on PA7300LC */
27 " extrw,u,= %0,31,32,%%r0\n"
28#endif
29 " ldw 0(%0), %%r0" : : "r" (addr));
25} 30}
26 31
27/* LDD is a PA2.0 addition. */ 32/* LDD is a PA2.0 addition. */
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 6f0594439143..535034217021 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -581,7 +581,11 @@
581 */ 581 */
582 cmpiclr,= 0x01,\tmp,%r0 582 cmpiclr,= 0x01,\tmp,%r0
583 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot 583 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
584#ifdef CONFIG_64BIT
584 depd,z \prot,8,7,\prot 585 depd,z \prot,8,7,\prot
586#else
587 depw,z \prot,8,7,\prot
588#endif
585 /* 589 /*
586 * OK, it is in the temp alias region, check whether "from" or "to". 590 * OK, it is in the temp alias region, check whether "from" or "to".
587 * Check "subtle" note in pacache.S re: r23/r26. 591 * Check "subtle" note in pacache.S re: r23/r26.
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 93ff3d90edd1..5d7218ad885c 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -692,7 +692,7 @@ ENTRY(flush_icache_page_asm)
692 692
693 /* Purge any old translation */ 693 /* Purge any old translation */
694 694
695 pitlb (%sr0,%r28) 695 pitlb (%sr4,%r28)
696 696
697 ldil L%icache_stride, %r1 697 ldil L%icache_stride, %r1
698 ldw R%icache_stride(%r1), %r1 698 ldw R%icache_stride(%r1), %r1
@@ -706,27 +706,29 @@ ENTRY(flush_icache_page_asm)
706 sub %r25, %r1, %r25 706 sub %r25, %r1, %r25
707 707
708 708
7091: fic,m %r1(%r28) 709 /* fic only has the type 26 form on PA1.1, requiring an
710 fic,m %r1(%r28) 710 * explicit space specification, so use %sr4 */
711 fic,m %r1(%r28) 7111: fic,m %r1(%sr4,%r28)
712 fic,m %r1(%r28) 712 fic,m %r1(%sr4,%r28)
713 fic,m %r1(%r28) 713 fic,m %r1(%sr4,%r28)
714 fic,m %r1(%r28) 714 fic,m %r1(%sr4,%r28)
715 fic,m %r1(%r28) 715 fic,m %r1(%sr4,%r28)
716 fic,m %r1(%r28) 716 fic,m %r1(%sr4,%r28)
717 fic,m %r1(%r28) 717 fic,m %r1(%sr4,%r28)
718 fic,m %r1(%r28) 718 fic,m %r1(%sr4,%r28)
719 fic,m %r1(%r28) 719 fic,m %r1(%sr4,%r28)
720 fic,m %r1(%r28) 720 fic,m %r1(%sr4,%r28)
721 fic,m %r1(%r28) 721 fic,m %r1(%sr4,%r28)
722 fic,m %r1(%r28) 722 fic,m %r1(%sr4,%r28)
723 fic,m %r1(%r28) 723 fic,m %r1(%sr4,%r28)
724 fic,m %r1(%sr4,%r28)
725 fic,m %r1(%sr4,%r28)
724 cmpb,COND(<<) %r28, %r25,1b 726 cmpb,COND(<<) %r28, %r25,1b
725 fic,m %r1(%r28) 727 fic,m %r1(%sr4,%r28)
726 728
727 sync 729 sync
728 bv %r0(%r2) 730 bv %r0(%r2)
729 pitlb (%sr0,%r25) 731 pitlb (%sr4,%r25)
730 .exit 732 .exit
731 733
732 .procend 734 .procend
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 0bb1d63907f8..4dc7b7942b4c 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -31,6 +31,7 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/bitops.h> 32#include <linux/bitops.h>
33#include <linux/ftrace.h> 33#include <linux/ftrace.h>
34#include <linux/cpu.h>
34 35
35#include <linux/atomic.h> 36#include <linux/atomic.h>
36#include <asm/current.h> 37#include <asm/current.h>
@@ -295,8 +296,13 @@ smp_cpu_init(int cpunum)
295 296
296 printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); 297 printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
297 machine_halt(); 298 machine_halt();
298 } 299 }
300
301 notify_cpu_starting(cpunum);
302
303 ipi_call_lock();
299 set_cpu_online(cpunum, true); 304 set_cpu_online(cpunum, true);
305 ipi_call_unlock();
300 306
301 /* Initialise the idle task for this CPU */ 307 /* Initialise the idle task for this CPU */
302 atomic_inc(&init_mm.mm_count); 308 atomic_inc(&init_mm.mm_count);
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index aa795ccef294..fd07f43d6622 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -81,12 +81,13 @@ struct kvmppc_vcpu_book3s {
81 u64 sdr1; 81 u64 sdr1;
82 u64 hior; 82 u64 hior;
83 u64 msr_mask; 83 u64 msr_mask;
84 u64 vsid_next;
85#ifdef CONFIG_PPC_BOOK3S_32 84#ifdef CONFIG_PPC_BOOK3S_32
86 u32 vsid_pool[VSID_POOL_SIZE]; 85 u32 vsid_pool[VSID_POOL_SIZE];
86 u32 vsid_next;
87#else 87#else
88 u64 vsid_first; 88 u64 proto_vsid_first;
89 u64 vsid_max; 89 u64 proto_vsid_max;
90 u64 proto_vsid_next;
90#endif 91#endif
91 int context_id[SID_CONTEXTS]; 92 int context_id[SID_CONTEXTS];
92 93
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
index 6f87f39a1ac2..10fc8ec9d2a8 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -194,14 +194,14 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
194 backwards_map = !backwards_map; 194 backwards_map = !backwards_map;
195 195
196 /* Uh-oh ... out of mappings. Let's flush! */ 196 /* Uh-oh ... out of mappings. Let's flush! */
197 if (vcpu_book3s->vsid_next == vcpu_book3s->vsid_max) { 197 if (vcpu_book3s->proto_vsid_next == vcpu_book3s->proto_vsid_max) {
198 vcpu_book3s->vsid_next = vcpu_book3s->vsid_first; 198 vcpu_book3s->proto_vsid_next = vcpu_book3s->proto_vsid_first;
199 memset(vcpu_book3s->sid_map, 0, 199 memset(vcpu_book3s->sid_map, 0,
200 sizeof(struct kvmppc_sid_map) * SID_MAP_NUM); 200 sizeof(struct kvmppc_sid_map) * SID_MAP_NUM);
201 kvmppc_mmu_pte_flush(vcpu, 0, 0); 201 kvmppc_mmu_pte_flush(vcpu, 0, 0);
202 kvmppc_mmu_flush_segments(vcpu); 202 kvmppc_mmu_flush_segments(vcpu);
203 } 203 }
204 map->host_vsid = vcpu_book3s->vsid_next++; 204 map->host_vsid = vsid_scramble(vcpu_book3s->proto_vsid_next++, 256M);
205 205
206 map->guest_vsid = gvsid; 206 map->guest_vsid = gvsid;
207 map->valid = true; 207 map->valid = true;
@@ -319,9 +319,10 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
319 return -1; 319 return -1;
320 vcpu3s->context_id[0] = err; 320 vcpu3s->context_id[0] = err;
321 321
322 vcpu3s->vsid_max = ((vcpu3s->context_id[0] + 1) << USER_ESID_BITS) - 1; 322 vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1)
323 vcpu3s->vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS; 323 << USER_ESID_BITS) - 1;
324 vcpu3s->vsid_next = vcpu3s->vsid_first; 324 vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS;
325 vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first;
325 326
326 kvmppc_mmu_hpte_init(vcpu); 327 kvmppc_mmu_hpte_init(vcpu);
327 328
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index def880aea63a..cec4daddbf31 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -463,6 +463,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
463 /* insert R and C bits from PTE */ 463 /* insert R and C bits from PTE */
464 rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); 464 rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C);
465 args[j] |= rcbits << (56 - 5); 465 args[j] |= rcbits << (56 - 5);
466 hp[0] = 0;
466 continue; 467 continue;
467 } 468 }
468 469
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S
index 0676ae249b9f..6e6e9cef34a8 100644
--- a/arch/powerpc/kvm/book3s_segment.S
+++ b/arch/powerpc/kvm/book3s_segment.S
@@ -197,7 +197,8 @@ kvmppc_interrupt:
197 /* Save guest PC and MSR */ 197 /* Save guest PC and MSR */
198#ifdef CONFIG_PPC64 198#ifdef CONFIG_PPC64
199BEGIN_FTR_SECTION 199BEGIN_FTR_SECTION
200 andi. r0,r12,0x2 200 andi. r0, r12, 0x2
201 cmpwi cr1, r0, 0
201 beq 1f 202 beq 1f
202 mfspr r3,SPRN_HSRR0 203 mfspr r3,SPRN_HSRR0
203 mfspr r4,SPRN_HSRR1 204 mfspr r4,SPRN_HSRR1
@@ -250,6 +251,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
250 beq ld_last_prev_inst 251 beq ld_last_prev_inst
251 cmpwi r12, BOOK3S_INTERRUPT_ALIGNMENT 252 cmpwi r12, BOOK3S_INTERRUPT_ALIGNMENT
252 beq- ld_last_inst 253 beq- ld_last_inst
254#ifdef CONFIG_PPC64
255BEGIN_FTR_SECTION
256 cmpwi r12, BOOK3S_INTERRUPT_H_EMUL_ASSIST
257 beq- ld_last_inst
258END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
259#endif
253 260
254 b no_ld_last_inst 261 b no_ld_last_inst
255 262
@@ -316,23 +323,17 @@ no_dcbz32_off:
316 * Having set up SRR0/1 with the address where we want 323 * Having set up SRR0/1 with the address where we want
317 * to continue with relocation on (potentially in module 324 * to continue with relocation on (potentially in module
318 * space), we either just go straight there with rfi[d], 325 * space), we either just go straight there with rfi[d],
319 * or we jump to an interrupt handler with bctr if there 326 * or we jump to an interrupt handler if there is an
320 * is an interrupt to be handled first. In the latter 327 * interrupt to be handled first. In the latter case,
321 * case, the rfi[d] at the end of the interrupt handler 328 * the rfi[d] at the end of the interrupt handler will
322 * will get us back to where we want to continue. 329 * get us back to where we want to continue.
323 */ 330 */
324 331
325 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
326 beq 1f
327 cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
328 beq 1f
329 cmpwi r12, BOOK3S_INTERRUPT_PERFMON
3301: mtctr r12
331
332 /* Register usage at this point: 332 /* Register usage at this point:
333 * 333 *
334 * R1 = host R1 334 * R1 = host R1
335 * R2 = host R2 335 * R2 = host R2
336 * R10 = raw exit handler id
336 * R12 = exit handler id 337 * R12 = exit handler id
337 * R13 = shadow vcpu (32-bit) or PACA (64-bit) 338 * R13 = shadow vcpu (32-bit) or PACA (64-bit)
338 * SVCPU.* = guest * 339 * SVCPU.* = guest *
@@ -342,12 +343,25 @@ no_dcbz32_off:
342 PPC_LL r6, HSTATE_HOST_MSR(r13) 343 PPC_LL r6, HSTATE_HOST_MSR(r13)
343 PPC_LL r8, HSTATE_VMHANDLER(r13) 344 PPC_LL r8, HSTATE_VMHANDLER(r13)
344 345
345 /* Restore host msr -> SRR1 */ 346#ifdef CONFIG_PPC64
347BEGIN_FTR_SECTION
348 beq cr1, 1f
349 mtspr SPRN_HSRR1, r6
350 mtspr SPRN_HSRR0, r8
351END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
352#endif
3531: /* Restore host msr -> SRR1 */
346 mtsrr1 r6 354 mtsrr1 r6
347 /* Load highmem handler address */ 355 /* Load highmem handler address */
348 mtsrr0 r8 356 mtsrr0 r8
349 357
350 /* RFI into the highmem handler, or jump to interrupt handler */ 358 /* RFI into the highmem handler, or jump to interrupt handler */
351 beqctr 359 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
360 beqa BOOK3S_INTERRUPT_EXTERNAL
361 cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
362 beqa BOOK3S_INTERRUPT_DECREMENTER
363 cmpwi r12, BOOK3S_INTERRUPT_PERFMON
364 beqa BOOK3S_INTERRUPT_PERFMON
365
352 RFI 366 RFI
353kvmppc_handler_trampoline_exit_end: 367kvmppc_handler_trampoline_exit_end:
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 96033e2d6845..74239dd77e06 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -11,6 +11,7 @@ config TILE
11 select GENERIC_IRQ_PROBE 11 select GENERIC_IRQ_PROBE
12 select GENERIC_PENDING_IRQ if SMP 12 select GENERIC_PENDING_IRQ if SMP
13 select GENERIC_IRQ_SHOW 13 select GENERIC_IRQ_SHOW
14 select HAVE_SYSCALL_WRAPPERS if TILEGX
14 select SYS_HYPERVISOR 15 select SYS_HYPERVISOR
15 select ARCH_HAVE_NMI_SAFE_CMPXCHG 16 select ARCH_HAVE_NMI_SAFE_CMPXCHG
16 17
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h
index bc4f562bd459..7594764d8a69 100644
--- a/arch/tile/include/asm/thread_info.h
+++ b/arch/tile/include/asm/thread_info.h
@@ -100,9 +100,14 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
100 100
101#else /* __ASSEMBLY__ */ 101#else /* __ASSEMBLY__ */
102 102
103/* how to get the thread information struct from ASM */ 103/*
104 * How to get the thread information struct from assembly.
105 * Note that we use different macros since different architectures
106 * have different semantics in their "mm" instruction and we would
107 * like to guarantee that the macro expands to exactly one instruction.
108 */
104#ifdef __tilegx__ 109#ifdef __tilegx__
105#define GET_THREAD_INFO(reg) move reg, sp; mm reg, zero, LOG2_THREAD_SIZE, 63 110#define EXTRACT_THREAD_INFO(reg) mm reg, zero, LOG2_THREAD_SIZE, 63
106#else 111#else
107#define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31 112#define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31
108#endif 113#endif
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 77763ccd5a7d..cdef6e5ec022 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -403,19 +403,17 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
403 * Set up registers for signal handler. 403 * Set up registers for signal handler.
404 * Registers that we don't modify keep the value they had from 404 * Registers that we don't modify keep the value they had from
405 * user-space at the time we took the signal. 405 * user-space at the time we took the signal.
406 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
407 * since some things rely on this (e.g. glibc's debug/segfault.c).
406 */ 408 */
407 regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); 409 regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
408 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ 410 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
409 regs->sp = ptr_to_compat_reg(frame); 411 regs->sp = ptr_to_compat_reg(frame);
410 regs->lr = restorer; 412 regs->lr = restorer;
411 regs->regs[0] = (unsigned long) usig; 413 regs->regs[0] = (unsigned long) usig;
412 414 regs->regs[1] = ptr_to_compat_reg(&frame->info);
413 if (ka->sa.sa_flags & SA_SIGINFO) { 415 regs->regs[2] = ptr_to_compat_reg(&frame->uc);
414 /* Need extra arguments, so mark to restore caller-saves. */ 416 regs->flags |= PT_FLAGS_CALLER_SAVES;
415 regs->regs[1] = ptr_to_compat_reg(&frame->info);
416 regs->regs[2] = ptr_to_compat_reg(&frame->uc);
417 regs->flags |= PT_FLAGS_CALLER_SAVES;
418 }
419 417
420 /* 418 /*
421 * Notify any tracer that was single-stepping it. 419 * Notify any tracer that was single-stepping it.
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index 5d56a1ef5ba5..6943515100f8 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -839,6 +839,18 @@ STD_ENTRY(interrupt_return)
839 FEEDBACK_REENTER(interrupt_return) 839 FEEDBACK_REENTER(interrupt_return)
840 840
841 /* 841 /*
842 * Use r33 to hold whether we have already loaded the callee-saves
843 * into ptregs. We don't want to do it twice in this loop, since
844 * then we'd clobber whatever changes are made by ptrace, etc.
845 * Get base of stack in r32.
846 */
847 {
848 GET_THREAD_INFO(r32)
849 movei r33, 0
850 }
851
852.Lretry_work_pending:
853 /*
842 * Disable interrupts so as to make sure we don't 854 * Disable interrupts so as to make sure we don't
843 * miss an interrupt that sets any of the thread flags (like 855 * miss an interrupt that sets any of the thread flags (like
844 * need_resched or sigpending) between sampling and the iret. 856 * need_resched or sigpending) between sampling and the iret.
@@ -848,9 +860,6 @@ STD_ENTRY(interrupt_return)
848 IRQ_DISABLE(r20, r21) 860 IRQ_DISABLE(r20, r21)
849 TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ 861 TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */
850 862
851 /* Get base of stack in r32; note r30/31 are used as arguments here. */
852 GET_THREAD_INFO(r32)
853
854 863
855 /* Check to see if there is any work to do before returning to user. */ 864 /* Check to see if there is any work to do before returning to user. */
856 { 865 {
@@ -866,16 +875,18 @@ STD_ENTRY(interrupt_return)
866 875
867 /* 876 /*
868 * Make sure we have all the registers saved for signal 877 * Make sure we have all the registers saved for signal
869 * handling or single-step. Call out to C code to figure out 878 * handling, notify-resume, or single-step. Call out to C
870 * exactly what we need to do for each flag bit, then if 879 * code to figure out exactly what we need to do for each flag bit,
871 * necessary, reload the flags and recheck. 880 * then if necessary, reload the flags and recheck.
872 */ 881 */
873 push_extra_callee_saves r0
874 { 882 {
875 PTREGS_PTR(r0, PTREGS_OFFSET_BASE) 883 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
876 jal do_work_pending 884 bnz r33, 1f
877 } 885 }
878 bnz r0, .Lresume_userspace 886 push_extra_callee_saves r0
887 movei r33, 1
8881: jal do_work_pending
889 bnz r0, .Lretry_work_pending
879 890
880 /* 891 /*
881 * In the NMI case we 892 * In the NMI case we
@@ -1180,10 +1191,12 @@ handle_syscall:
1180 add r20, r20, tp 1191 add r20, r20, tp
1181 lw r21, r20 1192 lw r21, r20
1182 addi r21, r21, 1 1193 addi r21, r21, 1
1183 sw r20, r21 1194 {
1195 sw r20, r21
1196 GET_THREAD_INFO(r31)
1197 }
1184 1198
1185 /* Trace syscalls, if requested. */ 1199 /* Trace syscalls, if requested. */
1186 GET_THREAD_INFO(r31)
1187 addi r31, r31, THREAD_INFO_FLAGS_OFFSET 1200 addi r31, r31, THREAD_INFO_FLAGS_OFFSET
1188 lw r30, r31 1201 lw r30, r31
1189 andi r30, r30, _TIF_SYSCALL_TRACE 1202 andi r30, r30, _TIF_SYSCALL_TRACE
@@ -1362,7 +1375,10 @@ handle_ill:
13623: 13753:
1363 /* set PC and continue */ 1376 /* set PC and continue */
1364 lw r26, r24 1377 lw r26, r24
1365 sw r28, r26 1378 {
1379 sw r28, r26
1380 GET_THREAD_INFO(r0)
1381 }
1366 1382
1367 /* 1383 /*
1368 * Clear TIF_SINGLESTEP to prevent recursion if we execute an ill. 1384 * Clear TIF_SINGLESTEP to prevent recursion if we execute an ill.
@@ -1370,7 +1386,6 @@ handle_ill:
1370 * need to clear it here and can't really impose on all other arches. 1386 * need to clear it here and can't really impose on all other arches.
1371 * So what's another write between friends? 1387 * So what's another write between friends?
1372 */ 1388 */
1373 GET_THREAD_INFO(r0)
1374 1389
1375 addi r1, r0, THREAD_INFO_FLAGS_OFFSET 1390 addi r1, r0, THREAD_INFO_FLAGS_OFFSET
1376 { 1391 {
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 49d9d6621682..30ae76e50c44 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -647,6 +647,20 @@ STD_ENTRY(interrupt_return)
647 FEEDBACK_REENTER(interrupt_return) 647 FEEDBACK_REENTER(interrupt_return)
648 648
649 /* 649 /*
650 * Use r33 to hold whether we have already loaded the callee-saves
651 * into ptregs. We don't want to do it twice in this loop, since
652 * then we'd clobber whatever changes are made by ptrace, etc.
653 */
654 {
655 movei r33, 0
656 move r32, sp
657 }
658
659 /* Get base of stack in r32. */
660 EXTRACT_THREAD_INFO(r32)
661
662.Lretry_work_pending:
663 /*
650 * Disable interrupts so as to make sure we don't 664 * Disable interrupts so as to make sure we don't
651 * miss an interrupt that sets any of the thread flags (like 665 * miss an interrupt that sets any of the thread flags (like
652 * need_resched or sigpending) between sampling and the iret. 666 * need_resched or sigpending) between sampling and the iret.
@@ -656,9 +670,6 @@ STD_ENTRY(interrupt_return)
656 IRQ_DISABLE(r20, r21) 670 IRQ_DISABLE(r20, r21)
657 TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ 671 TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */
658 672
659 /* Get base of stack in r32; note r30/31 are used as arguments here. */
660 GET_THREAD_INFO(r32)
661
662 673
663 /* Check to see if there is any work to do before returning to user. */ 674 /* Check to see if there is any work to do before returning to user. */
664 { 675 {
@@ -674,16 +685,18 @@ STD_ENTRY(interrupt_return)
674 685
675 /* 686 /*
676 * Make sure we have all the registers saved for signal 687 * Make sure we have all the registers saved for signal
677 * handling or single-step. Call out to C code to figure out 688 * handling or notify-resume. Call out to C code to figure out
678 * exactly what we need to do for each flag bit, then if 689 * exactly what we need to do for each flag bit, then if
679 * necessary, reload the flags and recheck. 690 * necessary, reload the flags and recheck.
680 */ 691 */
681 push_extra_callee_saves r0
682 { 692 {
683 PTREGS_PTR(r0, PTREGS_OFFSET_BASE) 693 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
684 jal do_work_pending 694 bnez r33, 1f
685 } 695 }
686 bnez r0, .Lresume_userspace 696 push_extra_callee_saves r0
697 movei r33, 1
6981: jal do_work_pending
699 bnez r0, .Lretry_work_pending
687 700
688 /* 701 /*
689 * In the NMI case we 702 * In the NMI case we
@@ -968,11 +981,16 @@ handle_syscall:
968 shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET) 981 shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
969 add r20, r20, tp 982 add r20, r20, tp
970 ld4s r21, r20 983 ld4s r21, r20
971 addi r21, r21, 1 984 {
972 st4 r20, r21 985 addi r21, r21, 1
986 move r31, sp
987 }
988 {
989 st4 r20, r21
990 EXTRACT_THREAD_INFO(r31)
991 }
973 992
974 /* Trace syscalls, if requested. */ 993 /* Trace syscalls, if requested. */
975 GET_THREAD_INFO(r31)
976 addi r31, r31, THREAD_INFO_FLAGS_OFFSET 994 addi r31, r31, THREAD_INFO_FLAGS_OFFSET
977 ld r30, r31 995 ld r30, r31
978 andi r30, r30, _TIF_SYSCALL_TRACE 996 andi r30, r30, _TIF_SYSCALL_TRACE
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 2d5ef617bb39..54e6c64b85cc 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -567,6 +567,10 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
567 */ 567 */
568int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) 568int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
569{ 569{
570 /* If we enter in kernel mode, do nothing and exit the caller loop. */
571 if (!user_mode(regs))
572 return 0;
573
570 if (thread_info_flags & _TIF_NEED_RESCHED) { 574 if (thread_info_flags & _TIF_NEED_RESCHED) {
571 schedule(); 575 schedule();
572 return 1; 576 return 1;
@@ -589,8 +593,7 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
589 return 1; 593 return 1;
590 } 594 }
591 if (thread_info_flags & _TIF_SINGLESTEP) { 595 if (thread_info_flags & _TIF_SINGLESTEP) {
592 if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0) 596 single_step_once(regs);
593 single_step_once(regs);
594 return 0; 597 return 0;
595 } 598 }
596 panic("work_pending: bad flags %#x\n", thread_info_flags); 599 panic("work_pending: bad flags %#x\n", thread_info_flags);
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 41a7237606a3..94e91e401da9 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -134,6 +134,9 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
134KBUILD_CFLAGS += $(mflags-y) 134KBUILD_CFLAGS += $(mflags-y)
135KBUILD_AFLAGS += $(mflags-y) 135KBUILD_AFLAGS += $(mflags-y)
136 136
137archscripts:
138 $(Q)$(MAKE) $(build)=arch/x86/tools relocs
139
137### 140###
138# Syscall table generation 141# Syscall table generation
139 142
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index fd55a2ff3ad8..e398bb5d63bb 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -40,13 +40,12 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
40$(obj)/vmlinux.bin: vmlinux FORCE 40$(obj)/vmlinux.bin: vmlinux FORCE
41 $(call if_changed,objcopy) 41 $(call if_changed,objcopy)
42 42
43targets += vmlinux.bin.all vmlinux.relocs
43 44
44targets += vmlinux.bin.all vmlinux.relocs relocs 45CMD_RELOCS = arch/x86/tools/relocs
45hostprogs-$(CONFIG_X86_NEED_RELOCS) += relocs
46
47quiet_cmd_relocs = RELOCS $@ 46quiet_cmd_relocs = RELOCS $@
48 cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $< 47 cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $<
49$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE 48$(obj)/vmlinux.relocs: vmlinux FORCE
50 $(call if_changed,relocs) 49 $(call if_changed,relocs)
51 50
52vmlinux.bin.all-y := $(obj)/vmlinux.bin 51vmlinux.bin.all-y := $(obj)/vmlinux.bin
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index 734c3767cfac..183922e13de1 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -170,6 +170,9 @@ static inline int kvm_para_available(void)
170 unsigned int eax, ebx, ecx, edx; 170 unsigned int eax, ebx, ecx, edx;
171 char signature[13]; 171 char signature[13];
172 172
173 if (boot_cpu_data.cpuid_level < 0)
174 return 0; /* So we don't blow up on old processors */
175
173 cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); 176 cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
174 memcpy(signature + 0, &ebx, 4); 177 memcpy(signature + 0, &ebx, 4);
175 memcpy(signature + 4, &ecx, 4); 178 memcpy(signature + 4, &ecx, 4);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index a415b1f44365..7c439fe4941b 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -593,7 +593,7 @@ void __init acpi_set_irq_model_ioapic(void)
593#ifdef CONFIG_ACPI_HOTPLUG_CPU 593#ifdef CONFIG_ACPI_HOTPLUG_CPU
594#include <acpi/processor.h> 594#include <acpi/processor.h>
595 595
596static void __cpuinitdata acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) 596static void __cpuinit acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
597{ 597{
598#ifdef CONFIG_ACPI_NUMA 598#ifdef CONFIG_ACPI_NUMA
599 int nid; 599 int nid;
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index d086a09c087d..11c9166c3337 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -945,9 +945,10 @@ struct mce_info {
945 atomic_t inuse; 945 atomic_t inuse;
946 struct task_struct *t; 946 struct task_struct *t;
947 __u64 paddr; 947 __u64 paddr;
948 int restartable;
948} mce_info[MCE_INFO_MAX]; 949} mce_info[MCE_INFO_MAX];
949 950
950static void mce_save_info(__u64 addr) 951static void mce_save_info(__u64 addr, int c)
951{ 952{
952 struct mce_info *mi; 953 struct mce_info *mi;
953 954
@@ -955,6 +956,7 @@ static void mce_save_info(__u64 addr)
955 if (atomic_cmpxchg(&mi->inuse, 0, 1) == 0) { 956 if (atomic_cmpxchg(&mi->inuse, 0, 1) == 0) {
956 mi->t = current; 957 mi->t = current;
957 mi->paddr = addr; 958 mi->paddr = addr;
959 mi->restartable = c;
958 return; 960 return;
959 } 961 }
960 } 962 }
@@ -1130,7 +1132,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1130 mce_panic("Fatal machine check on current CPU", &m, msg); 1132 mce_panic("Fatal machine check on current CPU", &m, msg);
1131 if (worst == MCE_AR_SEVERITY) { 1133 if (worst == MCE_AR_SEVERITY) {
1132 /* schedule action before return to userland */ 1134 /* schedule action before return to userland */
1133 mce_save_info(m.addr); 1135 mce_save_info(m.addr, m.mcgstatus & MCG_STATUS_RIPV);
1134 set_thread_flag(TIF_MCE_NOTIFY); 1136 set_thread_flag(TIF_MCE_NOTIFY);
1135 } else if (kill_it) { 1137 } else if (kill_it) {
1136 force_sig(SIGBUS, current); 1138 force_sig(SIGBUS, current);
@@ -1179,7 +1181,13 @@ void mce_notify_process(void)
1179 1181
1180 pr_err("Uncorrected hardware memory error in user-access at %llx", 1182 pr_err("Uncorrected hardware memory error in user-access at %llx",
1181 mi->paddr); 1183 mi->paddr);
1182 if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0) { 1184 /*
1185 * We must call memory_failure() here even if the current process is
1186 * doomed. We still need to mark the page as poisoned and alert any
1187 * other users of the page.
1188 */
1189 if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0 ||
1190 mi->restartable == 0) {
1183 pr_err("Memory error not recovered"); 1191 pr_err("Memory error not recovered");
1184 force_sig(SIGBUS, current); 1192 force_sig(SIGBUS, current);
1185 } 1193 }
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 3ca42d0e43a2..0327e2b3c408 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -147,12 +147,6 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
147 147
148 memset(csig, 0, sizeof(*csig)); 148 memset(csig, 0, sizeof(*csig));
149 149
150 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
151 cpu_has(c, X86_FEATURE_IA64)) {
152 pr_err("CPU%d not a capable Intel processor\n", cpu_num);
153 return -1;
154 }
155
156 csig->sig = cpuid_eax(0x00000001); 150 csig->sig = cpuid_eax(0x00000001);
157 151
158 if ((c->x86_model >= 5) || (c->x86 > 6)) { 152 if ((c->x86_model >= 5) || (c->x86 > 6)) {
@@ -463,6 +457,14 @@ static struct microcode_ops microcode_intel_ops = {
463 457
464struct microcode_ops * __init init_intel_microcode(void) 458struct microcode_ops * __init init_intel_microcode(void)
465{ 459{
460 struct cpuinfo_x86 *c = &cpu_data(0);
461
462 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
463 cpu_has(c, X86_FEATURE_IA64)) {
464 pr_err("Intel CPU family 0x%x not supported\n", c->x86);
465 return NULL;
466 }
467
466 return &microcode_intel_ops; 468 return &microcode_intel_ops;
467} 469}
468 470
diff --git a/arch/x86/tools/.gitignore b/arch/x86/tools/.gitignore
new file mode 100644
index 000000000000..be0ed065249b
--- /dev/null
+++ b/arch/x86/tools/.gitignore
@@ -0,0 +1 @@
relocs
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile
index d511aa97533a..733057b435b0 100644
--- a/arch/x86/tools/Makefile
+++ b/arch/x86/tools/Makefile
@@ -36,3 +36,7 @@ HOSTCFLAGS_insn_sanity.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x
36$(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c 36$(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c
37 37
38$(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c 38$(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c
39
40HOST_EXTRACFLAGS += -I$(srctree)/tools/include
41hostprogs-y += relocs
42relocs: $(obj)/relocs
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/tools/relocs.c
index fb7117a4ade1..b43cfcd9bf40 100644
--- a/arch/x86/boot/compressed/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -18,6 +18,8 @@ static void die(char *fmt, ...);
18static Elf32_Ehdr ehdr; 18static Elf32_Ehdr ehdr;
19static unsigned long reloc_count, reloc_idx; 19static unsigned long reloc_count, reloc_idx;
20static unsigned long *relocs; 20static unsigned long *relocs;
21static unsigned long reloc16_count, reloc16_idx;
22static unsigned long *relocs16;
21 23
22struct section { 24struct section {
23 Elf32_Shdr shdr; 25 Elf32_Shdr shdr;
@@ -28,52 +30,86 @@ struct section {
28}; 30};
29static struct section *secs; 31static struct section *secs;
30 32
33enum symtype {
34 S_ABS,
35 S_REL,
36 S_SEG,
37 S_LIN,
38 S_NSYMTYPES
39};
40
41static const char * const sym_regex_kernel[S_NSYMTYPES] = {
31/* 42/*
32 * Following symbols have been audited. There values are constant and do 43 * Following symbols have been audited. There values are constant and do
33 * not change if bzImage is loaded at a different physical address than 44 * not change if bzImage is loaded at a different physical address than
34 * the address for which it has been compiled. Don't warn user about 45 * the address for which it has been compiled. Don't warn user about
35 * absolute relocations present w.r.t these symbols. 46 * absolute relocations present w.r.t these symbols.
36 */ 47 */
37static const char abs_sym_regex[] = 48 [S_ABS] =
38 "^(xen_irq_disable_direct_reloc$|" 49 "^(xen_irq_disable_direct_reloc$|"
39 "xen_save_fl_direct_reloc$|" 50 "xen_save_fl_direct_reloc$|"
40 "VDSO|" 51 "VDSO|"
41 "__crc_)"; 52 "__crc_)",
42static regex_t abs_sym_regex_c;
43static int is_abs_reloc(const char *sym_name)
44{
45 return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0);
46}
47 53
48/* 54/*
49 * These symbols are known to be relative, even if the linker marks them 55 * These symbols are known to be relative, even if the linker marks them
50 * as absolute (typically defined outside any section in the linker script.) 56 * as absolute (typically defined outside any section in the linker script.)
51 */ 57 */
52static const char rel_sym_regex[] = 58 [S_REL] =
53 "^_end$"; 59 "^(__init_(begin|end)|"
54static regex_t rel_sym_regex_c; 60 "__x86_cpu_dev_(start|end)|"
55static int is_rel_reloc(const char *sym_name) 61 "(__parainstructions|__alt_instructions)(|_end)|"
62 "(__iommu_table|__apicdrivers|__smp_locks)(|_end)|"
63 "_end)$"
64};
65
66
67static const char * const sym_regex_realmode[S_NSYMTYPES] = {
68/*
69 * These are 16-bit segment symbols when compiling 16-bit code.
70 */
71 [S_SEG] =
72 "^real_mode_seg$",
73
74/*
75 * These are offsets belonging to segments, as opposed to linear addresses,
76 * when compiling 16-bit code.
77 */
78 [S_LIN] =
79 "^pa_",
80};
81
82static const char * const *sym_regex;
83
84static regex_t sym_regex_c[S_NSYMTYPES];
85static int is_reloc(enum symtype type, const char *sym_name)
56{ 86{
57 return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); 87 return sym_regex[type] &&
88 !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
58} 89}
59 90
60static void regex_init(void) 91static void regex_init(int use_real_mode)
61{ 92{
62 char errbuf[128]; 93 char errbuf[128];
63 int err; 94 int err;
64 95 int i;
65 err = regcomp(&abs_sym_regex_c, abs_sym_regex, 96
66 REG_EXTENDED|REG_NOSUB); 97 if (use_real_mode)
67 if (err) { 98 sym_regex = sym_regex_realmode;
68 regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); 99 else
69 die("%s", errbuf); 100 sym_regex = sym_regex_kernel;
70 }
71 101
72 err = regcomp(&rel_sym_regex_c, rel_sym_regex, 102 for (i = 0; i < S_NSYMTYPES; i++) {
73 REG_EXTENDED|REG_NOSUB); 103 if (!sym_regex[i])
74 if (err) { 104 continue;
75 regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); 105
76 die("%s", errbuf); 106 err = regcomp(&sym_regex_c[i], sym_regex[i],
107 REG_EXTENDED|REG_NOSUB);
108
109 if (err) {
110 regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf);
111 die("%s", errbuf);
112 }
77 } 113 }
78} 114}
79 115
@@ -154,6 +190,10 @@ static const char *rel_type(unsigned type)
154 REL_TYPE(R_386_RELATIVE), 190 REL_TYPE(R_386_RELATIVE),
155 REL_TYPE(R_386_GOTOFF), 191 REL_TYPE(R_386_GOTOFF),
156 REL_TYPE(R_386_GOTPC), 192 REL_TYPE(R_386_GOTPC),
193 REL_TYPE(R_386_8),
194 REL_TYPE(R_386_PC8),
195 REL_TYPE(R_386_16),
196 REL_TYPE(R_386_PC16),
157#undef REL_TYPE 197#undef REL_TYPE
158 }; 198 };
159 const char *name = "unknown type rel type name"; 199 const char *name = "unknown type rel type name";
@@ -189,7 +229,7 @@ static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym)
189 name = sym_strtab + sym->st_name; 229 name = sym_strtab + sym->st_name;
190 } 230 }
191 else { 231 else {
192 name = sec_name(secs[sym->st_shndx].shdr.sh_name); 232 name = sec_name(sym->st_shndx);
193 } 233 }
194 return name; 234 return name;
195} 235}
@@ -472,7 +512,7 @@ static void print_absolute_relocs(void)
472 * Before warning check if this absolute symbol 512 * Before warning check if this absolute symbol
473 * relocation is harmless. 513 * relocation is harmless.
474 */ 514 */
475 if (is_abs_reloc(name) || is_rel_reloc(name)) 515 if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
476 continue; 516 continue;
477 517
478 if (!printed) { 518 if (!printed) {
@@ -496,7 +536,8 @@ static void print_absolute_relocs(void)
496 printf("\n"); 536 printf("\n");
497} 537}
498 538
499static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) 539static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym),
540 int use_real_mode)
500{ 541{
501 int i; 542 int i;
502 /* Walk through the relocations */ 543 /* Walk through the relocations */
@@ -521,30 +562,67 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
521 Elf32_Rel *rel; 562 Elf32_Rel *rel;
522 Elf32_Sym *sym; 563 Elf32_Sym *sym;
523 unsigned r_type; 564 unsigned r_type;
565 const char *symname;
566 int shn_abs;
567
524 rel = &sec->reltab[j]; 568 rel = &sec->reltab[j];
525 sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; 569 sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
526 r_type = ELF32_R_TYPE(rel->r_info); 570 r_type = ELF32_R_TYPE(rel->r_info);
527 /* Don't visit relocations to absolute symbols */ 571
528 if (sym->st_shndx == SHN_ABS && 572 shn_abs = sym->st_shndx == SHN_ABS;
529 !is_rel_reloc(sym_name(sym_strtab, sym))) { 573
530 continue;
531 }
532 switch (r_type) { 574 switch (r_type) {
533 case R_386_NONE: 575 case R_386_NONE:
534 case R_386_PC32: 576 case R_386_PC32:
577 case R_386_PC16:
578 case R_386_PC8:
535 /* 579 /*
536 * NONE can be ignored and and PC relative 580 * NONE can be ignored and and PC relative
537 * relocations don't need to be adjusted. 581 * relocations don't need to be adjusted.
538 */ 582 */
539 break; 583 break;
584
585 case R_386_16:
586 symname = sym_name(sym_strtab, sym);
587 if (!use_real_mode)
588 goto bad;
589 if (shn_abs) {
590 if (is_reloc(S_ABS, symname))
591 break;
592 else if (!is_reloc(S_SEG, symname))
593 goto bad;
594 } else {
595 if (is_reloc(S_LIN, symname))
596 goto bad;
597 else
598 break;
599 }
600 visit(rel, sym);
601 break;
602
540 case R_386_32: 603 case R_386_32:
541 /* Visit relocations that need to be adjusted */ 604 symname = sym_name(sym_strtab, sym);
605 if (shn_abs) {
606 if (is_reloc(S_ABS, symname))
607 break;
608 else if (!is_reloc(S_REL, symname))
609 goto bad;
610 } else {
611 if (use_real_mode &&
612 !is_reloc(S_LIN, symname))
613 break;
614 }
542 visit(rel, sym); 615 visit(rel, sym);
543 break; 616 break;
544 default: 617 default:
545 die("Unsupported relocation type: %s (%d)\n", 618 die("Unsupported relocation type: %s (%d)\n",
546 rel_type(r_type), r_type); 619 rel_type(r_type), r_type);
547 break; 620 break;
621 bad:
622 symname = sym_name(sym_strtab, sym);
623 die("Invalid %s %s relocation: %s\n",
624 shn_abs ? "absolute" : "relative",
625 rel_type(r_type), symname);
548 } 626 }
549 } 627 }
550 } 628 }
@@ -552,13 +630,19 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
552 630
553static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) 631static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
554{ 632{
555 reloc_count += 1; 633 if (ELF32_R_TYPE(rel->r_info) == R_386_16)
634 reloc16_count++;
635 else
636 reloc_count++;
556} 637}
557 638
558static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) 639static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
559{ 640{
560 /* Remember the address that needs to be adjusted. */ 641 /* Remember the address that needs to be adjusted. */
561 relocs[reloc_idx++] = rel->r_offset; 642 if (ELF32_R_TYPE(rel->r_info) == R_386_16)
643 relocs16[reloc16_idx++] = rel->r_offset;
644 else
645 relocs[reloc_idx++] = rel->r_offset;
562} 646}
563 647
564static int cmp_relocs(const void *va, const void *vb) 648static int cmp_relocs(const void *va, const void *vb)
@@ -568,23 +652,41 @@ static int cmp_relocs(const void *va, const void *vb)
568 return (*a == *b)? 0 : (*a > *b)? 1 : -1; 652 return (*a == *b)? 0 : (*a > *b)? 1 : -1;
569} 653}
570 654
571static void emit_relocs(int as_text) 655static int write32(unsigned int v, FILE *f)
656{
657 unsigned char buf[4];
658
659 put_unaligned_le32(v, buf);
660 return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
661}
662
663static void emit_relocs(int as_text, int use_real_mode)
572{ 664{
573 int i; 665 int i;
574 /* Count how many relocations I have and allocate space for them. */ 666 /* Count how many relocations I have and allocate space for them. */
575 reloc_count = 0; 667 reloc_count = 0;
576 walk_relocs(count_reloc); 668 walk_relocs(count_reloc, use_real_mode);
577 relocs = malloc(reloc_count * sizeof(relocs[0])); 669 relocs = malloc(reloc_count * sizeof(relocs[0]));
578 if (!relocs) { 670 if (!relocs) {
579 die("malloc of %d entries for relocs failed\n", 671 die("malloc of %d entries for relocs failed\n",
580 reloc_count); 672 reloc_count);
581 } 673 }
674
675 relocs16 = malloc(reloc16_count * sizeof(relocs[0]));
676 if (!relocs16) {
677 die("malloc of %d entries for relocs16 failed\n",
678 reloc16_count);
679 }
582 /* Collect up the relocations */ 680 /* Collect up the relocations */
583 reloc_idx = 0; 681 reloc_idx = 0;
584 walk_relocs(collect_reloc); 682 walk_relocs(collect_reloc, use_real_mode);
683
684 if (reloc16_count && !use_real_mode)
685 die("Segment relocations found but --realmode not specified\n");
585 686
586 /* Order the relocations for more efficient processing */ 687 /* Order the relocations for more efficient processing */
587 qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); 688 qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs);
689 qsort(relocs16, reloc16_count, sizeof(relocs16[0]), cmp_relocs);
588 690
589 /* Print the relocations */ 691 /* Print the relocations */
590 if (as_text) { 692 if (as_text) {
@@ -593,58 +695,83 @@ static void emit_relocs(int as_text)
593 */ 695 */
594 printf(".section \".data.reloc\",\"a\"\n"); 696 printf(".section \".data.reloc\",\"a\"\n");
595 printf(".balign 4\n"); 697 printf(".balign 4\n");
596 for (i = 0; i < reloc_count; i++) { 698 if (use_real_mode) {
597 printf("\t .long 0x%08lx\n", relocs[i]); 699 printf("\t.long %lu\n", reloc16_count);
700 for (i = 0; i < reloc16_count; i++)
701 printf("\t.long 0x%08lx\n", relocs16[i]);
702 printf("\t.long %lu\n", reloc_count);
703 for (i = 0; i < reloc_count; i++) {
704 printf("\t.long 0x%08lx\n", relocs[i]);
705 }
706 } else {
707 /* Print a stop */
708 printf("\t.long 0x%08lx\n", (unsigned long)0);
709 for (i = 0; i < reloc_count; i++) {
710 printf("\t.long 0x%08lx\n", relocs[i]);
711 }
598 } 712 }
713
599 printf("\n"); 714 printf("\n");
600 } 715 }
601 else { 716 else {
602 unsigned char buf[4]; 717 if (use_real_mode) {
603 /* Print a stop */ 718 write32(reloc16_count, stdout);
604 fwrite("\0\0\0\0", 4, 1, stdout); 719 for (i = 0; i < reloc16_count; i++)
605 /* Now print each relocation */ 720 write32(relocs16[i], stdout);
606 for (i = 0; i < reloc_count; i++) { 721 write32(reloc_count, stdout);
607 put_unaligned_le32(relocs[i], buf); 722
608 fwrite(buf, 4, 1, stdout); 723 /* Now print each relocation */
724 for (i = 0; i < reloc_count; i++)
725 write32(relocs[i], stdout);
726 } else {
727 /* Print a stop */
728 write32(0, stdout);
729
730 /* Now print each relocation */
731 for (i = 0; i < reloc_count; i++) {
732 write32(relocs[i], stdout);
733 }
609 } 734 }
610 } 735 }
611} 736}
612 737
613static void usage(void) 738static void usage(void)
614{ 739{
615 die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); 740 die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n");
616} 741}
617 742
618int main(int argc, char **argv) 743int main(int argc, char **argv)
619{ 744{
620 int show_absolute_syms, show_absolute_relocs; 745 int show_absolute_syms, show_absolute_relocs;
621 int as_text; 746 int as_text, use_real_mode;
622 const char *fname; 747 const char *fname;
623 FILE *fp; 748 FILE *fp;
624 int i; 749 int i;
625 750
626 regex_init();
627
628 show_absolute_syms = 0; 751 show_absolute_syms = 0;
629 show_absolute_relocs = 0; 752 show_absolute_relocs = 0;
630 as_text = 0; 753 as_text = 0;
754 use_real_mode = 0;
631 fname = NULL; 755 fname = NULL;
632 for (i = 1; i < argc; i++) { 756 for (i = 1; i < argc; i++) {
633 char *arg = argv[i]; 757 char *arg = argv[i];
634 if (*arg == '-') { 758 if (*arg == '-') {
635 if (strcmp(argv[1], "--abs-syms") == 0) { 759 if (strcmp(arg, "--abs-syms") == 0) {
636 show_absolute_syms = 1; 760 show_absolute_syms = 1;
637 continue; 761 continue;
638 } 762 }
639 763 if (strcmp(arg, "--abs-relocs") == 0) {
640 if (strcmp(argv[1], "--abs-relocs") == 0) {
641 show_absolute_relocs = 1; 764 show_absolute_relocs = 1;
642 continue; 765 continue;
643 } 766 }
644 else if (strcmp(argv[1], "--text") == 0) { 767 if (strcmp(arg, "--text") == 0) {
645 as_text = 1; 768 as_text = 1;
646 continue; 769 continue;
647 } 770 }
771 if (strcmp(arg, "--realmode") == 0) {
772 use_real_mode = 1;
773 continue;
774 }
648 } 775 }
649 else if (!fname) { 776 else if (!fname) {
650 fname = arg; 777 fname = arg;
@@ -655,6 +782,7 @@ int main(int argc, char **argv)
655 if (!fname) { 782 if (!fname) {
656 usage(); 783 usage();
657 } 784 }
785 regex_init(use_real_mode);
658 fp = fopen(fname, "r"); 786 fp = fopen(fname, "r");
659 if (!fp) { 787 if (!fp) {
660 die("Cannot open %s: %s\n", 788 die("Cannot open %s: %s\n",
@@ -673,6 +801,6 @@ int main(int argc, char **argv)
673 print_absolute_relocs(); 801 print_absolute_relocs();
674 return 0; 802 return 0;
675 } 803 }
676 emit_relocs(as_text); 804 emit_relocs(as_text, use_real_mode);
677 return 0; 805 return 0;
678} 806}