diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-01-17 18:34:51 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-01-17 18:34:51 -0500 |
commit | 9cdf083f981b8d37b3212400a359368661385099 (patch) | |
tree | aa15a6a08ad87e650dea40fb59b3180bef0d345b /arch/sparc64/kernel | |
parent | e499e01d234a31d59679b7b1e1cf628d917ba49a (diff) | |
parent | a8b3485287731978899ced11f24628c927890e78 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/binfmt_aout32.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/binfmt_elf32.c | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/chmc.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/entry.S | 27 | ||||
-rw-r--r-- | arch/sparc64/kernel/head.S | 15 | ||||
-rw-r--r-- | arch/sparc64/kernel/irq.c | 24 | ||||
-rw-r--r-- | arch/sparc64/kernel/isa.c | 32 | ||||
-rw-r--r-- | arch/sparc64/kernel/kprobes.c | 91 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci.c | 9 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 16 | ||||
-rw-r--r-- | arch/sparc64/kernel/ptrace.c | 5 | ||||
-rw-r--r-- | arch/sparc64/kernel/rtrap.S | 23 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 9 | ||||
-rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 41 | ||||
-rw-r--r-- | arch/sparc64/kernel/sun4v_ivec.S | 20 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sunos32.c | 8 | ||||
-rw-r--r-- | arch/sparc64/kernel/traps.c | 30 | ||||
-rw-r--r-- | arch/sparc64/kernel/unaligned.c | 44 | ||||
-rw-r--r-- | arch/sparc64/kernel/visemul.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/vmlinux.lds.S | 1 |
22 files changed, 251 insertions, 169 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index e1eabebaed39..eff0c01d3579 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ | |||
14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ | 14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ |
15 | visemul.o prom.o of_device.o | 15 | visemul.o prom.o of_device.o |
16 | 16 | ||
17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | ||
17 | obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ | 18 | obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ |
18 | pci_psycho.o pci_sabre.o pci_schizo.o \ | 19 | pci_psycho.o pci_sabre.o pci_schizo.o \ |
19 | pci_sun4v.o pci_sun4v_asm.o | 20 | pci_sun4v.o pci_sun4v_asm.o |
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index d7caa60a0074..f205fc7cbcd0 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c | |||
@@ -209,7 +209,7 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
209 | if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && | 209 | if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && |
210 | N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || | 210 | N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || |
211 | N_TRSIZE(ex) || N_DRSIZE(ex) || | 211 | N_TRSIZE(ex) || N_DRSIZE(ex) || |
212 | bprm->file->f_dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { | 212 | bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { |
213 | return -ENOEXEC; | 213 | return -ENOEXEC; |
214 | } | 214 | } |
215 | 215 | ||
@@ -349,7 +349,7 @@ static int load_aout32_library(struct file *file) | |||
349 | int retval; | 349 | int retval; |
350 | struct exec ex; | 350 | struct exec ex; |
351 | 351 | ||
352 | inode = file->f_dentry->d_inode; | 352 | inode = file->f_path.dentry->d_inode; |
353 | 353 | ||
354 | retval = -ENOEXEC; | 354 | retval = -ENOEXEC; |
355 | error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); | 355 | error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); |
diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c index a98f3ae175a3..9ad84ff10a17 100644 --- a/arch/sparc64/kernel/binfmt_elf32.c +++ b/arch/sparc64/kernel/binfmt_elf32.c | |||
@@ -141,7 +141,6 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) | |||
141 | value->tv_sec = jiffies / HZ; | 141 | value->tv_sec = jiffies / HZ; |
142 | } | 142 | } |
143 | 143 | ||
144 | #define elf_addr_t u32 | ||
145 | #undef start_thread | 144 | #undef start_thread |
146 | #define start_thread start_thread32 | 145 | #define start_thread start_thread32 |
147 | #define init_elf_binfmt init_elf32_binfmt | 146 | #define init_elf_binfmt init_elf32_binfmt |
diff --git a/arch/sparc64/kernel/chmc.c b/arch/sparc64/kernel/chmc.c index 259f37e516f5..9699abeb9907 100644 --- a/arch/sparc64/kernel/chmc.c +++ b/arch/sparc64/kernel/chmc.c | |||
@@ -341,7 +341,7 @@ static void fetch_decode_regs(struct mctrl_info *mp) | |||
341 | 341 | ||
342 | static int init_one_mctrl(struct device_node *dp) | 342 | static int init_one_mctrl(struct device_node *dp) |
343 | { | 343 | { |
344 | struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL); | 344 | struct mctrl_info *mp = kzalloc(sizeof(*mp), GFP_KERNEL); |
345 | int portid = of_getintprop_default(dp, "portid", -1); | 345 | int portid = of_getintprop_default(dp, "portid", -1); |
346 | struct linux_prom64_registers *regs; | 346 | struct linux_prom64_registers *regs; |
347 | void *pval; | 347 | void *pval; |
@@ -349,7 +349,6 @@ static int init_one_mctrl(struct device_node *dp) | |||
349 | 349 | ||
350 | if (!mp) | 350 | if (!mp) |
351 | return -1; | 351 | return -1; |
352 | memset(mp, 0, sizeof(*mp)); | ||
353 | if (portid == -1) | 352 | if (portid == -1) |
354 | goto fail; | 353 | goto fail; |
355 | 354 | ||
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 6f28bec0a9bf..c15a3edcb826 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -597,7 +597,12 @@ __spitfire_cee_trap_continue: | |||
597 | 1: ba,pt %xcc, etrap_irq | 597 | 1: ba,pt %xcc, etrap_irq |
598 | rd %pc, %g7 | 598 | rd %pc, %g7 |
599 | 599 | ||
600 | 2: mov %l4, %o1 | 600 | 2: |
601 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
602 | call trace_hardirqs_off | ||
603 | nop | ||
604 | #endif | ||
605 | mov %l4, %o1 | ||
601 | mov %l5, %o2 | 606 | mov %l5, %o2 |
602 | call spitfire_access_error | 607 | call spitfire_access_error |
603 | add %sp, PTREGS_OFF, %o0 | 608 | add %sp, PTREGS_OFF, %o0 |
@@ -824,6 +829,10 @@ do_cheetah_plus_data_parity: | |||
824 | wrpr %g0, 15, %pil | 829 | wrpr %g0, 15, %pil |
825 | ba,pt %xcc, etrap_irq | 830 | ba,pt %xcc, etrap_irq |
826 | rd %pc, %g7 | 831 | rd %pc, %g7 |
832 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
833 | call trace_hardirqs_off | ||
834 | nop | ||
835 | #endif | ||
827 | mov 0x0, %o0 | 836 | mov 0x0, %o0 |
828 | call cheetah_plus_parity_error | 837 | call cheetah_plus_parity_error |
829 | add %sp, PTREGS_OFF, %o1 | 838 | add %sp, PTREGS_OFF, %o1 |
@@ -855,6 +864,10 @@ do_cheetah_plus_insn_parity: | |||
855 | wrpr %g0, 15, %pil | 864 | wrpr %g0, 15, %pil |
856 | ba,pt %xcc, etrap_irq | 865 | ba,pt %xcc, etrap_irq |
857 | rd %pc, %g7 | 866 | rd %pc, %g7 |
867 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
868 | call trace_hardirqs_off | ||
869 | nop | ||
870 | #endif | ||
858 | mov 0x1, %o0 | 871 | mov 0x1, %o0 |
859 | call cheetah_plus_parity_error | 872 | call cheetah_plus_parity_error |
860 | add %sp, PTREGS_OFF, %o1 | 873 | add %sp, PTREGS_OFF, %o1 |
@@ -1183,6 +1196,10 @@ c_fast_ecc: | |||
1183 | wrpr %g0, 15, %pil | 1196 | wrpr %g0, 15, %pil |
1184 | ba,pt %xcc, etrap_irq | 1197 | ba,pt %xcc, etrap_irq |
1185 | rd %pc, %g7 | 1198 | rd %pc, %g7 |
1199 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
1200 | call trace_hardirqs_off | ||
1201 | nop | ||
1202 | #endif | ||
1186 | mov %l4, %o1 | 1203 | mov %l4, %o1 |
1187 | mov %l5, %o2 | 1204 | mov %l5, %o2 |
1188 | call cheetah_fecc_handler | 1205 | call cheetah_fecc_handler |
@@ -1211,6 +1228,10 @@ c_cee: | |||
1211 | wrpr %g0, 15, %pil | 1228 | wrpr %g0, 15, %pil |
1212 | ba,pt %xcc, etrap_irq | 1229 | ba,pt %xcc, etrap_irq |
1213 | rd %pc, %g7 | 1230 | rd %pc, %g7 |
1231 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
1232 | call trace_hardirqs_off | ||
1233 | nop | ||
1234 | #endif | ||
1214 | mov %l4, %o1 | 1235 | mov %l4, %o1 |
1215 | mov %l5, %o2 | 1236 | mov %l5, %o2 |
1216 | call cheetah_cee_handler | 1237 | call cheetah_cee_handler |
@@ -1239,6 +1260,10 @@ c_deferred: | |||
1239 | wrpr %g0, 15, %pil | 1260 | wrpr %g0, 15, %pil |
1240 | ba,pt %xcc, etrap_irq | 1261 | ba,pt %xcc, etrap_irq |
1241 | rd %pc, %g7 | 1262 | rd %pc, %g7 |
1263 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
1264 | call trace_hardirqs_off | ||
1265 | nop | ||
1266 | #endif | ||
1242 | mov %l4, %o1 | 1267 | mov %l4, %o1 |
1243 | mov %l5, %o2 | 1268 | mov %l5, %o2 |
1244 | call cheetah_deferred_handler | 1269 | call cheetah_deferred_handler |
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index c8e9dc9d68a9..baea10a98196 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -78,11 +78,7 @@ sparc_ramdisk_image64: | |||
78 | 78 | ||
79 | /* PROM cif handler code address is in %o4. */ | 79 | /* PROM cif handler code address is in %o4. */ |
80 | sparc64_boot: | 80 | sparc64_boot: |
81 | 1: rd %pc, %g7 | 81 | mov %o4, %l7 |
82 | set 1b, %g1 | ||
83 | cmp %g1, %g7 | ||
84 | be,pn %xcc, sparc64_boot_after_remap | ||
85 | mov %o4, %l7 | ||
86 | 82 | ||
87 | /* We need to remap the kernel. Use position independant | 83 | /* We need to remap the kernel. Use position independant |
88 | * code to remap us to KERNBASE. | 84 | * code to remap us to KERNBASE. |
@@ -295,7 +291,6 @@ is_sun4v: | |||
295 | 291 | ||
296 | add %sp, (192 + 128), %sp | 292 | add %sp, (192 + 128), %sp |
297 | 293 | ||
298 | sparc64_boot_after_remap: | ||
299 | sethi %hi(prom_root_compatible), %g1 | 294 | sethi %hi(prom_root_compatible), %g1 |
300 | or %g1, %lo(prom_root_compatible), %g1 | 295 | or %g1, %lo(prom_root_compatible), %g1 |
301 | sethi %hi(prom_sun4v_name), %g7 | 296 | sethi %hi(prom_sun4v_name), %g7 |
@@ -489,6 +484,14 @@ tlb_fixup_done: | |||
489 | call __bzero | 484 | call __bzero |
490 | sub %o1, %o0, %o1 | 485 | sub %o1, %o0, %o1 |
491 | 486 | ||
487 | #ifdef CONFIG_LOCKDEP | ||
488 | /* We have this call this super early, as even prom_init can grab | ||
489 | * spinlocks and thus call into the lockdep code. | ||
490 | */ | ||
491 | call lockdep_init | ||
492 | nop | ||
493 | #endif | ||
494 | |||
492 | mov %l6, %o1 ! OpenPROM stack | 495 | mov %l6, %o1 ! OpenPROM stack |
493 | call prom_init | 496 | call prom_init |
494 | mov %l7, %o0 ! OpenPROM cif handler | 497 | mov %l7, %o0 ! OpenPROM cif handler |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index d64b1ea848de..c3d068c7a412 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -372,14 +372,14 @@ static void run_pre_handler(unsigned int virt_irq) | |||
372 | } | 372 | } |
373 | } | 373 | } |
374 | 374 | ||
375 | static struct hw_interrupt_type sun4u_irq = { | 375 | static struct irq_chip sun4u_irq = { |
376 | .typename = "sun4u", | 376 | .typename = "sun4u", |
377 | .enable = sun4u_irq_enable, | 377 | .enable = sun4u_irq_enable, |
378 | .disable = sun4u_irq_disable, | 378 | .disable = sun4u_irq_disable, |
379 | .end = sun4u_irq_end, | 379 | .end = sun4u_irq_end, |
380 | }; | 380 | }; |
381 | 381 | ||
382 | static struct hw_interrupt_type sun4u_irq_ack = { | 382 | static struct irq_chip sun4u_irq_ack = { |
383 | .typename = "sun4u+ack", | 383 | .typename = "sun4u+ack", |
384 | .enable = sun4u_irq_enable, | 384 | .enable = sun4u_irq_enable, |
385 | .disable = sun4u_irq_disable, | 385 | .disable = sun4u_irq_disable, |
@@ -387,14 +387,14 @@ static struct hw_interrupt_type sun4u_irq_ack = { | |||
387 | .end = sun4u_irq_end, | 387 | .end = sun4u_irq_end, |
388 | }; | 388 | }; |
389 | 389 | ||
390 | static struct hw_interrupt_type sun4v_irq = { | 390 | static struct irq_chip sun4v_irq = { |
391 | .typename = "sun4v", | 391 | .typename = "sun4v", |
392 | .enable = sun4v_irq_enable, | 392 | .enable = sun4v_irq_enable, |
393 | .disable = sun4v_irq_disable, | 393 | .disable = sun4v_irq_disable, |
394 | .end = sun4v_irq_end, | 394 | .end = sun4v_irq_end, |
395 | }; | 395 | }; |
396 | 396 | ||
397 | static struct hw_interrupt_type sun4v_irq_ack = { | 397 | static struct irq_chip sun4v_irq_ack = { |
398 | .typename = "sun4v+ack", | 398 | .typename = "sun4v+ack", |
399 | .enable = sun4v_irq_enable, | 399 | .enable = sun4v_irq_enable, |
400 | .disable = sun4v_irq_disable, | 400 | .disable = sun4v_irq_disable, |
@@ -493,22 +493,6 @@ out: | |||
493 | return bucket->virt_irq; | 493 | return bucket->virt_irq; |
494 | } | 494 | } |
495 | 495 | ||
496 | void hw_resend_irq(struct hw_interrupt_type *handler, unsigned int virt_irq) | ||
497 | { | ||
498 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | ||
499 | unsigned long pstate; | ||
500 | unsigned int *ent; | ||
501 | |||
502 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | ||
503 | __asm__ __volatile__("wrpr %0, %1, %%pstate" | ||
504 | : : "r" (pstate), "i" (PSTATE_IE)); | ||
505 | ent = irq_work(smp_processor_id()); | ||
506 | bucket->irq_chain = *ent; | ||
507 | *ent = __irq(bucket); | ||
508 | set_softint(1 << PIL_DEVICE_IRQ); | ||
509 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); | ||
510 | } | ||
511 | |||
512 | void ack_bad_irq(unsigned int virt_irq) | 496 | void ack_bad_irq(unsigned int virt_irq) |
513 | { | 497 | { |
514 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 498 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index f028e68b23f2..98721a8f8619 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c | |||
@@ -22,14 +22,15 @@ static void __init report_dev(struct sparc_isa_device *isa_dev, int child) | |||
22 | printk(" [%s", isa_dev->prom_node->name); | 22 | printk(" [%s", isa_dev->prom_node->name); |
23 | } | 23 | } |
24 | 24 | ||
25 | static struct linux_prom_registers * __init | 25 | static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev) |
26 | isa_dev_get_resource(struct sparc_isa_device *isa_dev) | ||
27 | { | 26 | { |
28 | struct linux_prom_registers *pregs; | 27 | struct linux_prom_registers *pregs; |
29 | unsigned long base, len; | 28 | unsigned long base, len; |
30 | int prop_len; | 29 | int prop_len; |
31 | 30 | ||
32 | pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len); | 31 | pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len); |
32 | if (!pregs) | ||
33 | return; | ||
33 | 34 | ||
34 | /* Only the first one is interesting. */ | 35 | /* Only the first one is interesting. */ |
35 | len = pregs[0].reg_size; | 36 | len = pregs[0].reg_size; |
@@ -44,12 +45,9 @@ isa_dev_get_resource(struct sparc_isa_device *isa_dev) | |||
44 | 45 | ||
45 | request_resource(&isa_dev->bus->parent->io_space, | 46 | request_resource(&isa_dev->bus->parent->io_space, |
46 | &isa_dev->resource); | 47 | &isa_dev->resource); |
47 | |||
48 | return pregs; | ||
49 | } | 48 | } |
50 | 49 | ||
51 | static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, | 50 | static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev) |
52 | struct linux_prom_registers *pregs) | ||
53 | { | 51 | { |
54 | struct of_device *op = of_find_device_by_node(isa_dev->prom_node); | 52 | struct of_device *op = of_find_device_by_node(isa_dev->prom_node); |
55 | 53 | ||
@@ -69,17 +67,14 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) | |||
69 | 67 | ||
70 | printk(" ->"); | 68 | printk(" ->"); |
71 | while (dp) { | 69 | while (dp) { |
72 | struct linux_prom_registers *regs; | ||
73 | struct sparc_isa_device *isa_dev; | 70 | struct sparc_isa_device *isa_dev; |
74 | 71 | ||
75 | isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); | 72 | isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); |
76 | if (!isa_dev) { | 73 | if (!isa_dev) { |
77 | fatal_err("cannot allocate child isa_dev"); | 74 | fatal_err("cannot allocate child isa_dev"); |
78 | prom_halt(); | 75 | prom_halt(); |
79 | } | 76 | } |
80 | 77 | ||
81 | memset(isa_dev, 0, sizeof(*isa_dev)); | ||
82 | |||
83 | /* Link it in to parent. */ | 78 | /* Link it in to parent. */ |
84 | isa_dev->next = parent_isa_dev->child; | 79 | isa_dev->next = parent_isa_dev->child; |
85 | parent_isa_dev->child = isa_dev; | 80 | parent_isa_dev->child = isa_dev; |
@@ -87,8 +82,8 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) | |||
87 | isa_dev->bus = parent_isa_dev->bus; | 82 | isa_dev->bus = parent_isa_dev->bus; |
88 | isa_dev->prom_node = dp; | 83 | isa_dev->prom_node = dp; |
89 | 84 | ||
90 | regs = isa_dev_get_resource(isa_dev); | 85 | isa_dev_get_resource(isa_dev); |
91 | isa_dev_get_irq(isa_dev, regs); | 86 | isa_dev_get_irq(isa_dev); |
92 | 87 | ||
93 | report_dev(isa_dev, 1); | 88 | report_dev(isa_dev, 1); |
94 | 89 | ||
@@ -101,17 +96,14 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) | |||
101 | struct device_node *dp = isa_br->prom_node->child; | 96 | struct device_node *dp = isa_br->prom_node->child; |
102 | 97 | ||
103 | while (dp) { | 98 | while (dp) { |
104 | struct linux_prom_registers *regs; | ||
105 | struct sparc_isa_device *isa_dev; | 99 | struct sparc_isa_device *isa_dev; |
106 | 100 | ||
107 | isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); | 101 | isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); |
108 | if (!isa_dev) { | 102 | if (!isa_dev) { |
109 | printk(KERN_DEBUG "ISA: cannot allocate isa_dev"); | 103 | printk(KERN_DEBUG "ISA: cannot allocate isa_dev"); |
110 | return; | 104 | return; |
111 | } | 105 | } |
112 | 106 | ||
113 | memset(isa_dev, 0, sizeof(*isa_dev)); | ||
114 | |||
115 | isa_dev->ofdev.node = dp; | 107 | isa_dev->ofdev.node = dp; |
116 | isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; | 108 | isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; |
117 | isa_dev->ofdev.dev.bus = &isa_bus_type; | 109 | isa_dev->ofdev.dev.bus = &isa_bus_type; |
@@ -141,8 +133,8 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) | |||
141 | isa_dev->bus = isa_br; | 133 | isa_dev->bus = isa_br; |
142 | isa_dev->prom_node = dp; | 134 | isa_dev->prom_node = dp; |
143 | 135 | ||
144 | regs = isa_dev_get_resource(isa_dev); | 136 | isa_dev_get_resource(isa_dev); |
145 | isa_dev_get_irq(isa_dev, regs); | 137 | isa_dev_get_irq(isa_dev); |
146 | 138 | ||
147 | report_dev(isa_dev, 0); | 139 | report_dev(isa_dev, 0); |
148 | 140 | ||
@@ -180,14 +172,12 @@ void __init isa_init(void) | |||
180 | pbm = pdev_cookie->pbm; | 172 | pbm = pdev_cookie->pbm; |
181 | dp = pdev_cookie->prom_node; | 173 | dp = pdev_cookie->prom_node; |
182 | 174 | ||
183 | isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); | 175 | isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL); |
184 | if (!isa_br) { | 176 | if (!isa_br) { |
185 | printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); | 177 | printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); |
186 | return; | 178 | return; |
187 | } | 179 | } |
188 | 180 | ||
189 | memset(isa_br, 0, sizeof(*isa_br)); | ||
190 | |||
191 | isa_br->ofdev.node = dp; | 181 | isa_br->ofdev.node = dp; |
192 | isa_br->ofdev.dev.parent = &pdev->dev; | 182 | isa_br->ofdev.dev.parent = &pdev->dev; |
193 | isa_br->ofdev.dev.bus = &isa_bus_type; | 183 | isa_br->ofdev.dev.bus = &isa_bus_type; |
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index 8e75ed762fd8..ae221f0d4a6f 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c | |||
@@ -45,7 +45,11 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | |||
45 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | 45 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
46 | { | 46 | { |
47 | p->ainsn.insn[0] = *p->addr; | 47 | p->ainsn.insn[0] = *p->addr; |
48 | flushi(&p->ainsn.insn[0]); | ||
49 | |||
48 | p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; | 50 | p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; |
51 | flushi(&p->ainsn.insn[1]); | ||
52 | |||
49 | p->opcode = *p->addr; | 53 | p->opcode = *p->addr; |
50 | return 0; | 54 | return 0; |
51 | } | 55 | } |
@@ -185,16 +189,19 @@ no_kprobe: | |||
185 | /* If INSN is a relative control transfer instruction, | 189 | /* If INSN is a relative control transfer instruction, |
186 | * return the corrected branch destination value. | 190 | * return the corrected branch destination value. |
187 | * | 191 | * |
188 | * The original INSN location was REAL_PC, it actually | 192 | * regs->tpc and regs->tnpc still hold the values of the |
189 | * executed at PC and produced destination address NPC. | 193 | * program counters at the time of trap due to the execution |
194 | * of the BREAKPOINT_INSTRUCTION_2 at p->ainsn.insn[1] | ||
195 | * | ||
190 | */ | 196 | */ |
191 | static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc, | 197 | static unsigned long __kprobes relbranch_fixup(u32 insn, struct kprobe *p, |
192 | unsigned long pc, | 198 | struct pt_regs *regs) |
193 | unsigned long npc) | ||
194 | { | 199 | { |
200 | unsigned long real_pc = (unsigned long) p->addr; | ||
201 | |||
195 | /* Branch not taken, no mods necessary. */ | 202 | /* Branch not taken, no mods necessary. */ |
196 | if (npc == pc + 0x4UL) | 203 | if (regs->tnpc == regs->tpc + 0x4UL) |
197 | return real_pc + 0x4UL; | 204 | return real_pc + 0x8UL; |
198 | 205 | ||
199 | /* The three cases are call, branch w/prediction, | 206 | /* The three cases are call, branch w/prediction, |
200 | * and traditional branch. | 207 | * and traditional branch. |
@@ -202,14 +209,21 @@ static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc, | |||
202 | if ((insn & 0xc0000000) == 0x40000000 || | 209 | if ((insn & 0xc0000000) == 0x40000000 || |
203 | (insn & 0xc1c00000) == 0x00400000 || | 210 | (insn & 0xc1c00000) == 0x00400000 || |
204 | (insn & 0xc1c00000) == 0x00800000) { | 211 | (insn & 0xc1c00000) == 0x00800000) { |
212 | unsigned long ainsn_addr; | ||
213 | |||
214 | ainsn_addr = (unsigned long) &p->ainsn.insn[0]; | ||
215 | |||
205 | /* The instruction did all the work for us | 216 | /* The instruction did all the work for us |
206 | * already, just apply the offset to the correct | 217 | * already, just apply the offset to the correct |
207 | * instruction location. | 218 | * instruction location. |
208 | */ | 219 | */ |
209 | return (real_pc + (npc - pc)); | 220 | return (real_pc + (regs->tnpc - ainsn_addr)); |
210 | } | 221 | } |
211 | 222 | ||
212 | return real_pc + 0x4UL; | 223 | /* It is jmpl or some other absolute PC modification instruction, |
224 | * leave NPC as-is. | ||
225 | */ | ||
226 | return regs->tnpc; | ||
213 | } | 227 | } |
214 | 228 | ||
215 | /* If INSN is an instruction which writes it's PC location | 229 | /* If INSN is an instruction which writes it's PC location |
@@ -220,12 +234,12 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn, | |||
220 | { | 234 | { |
221 | unsigned long *slot = NULL; | 235 | unsigned long *slot = NULL; |
222 | 236 | ||
223 | /* Simplest cast is call, which always uses %o7 */ | 237 | /* Simplest case is 'call', which always uses %o7 */ |
224 | if ((insn & 0xc0000000) == 0x40000000) { | 238 | if ((insn & 0xc0000000) == 0x40000000) { |
225 | slot = ®s->u_regs[UREG_I7]; | 239 | slot = ®s->u_regs[UREG_I7]; |
226 | } | 240 | } |
227 | 241 | ||
228 | /* Jmpl encodes the register inside of the opcode */ | 242 | /* 'jmpl' encodes the register inside of the opcode */ |
229 | if ((insn & 0xc1f80000) == 0x81c00000) { | 243 | if ((insn & 0xc1f80000) == 0x81c00000) { |
230 | unsigned long rd = ((insn >> 25) & 0x1f); | 244 | unsigned long rd = ((insn >> 25) & 0x1f); |
231 | 245 | ||
@@ -247,11 +261,11 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn, | |||
247 | 261 | ||
248 | /* | 262 | /* |
249 | * Called after single-stepping. p->addr is the address of the | 263 | * Called after single-stepping. p->addr is the address of the |
250 | * instruction whose first byte has been replaced by the breakpoint | 264 | * instruction which has been replaced by the breakpoint |
251 | * instruction. To avoid the SMP problems that can occur when we | 265 | * instruction. To avoid the SMP problems that can occur when we |
252 | * temporarily put back the original opcode to single-step, we | 266 | * temporarily put back the original opcode to single-step, we |
253 | * single-stepped a copy of the instruction. The address of this | 267 | * single-stepped a copy of the instruction. The address of this |
254 | * copy is p->ainsn.insn. | 268 | * copy is &p->ainsn.insn[0]. |
255 | * | 269 | * |
256 | * This function prepares to return from the post-single-step | 270 | * This function prepares to return from the post-single-step |
257 | * breakpoint trap. | 271 | * breakpoint trap. |
@@ -261,11 +275,11 @@ static void __kprobes resume_execution(struct kprobe *p, | |||
261 | { | 275 | { |
262 | u32 insn = p->ainsn.insn[0]; | 276 | u32 insn = p->ainsn.insn[0]; |
263 | 277 | ||
278 | regs->tnpc = relbranch_fixup(insn, p, regs); | ||
279 | |||
280 | /* This assignment must occur after relbranch_fixup() */ | ||
264 | regs->tpc = kcb->kprobe_orig_tnpc; | 281 | regs->tpc = kcb->kprobe_orig_tnpc; |
265 | regs->tnpc = relbranch_fixup(insn, | 282 | |
266 | (unsigned long) p->addr, | ||
267 | (unsigned long) &p->ainsn.insn[0], | ||
268 | regs->tnpc); | ||
269 | retpc_fixup(regs, insn, (unsigned long) p->addr); | 283 | retpc_fixup(regs, insn, (unsigned long) p->addr); |
270 | 284 | ||
271 | regs->tstate = ((regs->tstate & ~TSTATE_PIL) | | 285 | regs->tstate = ((regs->tstate & ~TSTATE_PIL) | |
@@ -430,17 +444,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
430 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 444 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
431 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 445 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
432 | 446 | ||
433 | kcb->jprobe_saved_regs_location = regs; | ||
434 | memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs)); | 447 | memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs)); |
435 | 448 | ||
436 | /* Save a whole stack frame, this gets arguments | ||
437 | * pushed onto the stack after using up all the | ||
438 | * arg registers. | ||
439 | */ | ||
440 | memcpy(&(kcb->jprobe_saved_stack), | ||
441 | (char *) (regs->u_regs[UREG_FP] + STACK_BIAS), | ||
442 | sizeof(kcb->jprobe_saved_stack)); | ||
443 | |||
444 | regs->tpc = (unsigned long) jp->entry; | 449 | regs->tpc = (unsigned long) jp->entry; |
445 | regs->tnpc = ((unsigned long) jp->entry) + 0x4UL; | 450 | regs->tnpc = ((unsigned long) jp->entry) + 0x4UL; |
446 | regs->tstate |= TSTATE_PIL; | 451 | regs->tstate |= TSTATE_PIL; |
@@ -450,10 +455,19 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
450 | 455 | ||
451 | void __kprobes jprobe_return(void) | 456 | void __kprobes jprobe_return(void) |
452 | { | 457 | { |
453 | __asm__ __volatile__( | 458 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
454 | ".globl jprobe_return_trap_instruction\n" | 459 | register unsigned long orig_fp asm("g1"); |
460 | |||
461 | orig_fp = kcb->jprobe_saved_regs.u_regs[UREG_FP]; | ||
462 | __asm__ __volatile__("\n" | ||
463 | "1: cmp %%sp, %0\n\t" | ||
464 | "blu,a,pt %%xcc, 1b\n\t" | ||
465 | " restore\n\t" | ||
466 | ".globl jprobe_return_trap_instruction\n" | ||
455 | "jprobe_return_trap_instruction:\n\t" | 467 | "jprobe_return_trap_instruction:\n\t" |
456 | "ta 0x70"); | 468 | "ta 0x70" |
469 | : /* no outputs */ | ||
470 | : "r" (orig_fp)); | ||
457 | } | 471 | } |
458 | 472 | ||
459 | extern void jprobe_return_trap_instruction(void); | 473 | extern void jprobe_return_trap_instruction(void); |
@@ -466,26 +480,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
466 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 480 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
467 | 481 | ||
468 | if (addr == (u32 *) jprobe_return_trap_instruction) { | 482 | if (addr == (u32 *) jprobe_return_trap_instruction) { |
469 | if (kcb->jprobe_saved_regs_location != regs) { | ||
470 | printk("JPROBE: Current regs (%p) does not match " | ||
471 | "saved regs (%p).\n", | ||
472 | regs, kcb->jprobe_saved_regs_location); | ||
473 | printk("JPROBE: Saved registers\n"); | ||
474 | __show_regs(kcb->jprobe_saved_regs_location); | ||
475 | printk("JPROBE: Current registers\n"); | ||
476 | __show_regs(regs); | ||
477 | BUG(); | ||
478 | } | ||
479 | /* Restore old register state. Do pt_regs | ||
480 | * first so that UREG_FP is the original one for | ||
481 | * the stack frame restore. | ||
482 | */ | ||
483 | memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs)); | 483 | memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs)); |
484 | |||
485 | memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS), | ||
486 | &(kcb->jprobe_saved_stack), | ||
487 | sizeof(kcb->jprobe_saved_stack)); | ||
488 | |||
489 | preempt_enable_no_resched(); | 484 | preempt_enable_no_resched(); |
490 | return 1; | 485 | return 1; |
491 | } | 486 | } |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 8cc14fc6b6f1..b0f3e0082a0d 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -144,9 +144,12 @@ void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned lo | |||
144 | } | 144 | } |
145 | EXPORT_SYMBOL(of_ioremap); | 145 | EXPORT_SYMBOL(of_ioremap); |
146 | 146 | ||
147 | void of_iounmap(void __iomem *base, unsigned long size) | 147 | void of_iounmap(struct resource *res, void __iomem *base, unsigned long size) |
148 | { | 148 | { |
149 | release_region((unsigned long) base, size); | 149 | if (res->flags & IORESOURCE_MEM) |
150 | release_mem_region((unsigned long) base, size); | ||
151 | else | ||
152 | release_region((unsigned long) base, size); | ||
150 | } | 153 | } |
151 | EXPORT_SYMBOL(of_iounmap); | 154 | EXPORT_SYMBOL(of_iounmap); |
152 | 155 | ||
@@ -1007,10 +1010,9 @@ struct of_device* of_platform_device_create(struct device_node *np, | |||
1007 | { | 1010 | { |
1008 | struct of_device *dev; | 1011 | struct of_device *dev; |
1009 | 1012 | ||
1010 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | 1013 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1011 | if (!dev) | 1014 | if (!dev) |
1012 | return NULL; | 1015 | return NULL; |
1013 | memset(dev, 0, sizeof(*dev)); | ||
1014 | 1016 | ||
1015 | dev->dev.parent = parent; | 1017 | dev->dev.parent = parent; |
1016 | dev->dev.bus = bus; | 1018 | dev->dev.bus = bus; |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index e02f01b644af..dfc41cd4bb5d 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -646,13 +646,4 @@ int pci_domain_nr(struct pci_bus *pbus) | |||
646 | } | 646 | } |
647 | EXPORT_SYMBOL(pci_domain_nr); | 647 | EXPORT_SYMBOL(pci_domain_nr); |
648 | 648 | ||
649 | int pcibios_prep_mwi(struct pci_dev *dev) | ||
650 | { | ||
651 | /* We set correct PCI_CACHE_LINE_SIZE register values for every | ||
652 | * device probed on this platform. So there is nothing to check | ||
653 | * and this always succeeds. | ||
654 | */ | ||
655 | return 0; | ||
656 | } | ||
657 | |||
658 | #endif /* !(CONFIG_PCI) */ | 649 | #endif /* !(CONFIG_PCI) */ |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 03ad4c06758e..6b04794b7a97 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -798,7 +798,7 @@ static struct pci_ops pci_sun4v_ops = { | |||
798 | static void pbm_scan_bus(struct pci_controller_info *p, | 798 | static void pbm_scan_bus(struct pci_controller_info *p, |
799 | struct pci_pbm_info *pbm) | 799 | struct pci_pbm_info *pbm) |
800 | { | 800 | { |
801 | struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); | 801 | struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); |
802 | 802 | ||
803 | if (!cookie) { | 803 | if (!cookie) { |
804 | prom_printf("%s: Critical allocation failure.\n", pbm->name); | 804 | prom_printf("%s: Critical allocation failure.\n", pbm->name); |
@@ -806,7 +806,6 @@ static void pbm_scan_bus(struct pci_controller_info *p, | |||
806 | } | 806 | } |
807 | 807 | ||
808 | /* All we care about is the PBM. */ | 808 | /* All we care about is the PBM. */ |
809 | memset(cookie, 0, sizeof(*cookie)); | ||
810 | cookie->pbm = pbm; | 809 | cookie->pbm = pbm; |
811 | 810 | ||
812 | pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); | 811 | pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); |
@@ -1048,12 +1047,11 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | |||
1048 | /* Allocate and initialize the free area map. */ | 1047 | /* Allocate and initialize the free area map. */ |
1049 | sz = num_tsb_entries / 8; | 1048 | sz = num_tsb_entries / 8; |
1050 | sz = (sz + 7UL) & ~7UL; | 1049 | sz = (sz + 7UL) & ~7UL; |
1051 | iommu->arena.map = kmalloc(sz, GFP_KERNEL); | 1050 | iommu->arena.map = kzalloc(sz, GFP_KERNEL); |
1052 | if (!iommu->arena.map) { | 1051 | if (!iommu->arena.map) { |
1053 | prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); | 1052 | prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); |
1054 | prom_halt(); | 1053 | prom_halt(); |
1055 | } | 1054 | } |
1056 | memset(iommu->arena.map, 0, sz); | ||
1057 | iommu->arena.limit = num_tsb_entries; | 1055 | iommu->arena.limit = num_tsb_entries; |
1058 | 1056 | ||
1059 | sz = probe_existing_entries(pbm, iommu); | 1057 | sz = probe_existing_entries(pbm, iommu); |
@@ -1164,24 +1162,20 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) | |||
1164 | per_cpu(pci_iommu_batch, i).pglist = (u64 *) page; | 1162 | per_cpu(pci_iommu_batch, i).pglist = (u64 *) page; |
1165 | } | 1163 | } |
1166 | 1164 | ||
1167 | p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 1165 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); |
1168 | if (!p) | 1166 | if (!p) |
1169 | goto fatal_memory_error; | 1167 | goto fatal_memory_error; |
1170 | 1168 | ||
1171 | memset(p, 0, sizeof(*p)); | 1169 | iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); |
1172 | |||
1173 | iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); | ||
1174 | if (!iommu) | 1170 | if (!iommu) |
1175 | goto fatal_memory_error; | 1171 | goto fatal_memory_error; |
1176 | 1172 | ||
1177 | memset(iommu, 0, sizeof(*iommu)); | ||
1178 | p->pbm_A.iommu = iommu; | 1173 | p->pbm_A.iommu = iommu; |
1179 | 1174 | ||
1180 | iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); | 1175 | iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); |
1181 | if (!iommu) | 1176 | if (!iommu) |
1182 | goto fatal_memory_error; | 1177 | goto fatal_memory_error; |
1183 | 1178 | ||
1184 | memset(iommu, 0, sizeof(*iommu)); | ||
1185 | p->pbm_B.iommu = iommu; | 1179 | p->pbm_B.iommu = iommu; |
1186 | 1180 | ||
1187 | p->next = pci_controller_root; | 1181 | p->next = pci_controller_root; |
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index d31975e6d6f6..81111a12f0a8 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c | |||
@@ -202,7 +202,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) | |||
202 | #endif | 202 | #endif |
203 | if (request == PTRACE_TRACEME) { | 203 | if (request == PTRACE_TRACEME) { |
204 | ret = ptrace_traceme(); | 204 | ret = ptrace_traceme(); |
205 | pt_succ_return(regs, 0); | 205 | if (ret < 0) |
206 | pt_error_return(regs, -ret); | ||
207 | else | ||
208 | pt_succ_return(regs, 0); | ||
206 | goto out; | 209 | goto out; |
207 | } | 210 | } |
208 | 211 | ||
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 3522cd66f3bb..079d18a11d24 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
@@ -165,14 +165,26 @@ rtrap: | |||
165 | __handle_softirq_continue: | 165 | __handle_softirq_continue: |
166 | rtrap_xcall: | 166 | rtrap_xcall: |
167 | sethi %hi(0xf << 20), %l4 | 167 | sethi %hi(0xf << 20), %l4 |
168 | andcc %l1, TSTATE_PRIV, %l3 | ||
169 | and %l1, %l4, %l4 | 168 | and %l1, %l4, %l4 |
169 | andn %l1, %l4, %l1 | ||
170 | srl %l4, 20, %l4 | ||
171 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
172 | brnz,pn %l4, rtrap_no_irq_enable | ||
173 | nop | ||
174 | call trace_hardirqs_on | ||
175 | nop | ||
176 | wrpr %l4, %pil | ||
177 | rtrap_no_irq_enable: | ||
178 | #endif | ||
179 | andcc %l1, TSTATE_PRIV, %l3 | ||
170 | bne,pn %icc, to_kernel | 180 | bne,pn %icc, to_kernel |
171 | andn %l1, %l4, %l1 | 181 | nop |
172 | 182 | ||
173 | /* We must hold IRQs off and atomically test schedule+signal | 183 | /* We must hold IRQs off and atomically test schedule+signal |
174 | * state, then hold them off all the way back to userspace. | 184 | * state, then hold them off all the way back to userspace. |
175 | * If we are returning to kernel, none of this matters. | 185 | * If we are returning to kernel, none of this matters. Note |
186 | * that we are disabling interrupts via PSTATE_IE, not using | ||
187 | * %pil. | ||
176 | * | 188 | * |
177 | * If we do not do this, there is a window where we would do | 189 | * If we do not do this, there is a window where we would do |
178 | * the tests, later the signal/resched event arrives but we do | 190 | * the tests, later the signal/resched event arrives but we do |
@@ -256,7 +268,6 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 | |||
256 | 268 | ||
257 | ld [%sp + PTREGS_OFF + PT_V9_Y], %o3 | 269 | ld [%sp + PTREGS_OFF + PT_V9_Y], %o3 |
258 | wr %o3, %g0, %y | 270 | wr %o3, %g0, %y |
259 | srl %l4, 20, %l4 | ||
260 | wrpr %l4, 0x0, %pil | 271 | wrpr %l4, 0x0, %pil |
261 | wrpr %g0, 0x1, %tl | 272 | wrpr %g0, 0x1, %tl |
262 | wrpr %l1, %g0, %tstate | 273 | wrpr %l1, %g0, %tstate |
@@ -374,8 +385,8 @@ to_kernel: | |||
374 | ldx [%g6 + TI_FLAGS], %l5 | 385 | ldx [%g6 + TI_FLAGS], %l5 |
375 | andcc %l5, _TIF_NEED_RESCHED, %g0 | 386 | andcc %l5, _TIF_NEED_RESCHED, %g0 |
376 | be,pt %xcc, kern_fpucheck | 387 | be,pt %xcc, kern_fpucheck |
377 | srl %l4, 20, %l5 | 388 | nop |
378 | cmp %l5, 0 | 389 | cmp %l4, 0 |
379 | bne,pn %xcc, kern_fpucheck | 390 | bne,pn %xcc, kern_fpucheck |
380 | sethi %hi(PREEMPT_ACTIVE), %l6 | 391 | sethi %hi(PREEMPT_ACTIVE), %l6 |
381 | stw %l6, [%g6 + TI_PRE_COUNT] | 392 | stw %l6, [%g6 + TI_PRE_COUNT] |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index cc09d8266414..fc99f7b8012f 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -1388,7 +1388,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
1388 | { | 1388 | { |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | int __devinit __cpu_up(unsigned int cpu) | 1391 | int __cpuinit __cpu_up(unsigned int cpu) |
1392 | { | 1392 | { |
1393 | int ret = smp_boot_one_cpu(cpu); | 1393 | int ret = smp_boot_one_cpu(cpu); |
1394 | 1394 | ||
@@ -1447,11 +1447,8 @@ void __init setup_per_cpu_areas(void) | |||
1447 | char *ptr; | 1447 | char *ptr; |
1448 | 1448 | ||
1449 | /* Copy section for each CPU (we discard the original) */ | 1449 | /* Copy section for each CPU (we discard the original) */ |
1450 | goal = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); | 1450 | goal = PERCPU_ENOUGH_ROOM; |
1451 | #ifdef CONFIG_MODULES | 1451 | |
1452 | if (goal < PERCPU_ENOUGH_ROOM) | ||
1453 | goal = PERCPU_ENOUGH_ROOM; | ||
1454 | #endif | ||
1455 | __per_cpu_shift = 0; | 1452 | __per_cpu_shift = 0; |
1456 | for (size = 1UL; size < goal; size <<= 1UL) | 1453 | for (size = 1UL; size < goal; size <<= 1UL) |
1457 | __per_cpu_shift++; | 1454 | __per_cpu_shift++; |
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c new file mode 100644 index 000000000000..c4d15f2762b9 --- /dev/null +++ b/arch/sparc64/kernel/stacktrace.c | |||
@@ -0,0 +1,41 @@ | |||
1 | #include <linux/sched.h> | ||
2 | #include <linux/stacktrace.h> | ||
3 | #include <linux/thread_info.h> | ||
4 | #include <asm/ptrace.h> | ||
5 | |||
6 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | ||
7 | { | ||
8 | unsigned long ksp, fp, thread_base; | ||
9 | struct thread_info *tp; | ||
10 | |||
11 | if (!task) | ||
12 | task = current; | ||
13 | tp = task_thread_info(task); | ||
14 | if (task == current) { | ||
15 | flushw_all(); | ||
16 | __asm__ __volatile__( | ||
17 | "mov %%fp, %0" | ||
18 | : "=r" (ksp) | ||
19 | ); | ||
20 | } else | ||
21 | ksp = tp->ksp; | ||
22 | |||
23 | fp = ksp + STACK_BIAS; | ||
24 | thread_base = (unsigned long) tp; | ||
25 | do { | ||
26 | struct reg_window *rw; | ||
27 | |||
28 | /* Bogus frame pointer? */ | ||
29 | if (fp < (thread_base + sizeof(struct thread_info)) || | ||
30 | fp >= (thread_base + THREAD_SIZE)) | ||
31 | break; | ||
32 | |||
33 | rw = (struct reg_window *) fp; | ||
34 | if (trace->skip > 0) | ||
35 | trace->skip--; | ||
36 | else | ||
37 | trace->entries[trace->nr_entries++] = rw->ins[7]; | ||
38 | |||
39 | fp = rw->ins[6] + STACK_BIAS; | ||
40 | } while (trace->nr_entries < trace->max_entries); | ||
41 | } | ||
diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S index 49703c3c5769..405855dd886b 100644 --- a/arch/sparc64/kernel/sun4v_ivec.S +++ b/arch/sparc64/kernel/sun4v_ivec.S | |||
@@ -190,7 +190,10 @@ sun4v_res_mondo: | |||
190 | mov %g1, %g4 | 190 | mov %g1, %g4 |
191 | ba,pt %xcc, etrap_irq | 191 | ba,pt %xcc, etrap_irq |
192 | rd %pc, %g7 | 192 | rd %pc, %g7 |
193 | 193 | #ifdef CONFIG_TRACE_IRQFLAGS | |
194 | call trace_hardirqs_off | ||
195 | nop | ||
196 | #endif | ||
194 | /* Log the event. */ | 197 | /* Log the event. */ |
195 | add %sp, PTREGS_OFF, %o0 | 198 | add %sp, PTREGS_OFF, %o0 |
196 | call sun4v_resum_error | 199 | call sun4v_resum_error |
@@ -216,7 +219,10 @@ sun4v_res_mondo_queue_full: | |||
216 | wrpr %g0, 15, %pil | 219 | wrpr %g0, 15, %pil |
217 | ba,pt %xcc, etrap_irq | 220 | ba,pt %xcc, etrap_irq |
218 | rd %pc, %g7 | 221 | rd %pc, %g7 |
219 | 222 | #ifdef CONFIG_TRACE_IRQFLAGS | |
223 | call trace_hardirqs_off | ||
224 | nop | ||
225 | #endif | ||
220 | call sun4v_resum_overflow | 226 | call sun4v_resum_overflow |
221 | add %sp, PTREGS_OFF, %o0 | 227 | add %sp, PTREGS_OFF, %o0 |
222 | 228 | ||
@@ -295,7 +301,10 @@ sun4v_nonres_mondo: | |||
295 | mov %g1, %g4 | 301 | mov %g1, %g4 |
296 | ba,pt %xcc, etrap_irq | 302 | ba,pt %xcc, etrap_irq |
297 | rd %pc, %g7 | 303 | rd %pc, %g7 |
298 | 304 | #ifdef CONFIG_TRACE_IRQFLAGS | |
305 | call trace_hardirqs_off | ||
306 | nop | ||
307 | #endif | ||
299 | /* Log the event. */ | 308 | /* Log the event. */ |
300 | add %sp, PTREGS_OFF, %o0 | 309 | add %sp, PTREGS_OFF, %o0 |
301 | call sun4v_nonresum_error | 310 | call sun4v_nonresum_error |
@@ -321,7 +330,10 @@ sun4v_nonres_mondo_queue_full: | |||
321 | wrpr %g0, 15, %pil | 330 | wrpr %g0, 15, %pil |
322 | ba,pt %xcc, etrap_irq | 331 | ba,pt %xcc, etrap_irq |
323 | rd %pc, %g7 | 332 | rd %pc, %g7 |
324 | 333 | #ifdef CONFIG_TRACE_IRQFLAGS | |
334 | call trace_hardirqs_off | ||
335 | nop | ||
336 | #endif | ||
325 | call sun4v_nonresum_overflow | 337 | call sun4v_nonresum_overflow |
326 | add %sp, PTREGS_OFF, %o0 | 338 | add %sp, PTREGS_OFF, %o0 |
327 | 339 | ||
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 7da72d3b322a..2ebc2c051383 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c | |||
@@ -83,7 +83,7 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of | |||
83 | file = fget(fd); | 83 | file = fget(fd); |
84 | if (!file) | 84 | if (!file) |
85 | goto out; | 85 | goto out; |
86 | inode = file->f_dentry->d_inode; | 86 | inode = file->f_path.dentry->d_inode; |
87 | if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { | 87 | if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { |
88 | flags |= MAP_ANONYMOUS; | 88 | flags |= MAP_ANONYMOUS; |
89 | fput(file); | 89 | fput(file); |
@@ -615,7 +615,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) | |||
615 | if (!file) | 615 | if (!file) |
616 | return 0; | 616 | return 0; |
617 | 617 | ||
618 | inode = file->f_dentry->d_inode; | 618 | inode = file->f_path.dentry->d_inode; |
619 | 619 | ||
620 | socket = SOCKET_I(inode); | 620 | socket = SOCKET_I(inode); |
621 | local.sin_family = AF_INET; | 621 | local.sin_family = AF_INET; |
@@ -1055,7 +1055,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) | |||
1055 | break; | 1055 | break; |
1056 | case 2: | 1056 | case 2: |
1057 | rval = -EFAULT; | 1057 | rval = -EFAULT; |
1058 | kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3, | 1058 | kmbuf = kmalloc(sizeof(struct msgbuf) + arg3, |
1059 | GFP_KERNEL); | 1059 | GFP_KERNEL); |
1060 | if (!kmbuf) | 1060 | if (!kmbuf) |
1061 | break; | 1061 | break; |
@@ -1078,7 +1078,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) | |||
1078 | break; | 1078 | break; |
1079 | case 3: | 1079 | case 3: |
1080 | rval = -EFAULT; | 1080 | rval = -EFAULT; |
1081 | kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3, | 1081 | kmbuf = kmalloc(sizeof(struct msgbuf) + arg3, |
1082 | GFP_KERNEL); | 1082 | GFP_KERNEL); |
1083 | if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2, | 1083 | if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2, |
1084 | kmbuf, arg3)) | 1084 | kmbuf, arg3)) |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index fe1796c939c3..ad67784292db 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/sched.h> /* for jiffies */ | 13 | #include <linux/sched.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/kallsyms.h> | 15 | #include <linux/kallsyms.h> |
16 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
@@ -1873,6 +1873,16 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) | |||
1873 | 1873 | ||
1874 | put_cpu(); | 1874 | put_cpu(); |
1875 | 1875 | ||
1876 | if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) { | ||
1877 | /* If err_type is 0x4, it's a powerdown request. Do | ||
1878 | * not do the usual resumable error log because that | ||
1879 | * makes it look like some abnormal error. | ||
1880 | */ | ||
1881 | printk(KERN_INFO "Power down request...\n"); | ||
1882 | kill_cad_pid(SIGINT, 1); | ||
1883 | return; | ||
1884 | } | ||
1885 | |||
1876 | sun4v_log_error(regs, &local_copy, cpu, | 1886 | sun4v_log_error(regs, &local_copy, cpu, |
1877 | KERN_ERR "RESUMABLE ERROR", | 1887 | KERN_ERR "RESUMABLE ERROR", |
1878 | &sun4v_resum_oflow_cnt); | 1888 | &sun4v_resum_oflow_cnt); |
@@ -2261,8 +2271,12 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2261 | do_exit(SIGSEGV); | 2271 | do_exit(SIGSEGV); |
2262 | } | 2272 | } |
2263 | 2273 | ||
2274 | #define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) | ||
2275 | #define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) | ||
2276 | |||
2264 | extern int handle_popc(u32 insn, struct pt_regs *regs); | 2277 | extern int handle_popc(u32 insn, struct pt_regs *regs); |
2265 | extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); | 2278 | extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); |
2279 | extern int vis_emul(struct pt_regs *, unsigned int); | ||
2266 | 2280 | ||
2267 | void do_illegal_instruction(struct pt_regs *regs) | 2281 | void do_illegal_instruction(struct pt_regs *regs) |
2268 | { | 2282 | { |
@@ -2287,10 +2301,18 @@ void do_illegal_instruction(struct pt_regs *regs) | |||
2287 | if (handle_ldf_stq(insn, regs)) | 2301 | if (handle_ldf_stq(insn, regs)) |
2288 | return; | 2302 | return; |
2289 | } else if (tlb_type == hypervisor) { | 2303 | } else if (tlb_type == hypervisor) { |
2290 | extern int vis_emul(struct pt_regs *, unsigned int); | 2304 | if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) { |
2305 | if (!vis_emul(regs, insn)) | ||
2306 | return; | ||
2307 | } else { | ||
2308 | struct fpustate *f = FPUSTATE; | ||
2291 | 2309 | ||
2292 | if (!vis_emul(regs, insn)) | 2310 | /* XXX maybe verify XFSR bits like |
2293 | return; | 2311 | * XXX do_fpother() does? |
2312 | */ | ||
2313 | if (do_mathemu(regs, f)) | ||
2314 | return; | ||
2315 | } | ||
2294 | } | 2316 | } |
2295 | } | 2317 | } |
2296 | info.si_signo = SIGILL; | 2318 | info.si_signo = SIGILL; |
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index a9b765271b85..bc18d480dd1c 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c | |||
@@ -243,7 +243,7 @@ static inline int ok_for_kernel(unsigned int insn) | |||
243 | return !floating_point_load_or_store_p(insn); | 243 | return !floating_point_load_or_store_p(insn); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void kernel_mna_trap_fault(void) | 246 | static void kernel_mna_trap_fault(int fixup_tstate_asi) |
247 | { | 247 | { |
248 | struct pt_regs *regs = current_thread_info()->kern_una_regs; | 248 | struct pt_regs *regs = current_thread_info()->kern_una_regs; |
249 | unsigned int insn = current_thread_info()->kern_una_insn; | 249 | unsigned int insn = current_thread_info()->kern_una_insn; |
@@ -274,18 +274,15 @@ static void kernel_mna_trap_fault(void) | |||
274 | regs->tpc = entry->fixup; | 274 | regs->tpc = entry->fixup; |
275 | regs->tnpc = regs->tpc + 4; | 275 | regs->tnpc = regs->tpc + 4; |
276 | 276 | ||
277 | regs->tstate &= ~TSTATE_ASI; | 277 | if (fixup_tstate_asi) { |
278 | regs->tstate |= (ASI_AIUS << 24UL); | 278 | regs->tstate &= ~TSTATE_ASI; |
279 | regs->tstate |= (ASI_AIUS << 24UL); | ||
280 | } | ||
279 | } | 281 | } |
280 | 282 | ||
281 | asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | 283 | static void log_unaligned(struct pt_regs *regs) |
282 | { | 284 | { |
283 | static unsigned long count, last_time; | 285 | static unsigned long count, last_time; |
284 | enum direction dir = decode_direction(insn); | ||
285 | int size = decode_access_size(insn); | ||
286 | |||
287 | current_thread_info()->kern_una_regs = regs; | ||
288 | current_thread_info()->kern_una_insn = insn; | ||
289 | 286 | ||
290 | if (jiffies - last_time > 5 * HZ) | 287 | if (jiffies - last_time > 5 * HZ) |
291 | count = 0; | 288 | count = 0; |
@@ -295,6 +292,28 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
295 | printk("Kernel unaligned access at TPC[%lx] ", regs->tpc); | 292 | printk("Kernel unaligned access at TPC[%lx] ", regs->tpc); |
296 | print_symbol("%s\n", regs->tpc); | 293 | print_symbol("%s\n", regs->tpc); |
297 | } | 294 | } |
295 | } | ||
296 | |||
297 | asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | ||
298 | { | ||
299 | enum direction dir = decode_direction(insn); | ||
300 | int size = decode_access_size(insn); | ||
301 | int orig_asi, asi; | ||
302 | |||
303 | current_thread_info()->kern_una_regs = regs; | ||
304 | current_thread_info()->kern_una_insn = insn; | ||
305 | |||
306 | orig_asi = asi = decode_asi(insn, regs); | ||
307 | |||
308 | /* If this is a {get,put}_user() on an unaligned userspace pointer, | ||
309 | * just signal a fault and do not log the event. | ||
310 | */ | ||
311 | if (asi == ASI_AIUS) { | ||
312 | kernel_mna_trap_fault(0); | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | log_unaligned(regs); | ||
298 | 317 | ||
299 | if (!ok_for_kernel(insn) || dir == both) { | 318 | if (!ok_for_kernel(insn) || dir == both) { |
300 | printk("Unsupported unaligned load/store trap for kernel " | 319 | printk("Unsupported unaligned load/store trap for kernel " |
@@ -302,10 +321,10 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
302 | unaligned_panic("Kernel does fpu/atomic " | 321 | unaligned_panic("Kernel does fpu/atomic " |
303 | "unaligned load/store.", regs); | 322 | "unaligned load/store.", regs); |
304 | 323 | ||
305 | kernel_mna_trap_fault(); | 324 | kernel_mna_trap_fault(0); |
306 | } else { | 325 | } else { |
307 | unsigned long addr, *reg_addr; | 326 | unsigned long addr, *reg_addr; |
308 | int orig_asi, asi, err; | 327 | int err; |
309 | 328 | ||
310 | addr = compute_effective_address(regs, insn, | 329 | addr = compute_effective_address(regs, insn, |
311 | ((insn >> 25) & 0x1f)); | 330 | ((insn >> 25) & 0x1f)); |
@@ -315,7 +334,6 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
315 | regs->tpc, dirstrings[dir], addr, size, | 334 | regs->tpc, dirstrings[dir], addr, size, |
316 | regs->u_regs[UREG_RETPC]); | 335 | regs->u_regs[UREG_RETPC]); |
317 | #endif | 336 | #endif |
318 | orig_asi = asi = decode_asi(insn, regs); | ||
319 | switch (asi) { | 337 | switch (asi) { |
320 | case ASI_NL: | 338 | case ASI_NL: |
321 | case ASI_AIUPL: | 339 | case ASI_AIUPL: |
@@ -365,7 +383,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
365 | /* Not reached... */ | 383 | /* Not reached... */ |
366 | } | 384 | } |
367 | if (unlikely(err)) | 385 | if (unlikely(err)) |
368 | kernel_mna_trap_fault(); | 386 | kernel_mna_trap_fault(1); |
369 | else | 387 | else |
370 | advance(regs); | 388 | advance(regs); |
371 | } | 389 | } |
diff --git a/arch/sparc64/kernel/visemul.c b/arch/sparc64/kernel/visemul.c index 84fedaa38aae..c3fd64706b53 100644 --- a/arch/sparc64/kernel/visemul.c +++ b/arch/sparc64/kernel/visemul.c | |||
@@ -128,9 +128,6 @@ | |||
128 | /* 001001100 - Permute bytes as specified by GSR.MASK */ | 128 | /* 001001100 - Permute bytes as specified by GSR.MASK */ |
129 | #define BSHUFFLE_OPF 0x04c | 129 | #define BSHUFFLE_OPF 0x04c |
130 | 130 | ||
131 | #define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) | ||
132 | #define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) | ||
133 | |||
134 | #define VIS_OPF_SHIFT 5 | 131 | #define VIS_OPF_SHIFT 5 |
135 | #define VIS_OPF_MASK (0x1ff << VIS_OPF_SHIFT) | 132 | #define VIS_OPF_MASK (0x1ff << VIS_OPF_SHIFT) |
136 | 133 | ||
@@ -810,9 +807,6 @@ int vis_emul(struct pt_regs *regs, unsigned int insn) | |||
810 | if (get_user(insn, (u32 __user *) pc)) | 807 | if (get_user(insn, (u32 __user *) pc)) |
811 | return -EFAULT; | 808 | return -EFAULT; |
812 | 809 | ||
813 | if ((insn & VIS_OPCODE_MASK) != VIS_OPCODE_VAL) | ||
814 | return -EINVAL; | ||
815 | |||
816 | opf = (insn & VIS_OPF_MASK) >> VIS_OPF_SHIFT; | 810 | opf = (insn & VIS_OPF_MASK) >> VIS_OPF_SHIFT; |
817 | switch (opf) { | 811 | switch (opf) { |
818 | default: | 812 | default: |
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index bd9de8c2a2aa..4a6063f33e7a 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S | |||
@@ -13,6 +13,7 @@ SECTIONS | |||
13 | . = 0x4000; | 13 | . = 0x4000; |
14 | .text 0x0000000000404000 : | 14 | .text 0x0000000000404000 : |
15 | { | 15 | { |
16 | _text = .; | ||
16 | *(.text) | 17 | *(.text) |
17 | SCHED_TEXT | 18 | SCHED_TEXT |
18 | LOCK_TEXT | 19 | LOCK_TEXT |