diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/alternative.c | 37 | ||||
-rw-r--r-- | arch/i386/kernel/apic.c | 10 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/amd.c | 7 | ||||
-rw-r--r-- | arch/i386/kernel/doublefault.c | 13 | ||||
-rw-r--r-- | arch/i386/kernel/head.S | 4 | ||||
-rw-r--r-- | arch/i386/kernel/paravirt.c | 52 | ||||
-rw-r--r-- | arch/i386/kernel/vmi.c | 35 | ||||
-rw-r--r-- | arch/i386/mm/pageattr.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/common.c | 23 | ||||
-rw-r--r-- | arch/i386/pci/fixup.c | 6 | ||||
-rw-r--r-- | arch/i386/pci/irq.c | 5 | ||||
-rw-r--r-- | arch/i386/pci/legacy.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 14 | ||||
-rw-r--r-- | arch/i386/pci/numa.c | 15 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 43 | ||||
-rw-r--r-- | arch/i386/pci/visws.c | 4 | ||||
-rw-r--r-- | arch/i386/xen/enlighten.c | 12 |
17 files changed, 186 insertions, 98 deletions
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index c85598acb8fd..1b66d5c70eaf 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <asm/mce.h> | 11 | #include <asm/mce.h> |
12 | #include <asm/nmi.h> | 12 | #include <asm/nmi.h> |
13 | 13 | ||
14 | #define MAX_PATCH_LEN (255-1) | ||
15 | |||
14 | #ifdef CONFIG_HOTPLUG_CPU | 16 | #ifdef CONFIG_HOTPLUG_CPU |
15 | static int smp_alt_once; | 17 | static int smp_alt_once; |
16 | 18 | ||
@@ -148,7 +150,8 @@ static unsigned char** find_nop_table(void) | |||
148 | 150 | ||
149 | #endif /* CONFIG_X86_64 */ | 151 | #endif /* CONFIG_X86_64 */ |
150 | 152 | ||
151 | static void nop_out(void *insns, unsigned int len) | 153 | /* Use this to add nops to a buffer, then text_poke the whole buffer. */ |
154 | static void add_nops(void *insns, unsigned int len) | ||
152 | { | 155 | { |
153 | unsigned char **noptable = find_nop_table(); | 156 | unsigned char **noptable = find_nop_table(); |
154 | 157 | ||
@@ -156,7 +159,7 @@ static void nop_out(void *insns, unsigned int len) | |||
156 | unsigned int noplen = len; | 159 | unsigned int noplen = len; |
157 | if (noplen > ASM_NOP_MAX) | 160 | if (noplen > ASM_NOP_MAX) |
158 | noplen = ASM_NOP_MAX; | 161 | noplen = ASM_NOP_MAX; |
159 | text_poke(insns, noptable[noplen], noplen); | 162 | memcpy(insns, noptable[noplen], noplen); |
160 | insns += noplen; | 163 | insns += noplen; |
161 | len -= noplen; | 164 | len -= noplen; |
162 | } | 165 | } |
@@ -174,15 +177,15 @@ extern u8 *__smp_locks[], *__smp_locks_end[]; | |||
174 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) | 177 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) |
175 | { | 178 | { |
176 | struct alt_instr *a; | 179 | struct alt_instr *a; |
177 | u8 *instr; | 180 | char insnbuf[MAX_PATCH_LEN]; |
178 | int diff; | ||
179 | 181 | ||
180 | DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); | 182 | DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); |
181 | for (a = start; a < end; a++) { | 183 | for (a = start; a < end; a++) { |
184 | u8 *instr = a->instr; | ||
182 | BUG_ON(a->replacementlen > a->instrlen); | 185 | BUG_ON(a->replacementlen > a->instrlen); |
186 | BUG_ON(a->instrlen > sizeof(insnbuf)); | ||
183 | if (!boot_cpu_has(a->cpuid)) | 187 | if (!boot_cpu_has(a->cpuid)) |
184 | continue; | 188 | continue; |
185 | instr = a->instr; | ||
186 | #ifdef CONFIG_X86_64 | 189 | #ifdef CONFIG_X86_64 |
187 | /* vsyscall code is not mapped yet. resolve it manually. */ | 190 | /* vsyscall code is not mapped yet. resolve it manually. */ |
188 | if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { | 191 | if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { |
@@ -191,9 +194,10 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) | |||
191 | __FUNCTION__, a->instr, instr); | 194 | __FUNCTION__, a->instr, instr); |
192 | } | 195 | } |
193 | #endif | 196 | #endif |
194 | memcpy(instr, a->replacement, a->replacementlen); | 197 | memcpy(insnbuf, a->replacement, a->replacementlen); |
195 | diff = a->instrlen - a->replacementlen; | 198 | add_nops(insnbuf + a->replacementlen, |
196 | nop_out(instr + a->replacementlen, diff); | 199 | a->instrlen - a->replacementlen); |
200 | text_poke(instr, insnbuf, a->instrlen); | ||
197 | } | 201 | } |
198 | } | 202 | } |
199 | 203 | ||
@@ -215,16 +219,18 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) | |||
215 | static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) | 219 | static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) |
216 | { | 220 | { |
217 | u8 **ptr; | 221 | u8 **ptr; |
222 | char insn[1]; | ||
218 | 223 | ||
219 | if (noreplace_smp) | 224 | if (noreplace_smp) |
220 | return; | 225 | return; |
221 | 226 | ||
227 | add_nops(insn, 1); | ||
222 | for (ptr = start; ptr < end; ptr++) { | 228 | for (ptr = start; ptr < end; ptr++) { |
223 | if (*ptr < text) | 229 | if (*ptr < text) |
224 | continue; | 230 | continue; |
225 | if (*ptr > text_end) | 231 | if (*ptr > text_end) |
226 | continue; | 232 | continue; |
227 | nop_out(*ptr, 1); | 233 | text_poke(*ptr, insn, 1); |
228 | }; | 234 | }; |
229 | } | 235 | } |
230 | 236 | ||
@@ -351,6 +357,7 @@ void apply_paravirt(struct paravirt_patch_site *start, | |||
351 | struct paravirt_patch_site *end) | 357 | struct paravirt_patch_site *end) |
352 | { | 358 | { |
353 | struct paravirt_patch_site *p; | 359 | struct paravirt_patch_site *p; |
360 | char insnbuf[MAX_PATCH_LEN]; | ||
354 | 361 | ||
355 | if (noreplace_paravirt) | 362 | if (noreplace_paravirt) |
356 | return; | 363 | return; |
@@ -358,13 +365,15 @@ void apply_paravirt(struct paravirt_patch_site *start, | |||
358 | for (p = start; p < end; p++) { | 365 | for (p = start; p < end; p++) { |
359 | unsigned int used; | 366 | unsigned int used; |
360 | 367 | ||
361 | used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, | 368 | BUG_ON(p->len > MAX_PATCH_LEN); |
362 | p->len); | 369 | used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf, |
370 | (unsigned long)p->instr, p->len); | ||
363 | 371 | ||
364 | BUG_ON(used > p->len); | 372 | BUG_ON(used > p->len); |
365 | 373 | ||
366 | /* Pad the rest with nops */ | 374 | /* Pad the rest with nops */ |
367 | nop_out(p->instr + used, p->len - used); | 375 | add_nops(insnbuf + used, p->len - used); |
376 | text_poke(p->instr, insnbuf, p->len); | ||
368 | } | 377 | } |
369 | } | 378 | } |
370 | extern struct paravirt_patch_site __start_parainstructions[], | 379 | extern struct paravirt_patch_site __start_parainstructions[], |
@@ -379,7 +388,7 @@ void __init alternative_instructions(void) | |||
379 | that might execute the to be patched code. | 388 | that might execute the to be patched code. |
380 | Other CPUs are not running. */ | 389 | Other CPUs are not running. */ |
381 | stop_nmi(); | 390 | stop_nmi(); |
382 | #ifdef CONFIG_MCE | 391 | #ifdef CONFIG_X86_MCE |
383 | stop_mce(); | 392 | stop_mce(); |
384 | #endif | 393 | #endif |
385 | 394 | ||
@@ -417,7 +426,7 @@ void __init alternative_instructions(void) | |||
417 | local_irq_restore(flags); | 426 | local_irq_restore(flags); |
418 | 427 | ||
419 | restart_nmi(); | 428 | restart_nmi(); |
420 | #ifdef CONFIG_MCE | 429 | #ifdef CONFIG_X86_MCE |
421 | restart_mce(); | 430 | restart_mce(); |
422 | #endif | 431 | #endif |
423 | } | 432 | } |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index bfc6cb7df7e7..f9fff29e01a9 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -61,8 +61,9 @@ static int enable_local_apic __initdata = 0; | |||
61 | 61 | ||
62 | /* Local APIC timer verification ok */ | 62 | /* Local APIC timer verification ok */ |
63 | static int local_apic_timer_verify_ok; | 63 | static int local_apic_timer_verify_ok; |
64 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ | 64 | /* Disable local APIC timer from the kernel commandline or via dmi quirk |
65 | static int local_apic_timer_disabled; | 65 | or using CPU MSR check */ |
66 | int local_apic_timer_disabled; | ||
66 | /* Local APIC timer works in C2 */ | 67 | /* Local APIC timer works in C2 */ |
67 | int local_apic_timer_c2_ok; | 68 | int local_apic_timer_c2_ok; |
68 | EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); | 69 | EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); |
@@ -370,12 +371,9 @@ void __init setup_boot_APIC_clock(void) | |||
370 | long delta, deltapm; | 371 | long delta, deltapm; |
371 | int pm_referenced = 0; | 372 | int pm_referenced = 0; |
372 | 373 | ||
373 | if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN)) | ||
374 | local_apic_timer_disabled = 1; | ||
375 | |||
376 | /* | 374 | /* |
377 | * The local apic timer can be disabled via the kernel | 375 | * The local apic timer can be disabled via the kernel |
378 | * commandline or from the test above. Register the lapic | 376 | * commandline or from the CPU detection code. Register the lapic |
379 | * timer as a dummy clock event source on SMP systems, so the | 377 | * timer as a dummy clock event source on SMP systems, so the |
380 | * broadcast mechanism is used. On UP systems simply ignore it. | 378 | * broadcast mechanism is used. On UP systems simply ignore it. |
381 | */ | 379 | */ |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index c7ba455d5ac7..dcf6bbb1c7c0 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/mm.h> | 3 | #include <linux/mm.h> |
4 | #include <asm/io.h> | 4 | #include <asm/io.h> |
5 | #include <asm/processor.h> | 5 | #include <asm/processor.h> |
6 | #include <asm/apic.h> | ||
6 | 7 | ||
7 | #include "cpu.h" | 8 | #include "cpu.h" |
8 | 9 | ||
@@ -22,6 +23,7 @@ | |||
22 | extern void vide(void); | 23 | extern void vide(void); |
23 | __asm__(".align 4\nvide: ret"); | 24 | __asm__(".align 4\nvide: ret"); |
24 | 25 | ||
26 | #ifdef CONFIG_X86_LOCAL_APIC | ||
25 | #define ENABLE_C1E_MASK 0x18000000 | 27 | #define ENABLE_C1E_MASK 0x18000000 |
26 | #define CPUID_PROCESSOR_SIGNATURE 1 | 28 | #define CPUID_PROCESSOR_SIGNATURE 1 |
27 | #define CPUID_XFAM 0x0ff00000 | 29 | #define CPUID_XFAM 0x0ff00000 |
@@ -52,6 +54,7 @@ static __cpuinit int amd_apic_timer_broken(void) | |||
52 | } | 54 | } |
53 | return 0; | 55 | return 0; |
54 | } | 56 | } |
57 | #endif | ||
55 | 58 | ||
56 | int force_mwait __cpuinitdata; | 59 | int force_mwait __cpuinitdata; |
57 | 60 | ||
@@ -282,8 +285,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
282 | num_cache_leaves = 3; | 285 | num_cache_leaves = 3; |
283 | } | 286 | } |
284 | 287 | ||
288 | #ifdef CONFIG_X86_LOCAL_APIC | ||
285 | if (amd_apic_timer_broken()) | 289 | if (amd_apic_timer_broken()) |
286 | set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); | 290 | local_apic_timer_disabled = 1; |
291 | #endif | ||
287 | 292 | ||
288 | if (c->x86 == 0x10 && !force_mwait) | 293 | if (c->x86 == 0x10 && !force_mwait) |
289 | clear_bit(X86_FEATURE_MWAIT, c->x86_capability); | 294 | clear_bit(X86_FEATURE_MWAIT, c->x86_capability); |
diff --git a/arch/i386/kernel/doublefault.c b/arch/i386/kernel/doublefault.c index 265c5597efb0..40978af630e7 100644 --- a/arch/i386/kernel/doublefault.c +++ b/arch/i386/kernel/doublefault.c | |||
@@ -13,7 +13,7 @@ | |||
13 | static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; | 13 | static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; |
14 | #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) | 14 | #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) |
15 | 15 | ||
16 | #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000) | 16 | #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM) |
17 | 17 | ||
18 | static void doublefault_fn(void) | 18 | static void doublefault_fn(void) |
19 | { | 19 | { |
@@ -23,23 +23,23 @@ static void doublefault_fn(void) | |||
23 | store_gdt(&gdt_desc); | 23 | store_gdt(&gdt_desc); |
24 | gdt = gdt_desc.address; | 24 | gdt = gdt_desc.address; |
25 | 25 | ||
26 | printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); | 26 | printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); |
27 | 27 | ||
28 | if (ptr_ok(gdt)) { | 28 | if (ptr_ok(gdt)) { |
29 | gdt += GDT_ENTRY_TSS << 3; | 29 | gdt += GDT_ENTRY_TSS << 3; |
30 | tss = *(u16 *)(gdt+2); | 30 | tss = *(u16 *)(gdt+2); |
31 | tss += *(u8 *)(gdt+4) << 16; | 31 | tss += *(u8 *)(gdt+4) << 16; |
32 | tss += *(u8 *)(gdt+7) << 24; | 32 | tss += *(u8 *)(gdt+7) << 24; |
33 | printk("double fault, tss at %08lx\n", tss); | 33 | printk(KERN_EMERG "double fault, tss at %08lx\n", tss); |
34 | 34 | ||
35 | if (ptr_ok(tss)) { | 35 | if (ptr_ok(tss)) { |
36 | struct i386_hw_tss *t = (struct i386_hw_tss *)tss; | 36 | struct i386_hw_tss *t = (struct i386_hw_tss *)tss; |
37 | 37 | ||
38 | printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp); | 38 | printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->eip, t->esp); |
39 | 39 | ||
40 | printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", | 40 | printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", |
41 | t->eax, t->ebx, t->ecx, t->edx); | 41 | t->eax, t->ebx, t->ecx, t->edx); |
42 | printk("esi = %08lx, edi = %08lx\n", | 42 | printk(KERN_EMERG "esi = %08lx, edi = %08lx\n", |
43 | t->esi, t->edi); | 43 | t->esi, t->edi); |
44 | } | 44 | } |
45 | } | 45 | } |
@@ -63,6 +63,7 @@ struct tss_struct doublefault_tss __cacheline_aligned = { | |||
63 | .cs = __KERNEL_CS, | 63 | .cs = __KERNEL_CS, |
64 | .ss = __KERNEL_DS, | 64 | .ss = __KERNEL_DS, |
65 | .ds = __USER_DS, | 65 | .ds = __USER_DS, |
66 | .fs = __KERNEL_PERCPU, | ||
66 | 67 | ||
67 | .__cr3 = __pa(swapper_pg_dir) | 68 | .__cr3 = __pa(swapper_pg_dir) |
68 | } | 69 | } |
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 7c52b222207e..8f0382161c91 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -162,9 +162,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20); | |||
162 | * which will be freed later | 162 | * which will be freed later |
163 | */ | 163 | */ |
164 | 164 | ||
165 | #ifdef CONFIG_HOTPLUG_CPU | 165 | #ifndef CONFIG_HOTPLUG_CPU |
166 | .section .text,"ax",@progbits | ||
167 | #else | ||
168 | .section .init.text,"ax",@progbits | 166 | .section .init.text,"ax",@progbits |
169 | #endif | 167 | #endif |
170 | 168 | ||
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index ea962c0667d5..739cfb207dd7 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c | |||
@@ -69,7 +69,8 @@ DEF_NATIVE(read_tsc, "rdtsc"); | |||
69 | 69 | ||
70 | DEF_NATIVE(ud2a, "ud2a"); | 70 | DEF_NATIVE(ud2a, "ud2a"); |
71 | 71 | ||
72 | static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) | 72 | static unsigned native_patch(u8 type, u16 clobbers, void *ibuf, |
73 | unsigned long addr, unsigned len) | ||
73 | { | 74 | { |
74 | const unsigned char *start, *end; | 75 | const unsigned char *start, *end; |
75 | unsigned ret; | 76 | unsigned ret; |
@@ -90,7 +91,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) | |||
90 | #undef SITE | 91 | #undef SITE |
91 | 92 | ||
92 | patch_site: | 93 | patch_site: |
93 | ret = paravirt_patch_insns(insns, len, start, end); | 94 | ret = paravirt_patch_insns(ibuf, len, start, end); |
94 | break; | 95 | break; |
95 | 96 | ||
96 | case PARAVIRT_PATCH(make_pgd): | 97 | case PARAVIRT_PATCH(make_pgd): |
@@ -107,7 +108,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) | |||
107 | break; | 108 | break; |
108 | 109 | ||
109 | default: | 110 | default: |
110 | ret = paravirt_patch_default(type, clobbers, insns, len); | 111 | ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); |
111 | break; | 112 | break; |
112 | } | 113 | } |
113 | 114 | ||
@@ -129,68 +130,67 @@ struct branch { | |||
129 | u32 delta; | 130 | u32 delta; |
130 | } __attribute__((packed)); | 131 | } __attribute__((packed)); |
131 | 132 | ||
132 | unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, | 133 | unsigned paravirt_patch_call(void *insnbuf, |
133 | void *site, u16 site_clobbers, | 134 | const void *target, u16 tgt_clobbers, |
135 | unsigned long addr, u16 site_clobbers, | ||
134 | unsigned len) | 136 | unsigned len) |
135 | { | 137 | { |
136 | unsigned char *call = site; | 138 | struct branch *b = insnbuf; |
137 | unsigned long delta = (unsigned long)target - (unsigned long)(call+5); | 139 | unsigned long delta = (unsigned long)target - (addr+5); |
138 | struct branch b; | ||
139 | 140 | ||
140 | if (tgt_clobbers & ~site_clobbers) | 141 | if (tgt_clobbers & ~site_clobbers) |
141 | return len; /* target would clobber too much for this site */ | 142 | return len; /* target would clobber too much for this site */ |
142 | if (len < 5) | 143 | if (len < 5) |
143 | return len; /* call too long for patch site */ | 144 | return len; /* call too long for patch site */ |
144 | 145 | ||
145 | b.opcode = 0xe8; /* call */ | 146 | b->opcode = 0xe8; /* call */ |
146 | b.delta = delta; | 147 | b->delta = delta; |
147 | BUILD_BUG_ON(sizeof(b) != 5); | 148 | BUILD_BUG_ON(sizeof(*b) != 5); |
148 | text_poke(call, (unsigned char *)&b, 5); | ||
149 | 149 | ||
150 | return 5; | 150 | return 5; |
151 | } | 151 | } |
152 | 152 | ||
153 | unsigned paravirt_patch_jmp(void *target, void *site, unsigned len) | 153 | unsigned paravirt_patch_jmp(const void *target, void *insnbuf, |
154 | unsigned long addr, unsigned len) | ||
154 | { | 155 | { |
155 | unsigned char *jmp = site; | 156 | struct branch *b = insnbuf; |
156 | unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); | 157 | unsigned long delta = (unsigned long)target - (addr+5); |
157 | struct branch b; | ||
158 | 158 | ||
159 | if (len < 5) | 159 | if (len < 5) |
160 | return len; /* call too long for patch site */ | 160 | return len; /* call too long for patch site */ |
161 | 161 | ||
162 | b.opcode = 0xe9; /* jmp */ | 162 | b->opcode = 0xe9; /* jmp */ |
163 | b.delta = delta; | 163 | b->delta = delta; |
164 | text_poke(jmp, (unsigned char *)&b, 5); | ||
165 | 164 | ||
166 | return 5; | 165 | return 5; |
167 | } | 166 | } |
168 | 167 | ||
169 | unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len) | 168 | unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, |
169 | unsigned long addr, unsigned len) | ||
170 | { | 170 | { |
171 | void *opfunc = *((void **)¶virt_ops + type); | 171 | void *opfunc = *((void **)¶virt_ops + type); |
172 | unsigned ret; | 172 | unsigned ret; |
173 | 173 | ||
174 | if (opfunc == NULL) | 174 | if (opfunc == NULL) |
175 | /* If there's no function, patch it with a ud2a (BUG) */ | 175 | /* If there's no function, patch it with a ud2a (BUG) */ |
176 | ret = paravirt_patch_insns(site, len, start_ud2a, end_ud2a); | 176 | ret = paravirt_patch_insns(insnbuf, len, start_ud2a, end_ud2a); |
177 | else if (opfunc == paravirt_nop) | 177 | else if (opfunc == paravirt_nop) |
178 | /* If the operation is a nop, then nop the callsite */ | 178 | /* If the operation is a nop, then nop the callsite */ |
179 | ret = paravirt_patch_nop(); | 179 | ret = paravirt_patch_nop(); |
180 | else if (type == PARAVIRT_PATCH(iret) || | 180 | else if (type == PARAVIRT_PATCH(iret) || |
181 | type == PARAVIRT_PATCH(irq_enable_sysexit)) | 181 | type == PARAVIRT_PATCH(irq_enable_sysexit)) |
182 | /* If operation requires a jmp, then jmp */ | 182 | /* If operation requires a jmp, then jmp */ |
183 | ret = paravirt_patch_jmp(opfunc, site, len); | 183 | ret = paravirt_patch_jmp(opfunc, insnbuf, addr, len); |
184 | else | 184 | else |
185 | /* Otherwise call the function; assume target could | 185 | /* Otherwise call the function; assume target could |
186 | clobber any caller-save reg */ | 186 | clobber any caller-save reg */ |
187 | ret = paravirt_patch_call(opfunc, CLBR_ANY, | 187 | ret = paravirt_patch_call(insnbuf, opfunc, CLBR_ANY, |
188 | site, clobbers, len); | 188 | addr, clobbers, len); |
189 | 189 | ||
190 | return ret; | 190 | return ret; |
191 | } | 191 | } |
192 | 192 | ||
193 | unsigned paravirt_patch_insns(void *site, unsigned len, | 193 | unsigned paravirt_patch_insns(void *insnbuf, unsigned len, |
194 | const char *start, const char *end) | 194 | const char *start, const char *end) |
195 | { | 195 | { |
196 | unsigned insn_len = end - start; | 196 | unsigned insn_len = end - start; |
@@ -198,7 +198,7 @@ unsigned paravirt_patch_insns(void *site, unsigned len, | |||
198 | if (insn_len > len || start == NULL) | 198 | if (insn_len > len || start == NULL) |
199 | insn_len = len; | 199 | insn_len = len; |
200 | else | 200 | else |
201 | memcpy(site, start, insn_len); | 201 | memcpy(insnbuf, start, insn_len); |
202 | 202 | ||
203 | return insn_len; | 203 | return insn_len; |
204 | } | 204 | } |
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 72042bb7ec94..18673e0f193b 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c | |||
@@ -87,12 +87,14 @@ struct vmi_timer_ops vmi_timer_ops; | |||
87 | #define IRQ_PATCH_INT_MASK 0 | 87 | #define IRQ_PATCH_INT_MASK 0 |
88 | #define IRQ_PATCH_DISABLE 5 | 88 | #define IRQ_PATCH_DISABLE 5 |
89 | 89 | ||
90 | static inline void patch_offset(unsigned char *eip, unsigned char *dest) | 90 | static inline void patch_offset(void *insnbuf, |
91 | unsigned long eip, unsigned long dest) | ||
91 | { | 92 | { |
92 | *(unsigned long *)(eip+1) = dest-eip-5; | 93 | *(unsigned long *)(insnbuf+1) = dest-eip-5; |
93 | } | 94 | } |
94 | 95 | ||
95 | static unsigned patch_internal(int call, unsigned len, void *insns) | 96 | static unsigned patch_internal(int call, unsigned len, void *insnbuf, |
97 | unsigned long eip) | ||
96 | { | 98 | { |
97 | u64 reloc; | 99 | u64 reloc; |
98 | struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; | 100 | struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; |
@@ -100,14 +102,14 @@ static unsigned patch_internal(int call, unsigned len, void *insns) | |||
100 | switch(rel->type) { | 102 | switch(rel->type) { |
101 | case VMI_RELOCATION_CALL_REL: | 103 | case VMI_RELOCATION_CALL_REL: |
102 | BUG_ON(len < 5); | 104 | BUG_ON(len < 5); |
103 | *(char *)insns = MNEM_CALL; | 105 | *(char *)insnbuf = MNEM_CALL; |
104 | patch_offset(insns, rel->eip); | 106 | patch_offset(insnbuf, eip, (unsigned long)rel->eip); |
105 | return 5; | 107 | return 5; |
106 | 108 | ||
107 | case VMI_RELOCATION_JUMP_REL: | 109 | case VMI_RELOCATION_JUMP_REL: |
108 | BUG_ON(len < 5); | 110 | BUG_ON(len < 5); |
109 | *(char *)insns = MNEM_JMP; | 111 | *(char *)insnbuf = MNEM_JMP; |
110 | patch_offset(insns, rel->eip); | 112 | patch_offset(insnbuf, eip, (unsigned long)rel->eip); |
111 | return 5; | 113 | return 5; |
112 | 114 | ||
113 | case VMI_RELOCATION_NOP: | 115 | case VMI_RELOCATION_NOP: |
@@ -128,21 +130,26 @@ static unsigned patch_internal(int call, unsigned len, void *insns) | |||
128 | * Apply patch if appropriate, return length of new instruction | 130 | * Apply patch if appropriate, return length of new instruction |
129 | * sequence. The callee does nop padding for us. | 131 | * sequence. The callee does nop padding for us. |
130 | */ | 132 | */ |
131 | static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) | 133 | static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, |
134 | unsigned long eip, unsigned len) | ||
132 | { | 135 | { |
133 | switch (type) { | 136 | switch (type) { |
134 | case PARAVIRT_PATCH(irq_disable): | 137 | case PARAVIRT_PATCH(irq_disable): |
135 | return patch_internal(VMI_CALL_DisableInterrupts, len, insns); | 138 | return patch_internal(VMI_CALL_DisableInterrupts, len, |
139 | insns, eip); | ||
136 | case PARAVIRT_PATCH(irq_enable): | 140 | case PARAVIRT_PATCH(irq_enable): |
137 | return patch_internal(VMI_CALL_EnableInterrupts, len, insns); | 141 | return patch_internal(VMI_CALL_EnableInterrupts, len, |
142 | insns, eip); | ||
138 | case PARAVIRT_PATCH(restore_fl): | 143 | case PARAVIRT_PATCH(restore_fl): |
139 | return patch_internal(VMI_CALL_SetInterruptMask, len, insns); | 144 | return patch_internal(VMI_CALL_SetInterruptMask, len, |
145 | insns, eip); | ||
140 | case PARAVIRT_PATCH(save_fl): | 146 | case PARAVIRT_PATCH(save_fl): |
141 | return patch_internal(VMI_CALL_GetInterruptMask, len, insns); | 147 | return patch_internal(VMI_CALL_GetInterruptMask, len, |
148 | insns, eip); | ||
142 | case PARAVIRT_PATCH(iret): | 149 | case PARAVIRT_PATCH(iret): |
143 | return patch_internal(VMI_CALL_IRET, len, insns); | 150 | return patch_internal(VMI_CALL_IRET, len, insns, eip); |
144 | case PARAVIRT_PATCH(irq_enable_sysexit): | 151 | case PARAVIRT_PATCH(irq_enable_sysexit): |
145 | return patch_internal(VMI_CALL_SYSEXIT, len, insns); | 152 | return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip); |
146 | default: | 153 | default: |
147 | break; | 154 | break; |
148 | } | 155 | } |
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 8927222b3ab2..4241a74d16c8 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c | |||
@@ -82,7 +82,7 @@ static void flush_kernel_map(void *arg) | |||
82 | struct page *p; | 82 | struct page *p; |
83 | 83 | ||
84 | /* High level code is not ready for clflush yet */ | 84 | /* High level code is not ready for clflush yet */ |
85 | if (cpu_has_clflush) { | 85 | if (0 && cpu_has_clflush) { |
86 | list_for_each_entry (p, lh, lru) | 86 | list_for_each_entry (p, lh, lru) |
87 | cache_flush_page(p); | 87 | cache_flush_page(p); |
88 | } else if (boot_cpu_data.x86_model >= 4) | 88 | } else if (boot_cpu_data.x86_model >= 4) |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 85503deeda46..ebc6f3c66340 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -455,3 +455,26 @@ void pcibios_disable_device (struct pci_dev *dev) | |||
455 | if (!dev->msi_enabled && pcibios_disable_irq) | 455 | if (!dev->msi_enabled && pcibios_disable_irq) |
456 | pcibios_disable_irq(dev); | 456 | pcibios_disable_irq(dev); |
457 | } | 457 | } |
458 | |||
459 | struct pci_bus *pci_scan_bus_with_sysdata(int busno) | ||
460 | { | ||
461 | struct pci_bus *bus = NULL; | ||
462 | struct pci_sysdata *sd; | ||
463 | |||
464 | /* | ||
465 | * Allocate per-root-bus (not per bus) arch-specific data. | ||
466 | * TODO: leak; this memory is never freed. | ||
467 | * It's arguable whether it's worth the trouble to care. | ||
468 | */ | ||
469 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); | ||
470 | if (!sd) { | ||
471 | printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); | ||
472 | return NULL; | ||
473 | } | ||
474 | sd->node = -1; | ||
475 | bus = pci_scan_bus(busno, &pci_root_ops, sd); | ||
476 | if (!bus) | ||
477 | kfree(sd); | ||
478 | |||
479 | return bus; | ||
480 | } | ||
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index e7306dbf6c42..c82cbf4c7226 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
@@ -25,9 +25,9 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) | |||
25 | pci_read_config_byte(d, reg++, &subb); | 25 | pci_read_config_byte(d, reg++, &subb); |
26 | DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); | 26 | DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); |
27 | if (busno) | 27 | if (busno) |
28 | pci_scan_bus(busno, &pci_root_ops, NULL); /* Bus A */ | 28 | pci_scan_bus_with_sysdata(busno); /* Bus A */ |
29 | if (suba < subb) | 29 | if (suba < subb) |
30 | pci_scan_bus(suba+1, &pci_root_ops, NULL); /* Bus B */ | 30 | pci_scan_bus_with_sysdata(suba+1); /* Bus B */ |
31 | } | 31 | } |
32 | pcibios_last_bus = -1; | 32 | pcibios_last_bus = -1; |
33 | } | 33 | } |
@@ -42,7 +42,7 @@ static void __devinit pci_fixup_i450gx(struct pci_dev *d) | |||
42 | u8 busno; | 42 | u8 busno; |
43 | pci_read_config_byte(d, 0x4a, &busno); | 43 | pci_read_config_byte(d, 0x4a, &busno); |
44 | printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno); | 44 | printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno); |
45 | pci_scan_bus(busno, &pci_root_ops, NULL); | 45 | pci_scan_bus_with_sysdata(busno); |
46 | pcibios_last_bus = -1; | 46 | pcibios_last_bus = -1; |
47 | } | 47 | } |
48 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx); | 48 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx); |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index f2cb942f8281..665db063a40a 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -138,8 +138,9 @@ static void __init pirq_peer_trick(void) | |||
138 | for(i = 1; i < 256; i++) { | 138 | for(i = 1; i < 256; i++) { |
139 | if (!busmap[i] || pci_find_bus(0, i)) | 139 | if (!busmap[i] || pci_find_bus(0, i)) |
140 | continue; | 140 | continue; |
141 | if (pci_scan_bus(i, &pci_root_ops, NULL)) | 141 | if (pci_scan_bus_with_sysdata(i)) |
142 | printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i); | 142 | printk(KERN_INFO "PCI: Discovered primary peer " |
143 | "bus %02x [IRQ]\n", i); | ||
143 | } | 144 | } |
144 | pcibios_last_bus = -1; | 145 | pcibios_last_bus = -1; |
145 | } | 146 | } |
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 149a9588c256..5565d7016b75 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c | |||
@@ -26,7 +26,7 @@ static void __devinit pcibios_fixup_peer_bridges(void) | |||
26 | l != 0x0000 && l != 0xffff) { | 26 | l != 0x0000 && l != 0xffff) { |
27 | DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); | 27 | DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); |
28 | printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); | 28 | printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); |
29 | pci_scan_bus(n, &pci_root_ops, NULL); | 29 | pci_scan_bus_with_sysdata(n); |
30 | break; | 30 | break; |
31 | } | 31 | } |
32 | } | 32 | } |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index bb1afd9e589d..0d46b7a88b3b 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -82,16 +82,15 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
82 | 82 | ||
83 | switch (len) { | 83 | switch (len) { |
84 | case 1: | 84 | case 1: |
85 | *value = readb(mmcfg_virt_addr + reg); | 85 | *value = mmio_config_readb(mmcfg_virt_addr + reg); |
86 | break; | 86 | break; |
87 | case 2: | 87 | case 2: |
88 | *value = readw(mmcfg_virt_addr + reg); | 88 | *value = mmio_config_readw(mmcfg_virt_addr + reg); |
89 | break; | 89 | break; |
90 | case 4: | 90 | case 4: |
91 | *value = readl(mmcfg_virt_addr + reg); | 91 | *value = mmio_config_readl(mmcfg_virt_addr + reg); |
92 | break; | 92 | break; |
93 | } | 93 | } |
94 | |||
95 | spin_unlock_irqrestore(&pci_config_lock, flags); | 94 | spin_unlock_irqrestore(&pci_config_lock, flags); |
96 | 95 | ||
97 | return 0; | 96 | return 0; |
@@ -116,16 +115,15 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
116 | 115 | ||
117 | switch (len) { | 116 | switch (len) { |
118 | case 1: | 117 | case 1: |
119 | writeb(value, mmcfg_virt_addr + reg); | 118 | mmio_config_writeb(mmcfg_virt_addr, value); |
120 | break; | 119 | break; |
121 | case 2: | 120 | case 2: |
122 | writew(value, mmcfg_virt_addr + reg); | 121 | mmio_config_writew(mmcfg_virt_addr, value); |
123 | break; | 122 | break; |
124 | case 4: | 123 | case 4: |
125 | writel(value, mmcfg_virt_addr + reg); | 124 | mmio_config_writel(mmcfg_virt_addr, value); |
126 | break; | 125 | break; |
127 | } | 126 | } |
128 | |||
129 | spin_unlock_irqrestore(&pci_config_lock, flags); | 127 | spin_unlock_irqrestore(&pci_config_lock, flags); |
130 | 128 | ||
131 | return 0; | 129 | return 0; |
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index adbe17a38f6f..f5f165f69e0c 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c | |||
@@ -96,10 +96,14 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) | |||
96 | pci_read_config_byte(d, reg++, &suba); | 96 | pci_read_config_byte(d, reg++, &suba); |
97 | pci_read_config_byte(d, reg++, &subb); | 97 | pci_read_config_byte(d, reg++, &subb); |
98 | DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); | 98 | DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); |
99 | if (busno) | 99 | if (busno) { |
100 | pci_scan_bus(QUADLOCAL2BUS(quad,busno), &pci_root_ops, NULL); /* Bus A */ | 100 | /* Bus A */ |
101 | if (suba < subb) | 101 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno)); |
102 | pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), &pci_root_ops, NULL); /* Bus B */ | 102 | } |
103 | if (suba < subb) { | ||
104 | /* Bus B */ | ||
105 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1)); | ||
106 | } | ||
103 | } | 107 | } |
104 | pcibios_last_bus = -1; | 108 | pcibios_last_bus = -1; |
105 | } | 109 | } |
@@ -123,8 +127,7 @@ static int __init pci_numa_init(void) | |||
123 | continue; | 127 | continue; |
124 | printk("Scanning PCI bus %d for quad %d\n", | 128 | printk("Scanning PCI bus %d for quad %d\n", |
125 | QUADLOCAL2BUS(quad,0), quad); | 129 | QUADLOCAL2BUS(quad,0), quad); |
126 | pci_scan_bus(QUADLOCAL2BUS(quad,0), | 130 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0)); |
127 | &pci_root_ops, NULL); | ||
128 | } | 131 | } |
129 | return 0; | 132 | return 0; |
130 | } | 133 | } |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index e58bae2076ad..8c66f275756f 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -104,3 +104,46 @@ extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); | |||
104 | extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, | 104 | extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, |
105 | unsigned int devfn); | 105 | unsigned int devfn); |
106 | extern int __init pci_mmcfg_arch_init(void); | 106 | extern int __init pci_mmcfg_arch_init(void); |
107 | |||
108 | /* | ||
109 | * AMD Fam10h CPUs are buggy, and cannot access MMIO config space | ||
110 | * on their northbrige except through the * %eax register. As such, you MUST | ||
111 | * NOT use normal IOMEM accesses, you need to only use the magic mmio-config | ||
112 | * accessor functions. | ||
113 | * In fact just use pci_config_*, nothing else please. | ||
114 | */ | ||
115 | static inline unsigned char mmio_config_readb(void __iomem *pos) | ||
116 | { | ||
117 | u8 val; | ||
118 | asm volatile("movb (%1),%%al" : "=a" (val) : "r" (pos)); | ||
119 | return val; | ||
120 | } | ||
121 | |||
122 | static inline unsigned short mmio_config_readw(void __iomem *pos) | ||
123 | { | ||
124 | u16 val; | ||
125 | asm volatile("movw (%1),%%ax" : "=a" (val) : "r" (pos)); | ||
126 | return val; | ||
127 | } | ||
128 | |||
129 | static inline unsigned int mmio_config_readl(void __iomem *pos) | ||
130 | { | ||
131 | u32 val; | ||
132 | asm volatile("movl (%1),%%eax" : "=a" (val) : "r" (pos)); | ||
133 | return val; | ||
134 | } | ||
135 | |||
136 | static inline void mmio_config_writeb(void __iomem *pos, u8 val) | ||
137 | { | ||
138 | asm volatile("movb %%al,(%1)" :: "a" (val), "r" (pos) : "memory"); | ||
139 | } | ||
140 | |||
141 | static inline void mmio_config_writew(void __iomem *pos, u16 val) | ||
142 | { | ||
143 | asm volatile("movw %%ax,(%1)" :: "a" (val), "r" (pos) : "memory"); | ||
144 | } | ||
145 | |||
146 | static inline void mmio_config_writel(void __iomem *pos, u32 val) | ||
147 | { | ||
148 | asm volatile("movl %%eax,(%1)" :: "a" (val), "r" (pos) : "memory"); | ||
149 | } | ||
diff --git a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c index f1b486d4190b..8ecb1c722594 100644 --- a/arch/i386/pci/visws.c +++ b/arch/i386/pci/visws.c | |||
@@ -101,8 +101,8 @@ static int __init pcibios_init(void) | |||
101 | "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0); | 101 | "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0); |
102 | 102 | ||
103 | raw_pci_ops = &pci_direct_conf1; | 103 | raw_pci_ops = &pci_direct_conf1; |
104 | pci_scan_bus(pci_bus0, &pci_root_ops, NULL); | 104 | pci_scan_bus_with_sysdata(pci_bus0); |
105 | pci_scan_bus(pci_bus1, &pci_root_ops, NULL); | 105 | pci_scan_bus_with_sysdata(pci_bus1); |
106 | pci_fixup_irqs(visws_swizzle, visws_map_irq); | 106 | pci_fixup_irqs(visws_swizzle, visws_map_irq); |
107 | pcibios_resource_survey(); | 107 | pcibios_resource_survey(); |
108 | return 0; | 108 | return 0; |
diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c index 9a8c1181c001..f0c37511d8da 100644 --- a/arch/i386/xen/enlighten.c +++ b/arch/i386/xen/enlighten.c | |||
@@ -842,7 +842,8 @@ void __init xen_setup_vcpu_info_placement(void) | |||
842 | } | 842 | } |
843 | } | 843 | } |
844 | 844 | ||
845 | static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) | 845 | static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf, |
846 | unsigned long addr, unsigned len) | ||
846 | { | 847 | { |
847 | char *start, *end, *reloc; | 848 | char *start, *end, *reloc; |
848 | unsigned ret; | 849 | unsigned ret; |
@@ -869,7 +870,7 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) | |||
869 | if (start == NULL || (end-start) > len) | 870 | if (start == NULL || (end-start) > len) |
870 | goto default_patch; | 871 | goto default_patch; |
871 | 872 | ||
872 | ret = paravirt_patch_insns(insns, len, start, end); | 873 | ret = paravirt_patch_insns(insnbuf, len, start, end); |
873 | 874 | ||
874 | /* Note: because reloc is assigned from something that | 875 | /* Note: because reloc is assigned from something that |
875 | appears to be an array, gcc assumes it's non-null, | 876 | appears to be an array, gcc assumes it's non-null, |
@@ -877,8 +878,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) | |||
877 | end. */ | 878 | end. */ |
878 | if (reloc > start && reloc < end) { | 879 | if (reloc > start && reloc < end) { |
879 | int reloc_off = reloc - start; | 880 | int reloc_off = reloc - start; |
880 | long *relocp = (long *)(insns + reloc_off); | 881 | long *relocp = (long *)(insnbuf + reloc_off); |
881 | long delta = start - (char *)insns; | 882 | long delta = start - (char *)addr; |
882 | 883 | ||
883 | *relocp += delta; | 884 | *relocp += delta; |
884 | } | 885 | } |
@@ -886,7 +887,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) | |||
886 | 887 | ||
887 | default_patch: | 888 | default_patch: |
888 | default: | 889 | default: |
889 | ret = paravirt_patch_default(type, clobbers, insns, len); | 890 | ret = paravirt_patch_default(type, clobbers, insnbuf, |
891 | addr, len); | ||
890 | break; | 892 | break; |
891 | } | 893 | } |
892 | 894 | ||