Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

Pull powerpc fixes from Ben Herrenschmidt:
 "A bit more endian problems found during testing of 3.13 and a few
  other simple fixes and regressions fixes"

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
  powerpc: Fix alignment of secondary cpu spin vars
  powerpc: Align p_end
  powernv/eeh: Add buffer for P7IOC hub error data
  powernv/eeh: Fix possible buffer overrun in ioda_eeh_phb_diag()
  powerpc: Make 64-bit non-VMX __copy_tofrom_user bi-endian
  powerpc: Make unaligned accesses endian-safe for powerpc
  powerpc: Fix bad stack check in exception entry
  powerpc/512x: dts: disable MPC5125 usb module
  powerpc/512x: dts: remove misplaced IRQ spec from 'soc' node (5125)
This commit is contained in:
Linus Torvalds 2013-12-30 10:22:57 -08:00
commit 6e4c61968b
7 changed files with 60 additions and 34 deletions

View File

@ -58,7 +58,6 @@ soc@80000000 {
compatible = "fsl,mpc5121-immr"; compatible = "fsl,mpc5121-immr";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
#interrupt-cells = <2>;
ranges = <0x0 0x80000000 0x400000>; ranges = <0x0 0x80000000 0x400000>;
reg = <0x80000000 0x400000>; reg = <0x80000000 0x400000>;
bus-frequency = <66000000>; // 66 MHz ips bus bus-frequency = <66000000>; // 66 MHz ips bus
@ -189,6 +188,10 @@ ioctl@a000 {
reg = <0xA000 0x1000>; reg = <0xA000 0x1000>;
}; };
// disable USB1 port
// TODO:
// correct pinmux config and fix USB3320 ulpi dependency
// before re-enabling it
usb@3000 { usb@3000 {
compatible = "fsl,mpc5121-usb2-dr"; compatible = "fsl,mpc5121-usb2-dr";
reg = <0x3000 0x400>; reg = <0x3000 0x400>;
@ -197,6 +200,7 @@ usb@3000 {
interrupts = <43 0x8>; interrupts = <43 0x8>;
dr_mode = "host"; dr_mode = "host";
phy_type = "ulpi"; phy_type = "ulpi";
status = "disabled";
}; };
// 5125 PSCs are not 52xx or 5121 PSC compatible // 5125 PSCs are not 52xx or 5121 PSC compatible

View File

@ -284,7 +284,7 @@ do_kvm_##n: \
subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
beq- 1f; \ beq- 1f; \
ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ 1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \
blt+ cr1,3f; /* abort if it is */ \ blt+ cr1,3f; /* abort if it is */ \
li r1,(n); /* will be reloaded later */ \ li r1,(n); /* will be reloaded later */ \
sth r1,PACA_TRAP_SAVE(r13); \ sth r1,PACA_TRAP_SAVE(r13); \

View File

@ -4,13 +4,18 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
/* /*
* The PowerPC can do unaligned accesses itself in big endian mode. * The PowerPC can do unaligned accesses itself based on its endian mode.
*/ */
#include <linux/unaligned/access_ok.h> #include <linux/unaligned/access_ok.h>
#include <linux/unaligned/generic.h> #include <linux/unaligned/generic.h>
#ifdef __LITTLE_ENDIAN__
#define get_unaligned __get_unaligned_le
#define put_unaligned __put_unaligned_le
#else
#define get_unaligned __get_unaligned_be #define get_unaligned __get_unaligned_be
#define put_unaligned __put_unaligned_be #define put_unaligned __put_unaligned_be
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_UNALIGNED_H */ #endif /* _ASM_POWERPC_UNALIGNED_H */

View File

@ -80,6 +80,7 @@ END_FTR_SECTION(0, 1)
* of the function that the cpu should jump to to continue * of the function that the cpu should jump to to continue
* initialization. * initialization.
*/ */
.balign 8
.globl __secondary_hold_spinloop .globl __secondary_hold_spinloop
__secondary_hold_spinloop: __secondary_hold_spinloop:
.llong 0x0 .llong 0x0
@ -470,6 +471,7 @@ _STATIC(__after_prom_start)
mtctr r8 mtctr r8
bctr bctr
.balign 8
p_end: .llong _end - _stext p_end: .llong _end - _stext
4: /* Now copy the rest of the kernel up to _end */ 4: /* Now copy the rest of the kernel up to _end */

View File

@ -9,6 +9,14 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/ppc_asm.h> #include <asm/ppc_asm.h>
#ifdef __BIG_ENDIAN__
#define sLd sld /* Shift towards low-numbered address. */
#define sHd srd /* Shift towards high-numbered address. */
#else
#define sLd srd /* Shift towards low-numbered address. */
#define sHd sld /* Shift towards high-numbered address. */
#endif
.align 7 .align 7
_GLOBAL(__copy_tofrom_user) _GLOBAL(__copy_tofrom_user)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
@ -118,10 +126,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
24: ld r9,0(r4) /* 3+2n loads, 2+2n stores */ 24: ld r9,0(r4) /* 3+2n loads, 2+2n stores */
25: ld r0,8(r4) 25: ld r0,8(r4)
sld r6,r9,r10 sLd r6,r9,r10
26: ldu r9,16(r4) 26: ldu r9,16(r4)
srd r7,r0,r11 sHd r7,r0,r11
sld r8,r0,r10 sLd r8,r0,r10
or r7,r7,r6 or r7,r7,r6
blt cr6,79f blt cr6,79f
27: ld r0,8(r4) 27: ld r0,8(r4)
@ -129,35 +137,35 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
28: ld r0,0(r4) /* 4+2n loads, 3+2n stores */ 28: ld r0,0(r4) /* 4+2n loads, 3+2n stores */
29: ldu r9,8(r4) 29: ldu r9,8(r4)
sld r8,r0,r10 sLd r8,r0,r10
addi r3,r3,-8 addi r3,r3,-8
blt cr6,5f blt cr6,5f
30: ld r0,8(r4) 30: ld r0,8(r4)
srd r12,r9,r11 sHd r12,r9,r11
sld r6,r9,r10 sLd r6,r9,r10
31: ldu r9,16(r4) 31: ldu r9,16(r4)
or r12,r8,r12 or r12,r8,r12
srd r7,r0,r11 sHd r7,r0,r11
sld r8,r0,r10 sLd r8,r0,r10
addi r3,r3,16 addi r3,r3,16
beq cr6,78f beq cr6,78f
1: or r7,r7,r6 1: or r7,r7,r6
32: ld r0,8(r4) 32: ld r0,8(r4)
76: std r12,8(r3) 76: std r12,8(r3)
2: srd r12,r9,r11 2: sHd r12,r9,r11
sld r6,r9,r10 sLd r6,r9,r10
33: ldu r9,16(r4) 33: ldu r9,16(r4)
or r12,r8,r12 or r12,r8,r12
77: stdu r7,16(r3) 77: stdu r7,16(r3)
srd r7,r0,r11 sHd r7,r0,r11
sld r8,r0,r10 sLd r8,r0,r10
bdnz 1b bdnz 1b
78: std r12,8(r3) 78: std r12,8(r3)
or r7,r7,r6 or r7,r7,r6
79: std r7,16(r3) 79: std r7,16(r3)
5: srd r12,r9,r11 5: sHd r12,r9,r11
or r12,r8,r12 or r12,r8,r12
80: std r12,24(r3) 80: std r12,24(r3)
bne 6f bne 6f
@ -165,23 +173,38 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
blr blr
6: cmpwi cr1,r5,8 6: cmpwi cr1,r5,8
addi r3,r3,32 addi r3,r3,32
sld r9,r9,r10 sLd r9,r9,r10
ble cr1,7f ble cr1,7f
34: ld r0,8(r4) 34: ld r0,8(r4)
srd r7,r0,r11 sHd r7,r0,r11
or r9,r7,r9 or r9,r7,r9
7: 7:
bf cr7*4+1,1f bf cr7*4+1,1f
#ifdef __BIG_ENDIAN__
rotldi r9,r9,32 rotldi r9,r9,32
#endif
94: stw r9,0(r3) 94: stw r9,0(r3)
#ifdef __LITTLE_ENDIAN__
rotrdi r9,r9,32
#endif
addi r3,r3,4 addi r3,r3,4
1: bf cr7*4+2,2f 1: bf cr7*4+2,2f
#ifdef __BIG_ENDIAN__
rotldi r9,r9,16 rotldi r9,r9,16
#endif
95: sth r9,0(r3) 95: sth r9,0(r3)
#ifdef __LITTLE_ENDIAN__
rotrdi r9,r9,16
#endif
addi r3,r3,2 addi r3,r3,2
2: bf cr7*4+3,3f 2: bf cr7*4+3,3f
#ifdef __BIG_ENDIAN__
rotldi r9,r9,8 rotldi r9,r9,8
#endif
96: stb r9,0(r3) 96: stb r9,0(r3)
#ifdef __LITTLE_ENDIAN__
rotrdi r9,r9,8
#endif
3: li r3,0 3: li r3,0
blr blr

View File

@ -36,7 +36,6 @@
#include "powernv.h" #include "powernv.h"
#include "pci.h" #include "pci.h"
static char *hub_diag = NULL;
static int ioda_eeh_nb_init = 0; static int ioda_eeh_nb_init = 0;
static int ioda_eeh_event(struct notifier_block *nb, static int ioda_eeh_event(struct notifier_block *nb,
@ -140,15 +139,6 @@ static int ioda_eeh_post_init(struct pci_controller *hose)
ioda_eeh_nb_init = 1; ioda_eeh_nb_init = 1;
} }
/* We needn't HUB diag-data on PHB3 */
if (phb->type == PNV_PHB_IODA1 && !hub_diag) {
hub_diag = (char *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
if (!hub_diag) {
pr_err("%s: Out of memory !\n", __func__);
return -ENOMEM;
}
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
if (phb->dbgfs) { if (phb->dbgfs) {
debugfs_create_file("err_injct_outbound", 0600, debugfs_create_file("err_injct_outbound", 0600,
@ -633,11 +623,10 @@ static void ioda_eeh_hub_diag_common(struct OpalIoP7IOCErrorData *data)
static void ioda_eeh_hub_diag(struct pci_controller *hose) static void ioda_eeh_hub_diag(struct pci_controller *hose)
{ {
struct pnv_phb *phb = hose->private_data; struct pnv_phb *phb = hose->private_data;
struct OpalIoP7IOCErrorData *data; struct OpalIoP7IOCErrorData *data = &phb->diag.hub_diag;
long rc; long rc;
data = (struct OpalIoP7IOCErrorData *)ioda_eeh_hub_diag; rc = opal_pci_get_hub_diag_data(phb->hub_id, data, sizeof(*data));
rc = opal_pci_get_hub_diag_data(phb->hub_id, data, PAGE_SIZE);
if (rc != OPAL_SUCCESS) { if (rc != OPAL_SUCCESS) {
pr_warning("%s: Failed to get HUB#%llx diag-data (%ld)\n", pr_warning("%s: Failed to get HUB#%llx diag-data (%ld)\n",
__func__, phb->hub_id, rc); __func__, phb->hub_id, rc);
@ -820,14 +809,15 @@ static void ioda_eeh_phb_diag(struct pci_controller *hose)
struct OpalIoPhbErrorCommon *common; struct OpalIoPhbErrorCommon *common;
long rc; long rc;
common = (struct OpalIoPhbErrorCommon *)phb->diag.blob; rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob,
rc = opal_pci_get_phb_diag_data2(phb->opal_id, common, PAGE_SIZE); PNV_PCI_DIAG_BUF_SIZE);
if (rc != OPAL_SUCCESS) { if (rc != OPAL_SUCCESS) {
pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n",
__func__, hose->global_number, rc); __func__, hose->global_number, rc);
return; return;
} }
common = (struct OpalIoPhbErrorCommon *)phb->diag.blob;
switch (common->ioType) { switch (common->ioType) {
case OPAL_PHB_ERROR_DATA_TYPE_P7IOC: case OPAL_PHB_ERROR_DATA_TYPE_P7IOC:
ioda_eeh_p7ioc_phb_diag(hose, common); ioda_eeh_p7ioc_phb_diag(hose, common);

View File

@ -172,11 +172,13 @@ struct pnv_phb {
} ioda; } ioda;
}; };
/* PHB status structure */ /* PHB and hub status structure */
union { union {
unsigned char blob[PNV_PCI_DIAG_BUF_SIZE]; unsigned char blob[PNV_PCI_DIAG_BUF_SIZE];
struct OpalIoP7IOCPhbErrorData p7ioc; struct OpalIoP7IOCPhbErrorData p7ioc;
struct OpalIoP7IOCErrorData hub_diag;
} diag; } diag;
}; };
extern struct pci_ops pnv_pci_ops; extern struct pci_ops pnv_pci_ops;