aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/align.c36
-rw-r--r--arch/powerpc/kernel/asm-offsets.c4
-rw-r--r--arch/powerpc/kernel/ftrace.c5
-rw-r--r--arch/powerpc/kernel/head_32.S15
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/pci-common.c22
-rw-r--r--arch/powerpc/kernel/prom.c5
-rw-r--r--arch/powerpc/kernel/vio.c7
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,
367static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, 367static 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 *) &current->thread.TS_FPR(reg); 370 char *ptr0 = (char *) &current->thread.TS_FPR(reg);
371 int i, ret; 371 char *ptr1 = (char *) &current->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 *) &current->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 *) &current->thread.TS_FPR(reg);
653 else
654 ptr = (char *) &current->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 */
516BEGIN_FTR_SECTION
517 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
518END_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 */
593BEGIN_FTR_SECTION
594 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
595END_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 */
664BEGIN_FTR_SECTION
665 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
666END_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
519static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page, 519static 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++)