diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/align.c | 36 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/ftrace.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_32.S | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 22 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/vio.c | 7 |
8 files changed, 62 insertions, 34 deletions
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 5af4e9b2dbe2..73cb6a3229ae 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c | |||
@@ -367,27 +367,24 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, | |||
367 | static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, | 367 | static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, |
368 | unsigned int flags) | 368 | unsigned int flags) |
369 | { | 369 | { |
370 | char *ptr = (char *) ¤t->thread.TS_FPR(reg); | 370 | char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); |
371 | int i, ret; | 371 | char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); |
372 | int i, ret, sw = 0; | ||
372 | 373 | ||
373 | if (!(flags & F)) | 374 | if (!(flags & F)) |
374 | return 0; | 375 | return 0; |
375 | if (reg & 1) | 376 | if (reg & 1) |
376 | return 0; /* invalid form: FRS/FRT must be even */ | 377 | return 0; /* invalid form: FRS/FRT must be even */ |
377 | if (!(flags & SW)) { | 378 | if (flags & SW) |
378 | /* not byte-swapped - easy */ | 379 | sw = 7; |
379 | if (!(flags & ST)) | 380 | ret = 0; |
380 | ret = __copy_from_user(ptr, addr, 16); | 381 | for (i = 0; i < 8; ++i) { |
381 | else | 382 | if (!(flags & ST)) { |
382 | ret = __copy_to_user(addr, ptr, 16); | 383 | ret |= __get_user(ptr0[i^sw], addr + i); |
383 | } else { | 384 | ret |= __get_user(ptr1[i^sw], addr + i + 8); |
384 | /* each FPR value is byte-swapped separately */ | 385 | } else { |
385 | ret = 0; | 386 | ret |= __put_user(ptr0[i^sw], addr + i); |
386 | for (i = 0; i < 16; ++i) { | 387 | ret |= __put_user(ptr1[i^sw], addr + i + 8); |
387 | if (!(flags & ST)) | ||
388 | ret |= __get_user(ptr[i^7], addr + i); | ||
389 | else | ||
390 | ret |= __put_user(ptr[i^7], addr + i); | ||
391 | } | 388 | } |
392 | } | 389 | } |
393 | if (ret) | 390 | if (ret) |
@@ -646,11 +643,16 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, | |||
646 | unsigned int areg, struct pt_regs *regs, | 643 | unsigned int areg, struct pt_regs *regs, |
647 | unsigned int flags, unsigned int length) | 644 | unsigned int flags, unsigned int length) |
648 | { | 645 | { |
649 | char *ptr = (char *) ¤t->thread.TS_FPR(reg); | 646 | char *ptr; |
650 | int ret = 0; | 647 | int ret = 0; |
651 | 648 | ||
652 | flush_vsx_to_thread(current); | 649 | flush_vsx_to_thread(current); |
653 | 650 | ||
651 | if (reg < 32) | ||
652 | ptr = (char *) ¤t->thread.TS_FPR(reg); | ||
653 | else | ||
654 | ptr = (char *) ¤t->thread.vr[reg - 32]; | ||
655 | |||
654 | if (flags & ST) | 656 | if (flags & ST) |
655 | ret = __copy_to_user(addr, ptr, length); | 657 | ret = __copy_to_user(addr, ptr, length); |
656 | else { | 658 | else { |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 19ee491e9e23..42fe4da4e8ae 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -49,7 +49,7 @@ | |||
49 | #include <asm/iseries/alpaca.h> | 49 | #include <asm/iseries/alpaca.h> |
50 | #endif | 50 | #endif |
51 | #ifdef CONFIG_KVM | 51 | #ifdef CONFIG_KVM |
52 | #include <asm/kvm_44x.h> | 52 | #include <linux/kvm_host.h> |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | 55 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) |
@@ -361,8 +361,6 @@ int main(void) | |||
361 | DEFINE(PTE_SIZE, sizeof(pte_t)); | 361 | DEFINE(PTE_SIZE, sizeof(pte_t)); |
362 | 362 | ||
363 | #ifdef CONFIG_KVM | 363 | #ifdef CONFIG_KVM |
364 | DEFINE(TLBE_BYTES, sizeof(struct kvmppc_44x_tlbe)); | ||
365 | |||
366 | DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); | 364 | DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); |
367 | DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); | 365 | DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); |
368 | DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); | 366 | DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); |
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 5355244c99ff..60c60ccf5e3c 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
@@ -195,8 +195,9 @@ __ftrace_make_nop(struct module *mod, | |||
195 | return -EINVAL; | 195 | return -EINVAL; |
196 | } | 196 | } |
197 | 197 | ||
198 | offset = (unsigned)((unsigned short)jmp[0]) << 16 | | 198 | /* The bottom half is signed extended */ |
199 | (unsigned)((unsigned short)jmp[1]); | 199 | offset = ((unsigned)((unsigned short)jmp[0]) << 16) + |
200 | (int)((short)jmp[1]); | ||
200 | 201 | ||
201 | DEBUGP(" %x ", offset); | 202 | DEBUGP(" %x ", offset); |
202 | 203 | ||
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index a1c4cfd25ded..d794a637e421 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
@@ -511,8 +511,11 @@ InstructionTLBMiss: | |||
511 | and r1,r1,r2 /* writable if _RW and _DIRTY */ | 511 | and r1,r1,r2 /* writable if _RW and _DIRTY */ |
512 | rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ | 512 | rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ |
513 | rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ | 513 | rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ |
514 | ori r1,r1,0xe14 /* clear out reserved bits and M */ | 514 | ori r1,r1,0xe04 /* clear out reserved bits */ |
515 | andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ | 515 | andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ |
516 | BEGIN_FTR_SECTION | ||
517 | rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ | ||
518 | END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) | ||
516 | mtspr SPRN_RPA,r1 | 519 | mtspr SPRN_RPA,r1 |
517 | mfspr r3,SPRN_IMISS | 520 | mfspr r3,SPRN_IMISS |
518 | tlbli r3 | 521 | tlbli r3 |
@@ -585,8 +588,11 @@ DataLoadTLBMiss: | |||
585 | and r1,r1,r2 /* writable if _RW and _DIRTY */ | 588 | and r1,r1,r2 /* writable if _RW and _DIRTY */ |
586 | rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ | 589 | rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ |
587 | rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ | 590 | rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ |
588 | ori r1,r1,0xe14 /* clear out reserved bits and M */ | 591 | ori r1,r1,0xe04 /* clear out reserved bits */ |
589 | andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ | 592 | andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ |
593 | BEGIN_FTR_SECTION | ||
594 | rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ | ||
595 | END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) | ||
590 | mtspr SPRN_RPA,r1 | 596 | mtspr SPRN_RPA,r1 |
591 | mfspr r3,SPRN_DMISS | 597 | mfspr r3,SPRN_DMISS |
592 | tlbld r3 | 598 | tlbld r3 |
@@ -653,8 +659,11 @@ DataStoreTLBMiss: | |||
653 | stw r3,0(r2) /* update PTE (accessed/dirty bits) */ | 659 | stw r3,0(r2) /* update PTE (accessed/dirty bits) */ |
654 | /* Convert linux-style PTE to low word of PPC-style PTE */ | 660 | /* Convert linux-style PTE to low word of PPC-style PTE */ |
655 | rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ | 661 | rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ |
656 | li r1,0xe15 /* clear out reserved bits and M */ | 662 | li r1,0xe05 /* clear out reserved bits & PP lsb */ |
657 | andc r1,r3,r1 /* PP = user? 2: 0 */ | 663 | andc r1,r3,r1 /* PP = user? 2: 0 */ |
664 | BEGIN_FTR_SECTION | ||
665 | rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ | ||
666 | END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) | ||
658 | mtspr SPRN_RPA,r1 | 667 | mtspr SPRN_RPA,r1 |
659 | mfspr r3,SPRN_DMISS | 668 | mfspr r3,SPRN_DMISS |
660 | tlbld r3 | 669 | tlbld r3 |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 23b8b5e36f98..17efb7118db1 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -190,7 +190,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
190 | seq_printf(p, "%3d: ", i); | 190 | seq_printf(p, "%3d: ", i); |
191 | #ifdef CONFIG_SMP | 191 | #ifdef CONFIG_SMP |
192 | for_each_online_cpu(j) | 192 | for_each_online_cpu(j) |
193 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 193 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); |
194 | #else | 194 | #else |
195 | seq_printf(p, "%10u ", kstat_irqs(i)); | 195 | seq_printf(p, "%10u ", kstat_irqs(i)); |
196 | #endif /* CONFIG_SMP */ | 196 | #endif /* CONFIG_SMP */ |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index da5a3855a0c4..0f4181272311 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -16,8 +16,6 @@ | |||
16 | * 2 of the License, or (at your option) any later version. | 16 | * 2 of the License, or (at your option) any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define DEBUG | ||
20 | |||
21 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
22 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
23 | #include <linux/string.h> | 21 | #include <linux/string.h> |
@@ -258,7 +256,8 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
258 | } else { | 256 | } else { |
259 | pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", | 257 | pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", |
260 | oirq.size, oirq.specifier[0], oirq.specifier[1], | 258 | oirq.size, oirq.specifier[0], oirq.specifier[1], |
261 | oirq.controller->full_name); | 259 | oirq.controller ? oirq.controller->full_name : |
260 | "<default>"); | ||
262 | 261 | ||
263 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | 262 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
264 | oirq.size); | 263 | oirq.size); |
@@ -562,8 +561,21 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, | |||
562 | (unsigned long long)(offset + size - 1)); | 561 | (unsigned long long)(offset + size - 1)); |
563 | 562 | ||
564 | if (mmap_state == pci_mmap_mem) { | 563 | if (mmap_state == pci_mmap_mem) { |
565 | if ((offset + size) > hose->isa_mem_size) | 564 | /* Hack alert ! |
566 | return -ENXIO; | 565 | * |
566 | * Because X is lame and can fail starting if it gets an error trying | ||
567 | * to mmap legacy_mem (instead of just moving on without legacy memory | ||
568 | * access) we fake it here by giving it anonymous memory, effectively | ||
569 | * behaving just like /dev/zero | ||
570 | */ | ||
571 | if ((offset + size) > hose->isa_mem_size) { | ||
572 | printk(KERN_DEBUG | ||
573 | "Process %s (pid:%d) mapped non-existing PCI legacy memory for 0%04x:%02x\n", | ||
574 | current->comm, current->pid, pci_domain_nr(bus), bus->number); | ||
575 | if (vma->vm_flags & VM_SHARED) | ||
576 | return shmem_zero_setup(vma); | ||
577 | return 0; | ||
578 | } | ||
567 | offset += hose->isa_mem_phys; | 579 | offset += hose->isa_mem_phys; |
568 | } else { | 580 | } else { |
569 | unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; | 581 | unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index c09cffafb6ee..f00f83109ab3 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -590,6 +590,11 @@ static void __init check_cpu_slb_size(unsigned long node) | |||
590 | { | 590 | { |
591 | u32 *slb_size_ptr; | 591 | u32 *slb_size_ptr; |
592 | 592 | ||
593 | slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL); | ||
594 | if (slb_size_ptr != NULL) { | ||
595 | mmu_slb_size = *slb_size_ptr; | ||
596 | return; | ||
597 | } | ||
593 | slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL); | 598 | slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL); |
594 | if (slb_size_ptr != NULL) { | 599 | if (slb_size_ptr != NULL) { |
595 | mmu_slb_size = *slb_size_ptr; | 600 | mmu_slb_size = *slb_size_ptr; |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 94aa7b011b27..d3694498f3af 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -492,14 +492,14 @@ static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, | |||
492 | struct vio_dev *viodev = to_vio_dev(dev); | 492 | struct vio_dev *viodev = to_vio_dev(dev); |
493 | void *ret; | 493 | void *ret; |
494 | 494 | ||
495 | if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE))) { | 495 | if (vio_cmo_alloc(viodev, roundup(size, PAGE_SIZE))) { |
496 | atomic_inc(&viodev->cmo.allocs_failed); | 496 | atomic_inc(&viodev->cmo.allocs_failed); |
497 | return NULL; | 497 | return NULL; |
498 | } | 498 | } |
499 | 499 | ||
500 | ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag); | 500 | ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag); |
501 | if (unlikely(ret == NULL)) { | 501 | if (unlikely(ret == NULL)) { |
502 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); | 502 | vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); |
503 | atomic_inc(&viodev->cmo.allocs_failed); | 503 | atomic_inc(&viodev->cmo.allocs_failed); |
504 | } | 504 | } |
505 | 505 | ||
@@ -513,7 +513,7 @@ static void vio_dma_iommu_free_coherent(struct device *dev, size_t size, | |||
513 | 513 | ||
514 | dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle); | 514 | dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle); |
515 | 515 | ||
516 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); | 516 | vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); |
517 | } | 517 | } |
518 | 518 | ||
519 | static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page, | 519 | static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page, |
@@ -572,6 +572,7 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, | |||
572 | if (unlikely(!ret)) { | 572 | if (unlikely(!ret)) { |
573 | vio_cmo_dealloc(viodev, alloc_size); | 573 | vio_cmo_dealloc(viodev, alloc_size); |
574 | atomic_inc(&viodev->cmo.allocs_failed); | 574 | atomic_inc(&viodev->cmo.allocs_failed); |
575 | return ret; | ||
575 | } | 576 | } |
576 | 577 | ||
577 | for (sgl = sglist, count = 0; count < ret; count++, sgl++) | 578 | for (sgl = sglist, count = 0; count < ret; count++, sgl++) |