aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig8
-rw-r--r--arch/x86/include/asm/entry_arch.h1
-rw-r--r--arch/x86/include/asm/feather_trace.h17
-rw-r--r--arch/x86/include/asm/feather_trace_32.h79
-rw-r--r--arch/x86/include/asm/feather_trace_64.h67
-rw-r--r--arch/x86/include/asm/hw_irq.h3
-rw-r--r--arch/x86/include/asm/irq_vectors.h5
-rw-r--r--arch/x86/include/asm/processor.h4
-rw-r--r--arch/x86/include/asm/unistd_32.h6
-rw-r--r--arch/x86/include/asm/unistd_64.h4
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c17
-rw-r--r--arch/x86/kernel/entry_64.S2
-rw-r--r--arch/x86/kernel/ft_event.c118
-rw-r--r--arch/x86/kernel/irqinit.c3
-rw-r--r--arch/x86/kernel/smp.c31
-rw-r--r--arch/x86/kernel/syscall_table_32.S12
17 files changed, 378 insertions, 1 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 37357a599dca..9f5e14388e17 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2166,3 +2166,11 @@ source "crypto/Kconfig"
2166source "arch/x86/kvm/Kconfig" 2166source "arch/x86/kvm/Kconfig"
2167 2167
2168source "lib/Kconfig" 2168source "lib/Kconfig"
2169
2170config ARCH_HAS_FEATHER_TRACE
2171 def_bool y
2172
2173config ARCH_HAS_SEND_PULL_TIMERS
2174 def_bool y
2175
2176source "litmus/Kconfig"
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index 1cd6d26a0a8d..3b0d7ef959b8 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -13,6 +13,7 @@
13BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) 13BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
14BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) 14BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
15BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) 15BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
16BUILD_INTERRUPT(pull_timers_interrupt,PULL_TIMERS_VECTOR)
16BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) 17BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
17BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) 18BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR)
18 19
diff --git a/arch/x86/include/asm/feather_trace.h b/arch/x86/include/asm/feather_trace.h
new file mode 100644
index 000000000000..4fd31633405d
--- /dev/null
+++ b/arch/x86/include/asm/feather_trace.h
@@ -0,0 +1,17 @@
1#ifndef _ARCH_FEATHER_TRACE_H
2#define _ARCH_FEATHER_TRACE_H
3
4#include <asm/msr.h>
5
6static inline unsigned long long ft_timestamp(void)
7{
8 return __native_read_tsc();
9}
10
11#ifdef CONFIG_X86_32
12#include "feather_trace_32.h"
13#else
14#include "feather_trace_64.h"
15#endif
16
17#endif
diff --git a/arch/x86/include/asm/feather_trace_32.h b/arch/x86/include/asm/feather_trace_32.h
new file mode 100644
index 000000000000..70202f90f169
--- /dev/null
+++ b/arch/x86/include/asm/feather_trace_32.h
@@ -0,0 +1,79 @@
1/* Do not directly include this file. Include feather_trace.h instead */
2
3#define feather_callback __attribute__((regparm(0)))
4
5/*
6 * make the compiler reload any register that is not saved in
7 * a cdecl function call
8 */
9#define CLOBBER_LIST "memory", "cc", "eax", "ecx", "edx"
10
11#define ft_event(id, callback) \
12 __asm__ __volatile__( \
13 "1: jmp 2f \n\t" \
14 " call " #callback " \n\t" \
15 ".section __event_table, \"aw\" \n\t" \
16 ".long " #id ", 0, 1b, 2f \n\t" \
17 ".previous \n\t" \
18 "2: \n\t" \
19 : : : CLOBBER_LIST)
20
21#define ft_event0(id, callback) \
22 __asm__ __volatile__( \
23 "1: jmp 2f \n\t" \
24 " subl $4, %%esp \n\t" \
25 " movl $" #id ", (%%esp) \n\t" \
26 " call " #callback " \n\t" \
27 " addl $4, %%esp \n\t" \
28 ".section __event_table, \"aw\" \n\t" \
29 ".long " #id ", 0, 1b, 2f \n\t" \
30 ".previous \n\t" \
31 "2: \n\t" \
32 : : : CLOBBER_LIST)
33
34#define ft_event1(id, callback, param) \
35 __asm__ __volatile__( \
36 "1: jmp 2f \n\t" \
37 " subl $8, %%esp \n\t" \
38 " movl %0, 4(%%esp) \n\t" \
39 " movl $" #id ", (%%esp) \n\t" \
40 " call " #callback " \n\t" \
41 " addl $8, %%esp \n\t" \
42 ".section __event_table, \"aw\" \n\t" \
43 ".long " #id ", 0, 1b, 2f \n\t" \
44 ".previous \n\t" \
45 "2: \n\t" \
46 : : "r" (param) : CLOBBER_LIST)
47
48#define ft_event2(id, callback, param, param2) \
49 __asm__ __volatile__( \
50 "1: jmp 2f \n\t" \
51 " subl $12, %%esp \n\t" \
52 " movl %1, 8(%%esp) \n\t" \
53 " movl %0, 4(%%esp) \n\t" \
54 " movl $" #id ", (%%esp) \n\t" \
55 " call " #callback " \n\t" \
56 " addl $12, %%esp \n\t" \
57 ".section __event_table, \"aw\" \n\t" \
58 ".long " #id ", 0, 1b, 2f \n\t" \
59 ".previous \n\t" \
60 "2: \n\t" \
61 : : "r" (param), "r" (param2) : CLOBBER_LIST)
62
63
64#define ft_event3(id, callback, p, p2, p3) \
65 __asm__ __volatile__( \
66 "1: jmp 2f \n\t" \
67 " subl $16, %%esp \n\t" \
68 " movl %2, 12(%%esp) \n\t" \
69 " movl %1, 8(%%esp) \n\t" \
70 " movl %0, 4(%%esp) \n\t" \
71 " movl $" #id ", (%%esp) \n\t" \
72 " call " #callback " \n\t" \
73 " addl $16, %%esp \n\t" \
74 ".section __event_table, \"aw\" \n\t" \
75 ".long " #id ", 0, 1b, 2f \n\t" \
76 ".previous \n\t" \
77 "2: \n\t" \
78 : : "r" (p), "r" (p2), "r" (p3) : CLOBBER_LIST)
79
diff --git a/arch/x86/include/asm/feather_trace_64.h b/arch/x86/include/asm/feather_trace_64.h
new file mode 100644
index 000000000000..54ac2aeb3a28
--- /dev/null
+++ b/arch/x86/include/asm/feather_trace_64.h
@@ -0,0 +1,67 @@
1/* Do not directly include this file. Include feather_trace.h instead */
2
3/* regparm is the default on x86_64 */
4#define feather_callback
5
6# define _EVENT_TABLE(id,from,to) \
7 ".section __event_table, \"aw\"\n\t" \
8 ".balign 8\n\t" \
9 ".quad " #id ", 0, " #from ", " #to " \n\t" \
10 ".previous \n\t"
11
12/*
13 * x86_64 callee only owns rbp, rbx, r12 -> r15
14 * the called can freely modify the others
15 */
16#define CLOBBER_LIST "memory", "cc", "rdi", "rsi", "rdx", "rcx", \
17 "r8", "r9", "r10", "r11", "rax"
18
19#define ft_event(id, callback) \
20 __asm__ __volatile__( \
21 "1: jmp 2f \n\t" \
22 " call " #callback " \n\t" \
23 _EVENT_TABLE(id,1b,2f) \
24 "2: \n\t" \
25 : : : CLOBBER_LIST)
26
27#define ft_event0(id, callback) \
28 __asm__ __volatile__( \
29 "1: jmp 2f \n\t" \
30 " movq $" #id ", %%rdi \n\t" \
31 " call " #callback " \n\t" \
32 _EVENT_TABLE(id,1b,2f) \
33 "2: \n\t" \
34 : : : CLOBBER_LIST)
35
36#define ft_event1(id, callback, param) \
37 __asm__ __volatile__( \
38 "1: jmp 2f \n\t" \
39 " movq %0, %%rsi \n\t" \
40 " movq $" #id ", %%rdi \n\t" \
41 " call " #callback " \n\t" \
42 _EVENT_TABLE(id,1b,2f) \
43 "2: \n\t" \
44 : : "r" (param) : CLOBBER_LIST)
45
46#define ft_event2(id, callback, param, param2) \
47 __asm__ __volatile__( \
48 "1: jmp 2f \n\t" \
49 " movq %1, %%rdx \n\t" \
50 " movq %0, %%rsi \n\t" \
51 " movq $" #id ", %%rdi \n\t" \
52 " call " #callback " \n\t" \
53 _EVENT_TABLE(id,1b,2f) \
54 "2: \n\t" \
55 : : "r" (param), "r" (param2) : CLOBBER_LIST)
56
57#define ft_event3(id, callback, p, p2, p3) \
58 __asm__ __volatile__( \
59 "1: jmp 2f \n\t" \
60 " movq %2, %%rcx \n\t" \
61 " movq %1, %%rdx \n\t" \
62 " movq %0, %%rsi \n\t" \
63 " movq $" #id ", %%rdi \n\t" \
64 " call " #callback " \n\t" \
65 _EVENT_TABLE(id,1b,2f) \
66 "2: \n\t" \
67 : : "r" (p), "r" (p2), "r" (p3) : CLOBBER_LIST)
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index bb9efe8706e2..c490d89a9b7b 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -77,6 +77,8 @@ extern void threshold_interrupt(void);
77extern void call_function_interrupt(void); 77extern void call_function_interrupt(void);
78extern void call_function_single_interrupt(void); 78extern void call_function_single_interrupt(void);
79 79
80extern void pull_timers_interrupt(void);
81
80/* IOAPIC */ 82/* IOAPIC */
81#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) 83#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
82extern unsigned long io_apic_irqs; 84extern unsigned long io_apic_irqs;
@@ -155,6 +157,7 @@ extern asmlinkage void smp_irq_move_cleanup_interrupt(void);
155extern void smp_reschedule_interrupt(struct pt_regs *); 157extern void smp_reschedule_interrupt(struct pt_regs *);
156extern void smp_call_function_interrupt(struct pt_regs *); 158extern void smp_call_function_interrupt(struct pt_regs *);
157extern void smp_call_function_single_interrupt(struct pt_regs *); 159extern void smp_call_function_single_interrupt(struct pt_regs *);
160extern void smp_pull_timers_interrupt(struct pt_regs *);
158#ifdef CONFIG_X86_32 161#ifdef CONFIG_X86_32
159extern void smp_invalidate_interrupt(struct pt_regs *); 162extern void smp_invalidate_interrupt(struct pt_regs *);
160#else 163#else
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 6e976ee3b3ef..cf72a7060bfd 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -98,6 +98,11 @@
98#define REBOOT_VECTOR 0xf8 98#define REBOOT_VECTOR 0xf8
99 99
100/* 100/*
101 * LITMUS^RT pull timers IRQ vector
102 */
103#define PULL_TIMERS_VECTOR 0xee
104
105/*
101 * Generic system vector for platform specific use 106 * Generic system vector for platform specific use
102 */ 107 */
103#define X86_PLATFORM_IPI_VECTOR 0xf7 108#define X86_PLATFORM_IPI_VECTOR 0xf7
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 219371546afd..b844edc69fe9 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -166,6 +166,10 @@ extern void print_cpu_info(struct cpuinfo_x86 *);
166extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); 166extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
167extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); 167extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
168extern unsigned short num_cache_leaves; 168extern unsigned short num_cache_leaves;
169#ifdef CONFIG_SYSFS
170extern int get_shared_cpu_map(cpumask_var_t mask,
171 unsigned int cpu, int index);
172#endif
169 173
170extern void detect_extended_topology(struct cpuinfo_x86 *c); 174extern void detect_extended_topology(struct cpuinfo_x86 *c);
171extern void detect_ht(struct cpuinfo_x86 *c); 175extern void detect_ht(struct cpuinfo_x86 *c);
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 593485b38ab3..2f6e127db30c 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -353,9 +353,13 @@
353#define __NR_sendmmsg 345 353#define __NR_sendmmsg 345
354#define __NR_setns 346 354#define __NR_setns 346
355 355
356#define __NR_LITMUS 347
357
358#include "litmus/unistd_32.h"
359
356#ifdef __KERNEL__ 360#ifdef __KERNEL__
357 361
358#define NR_syscalls 347 362#define NR_syscalls 347 + NR_litmus_syscalls
359 363
360#define __ARCH_WANT_IPC_PARSE_VERSION 364#define __ARCH_WANT_IPC_PARSE_VERSION
361#define __ARCH_WANT_OLD_READDIR 365#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index 705bf139288c..f24806cf3a01 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -682,6 +682,10 @@ __SYSCALL(__NR_sendmmsg, sys_sendmmsg)
682#define __NR_setns 308 682#define __NR_setns 308
683__SYSCALL(__NR_setns, sys_setns) 683__SYSCALL(__NR_setns, sys_setns)
684 684
685#define __NR_LITMUS 303
686
687#include "litmus/unistd_64.h"
688
685#ifndef __NO_STUBS 689#ifndef __NO_STUBS
686#define __ARCH_WANT_OLD_READDIR 690#define __ARCH_WANT_OLD_READDIR
687#define __ARCH_WANT_OLD_STAT 691#define __ARCH_WANT_OLD_STAT
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 90b06d4daee2..d727f8f94333 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -116,6 +116,8 @@ obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
116obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 116obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
117obj-$(CONFIG_OF) += devicetree.o 117obj-$(CONFIG_OF) += devicetree.o
118 118
119obj-$(CONFIG_FEATHER_TRACE) += ft_event.o
120
119### 121###
120# 64 bit specific files 122# 64 bit specific files
121ifeq ($(CONFIG_X86_64),y) 123ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index c105c533ed94..0bf12644aa73 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -747,6 +747,23 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
747static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); 747static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
748#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) 748#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
749 749
750/* returns CPUs that share the index cache with cpu */
751int get_shared_cpu_map(cpumask_var_t mask, unsigned int cpu, int index)
752{
753 int ret = 0;
754 struct _cpuid4_info *this_leaf;
755
756 if (index >= num_cache_leaves) {
757 index = num_cache_leaves - 1;
758 ret = index;
759 }
760
761 this_leaf = CPUID4_INFO_IDX(cpu,index);
762 cpumask_copy(mask, to_cpumask(this_leaf->shared_cpu_map));
763
764 return ret;
765}
766
750#ifdef CONFIG_SMP 767#ifdef CONFIG_SMP
751static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) 768static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
752{ 769{
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 8a445a0c989e..47a4bcd2e503 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1003,6 +1003,8 @@ apicinterrupt CALL_FUNCTION_VECTOR \
1003 call_function_interrupt smp_call_function_interrupt 1003 call_function_interrupt smp_call_function_interrupt
1004apicinterrupt RESCHEDULE_VECTOR \ 1004apicinterrupt RESCHEDULE_VECTOR \
1005 reschedule_interrupt smp_reschedule_interrupt 1005 reschedule_interrupt smp_reschedule_interrupt
1006apicinterrupt PULL_TIMERS_VECTOR \
1007 pull_timers_interrupt smp_pull_timers_interrupt
1006#endif 1008#endif
1007 1009
1008apicinterrupt ERROR_APIC_VECTOR \ 1010apicinterrupt ERROR_APIC_VECTOR \
diff --git a/arch/x86/kernel/ft_event.c b/arch/x86/kernel/ft_event.c
new file mode 100644
index 000000000000..37cc33252713
--- /dev/null
+++ b/arch/x86/kernel/ft_event.c
@@ -0,0 +1,118 @@
1#include <linux/types.h>
2
3#include <litmus/feather_trace.h>
4
5/* the feather trace management functions assume
6 * exclusive access to the event table
7 */
8
9#ifndef CONFIG_DEBUG_RODATA
10
11#define BYTE_JUMP 0xeb
12#define BYTE_JUMP_LEN 0x02
13
14/* for each event, there is an entry in the event table */
15struct trace_event {
16 long id;
17 long count;
18 long start_addr;
19 long end_addr;
20};
21
22extern struct trace_event __start___event_table[];
23extern struct trace_event __stop___event_table[];
24
25/* Workaround: if no events are defined, then the event_table section does not
26 * exist and the above references cause linker errors. This could probably be
27 * fixed by adjusting the linker script, but it is easier to maintain for us if
28 * we simply create a dummy symbol in the event table section.
29 */
30int __event_table_dummy[0] __attribute__ ((section("__event_table")));
31
32int ft_enable_event(unsigned long id)
33{
34 struct trace_event* te = __start___event_table;
35 int count = 0;
36 char* delta;
37 unsigned char* instr;
38
39 while (te < __stop___event_table) {
40 if (te->id == id && ++te->count == 1) {
41 instr = (unsigned char*) te->start_addr;
42 /* make sure we don't clobber something wrong */
43 if (*instr == BYTE_JUMP) {
44 delta = (((unsigned char*) te->start_addr) + 1);
45 *delta = 0;
46 }
47 }
48 if (te->id == id)
49 count++;
50 te++;
51 }
52
53 printk(KERN_DEBUG "ft_enable_event: enabled %d events\n", count);
54 return count;
55}
56
57int ft_disable_event(unsigned long id)
58{
59 struct trace_event* te = __start___event_table;
60 int count = 0;
61 char* delta;
62 unsigned char* instr;
63
64 while (te < __stop___event_table) {
65 if (te->id == id && --te->count == 0) {
66 instr = (unsigned char*) te->start_addr;
67 if (*instr == BYTE_JUMP) {
68 delta = (((unsigned char*) te->start_addr) + 1);
69 *delta = te->end_addr - te->start_addr -
70 BYTE_JUMP_LEN;
71 }
72 }
73 if (te->id == id)
74 count++;
75 te++;
76 }
77
78 printk(KERN_DEBUG "ft_disable_event: disabled %d events\n", count);
79 return count;
80}
81
82int ft_disable_all_events(void)
83{
84 struct trace_event* te = __start___event_table;
85 int count = 0;
86 char* delta;
87 unsigned char* instr;
88
89 while (te < __stop___event_table) {
90 if (te->count) {
91 instr = (unsigned char*) te->start_addr;
92 if (*instr == BYTE_JUMP) {
93 delta = (((unsigned char*) te->start_addr)
94 + 1);
95 *delta = te->end_addr - te->start_addr -
96 BYTE_JUMP_LEN;
97 te->count = 0;
98 count++;
99 }
100 }
101 te++;
102 }
103 return count;
104}
105
106int ft_is_event_enabled(unsigned long id)
107{
108 struct trace_event* te = __start___event_table;
109
110 while (te < __stop___event_table) {
111 if (te->id == id)
112 return te->count;
113 te++;
114 }
115 return 0;
116}
117
118#endif
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index f470e4ef993e..48acf71c6534 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -252,6 +252,9 @@ static void __init smp_intr_init(void)
252 alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, 252 alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
253 call_function_single_interrupt); 253 call_function_single_interrupt);
254 254
255 /* IPI for hrtimer pulling on remote cpus */
256 alloc_intr_gate(PULL_TIMERS_VECTOR, pull_timers_interrupt);
257
255 /* Low priority IPI to cleanup after moving an irq */ 258 /* Low priority IPI to cleanup after moving an irq */
256 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); 259 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
257 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); 260 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 013e7eba83bb..ed4c4f54e2ae 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -23,6 +23,10 @@
23#include <linux/cpu.h> 23#include <linux/cpu.h>
24#include <linux/gfp.h> 24#include <linux/gfp.h>
25 25
26#include <litmus/preempt.h>
27#include <litmus/debug_trace.h>
28#include <litmus/trace.h>
29
26#include <asm/mtrr.h> 30#include <asm/mtrr.h>
27#include <asm/tlbflush.h> 31#include <asm/tlbflush.h>
28#include <asm/mmu_context.h> 32#include <asm/mmu_context.h>
@@ -118,6 +122,7 @@ static void native_smp_send_reschedule(int cpu)
118 WARN_ON(1); 122 WARN_ON(1);
119 return; 123 return;
120 } 124 }
125 TS_SEND_RESCHED_START(cpu);
121 apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR); 126 apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
122} 127}
123 128
@@ -147,6 +152,16 @@ void native_send_call_func_ipi(const struct cpumask *mask)
147 free_cpumask_var(allbutself); 152 free_cpumask_var(allbutself);
148} 153}
149 154
155/* trigger timers on remote cpu */
156void smp_send_pull_timers(int cpu)
157{
158 if (unlikely(cpu_is_offline(cpu))) {
159 WARN_ON(1);
160 return;
161 }
162 apic->send_IPI_mask(cpumask_of(cpu), PULL_TIMERS_VECTOR);
163}
164
150/* 165/*
151 * this function calls the 'stop' function on all other CPUs in the system. 166 * this function calls the 'stop' function on all other CPUs in the system.
152 */ 167 */
@@ -199,8 +214,15 @@ static void native_stop_other_cpus(int wait)
199void smp_reschedule_interrupt(struct pt_regs *regs) 214void smp_reschedule_interrupt(struct pt_regs *regs)
200{ 215{
201 ack_APIC_irq(); 216 ack_APIC_irq();
217 /* LITMUS^RT: this IPI might need to trigger the sched state machine. */
218 sched_state_ipi();
202 inc_irq_stat(irq_resched_count); 219 inc_irq_stat(irq_resched_count);
220 /*
221 * LITMUS^RT: starting from 3.0 schedule_ipi() actually does something.
222 * This may increase IPI latencies compared with previous versions.
223 */
203 scheduler_ipi(); 224 scheduler_ipi();
225 TS_SEND_RESCHED_END;
204 /* 226 /*
205 * KVM uses this interrupt to force a cpu out of guest mode 227 * KVM uses this interrupt to force a cpu out of guest mode
206 */ 228 */
@@ -224,6 +246,15 @@ void smp_call_function_single_interrupt(struct pt_regs *regs)
224 irq_exit(); 246 irq_exit();
225} 247}
226 248
249extern void hrtimer_pull(void);
250
251void smp_pull_timers_interrupt(struct pt_regs *regs)
252{
253 ack_APIC_irq();
254 TRACE("pull timer interrupt\n");
255 hrtimer_pull();
256}
257
227struct smp_ops smp_ops = { 258struct smp_ops smp_ops = {
228 .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu, 259 .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu,
229 .smp_prepare_cpus = native_smp_prepare_cpus, 260 .smp_prepare_cpus = native_smp_prepare_cpus,
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index fbb0a045a1a2..d0126222b394 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -346,3 +346,15 @@ ENTRY(sys_call_table)
346 .long sys_syncfs 346 .long sys_syncfs
347 .long sys_sendmmsg /* 345 */ 347 .long sys_sendmmsg /* 345 */
348 .long sys_setns 348 .long sys_setns
349 .long sys_set_rt_task_param /* LITMUS^RT 347 */
350 .long sys_get_rt_task_param
351 .long sys_complete_job
352 .long sys_od_open
353 .long sys_od_close
354 .long sys_litmus_lock /* +5 */
355 .long sys_litmus_unlock
356 .long sys_query_job_no
357 .long sys_wait_for_job_release
358 .long sys_wait_for_ts_release
359 .long sys_release_ts /* +10 */
360 .long sys_null_call