Skip to content

Commit

Permalink
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/benh/powerpc

Pull more powerpc updates from Ben Herrenschmidt:
 "Here are a few more powerpc things for you.

  So you'll find here the conversion of the two new firmware sysfs
  interfaces to the new API for self-removing files that Greg and Tejun
  introduced, so they can finally remove the old one.

  I'm also reverting the hwmon driver for powernv.  I shouldn't have
  merged it, I got a bit carried away here.  I hadn't realized it was
  never CCed to the relevant maintainer(s) and list(s), and happens to
  have some issues so I'm taking it out and it will come back via the
  proper channels.

  The rest is a bunch of LE fixes (argh, some of the new stuff was
  broken on LE, I really need to start testing LE myself !) and various
  random fixes here and there.

  Finally one bit that's not strictly a fix, which is the HVC OPAL
  change to "kick" the HVC thread when the firmware tells us there is
  new incoming data.  I don't feel like waiting for this one, it's
  simple enough, and it makes a big difference in console responsiveness
  which is good for my nerves"

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (26 commits)
  powerpc/powernv Adapt opal-elog and opal-dump to new sysfs_remove_file_self
  Revert "powerpc/powernv: hwmon driver for power values, fan rpm and temperature"
  power, sched: stop updating inside arch_update_cpu_topology() when nothing to be update
  powerpc/le: Avoid creatng R_PPC64_TOCSAVE relocations for modules.
  arch/powerpc: Use RCU_INIT_POINTER(x, NULL) in platforms/cell/spu_syscalls.c
  powerpc/opal: Add missing include
  powerpc: Convert last uses of __FUNCTION__ to __func__
  powerpc: Add lq/stq emulation
  powerpc/powernv: Add invalid OPAL call
  powerpc/powernv: Add OPAL message log interface
  powerpc/book3s: Fix mc_recoverable_range buffer overrun issue.
  powerpc: Remove dead code in sycall entry
  powerpc: Use of_node_init() for the fakenode in msi_bitmap.c
  powerpc/mm: NUMA pte should be handled via slow path in get_user_pages_fast()
  powerpc/powernv: Fix endian issues with sensor code
  powerpc/powernv: Fix endian issues with OPAL async code
  tty/hvc_opal: Kick the HVC thread on OPAL console events
  powerpc/powernv: Add opal_notifier_unregister() and export to modules
  powerpc/ppc64: Do not turn AIL (reloc-on interrupts) too early
  powerpc/ppc64: Gracefully handle early interrupts
  ...
  • Loading branch information
Linus Torvalds committed Apr 9, 2014
2 parents 69cd9eb + cc4f265 commit 042f7b7
Show file tree
Hide file tree
Showing 40 changed files with 546 additions and 738 deletions.
1 change: 1 addition & 0 deletions arch/powerpc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ override CROSS32AS += -mlittle-endian
LDEMULATION := lppc
GNUTARGET := powerpcle
MULTIPLEWORD := -mno-multiple
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-save-toc-indirect)
else
ifeq ($(call cc-option-yn,-mbig-endian),y)
override CC += -mbig-endian
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/emulated_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ extern struct ppc_emulated {
#ifdef CONFIG_PPC64
struct ppc_emulated_entry mfdscr;
struct ppc_emulated_entry mtdscr;
struct ppc_emulated_entry lq_stq;
#endif
} ppc_emulated;

Expand Down
19 changes: 14 additions & 5 deletions arch/powerpc/include/asm/opal.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
#define OPAL_ASYNC_COMPLETION -15

/* API Tokens (in r0) */
#define OPAL_INVALID_CALL -1
#define OPAL_CONSOLE_WRITE 1
#define OPAL_CONSOLE_READ 2
#define OPAL_RTC_READ 3
Expand Down Expand Up @@ -177,6 +178,8 @@ extern int opal_enter_rtas(struct rtas_args *args,

#ifndef __ASSEMBLY__

#include <linux/notifier.h>

/* Other enums */
enum OpalVendorApiTokens {
OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999
Expand Down Expand Up @@ -422,9 +425,9 @@ enum OpalSysparamPerm {
};

struct opal_msg {
uint32_t msg_type;
uint32_t reserved;
uint64_t params[8];
__be32 msg_type;
__be32 reserved;
__be64 params[8];
};

struct opal_machine_check_event {
Expand Down Expand Up @@ -730,7 +733,11 @@ typedef struct oppanel_line {
/* /sys/firmware/opal */
extern struct kobject *opal_kobj;

/* /ibm,opal */
extern struct device_node *opal_node;

/* API functions */
int64_t opal_invalid_call(void);
int64_t opal_console_write(int64_t term_number, __be64 *length,
const uint8_t *buffer);
int64_t opal_console_read(int64_t term_number, __be64 *length,
Expand Down Expand Up @@ -874,8 +881,7 @@ int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer,
size_t length);
int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
size_t length);
int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
uint32_t *sensor_data);
int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);

/* Internal functions */
extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
Expand All @@ -892,6 +898,8 @@ extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
int depth, void *data);

extern int opal_notifier_register(struct notifier_block *nb);
extern int opal_notifier_unregister(struct notifier_block *nb);

extern int opal_message_notifier_register(enum OpalMessageType msg_type,
struct notifier_block *nb);
extern void opal_notifier_enable(void);
Expand Down Expand Up @@ -919,6 +927,7 @@ extern void opal_flash_init(void);
extern int opal_elog_init(void);
extern void opal_platform_dump_init(void);
extern void opal_sys_param_init(void);
extern void opal_msglog_init(void);

extern int opal_machine_check(struct pt_regs *regs);
extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
Expand Down
127 changes: 94 additions & 33 deletions arch/powerpc/include/asm/rtas.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,53 @@ struct rtas_suspend_me_data {
#define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500

struct rtas_error_log {
unsigned long version:8; /* Architectural version */
unsigned long severity:3; /* Severity level of error */
unsigned long disposition:2; /* Degree of recovery */
unsigned long extended:1; /* extended log present? */
unsigned long /* reserved */ :2; /* Reserved for future use */
unsigned long initiator:4; /* Initiator of event */
unsigned long target:4; /* Target of failed operation */
unsigned long type:8; /* General event or error*/
unsigned long extended_log_length:32; /* length in bytes */
unsigned char buffer[1]; /* Start of extended log */
/* Byte 0 */
uint8_t byte0; /* Architectural version */

/* Byte 1 */
uint8_t byte1;
/* XXXXXXXX
* XXX 3: Severity level of error
* XX 2: Degree of recovery
* X 1: Extended log present?
* XX 2: Reserved
*/

/* Byte 2 */
uint8_t byte2;
/* XXXXXXXX
* XXXX 4: Initiator of event
* XXXX 4: Target of failed operation
*/
uint8_t byte3; /* General event or error*/
__be32 extended_log_length; /* length in bytes */
unsigned char buffer[1]; /* Start of extended log */
/* Variable length. */
};

static inline uint8_t rtas_error_severity(const struct rtas_error_log *elog)
{
return (elog->byte1 & 0xE0) >> 5;
}

static inline uint8_t rtas_error_disposition(const struct rtas_error_log *elog)
{
return (elog->byte1 & 0x18) >> 3;
}

static inline uint8_t rtas_error_extended(const struct rtas_error_log *elog)
{
return (elog->byte1 & 0x04) >> 2;
}

#define rtas_error_type(x) ((x)->byte3)

static inline
uint32_t rtas_error_extended_log_length(const struct rtas_error_log *elog)
{
return be32_to_cpu(elog->extended_log_length);
}

#define RTAS_V6EXT_LOG_FORMAT_EVENT_LOG 14

#define RTAS_V6EXT_COMPANY_ID_IBM (('I' << 24) | ('B' << 16) | ('M' << 8))
Expand All @@ -172,39 +206,54 @@ struct rtas_error_log {
*/
struct rtas_ext_event_log_v6 {
/* Byte 0 */
uint32_t log_valid:1; /* 1:Log valid */
uint32_t unrecoverable_error:1; /* 1:Unrecoverable error */
uint32_t recoverable_error:1; /* 1:recoverable (correctable */
/* or successfully retried) */
uint32_t degraded_operation:1; /* 1:Unrecoverable err, bypassed*/
/* - degraded operation (e.g. */
/* CPU or mem taken off-line) */
uint32_t predictive_error:1;
uint32_t new_log:1; /* 1:"New" log (Always 1 for */
/* data returned from RTAS */
uint32_t big_endian:1; /* 1: Big endian */
uint32_t :1; /* reserved */
uint8_t byte0;
/* XXXXXXXX
* X 1: Log valid
* X 1: Unrecoverable error
* X 1: Recoverable (correctable or successfully retried)
* X 1: Bypassed unrecoverable error (degraded operation)
* X 1: Predictive error
* X 1: "New" log (always 1 for data returned from RTAS)
* X 1: Big Endian
* X 1: Reserved
*/

/* Byte 1 */
uint32_t :8; /* reserved */
uint8_t byte1; /* reserved */

/* Byte 2 */
uint32_t powerpc_format:1; /* Set to 1 (indicating log is */
/* in PowerPC format */
uint32_t :3; /* reserved */
uint32_t log_format:4; /* Log format indicator. Define */
/* format used for byte 12-2047 */
uint8_t byte2;
/* XXXXXXXX
* X 1: Set to 1 (indicating log is in PowerPC format)
* XXX 3: Reserved
* XXXX 4: Log format used for bytes 12-2047
*/

/* Byte 3 */
uint32_t :8; /* reserved */
uint8_t byte3; /* reserved */
/* Byte 4-11 */
uint8_t reserved[8]; /* reserved */
/* Byte 12-15 */
uint32_t company_id; /* Company ID of the company */
__be32 company_id; /* Company ID of the company */
/* that defines the format for */
/* the vendor specific log type */
/* Byte 16-end of log */
uint8_t vendor_log[1]; /* Start of vendor specific log */
/* Variable length. */
};

static
inline uint8_t rtas_ext_event_log_format(struct rtas_ext_event_log_v6 *ext_log)
{
return ext_log->byte2 & 0x0F;
}

static
inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log)
{
return be32_to_cpu(ext_log->company_id);
}

/* pSeries event log format */

/* Two bytes ASCII section IDs */
Expand All @@ -227,14 +276,26 @@ struct rtas_ext_event_log_v6 {

/* Vendor specific Platform Event Log Format, Version 6, section header */
struct pseries_errorlog {
uint16_t id; /* 0x00 2-byte ASCII section ID */
uint16_t length; /* 0x02 Section length in bytes */
__be16 id; /* 0x00 2-byte ASCII section ID */
__be16 length; /* 0x02 Section length in bytes */
uint8_t version; /* 0x04 Section version */
uint8_t subtype; /* 0x05 Section subtype */
uint16_t creator_component; /* 0x06 Creator component ID */
__be16 creator_component; /* 0x06 Creator component ID */
uint8_t data[]; /* 0x08 Start of section data */
};

static
inline uint16_t pseries_errorlog_id(struct pseries_errorlog *sect)
{
return be16_to_cpu(sect->id);
}

static
inline uint16_t pseries_errorlog_length(struct pseries_errorlog *sect)
{
return be16_to_cpu(sect->length);
}

struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
uint16_t section_id);

Expand Down
52 changes: 44 additions & 8 deletions arch/powerpc/kernel/align.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static struct aligninfo aligninfo[128] = {
{ 8, LD+F }, /* 00 0 1001: lfd */
{ 4, ST+F+S }, /* 00 0 1010: stfs */
{ 8, ST+F }, /* 00 0 1011: stfd */
INVALID, /* 00 0 1100 */
{ 16, LD }, /* 00 0 1100: lq */
{ 8, LD }, /* 00 0 1101: ld/ldu/lwa */
INVALID, /* 00 0 1110 */
{ 8, ST }, /* 00 0 1111: std/stdu */
Expand Down Expand Up @@ -140,7 +140,7 @@ static struct aligninfo aligninfo[128] = {
{ 2, LD+SW }, /* 10 0 1100: lhbrx */
{ 4, LD+SE }, /* 10 0 1101 lwa */
{ 2, ST+SW }, /* 10 0 1110: sthbrx */
INVALID, /* 10 0 1111 */
{ 16, ST }, /* 10 0 1111: stq */
INVALID, /* 10 1 0000 */
INVALID, /* 10 1 0001 */
INVALID, /* 10 1 0010 */
Expand Down Expand Up @@ -385,8 +385,6 @@ static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg,
char *ptr1 = (char *) &current->thread.TS_FPR(reg+1);
int i, ret, sw = 0;

if (!(flags & F))
return 0;
if (reg & 1)
return 0; /* invalid form: FRS/FRT must be even */
if (flags & SW)
Expand All @@ -406,6 +404,34 @@ static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg,
return 1; /* exception handled and fixed up */
}

#ifdef CONFIG_PPC64
static int emulate_lq_stq(struct pt_regs *regs, unsigned char __user *addr,
unsigned int reg, unsigned int flags)
{
char *ptr0 = (char *)&regs->gpr[reg];
char *ptr1 = (char *)&regs->gpr[reg+1];
int i, ret, sw = 0;

if (reg & 1)
return 0; /* invalid form: GPR must be even */
if (flags & SW)
sw = 7;
ret = 0;
for (i = 0; i < 8; ++i) {
if (!(flags & ST)) {
ret |= __get_user(ptr0[i^sw], addr + i);
ret |= __get_user(ptr1[i^sw], addr + i + 8);
} else {
ret |= __put_user(ptr0[i^sw], addr + i);
ret |= __put_user(ptr1[i^sw], addr + i + 8);
}
}
if (ret)
return -EFAULT;
return 1; /* exception handled and fixed up */
}
#endif /* CONFIG_PPC64 */

#ifdef CONFIG_SPE

static struct aligninfo spe_aligninfo[32] = {
Expand Down Expand Up @@ -914,10 +940,20 @@ int fix_alignment(struct pt_regs *regs)
flush_fp_to_thread(current);
}

/* Special case for 16-byte FP loads and stores */
if (nb == 16) {
PPC_WARN_ALIGNMENT(fp_pair, regs);
return emulate_fp_pair(addr, reg, flags);
if ((nb == 16)) {
if (flags & F) {
/* Special case for 16-byte FP loads and stores */
PPC_WARN_ALIGNMENT(fp_pair, regs);
return emulate_fp_pair(addr, reg, flags);
} else {
#ifdef CONFIG_PPC64
/* Special case for 16-byte loads and stores */
PPC_WARN_ALIGNMENT(lq_stq, regs);
return emulate_lq_stq(regs, addr, reg, flags);
#else
return 0;
#endif
}
}

PPC_WARN_ALIGNMENT(unaligned, regs);
Expand Down
2 changes: 0 additions & 2 deletions arch/powerpc/kernel/cpu_setup_power.S
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ _GLOBAL(__setup_cpu_power8)
li r0,0
mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR
oris r3, r3, LPCR_AIL_3@h
bl __init_LPCR
bl __init_HFSCR
bl __init_tlb_power8
Expand All @@ -75,7 +74,6 @@ _GLOBAL(__restore_cpu_power8)
li r0,0
mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR
oris r3, r3, LPCR_AIL_3@h
bl __init_LPCR
bl __init_HFSCR
bl __init_tlb_power8
Expand Down
8 changes: 0 additions & 8 deletions arch/powerpc/kernel/exceptions-64s.S
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
xori r12,r12,MSR_LE ; \
mtspr SPRN_SRR1,r12 ; \
rfid ; /* return to userspace */ \
b . ; \
2: mfspr r12,SPRN_SRR1 ; \
andi. r12,r12,MSR_PR ; \
bne 0b ; \
mtspr SPRN_SRR0,r3 ; \
mtspr SPRN_SRR1,r4 ; \
mtspr SPRN_SDR1,r5 ; \
rfid ; \
b . ; /* prevent speculative execution */

#if defined(CONFIG_RELOCATABLE)
Expand Down
3 changes: 2 additions & 1 deletion arch/powerpc/kernel/paca.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
new_paca->paca_index = cpu;
new_paca->kernel_toc = kernel_toc;
new_paca->kernelbase = (unsigned long) _stext;
new_paca->kernel_msr = MSR_KERNEL;
/* Only set MSR:IR/DR when MMU is initialized */
new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR);
new_paca->hw_cpu_id = 0xffff;
new_paca->kexec_state = KEXEC_STATE_NONE;
new_paca->__current = &init_task;
Expand Down
Loading

0 comments on commit 042f7b7

Please sign in to comment.