Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 330304
b: refs/heads/master
c: eda485f
h: refs/heads/master
v: v3
  • Loading branch information
Benjamin Herrenschmidt committed Sep 17, 2012
1 parent 90a4adf commit 4507299
Show file tree
Hide file tree
Showing 96 changed files with 2,039 additions and 1,182 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9a5d5bd8480068c5829e3d997ee21dab9b3ed05f
refs/heads/master: eda485f06d17f98bd58559fb5dd331951ffd1608
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ config PPC_OF_PLATFORM_PCI
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
def_bool y

config ARCH_SUPPORTS_UPROBES
def_bool y

config PPC_ADV_DEBUG_REGS
bool
depends on 40x || BOOKE
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/boot/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
obj-plat: $(libfdt)

quiet_cmd_copy_zlib = COPY $@
cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
Expand Down
56 changes: 0 additions & 56 deletions trunk/arch/powerpc/include/asm/abs_addr.h

This file was deleted.

2 changes: 1 addition & 1 deletion trunk/arch/powerpc/include/asm/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
#endif

extern int set_dabr(unsigned long dabr);
extern int set_dabr(unsigned long dabr, unsigned long dabrx);
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
extern void do_send_trap(struct pt_regs *regs, unsigned long address,
unsigned long error_code, int signal_code, int brkpt);
Expand Down
136 changes: 98 additions & 38 deletions trunk/arch/powerpc/include/asm/eeh.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,62 @@ struct device_node;

#ifdef CONFIG_EEH

/*
* The struct is used to trace PE related EEH functionality.
* In theory, there will have one instance of the struct to
* be created against particular PE. In nature, PEs corelate
* to each other. the struct has to reflect that hierarchy in
* order to easily pick up those affected PEs when one particular
* PE has EEH errors.
*
* Also, one particular PE might be composed of PCI device, PCI
* bus and its subordinate components. The struct also need ship
* the information. Further more, one particular PE is only meaingful
* in the corresponding PHB. Therefore, the root PEs should be created
* against existing PHBs in on-to-one fashion.
*/
#define EEH_PE_PHB 1 /* PHB PE */
#define EEH_PE_DEVICE 2 /* Device PE */
#define EEH_PE_BUS 3 /* Bus PE */

#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */
#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */

struct eeh_pe {
int type; /* PE type: PHB/Bus/Device */
int state; /* PE EEH dependent mode */
int config_addr; /* Traditional PCI address */
int addr; /* PE configuration address */
struct pci_controller *phb; /* Associated PHB */
int check_count; /* Times of ignored error */
int freeze_count; /* Times of froze up */
int false_positives; /* Times of reported #ff's */
struct eeh_pe *parent; /* Parent PE */
struct list_head child_list; /* Link PE to the child list */
struct list_head edevs; /* Link list of EEH devices */
struct list_head child; /* Child PEs */
};

#define eeh_pe_for_each_dev(pe, edev) \
list_for_each_entry(edev, &pe->edevs, list)

/*
* The struct is used to trace EEH state for the associated
* PCI device node or PCI device. In future, it might
* represent PE as well so that the EEH device to form
* another tree except the currently existing tree of PCI
* buses and PCI devices
*/
#define EEH_MODE_SUPPORTED (1<<0) /* EEH supported on the device */
#define EEH_MODE_NOCHECK (1<<1) /* EEH check should be skipped */
#define EEH_MODE_ISOLATED (1<<2) /* The device has been isolated */
#define EEH_MODE_RECOVERING (1<<3) /* Recovering the device */
#define EEH_MODE_IRQ_DISABLED (1<<4) /* Interrupt disabled */
#define EEH_DEV_IRQ_DISABLED (1<<0) /* Interrupt disabled */

struct eeh_dev {
int mode; /* EEH mode */
int class_code; /* Class code of the device */
int config_addr; /* Config address */
int pe_config_addr; /* PE config address */
int check_count; /* Times of ignored error */
int freeze_count; /* Times of froze up */
int false_positives; /* Times of reported #ff's */
u32 config_space[16]; /* Saved PCI config space */
struct eeh_pe *pe; /* Associated PE */
struct list_head list; /* Form link list in the PE */
struct pci_controller *phb; /* Associated PHB */
struct device_node *dn; /* Associated device node */
struct pci_dev *pdev; /* Associated PCI device */
Expand Down Expand Up @@ -95,39 +129,75 @@ static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
struct eeh_ops {
char *name;
int (*init)(void);
int (*set_option)(struct device_node *dn, int option);
int (*get_pe_addr)(struct device_node *dn);
int (*get_state)(struct device_node *dn, int *state);
int (*reset)(struct device_node *dn, int option);
int (*wait_state)(struct device_node *dn, int max_wait);
int (*get_log)(struct device_node *dn, int severity, char *drv_log, unsigned long len);
int (*configure_bridge)(struct device_node *dn);
void* (*of_probe)(struct device_node *dn, void *flag);
void* (*dev_probe)(struct pci_dev *dev, void *flag);
int (*set_option)(struct eeh_pe *pe, int option);
int (*get_pe_addr)(struct eeh_pe *pe);
int (*get_state)(struct eeh_pe *pe, int *state);
int (*reset)(struct eeh_pe *pe, int option);
int (*wait_state)(struct eeh_pe *pe, int max_wait);
int (*get_log)(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len);
int (*configure_bridge)(struct eeh_pe *pe);
int (*read_config)(struct device_node *dn, int where, int size, u32 *val);
int (*write_config)(struct device_node *dn, int where, int size, u32 val);
};

extern struct eeh_ops *eeh_ops;
extern int eeh_subsystem_enabled;
extern struct mutex eeh_mutex;
extern int eeh_probe_mode;

#define EEH_PROBE_MODE_DEV (1<<0) /* From PCI device */
#define EEH_PROBE_MODE_DEVTREE (1<<1) /* From device tree */

static inline void eeh_probe_mode_set(int flag)
{
eeh_probe_mode = flag;
}

static inline int eeh_probe_mode_devtree(void)
{
return (eeh_probe_mode == EEH_PROBE_MODE_DEVTREE);
}

static inline int eeh_probe_mode_dev(void)
{
return (eeh_probe_mode == EEH_PROBE_MODE_DEV);
}

static inline void eeh_lock(void)
{
mutex_lock(&eeh_mutex);
}

static inline void eeh_unlock(void)
{
mutex_unlock(&eeh_mutex);
}

/*
* Max number of EEH freezes allowed before we consider the device
* to be permanently disabled.
*/
#define EEH_MAX_ALLOWED_FREEZES 5

typedef void *(*eeh_traverse_func)(void *data, void *flag);
int __devinit eeh_phb_pe_create(struct pci_controller *phb);
int eeh_add_to_parent_pe(struct eeh_dev *edev);
int eeh_rmv_from_parent_pe(struct eeh_dev *edev);
void *eeh_pe_dev_traverse(struct eeh_pe *root,
eeh_traverse_func fn, void *flag);
void eeh_pe_restore_bars(struct eeh_pe *pe);
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);

void * __devinit eeh_dev_init(struct device_node *dn, void *data);
void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb);
void __init eeh_dev_phb_init(void);
void __init eeh_init(void);
#ifdef CONFIG_PPC_PSERIES
int __init eeh_pseries_init(void);
#endif
int __init eeh_ops_register(struct eeh_ops *ops);
int __exit eeh_ops_unregister(const char *name);
unsigned long eeh_check_failure(const volatile void __iomem *token,
unsigned long val);
int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev);
void __init pci_addr_cache_build(void);
int eeh_dev_check_failure(struct eeh_dev *edev);
void __init eeh_addr_cache_build(void);
void eeh_add_device_tree_early(struct device_node *);
void eeh_add_device_tree_late(struct pci_bus *);
void eeh_remove_bus_device(struct pci_dev *);
Expand Down Expand Up @@ -156,34 +226,24 @@ static inline void *eeh_dev_init(struct device_node *dn, void *data)

static inline void eeh_dev_phb_init_dynamic(struct pci_controller *phb) { }

static inline void eeh_dev_phb_init(void) { }

static inline void eeh_init(void) { }

#ifdef CONFIG_PPC_PSERIES
static inline int eeh_pseries_init(void)
{
return 0;
}
#endif /* CONFIG_PPC_PSERIES */

static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
{
return val;
}

static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
{
return 0;
}
#define eeh_dev_check_failure(x) (0)

static inline void pci_addr_cache_build(void) { }
static inline void eeh_addr_cache_build(void) { }

static inline void eeh_add_device_tree_early(struct device_node *dn) { }

static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }

static inline void eeh_remove_bus_device(struct pci_dev *dev) { }

static inline void eeh_lock(void) { }
static inline void eeh_unlock(void) { }

#define EEH_POSSIBLE_ERROR(val, type) (0)
#define EEH_IO_ERROR_VALUE(size) (-1UL)
#endif /* CONFIG_EEH */
Expand Down
6 changes: 3 additions & 3 deletions trunk/arch/powerpc/include/asm/eeh_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
*/
struct eeh_event {
struct list_head list; /* to form event queue */
struct eeh_dev *edev; /* EEH device */
struct eeh_pe *pe; /* EEH PE */
};

int eeh_send_failure_event(struct eeh_dev *edev);
struct eeh_dev *handle_eeh_events(struct eeh_event *);
int eeh_send_failure_event(struct eeh_pe *pe);
void eeh_handle_event(struct eeh_pe *pe);

#endif /* __KERNEL__ */
#endif /* ASM_POWERPC_EEH_EVENT_H */
6 changes: 4 additions & 2 deletions trunk/arch/powerpc/include/asm/exception-64e.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* critical data
*/

#define PACA_EXGDBELL PACA_EXGEN

/* We are out of SPRGs so we save some things in the PACA. The normal
* exception frame is smaller than the CRIT or MC one though
Expand All @@ -45,8 +46,9 @@
#define EX_CR (1 * 8)
#define EX_R10 (2 * 8)
#define EX_R11 (3 * 8)
#define EX_R14 (4 * 8)
#define EX_R15 (5 * 8)
#define EX_R13 (4 * 8)
#define EX_R14 (5 * 8)
#define EX_R15 (6 * 8)

/*
* The TLB miss exception uses different slots.
Expand Down
5 changes: 0 additions & 5 deletions trunk/arch/powerpc/include/asm/hvcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,6 @@
#define H_VASI_RESUMED 5
#define H_VASI_COMPLETED 6

/* DABRX flags */
#define H_DABRX_HYPERVISOR (1UL<<(63-61))
#define H_DABRX_KERNEL (1UL<<(63-62))
#define H_DABRX_USER (1UL<<(63-63))

/* Each control block has to be on a 4K boundary */
#define H_CB_ALIGNMENT 4096

Expand Down
9 changes: 5 additions & 4 deletions trunk/arch/powerpc/include/asm/hw_breakpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
#ifdef CONFIG_HAVE_HW_BREAKPOINT

struct arch_hw_breakpoint {
bool extraneous_interrupt;
u8 len; /* length of the target data symbol */
int type;
unsigned long address;
unsigned long dabrx;
int type;
u8 len; /* length of the target data symbol */
bool extraneous_interrupt;
};

#include <linux/kdebug.h>
Expand Down Expand Up @@ -61,7 +62,7 @@ extern void ptrace_triggered(struct perf_event *bp,
struct perf_sample_data *data, struct pt_regs *regs);
static inline void hw_breakpoint_disable(void)
{
set_dabr(0);
set_dabr(0, 0);
}
extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);

Expand Down
15 changes: 2 additions & 13 deletions trunk/arch/powerpc/include/asm/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,16 @@
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/percpu.h>
#include <asm/probes.h>

#define __ARCH_WANT_KPROBES_INSN_SLOT

struct pt_regs;
struct kprobe;

typedef unsigned int kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */
typedef ppc_opcode_t kprobe_opcode_t;
#define MAX_INSN_SIZE 1

#define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008)
#define IS_TD(instr) (((instr) & 0xfc0007fe) == 0x7c000088)
#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000)
#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000)

#ifdef CONFIG_PPC64
/*
* 64bit powerpc uses function descriptors.
Expand Down Expand Up @@ -72,12 +67,6 @@ typedef unsigned int kprobe_opcode_t;
addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \
} \
}

#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
IS_TWI(instr) || IS_TDI(instr))
#else
/* Use stock kprobe_lookup_name since ppc32 doesn't use function descriptors */
#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr))
#endif

#define flush_insn_slot(p) do { } while (0)
Expand Down
Loading

0 comments on commit 4507299

Please sign in to comment.