aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/asm-offsets.c6
-rw-r--r--arch/arm/kernel/head-nommu.S4
-rw-r--r--arch/arm/kernel/head.S8
-rw-r--r--arch/arm/mach-aaec2000/aaed2000.c7
-rw-r--r--arch/arm/mach-aaec2000/core.c5
-rw-r--r--arch/arm/mach-aaec2000/core.h1
-rw-r--r--arch/arm/mach-imx/mx1ads.c2
-rw-r--r--arch/arm/mach-pxa/dma.c17
-rw-r--r--arch/arm/mach-sa1100/irq.c16
-rw-r--r--arch/arm/vfp/vfpmodule.c2
-rw-r--r--arch/i386/kernel/io_apic.c5
-rw-r--r--arch/i386/kernel/mpparse.c12
-rw-r--r--arch/ia64/lib/memcpy_mck.S9
-rw-r--r--arch/x86_64/kernel/e820.c6
-rw-r--r--arch/x86_64/kernel/io_apic.c5
-rw-r--r--arch/x86_64/kernel/mpparse.c12
-rw-r--r--arch/x86_64/kernel/pci-gart.c8
-rw-r--r--arch/x86_64/kernel/setup.c30
-rw-r--r--arch/x86_64/kernel/traps.c12
19 files changed, 124 insertions, 43 deletions
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index b324dcac1c56..45fdf4a51a2a 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -95,5 +95,11 @@ int main(void)
95 DEFINE(SYS_ERROR0, 0x9f0000); 95 DEFINE(SYS_ERROR0, 0x9f0000);
96 BLANK(); 96 BLANK();
97 DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); 97 DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc));
98 DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr));
99 DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name));
100 DEFINE(MACHINFO_PHYSIO, offsetof(struct machine_desc, phys_io));
101 DEFINE(MACHINFO_PGOFFIO, offsetof(struct machine_desc, io_pg_offst));
102 DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush));
103 DEFINE(PROCINFO_MMUFLAGS, offsetof(struct proc_info_list, __cpu_mmu_flags));
98 return 0; 104 return 0;
99} 105}
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 0bea65864051..adf62e5eaad7 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -20,12 +20,10 @@
20#include <asm/mach-types.h> 20#include <asm/mach-types.h>
21#include <asm/procinfo.h> 21#include <asm/procinfo.h>
22#include <asm/ptrace.h> 22#include <asm/ptrace.h>
23#include <asm/asm-offsets.h>
23#include <asm/thread_info.h> 24#include <asm/thread_info.h>
24#include <asm/system.h> 25#include <asm/system.h>
25 26
26#define PROCINFO_INITFUNC 12
27#define MACHINFO_TYPE 0
28
29/* 27/*
30 * Kernel startup entry point. 28 * Kernel startup entry point.
31 * --------------------------- 29 * ---------------------------
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 04b66a9328ef..04f7344e356a 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -24,14 +24,6 @@
24#include <asm/thread_info.h> 24#include <asm/thread_info.h>
25#include <asm/system.h> 25#include <asm/system.h>
26 26
27#define PROCINFO_MMUFLAGS 8
28#define PROCINFO_INITFUNC 12
29
30#define MACHINFO_TYPE 0
31#define MACHINFO_PHYSIO 4
32#define MACHINFO_PGOFFIO 8
33#define MACHINFO_NAME 12
34
35#define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET) 27#define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET)
36 28
37/* 29/*
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
index dc5fa8e5ebef..83f57da3184c 100644
--- a/arch/arm/mach-aaec2000/aaed2000.c
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -79,7 +79,12 @@ static void __init aaed2000_init(void)
79} 79}
80 80
81static struct map_desc aaed2000_io_desc[] __initdata = { 81static struct map_desc aaed2000_io_desc[] __initdata = {
82 { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */ 82 {
83 .virtual = EXT_GPIO_VBASE,
84 .pfn = __phys_to_pfn(EXT_GPIO_PBASE),
85 .length = EXT_GPIO_LENGTH,
86 .type = MT_DEVICE
87 },
83}; 88};
84 89
85static void __init aaed2000_map_io(void) 90static void __init aaed2000_map_io(void)
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index dce4815cf53c..65be5efd633c 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -20,7 +20,6 @@
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/timex.h> 21#include <linux/timex.h>
22#include <linux/signal.h> 22#include <linux/signal.h>
23#include <linux/amba/bus.h>
24 23
25#include <asm/hardware.h> 24#include <asm/hardware.h>
26#include <asm/irq.h> 25#include <asm/irq.h>
@@ -50,12 +49,12 @@
50static struct map_desc standard_io_desc[] __initdata = { 49static struct map_desc standard_io_desc[] __initdata = {
51 { 50 {
52 .virtual = VIO_APB_BASE, 51 .virtual = VIO_APB_BASE,
53 .physical = __phys_to_pfn(PIO_APB_BASE), 52 .pfn = __phys_to_pfn(PIO_APB_BASE),
54 .length = IO_APB_LENGTH, 53 .length = IO_APB_LENGTH,
55 .type = MT_DEVICE 54 .type = MT_DEVICE
56 }, { 55 }, {
57 .virtual = VIO_AHB_BASE, 56 .virtual = VIO_AHB_BASE,
58 .physical = __phys_to_pfn(PIO_AHB_BASE), 57 .pfn = __phys_to_pfn(PIO_AHB_BASE),
59 .length = IO_AHB_LENGTH, 58 .length = IO_AHB_LENGTH,
60 .type = MT_DEVICE 59 .type = MT_DEVICE
61 } 60 }
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
index b6029a95f19c..59501b573167 100644
--- a/arch/arm/mach-aaec2000/core.h
+++ b/arch/arm/mach-aaec2000/core.h
@@ -9,6 +9,7 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/amba/bus.h>
12#include <linux/amba/clcd.h> 13#include <linux/amba/clcd.h>
13 14
14struct sys_timer; 15struct sys_timer;
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index e1f6c0bbe1e7..da893c80d471 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -161,7 +161,7 @@ mx1ads_map_io(void)
161MACHINE_START(MX1ADS, "Motorola MX1ADS") 161MACHINE_START(MX1ADS, "Motorola MX1ADS")
162 /* Maintainer: Sascha Hauer, Pengutronix */ 162 /* Maintainer: Sascha Hauer, Pengutronix */
163 .phys_io = 0x00200000, 163 .phys_io = 0x00200000,
164 .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, 164 .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
165 .boot_params = 0x08000100, 165 .boot_params = 0x08000100,
166 .map_io = mx1ads_map_io, 166 .map_io = mx1ads_map_io,
167 .init_irq = imx_init_irq, 167 .init_irq = imx_init_irq,
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
index 458112b21e25..7d8c85486c66 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/mach-pxa/dma.c
@@ -45,23 +45,16 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
45 45
46 local_irq_save(flags); 46 local_irq_save(flags);
47 47
48 /* try grabbing a DMA channel with the requested priority */ 48 do {
49 for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) { 49 /* try grabbing a DMA channel with the requested priority */
50 if (!dma_channels[i].name) { 50 pxa_for_each_dma_prio (i, prio) {
51 found = 1;
52 break;
53 }
54 }
55
56 if (!found) {
57 /* requested prio group is full, try hier priorities */
58 for (i = prio-1; i >= 0; i--) {
59 if (!dma_channels[i].name) { 51 if (!dma_channels[i].name) {
60 found = 1; 52 found = 1;
61 break; 53 break;
62 } 54 }
63 } 55 }
64 } 56 /* if requested prio group is full, try a hier priority */
57 } while (!found && prio--);
65 58
66 if (found) { 59 if (found) {
67 DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; 60 DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index c131a5201b5b..b3a56024182e 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -199,10 +199,26 @@ static void sa1100_unmask_irq(unsigned int irq)
199 ICMR |= (1 << irq); 199 ICMR |= (1 << irq);
200} 200}
201 201
202/*
203 * Apart form GPIOs, only the RTC alarm can be a wakeup event.
204 */
205static int sa1100_set_wake(unsigned int irq, unsigned int on)
206{
207 if (irq == IRQ_RTCAlrm) {
208 if (on)
209 PWER |= PWER_RTC;
210 else
211 PWER &= ~PWER_RTC;
212 return 0;
213 }
214 return -EINVAL;
215}
216
202static struct irqchip sa1100_normal_chip = { 217static struct irqchip sa1100_normal_chip = {
203 .ack = sa1100_mask_irq, 218 .ack = sa1100_mask_irq,
204 .mask = sa1100_mask_irq, 219 .mask = sa1100_mask_irq,
205 .unmask = sa1100_unmask_irq, 220 .unmask = sa1100_unmask_irq,
221 .set_wake = sa1100_set_wake,
206}; 222};
207 223
208static struct resource irq_resource = { 224static struct resource irq_resource = {
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 37ff8145b5b5..03486be04193 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -245,7 +245,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
245 */ 245 */
246 barrier(); 246 barrier();
247 trigger = fmrx(FPINST2); 247 trigger = fmrx(FPINST2);
248 fpscr = fmrx(FPSCR); 248 orig_fpscr = fpscr = fmrx(FPSCR);
249 249
250 emulate: 250 emulate:
251 exceptions = vfp_emulate_instruction(trigger, fpscr, regs); 251 exceptions = vfp_emulate_instruction(trigger, fpscr, regs);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index f8f132aa5472..d70f2ade5cde 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -2238,6 +2238,8 @@ static inline void unlock_ExtINT_logic(void)
2238 spin_unlock_irqrestore(&ioapic_lock, flags); 2238 spin_unlock_irqrestore(&ioapic_lock, flags);
2239} 2239}
2240 2240
2241int timer_uses_ioapic_pin_0;
2242
2241/* 2243/*
2242 * This code may look a bit paranoid, but it's supposed to cooperate with 2244 * This code may look a bit paranoid, but it's supposed to cooperate with
2243 * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ 2245 * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ
@@ -2274,6 +2276,9 @@ static inline void check_timer(void)
2274 pin2 = ioapic_i8259.pin; 2276 pin2 = ioapic_i8259.pin;
2275 apic2 = ioapic_i8259.apic; 2277 apic2 = ioapic_i8259.apic;
2276 2278
2279 if (pin1 == 0)
2280 timer_uses_ioapic_pin_0 = 1;
2281
2277 printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", 2282 printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
2278 vector, apic1, pin1, apic2, pin2); 2283 vector, apic1, pin1, apic2, pin2);
2279 2284
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 34d21e21e012..6b1392d33ed5 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -1130,7 +1130,17 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity)
1130 */ 1130 */
1131 int irq = gsi; 1131 int irq = gsi;
1132 if (gsi < MAX_GSI_NUM) { 1132 if (gsi < MAX_GSI_NUM) {
1133 if (gsi > 15) 1133 /*
1134 * Retain the VIA chipset work-around (gsi > 15), but
1135 * avoid a problem where the 8254 timer (IRQ0) is setup
1136 * via an override (so it's not on pin 0 of the ioapic),
1137 * and at the same time, the pin 0 interrupt is a PCI
1138 * type. The gsi > 15 test could cause these two pins
1139 * to be shared as IRQ0, and they are not shareable.
1140 * So test for this condition, and if necessary, avoid
1141 * the pin collision.
1142 */
1143 if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
1134 gsi = pci_irq++; 1144 gsi = pci_irq++;
1135 /* 1145 /*
1136 * Don't assign IRQ used by ACPI SCI 1146 * Don't assign IRQ used by ACPI SCI
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
index 46c9331e7ab5..9e534d52b1d5 100644
--- a/arch/ia64/lib/memcpy_mck.S
+++ b/arch/ia64/lib/memcpy_mck.S
@@ -6,7 +6,9 @@
6 * in1: source address 6 * in1: source address
7 * in2: number of bytes to copy 7 * in2: number of bytes to copy
8 * Output: 8 * Output:
9 * 0 if success, or number of byte NOT copied if error occurred. 9 * for memcpy: return dest
10 * for copy_user: return 0 if success,
11 * or number of byte NOT copied if error occurred.
10 * 12 *
11 * Copyright (C) 2002 Intel Corp. 13 * Copyright (C) 2002 Intel Corp.
12 * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com> 14 * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
@@ -73,6 +75,7 @@ GLOBAL_ENTRY(memcpy)
73 and r28=0x7,in0 75 and r28=0x7,in0
74 and r29=0x7,in1 76 and r29=0x7,in1
75 mov f6=f0 77 mov f6=f0
78 mov retval=in0
76 br.cond.sptk .common_code 79 br.cond.sptk .common_code
77 ;; 80 ;;
78END(memcpy) 81END(memcpy)
@@ -84,7 +87,7 @@ GLOBAL_ENTRY(__copy_user)
84 mov f6=f1 87 mov f6=f1
85 mov saved_in0=in0 // save dest pointer 88 mov saved_in0=in0 // save dest pointer
86 mov saved_in1=in1 // save src pointer 89 mov saved_in1=in1 // save src pointer
87 mov saved_in2=in2 // save len 90 mov retval=r0 // initialize return value
88 ;; 91 ;;
89.common_code: 92.common_code:
90 cmp.gt p15,p0=8,in2 // check for small size 93 cmp.gt p15,p0=8,in2 // check for small size
@@ -92,7 +95,7 @@ GLOBAL_ENTRY(__copy_user)
92 cmp.ne p14,p0=0,r29 // check src alignment 95 cmp.ne p14,p0=0,r29 // check src alignment
93 add src0=0,in1 96 add src0=0,in1
94 sub r30=8,r28 // for .align_dest 97 sub r30=8,r28 // for .align_dest
95 mov retval=r0 // initialize return value 98 mov saved_in2=in2 // save len
96 ;; 99 ;;
97 add dst0=0,in0 100 add dst0=0,in0
98 add dst1=1,in0 // dest odd index 101 add dst1=1,in0 // dest odd index
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 62776c07cff1..222b5b46d2b2 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -76,6 +76,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
76 *addrp = __pa_symbol(&_end); 76 *addrp = __pa_symbol(&_end);
77 return 1; 77 return 1;
78 } 78 }
79
80 if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
81 *addrp = ebda_addr + ebda_size;
82 return 1;
83 }
84
79 /* XXX ramdisk image here? */ 85 /* XXX ramdisk image here? */
80 return 0; 86 return 0;
81} 87}
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 77b4c608cca0..0de3ea938830 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1777,6 +1777,8 @@ static inline void unlock_ExtINT_logic(void)
1777 spin_unlock_irqrestore(&ioapic_lock, flags); 1777 spin_unlock_irqrestore(&ioapic_lock, flags);
1778} 1778}
1779 1779
1780int timer_uses_ioapic_pin_0;
1781
1780/* 1782/*
1781 * This code may look a bit paranoid, but it's supposed to cooperate with 1783 * This code may look a bit paranoid, but it's supposed to cooperate with
1782 * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ 1784 * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ
@@ -1814,6 +1816,9 @@ static inline void check_timer(void)
1814 pin2 = ioapic_i8259.pin; 1816 pin2 = ioapic_i8259.pin;
1815 apic2 = ioapic_i8259.apic; 1817 apic2 = ioapic_i8259.apic;
1816 1818
1819 if (pin1 == 0)
1820 timer_uses_ioapic_pin_0 = 1;
1821
1817 apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", 1822 apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
1818 vector, apic1, pin1, apic2, pin2); 1823 vector, apic1, pin1, apic2, pin2);
1819 1824
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index b17cf3eba359..083da7e606b1 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -968,7 +968,17 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
968 */ 968 */
969 int irq = gsi; 969 int irq = gsi;
970 if (gsi < MAX_GSI_NUM) { 970 if (gsi < MAX_GSI_NUM) {
971 if (gsi > 15) 971 /*
972 * Retain the VIA chipset work-around (gsi > 15), but
973 * avoid a problem where the 8254 timer (IRQ0) is setup
974 * via an override (so it's not on pin 0 of the ioapic),
975 * and at the same time, the pin 0 interrupt is a PCI
976 * type. The gsi > 15 test could cause these two pins
977 * to be shared as IRQ0, and they are not shareable.
978 * So test for this condition, and if necessary, avoid
979 * the pin collision.
980 */
981 if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
972 gsi = pci_irq++; 982 gsi = pci_irq++;
973 /* 983 /*
974 * Don't assign IRQ used by ACPI SCI 984 * Don't assign IRQ used by ACPI SCI
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 9d3d76c85ae7..2480d3f08a47 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -639,6 +639,14 @@ static int __init pci_iommu_init(void)
639 return -1; 639 return -1;
640 } 640 }
641 641
642 i = 0;
643 for_all_nb(dev)
644 i++;
645 if (i > MAX_NB) {
646 printk(KERN_ERR "PCI-GART: Too many northbridges (%ld). Disabled\n", i);
647 return -1;
648 }
649
642 printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); 650 printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
643 aper_size = info.aper_size * 1024 * 1024; 651 aper_size = info.aper_size * 1024 * 1024;
644 iommu_size = check_iommu_size(info.aper_base, aper_size); 652 iommu_size = check_iommu_size(info.aper_base, aper_size);
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index ebc3c33b1c6c..f0870bef24d1 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -571,17 +571,28 @@ static inline void copy_edd(void)
571#endif 571#endif
572 572
573#define EBDA_ADDR_POINTER 0x40E 573#define EBDA_ADDR_POINTER 0x40E
574static void __init reserve_ebda_region(void) 574
575unsigned __initdata ebda_addr;
576unsigned __initdata ebda_size;
577
578static void discover_ebda(void)
575{ 579{
576 unsigned int addr; 580 /*
577 /**
578 * there is a real-mode segmented pointer pointing to the 581 * there is a real-mode segmented pointer pointing to the
579 * 4K EBDA area at 0x40E 582 * 4K EBDA area at 0x40E
580 */ 583 */
581 addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER); 584 ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER;
582 addr <<= 4; 585 ebda_addr <<= 4;
583 if (addr) 586
584 reserve_bootmem_generic(addr, PAGE_SIZE); 587 ebda_size = *(unsigned short *)(unsigned long)ebda_addr;
588
589 /* Round EBDA up to pages */
590 if (ebda_size == 0)
591 ebda_size = 1;
592 ebda_size <<= 10;
593 ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
594 if (ebda_size > 64*1024)
595 ebda_size = 64*1024;
585} 596}
586 597
587void __init setup_arch(char **cmdline_p) 598void __init setup_arch(char **cmdline_p)
@@ -627,6 +638,8 @@ void __init setup_arch(char **cmdline_p)
627 638
628 check_efer(); 639 check_efer();
629 640
641 discover_ebda();
642
630 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); 643 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
631 644
632 dmi_scan_machine(); 645 dmi_scan_machine();
@@ -669,7 +682,8 @@ void __init setup_arch(char **cmdline_p)
669 reserve_bootmem_generic(0, PAGE_SIZE); 682 reserve_bootmem_generic(0, PAGE_SIZE);
670 683
671 /* reserve ebda region */ 684 /* reserve ebda region */
672 reserve_ebda_region(); 685 if (ebda_addr)
686 reserve_bootmem_generic(ebda_addr, ebda_size);
673 687
674#ifdef CONFIG_SMP 688#ifdef CONFIG_SMP
675 /* 689 /*
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 2700b1375c1f..6b87268c5c2e 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -385,6 +385,7 @@ void out_of_line_bug(void)
385 385
386static DEFINE_SPINLOCK(die_lock); 386static DEFINE_SPINLOCK(die_lock);
387static int die_owner = -1; 387static int die_owner = -1;
388static unsigned int die_nest_count;
388 389
389unsigned __kprobes long oops_begin(void) 390unsigned __kprobes long oops_begin(void)
390{ 391{
@@ -399,6 +400,7 @@ unsigned __kprobes long oops_begin(void)
399 else 400 else
400 spin_lock(&die_lock); 401 spin_lock(&die_lock);
401 } 402 }
403 die_nest_count++;
402 die_owner = cpu; 404 die_owner = cpu;
403 console_verbose(); 405 console_verbose();
404 bust_spinlocks(1); 406 bust_spinlocks(1);
@@ -409,7 +411,13 @@ void __kprobes oops_end(unsigned long flags)
409{ 411{
410 die_owner = -1; 412 die_owner = -1;
411 bust_spinlocks(0); 413 bust_spinlocks(0);
412 spin_unlock_irqrestore(&die_lock, flags); 414 die_nest_count--;
415 if (die_nest_count)
416 /* We still own the lock */
417 local_irq_restore(flags);
418 else
419 /* Nest count reaches zero, release the lock. */
420 spin_unlock_irqrestore(&die_lock, flags);
413 if (panic_on_oops) 421 if (panic_on_oops)
414 panic("Oops"); 422 panic("Oops");
415} 423}
@@ -464,6 +472,8 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs)
464 panic("nmi watchdog"); 472 panic("nmi watchdog");
465 printk("console shuts up ...\n"); 473 printk("console shuts up ...\n");
466 oops_end(flags); 474 oops_end(flags);
475 nmi_exit();
476 local_irq_enable();
467 do_exit(SIGSEGV); 477 do_exit(SIGSEGV);
468} 478}
469 479