aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/asm-offsets.c1
-rw-r--r--arch/x86_64/kernel/setup64.c1
-rw-r--r--include/asm-x86_64/hardirq.h9
-rw-r--r--include/asm-x86_64/pda.h12
-rw-r--r--include/linux/interrupt.h7
-rw-r--r--kernel/softirq.c2
6 files changed, 18 insertions, 14 deletions
diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c
index 35b4c3fcbb37..aaa6d3833517 100644
--- a/arch/x86_64/kernel/asm-offsets.c
+++ b/arch/x86_64/kernel/asm-offsets.c
@@ -39,7 +39,6 @@ int main(void)
39 ENTRY(kernelstack); 39 ENTRY(kernelstack);
40 ENTRY(oldrsp); 40 ENTRY(oldrsp);
41 ENTRY(pcurrent); 41 ENTRY(pcurrent);
42 ENTRY(irqrsp);
43 ENTRY(irqcount); 42 ENTRY(irqcount);
44 ENTRY(cpunumber); 43 ENTRY(cpunumber);
45 ENTRY(irqstackptr); 44 ENTRY(irqstackptr);
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index e3ffcacc8c90..e8b54dccb3ee 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -119,7 +119,6 @@ void pda_init(int cpu)
119 asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); 119 asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
120 wrmsrl(MSR_GS_BASE, cpu_pda + cpu); 120 wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
121 121
122 pda->me = pda;
123 pda->cpunumber = cpu; 122 pda->cpunumber = cpu;
124 pda->irqcount = -1; 123 pda->irqcount = -1;
125 pda->kernelstack = 124 pda->kernelstack =
diff --git a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h
index 27c381fa1c9d..8661b476fb40 100644
--- a/include/asm-x86_64/hardirq.h
+++ b/include/asm-x86_64/hardirq.h
@@ -9,11 +9,12 @@
9 9
10#define __ARCH_IRQ_STAT 1 10#define __ARCH_IRQ_STAT 1
11 11
12/* Generate a lvalue for a pda member. Should fix softirq.c instead to use 12#define local_softirq_pending() read_pda(__softirq_pending)
13 special access macros. This would generate better code. */
14#define __IRQ_STAT(cpu,member) (read_pda(me)->member)
15 13
16#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 14#define __ARCH_SET_SOFTIRQ_PENDING 1
15
16#define set_softirq_pending(x) write_pda(__softirq_pending, (x))
17#define or_softirq_pending(x) or_pda(__softirq_pending, (x))
17 18
18/* 19/*
19 * 'what should we do if we get a hw irq event on an illegal vector'. 20 * 'what should we do if we get a hw irq event on an illegal vector'.
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
index e16d76c9deb0..bbf89aa8a1af 100644
--- a/include/asm-x86_64/pda.h
+++ b/include/asm-x86_64/pda.h
@@ -10,10 +10,8 @@
10struct x8664_pda { 10struct x8664_pda {
11 struct task_struct *pcurrent; /* Current process */ 11 struct task_struct *pcurrent; /* Current process */
12 unsigned long data_offset; /* Per cpu data offset from linker address */ 12 unsigned long data_offset; /* Per cpu data offset from linker address */
13 struct x8664_pda *me; /* Pointer to itself */
14 unsigned long kernelstack; /* top of kernel stack for current */ 13 unsigned long kernelstack; /* top of kernel stack for current */
15 unsigned long oldrsp; /* user rsp for system call */ 14 unsigned long oldrsp; /* user rsp for system call */
16 unsigned long irqrsp; /* Old rsp for interrupts. */
17 int irqcount; /* Irq nesting counter. Starts with -1 */ 15 int irqcount; /* Irq nesting counter. Starts with -1 */
18 int cpunumber; /* Logical CPU number */ 16 int cpunumber; /* Logical CPU number */
19 char *irqstackptr; /* top of irqstack */ 17 char *irqstackptr; /* top of irqstack */
@@ -42,13 +40,14 @@ extern void __bad_pda_field(void);
42#define pda_offset(field) offsetof(struct x8664_pda, field) 40#define pda_offset(field) offsetof(struct x8664_pda, field)
43 41
44#define pda_to_op(op,field,val) do { \ 42#define pda_to_op(op,field,val) do { \
43 typedef typeof_field(struct x8664_pda, field) T__; \
45 switch (sizeof_field(struct x8664_pda, field)) { \ 44 switch (sizeof_field(struct x8664_pda, field)) { \
46case 2: \ 45case 2: \
47asm volatile(op "w %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \ 46asm volatile(op "w %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
48case 4: \ 47case 4: \
49asm volatile(op "l %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \ 48asm volatile(op "l %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
50case 8: \ 49case 8: \
51asm volatile(op "q %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \ 50asm volatile(op "q %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
52 default: __bad_pda_field(); \ 51 default: __bad_pda_field(); \
53 } \ 52 } \
54 } while (0) 53 } while (0)
@@ -58,7 +57,7 @@ asm volatile(op "q %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); bre
58 * Unfortunately removing them causes all hell to break lose currently. 57 * Unfortunately removing them causes all hell to break lose currently.
59 */ 58 */
60#define pda_from_op(op,field) ({ \ 59#define pda_from_op(op,field) ({ \
61 typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \ 60 typeof_field(struct x8664_pda, field) ret__; \
62 switch (sizeof_field(struct x8664_pda, field)) { \ 61 switch (sizeof_field(struct x8664_pda, field)) { \
63case 2: \ 62case 2: \
64asm volatile(op "w %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\ 63asm volatile(op "w %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
@@ -75,6 +74,7 @@ asm volatile(op "q %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); b
75#define write_pda(field,val) pda_to_op("mov",field,val) 74#define write_pda(field,val) pda_to_op("mov",field,val)
76#define add_pda(field,val) pda_to_op("add",field,val) 75#define add_pda(field,val) pda_to_op("add",field,val)
77#define sub_pda(field,val) pda_to_op("sub",field,val) 76#define sub_pda(field,val) pda_to_op("sub",field,val)
77#define or_pda(field,val) pda_to_op("or",field,val)
78 78
79#endif 79#endif
80 80
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index d99e7aeb7d33..0a90205184b0 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -57,6 +57,11 @@ extern void disable_irq(unsigned int irq);
57extern void enable_irq(unsigned int irq); 57extern void enable_irq(unsigned int irq);
58#endif 58#endif
59 59
60#ifndef __ARCH_SET_SOFTIRQ_PENDING
61#define set_softirq_pending(x) (local_softirq_pending() = (x))
62#define or_softirq_pending(x) (local_softirq_pending() |= (x))
63#endif
64
60/* 65/*
61 * Temporary defines for UP kernels, until all code gets fixed. 66 * Temporary defines for UP kernels, until all code gets fixed.
62 */ 67 */
@@ -123,7 +128,7 @@ struct softirq_action
123asmlinkage void do_softirq(void); 128asmlinkage void do_softirq(void);
124extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data); 129extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data);
125extern void softirq_init(void); 130extern void softirq_init(void);
126#define __raise_softirq_irqoff(nr) do { local_softirq_pending() |= 1UL << (nr); } while (0) 131#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
127extern void FASTCALL(raise_softirq_irqoff(unsigned int nr)); 132extern void FASTCALL(raise_softirq_irqoff(unsigned int nr));
128extern void FASTCALL(raise_softirq(unsigned int nr)); 133extern void FASTCALL(raise_softirq(unsigned int nr));
129 134
diff --git a/kernel/softirq.c b/kernel/softirq.c
index b4ab6af1dea8..f766b2fc48be 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -84,7 +84,7 @@ asmlinkage void __do_softirq(void)
84 cpu = smp_processor_id(); 84 cpu = smp_processor_id();
85restart: 85restart:
86 /* Reset the pending bitmask before enabling irqs */ 86 /* Reset the pending bitmask before enabling irqs */
87 local_softirq_pending() = 0; 87 set_softirq_pending(0);
88 88
89 local_irq_enable(); 89 local_irq_enable();
90 90