diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
commit | bcd6acd51f3d4d1ada201e9bc5c40a31d6d80c71 (patch) | |
tree | 2f6dffd2d3e4dd67355a224de7e7a960335a92fd /arch/powerpc | |
parent | 11c34c7deaeeebcee342cbc35e1bb2a6711b2431 (diff) | |
parent | 3ff6a468b45b5dfeb0e903e56f4eb27d34b2437c (diff) |
Merge commit 'origin/master' into next
Conflicts:
include/linux/kvm.h
Diffstat (limited to 'arch/powerpc')
35 files changed, 363 insertions, 349 deletions
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 3b1005185390..bf3382f1904d 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -46,7 +46,7 @@ config DEBUG_STACK_USAGE | |||
46 | 46 | ||
47 | config HCALL_STATS | 47 | config HCALL_STATS |
48 | bool "Hypervisor call instrumentation" | 48 | bool "Hypervisor call instrumentation" |
49 | depends on PPC_PSERIES && DEBUG_FS | 49 | depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS |
50 | help | 50 | help |
51 | Adds code to keep track of the number of hypervisor calls made and | 51 | Adds code to keep track of the number of hypervisor calls made and |
52 | the amount of time spent in hypervisor calls. Wall time spent in | 52 | the amount of time spent in hypervisor calls. Wall time spent in |
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index f1889abb89b1..c568329723b8 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
@@ -1683,7 +1683,7 @@ CONFIG_HAVE_ARCH_KGDB=y | |||
1683 | CONFIG_DEBUG_STACKOVERFLOW=y | 1683 | CONFIG_DEBUG_STACKOVERFLOW=y |
1684 | # CONFIG_DEBUG_STACK_USAGE is not set | 1684 | # CONFIG_DEBUG_STACK_USAGE is not set |
1685 | # CONFIG_DEBUG_PAGEALLOC is not set | 1685 | # CONFIG_DEBUG_PAGEALLOC is not set |
1686 | CONFIG_HCALL_STATS=y | 1686 | # CONFIG_HCALL_STATS is not set |
1687 | # CONFIG_CODE_PATCHING_SELFTEST is not set | 1687 | # CONFIG_CODE_PATCHING_SELFTEST is not set |
1688 | # CONFIG_FTR_FIXUP_SELFTEST is not set | 1688 | # CONFIG_FTR_FIXUP_SELFTEST is not set |
1689 | # CONFIG_MSI_BITMAP_SELFTEST is not set | 1689 | # CONFIG_MSI_BITMAP_SELFTEST is not set |
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index ba667a383b8c..ab9e402518e8 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define flush_cache_vmap(start, end) do { } while (0) | 25 | #define flush_cache_vmap(start, end) do { } while (0) |
26 | #define flush_cache_vunmap(start, end) do { } while (0) | 26 | #define flush_cache_vunmap(start, end) do { } while (0) |
27 | 27 | ||
28 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||
28 | extern void flush_dcache_page(struct page *page); | 29 | extern void flush_dcache_page(struct page *page); |
29 | #define flush_dcache_mmap_lock(mapping) do { } while (0) | 30 | #define flush_dcache_mmap_lock(mapping) do { } while (0) |
30 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) | 31 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) |
diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h index 9154e8526732..f0fb4fc1f6e6 100644 --- a/arch/powerpc/include/asm/emulated_ops.h +++ b/arch/powerpc/include/asm/emulated_ops.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #define _ASM_POWERPC_EMULATED_OPS_H | 19 | #define _ASM_POWERPC_EMULATED_OPS_H |
20 | 20 | ||
21 | #include <asm/atomic.h> | 21 | #include <asm/atomic.h> |
22 | #include <linux/perf_event.h> | ||
22 | 23 | ||
23 | 24 | ||
24 | #ifdef CONFIG_PPC_EMULATED_STATS | 25 | #ifdef CONFIG_PPC_EMULATED_STATS |
@@ -57,7 +58,7 @@ extern u32 ppc_warn_emulated; | |||
57 | 58 | ||
58 | extern void ppc_warn_emulated_print(const char *type); | 59 | extern void ppc_warn_emulated_print(const char *type); |
59 | 60 | ||
60 | #define PPC_WARN_EMULATED(type) \ | 61 | #define __PPC_WARN_EMULATED(type) \ |
61 | do { \ | 62 | do { \ |
62 | atomic_inc(&ppc_emulated.type.val); \ | 63 | atomic_inc(&ppc_emulated.type.val); \ |
63 | if (ppc_warn_emulated) \ | 64 | if (ppc_warn_emulated) \ |
@@ -66,8 +67,22 @@ extern void ppc_warn_emulated_print(const char *type); | |||
66 | 67 | ||
67 | #else /* !CONFIG_PPC_EMULATED_STATS */ | 68 | #else /* !CONFIG_PPC_EMULATED_STATS */ |
68 | 69 | ||
69 | #define PPC_WARN_EMULATED(type) do { } while (0) | 70 | #define __PPC_WARN_EMULATED(type) do { } while (0) |
70 | 71 | ||
71 | #endif /* !CONFIG_PPC_EMULATED_STATS */ | 72 | #endif /* !CONFIG_PPC_EMULATED_STATS */ |
72 | 73 | ||
74 | #define PPC_WARN_EMULATED(type, regs) \ | ||
75 | do { \ | ||
76 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, \ | ||
77 | 1, 0, regs, 0); \ | ||
78 | __PPC_WARN_EMULATED(type); \ | ||
79 | } while (0) | ||
80 | |||
81 | #define PPC_WARN_ALIGNMENT(type, regs) \ | ||
82 | do { \ | ||
83 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, \ | ||
84 | 1, 0, regs, regs->dar); \ | ||
85 | __PPC_WARN_EMULATED(type); \ | ||
86 | } while (0) | ||
87 | |||
73 | #endif /* _ASM_POWERPC_EMULATED_OPS_H */ | 88 | #endif /* _ASM_POWERPC_EMULATED_OPS_H */ |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 3bf38af7c834..f0275818b95c 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -287,6 +287,8 @@ struct hcall_stats { | |||
287 | unsigned long num_calls; /* number of calls (on this CPU) */ | 287 | unsigned long num_calls; /* number of calls (on this CPU) */ |
288 | unsigned long tb_total; /* total wall time (mftb) of calls. */ | 288 | unsigned long tb_total; /* total wall time (mftb) of calls. */ |
289 | unsigned long purr_total; /* total cpu time (PURR) of calls. */ | 289 | unsigned long purr_total; /* total cpu time (PURR) of calls. */ |
290 | unsigned long tb_start; | ||
291 | unsigned long purr_start; | ||
290 | }; | 292 | }; |
291 | #define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1) | 293 | #define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1) |
292 | 294 | ||
diff --git a/arch/powerpc/include/asm/pmac_low_i2c.h b/arch/powerpc/include/asm/pmac_low_i2c.h index 131011bd7e76..01d71826d92f 100644 --- a/arch/powerpc/include/asm/pmac_low_i2c.h +++ b/arch/powerpc/include/asm/pmac_low_i2c.h | |||
@@ -72,11 +72,7 @@ extern int pmac_i2c_get_type(struct pmac_i2c_bus *bus); | |||
72 | extern int pmac_i2c_get_flags(struct pmac_i2c_bus *bus); | 72 | extern int pmac_i2c_get_flags(struct pmac_i2c_bus *bus); |
73 | extern int pmac_i2c_get_channel(struct pmac_i2c_bus *bus); | 73 | extern int pmac_i2c_get_channel(struct pmac_i2c_bus *bus); |
74 | 74 | ||
75 | /* i2c layer adapter attach/detach */ | 75 | /* i2c layer adapter helpers */ |
76 | extern void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus, | ||
77 | struct i2c_adapter *adapter); | ||
78 | extern void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus, | ||
79 | struct i2c_adapter *adapter); | ||
80 | extern struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus); | 76 | extern struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus); |
81 | extern struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter); | 77 | extern struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter); |
82 | 78 | ||
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 6ff04185d2aa..2ab9cbd98826 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/of.h> /* linux/of.h gets to determine #include ordering */ | ||
1 | #ifndef _POWERPC_PROM_H | 2 | #ifndef _POWERPC_PROM_H |
2 | #define _POWERPC_PROM_H | 3 | #define _POWERPC_PROM_H |
3 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
@@ -16,6 +17,7 @@ | |||
16 | * 2 of the License, or (at your option) any later version. | 17 | * 2 of the License, or (at your option) any later version. |
17 | */ | 18 | */ |
18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/of_fdt.h> | ||
19 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
20 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
21 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
@@ -28,133 +30,14 @@ | |||
28 | #define of_prop_cmp(s1, s2) strcmp((s1), (s2)) | 30 | #define of_prop_cmp(s1, s2) strcmp((s1), (s2)) |
29 | #define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) | 31 | #define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) |
30 | 32 | ||
31 | /* Definitions used by the flattened device tree */ | ||
32 | #define OF_DT_HEADER 0xd00dfeed /* marker */ | ||
33 | #define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ | ||
34 | #define OF_DT_END_NODE 0x2 /* End node */ | ||
35 | #define OF_DT_PROP 0x3 /* Property: name off, size, | ||
36 | * content */ | ||
37 | #define OF_DT_NOP 0x4 /* nop */ | ||
38 | #define OF_DT_END 0x9 | ||
39 | |||
40 | #define OF_DT_VERSION 0x10 | ||
41 | |||
42 | /* | ||
43 | * This is what gets passed to the kernel by prom_init or kexec | ||
44 | * | ||
45 | * The dt struct contains the device tree structure, full pathes and | ||
46 | * property contents. The dt strings contain a separate block with just | ||
47 | * the strings for the property names, and is fully page aligned and | ||
48 | * self contained in a page, so that it can be kept around by the kernel, | ||
49 | * each property name appears only once in this page (cheap compression) | ||
50 | * | ||
51 | * the mem_rsvmap contains a map of reserved ranges of physical memory, | ||
52 | * passing it here instead of in the device-tree itself greatly simplifies | ||
53 | * the job of everybody. It's just a list of u64 pairs (base/size) that | ||
54 | * ends when size is 0 | ||
55 | */ | ||
56 | struct boot_param_header | ||
57 | { | ||
58 | u32 magic; /* magic word OF_DT_HEADER */ | ||
59 | u32 totalsize; /* total size of DT block */ | ||
60 | u32 off_dt_struct; /* offset to structure */ | ||
61 | u32 off_dt_strings; /* offset to strings */ | ||
62 | u32 off_mem_rsvmap; /* offset to memory reserve map */ | ||
63 | u32 version; /* format version */ | ||
64 | u32 last_comp_version; /* last compatible version */ | ||
65 | /* version 2 fields below */ | ||
66 | u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ | ||
67 | /* version 3 fields below */ | ||
68 | u32 dt_strings_size; /* size of the DT strings block */ | ||
69 | /* version 17 fields below */ | ||
70 | u32 dt_struct_size; /* size of the DT structure block */ | ||
71 | }; | ||
72 | |||
73 | |||
74 | |||
75 | typedef u32 phandle; | ||
76 | typedef u32 ihandle; | ||
77 | |||
78 | struct property { | ||
79 | char *name; | ||
80 | int length; | ||
81 | void *value; | ||
82 | struct property *next; | ||
83 | }; | ||
84 | |||
85 | struct device_node { | ||
86 | const char *name; | ||
87 | const char *type; | ||
88 | phandle node; | ||
89 | phandle linux_phandle; | ||
90 | char *full_name; | ||
91 | |||
92 | struct property *properties; | ||
93 | struct property *deadprops; /* removed properties */ | ||
94 | struct device_node *parent; | ||
95 | struct device_node *child; | ||
96 | struct device_node *sibling; | ||
97 | struct device_node *next; /* next device of same type */ | ||
98 | struct device_node *allnext; /* next in list of all nodes */ | ||
99 | struct proc_dir_entry *pde; /* this node's proc directory */ | ||
100 | struct kref kref; | ||
101 | unsigned long _flags; | ||
102 | void *data; | ||
103 | }; | ||
104 | |||
105 | extern struct device_node *of_chosen; | 33 | extern struct device_node *of_chosen; |
106 | 34 | ||
107 | static inline int of_node_check_flag(struct device_node *n, unsigned long flag) | ||
108 | { | ||
109 | return test_bit(flag, &n->_flags); | ||
110 | } | ||
111 | |||
112 | static inline void of_node_set_flag(struct device_node *n, unsigned long flag) | ||
113 | { | ||
114 | set_bit(flag, &n->_flags); | ||
115 | } | ||
116 | |||
117 | |||
118 | #define HAVE_ARCH_DEVTREE_FIXUPS | 35 | #define HAVE_ARCH_DEVTREE_FIXUPS |
119 | 36 | ||
120 | static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) | ||
121 | { | ||
122 | dn->pde = de; | ||
123 | } | ||
124 | |||
125 | |||
126 | extern struct device_node *of_find_all_nodes(struct device_node *prev); | ||
127 | extern struct device_node *of_node_get(struct device_node *node); | ||
128 | extern void of_node_put(struct device_node *node); | ||
129 | |||
130 | /* For scanning the flat device-tree at boot time */ | ||
131 | extern int __init of_scan_flat_dt(int (*it)(unsigned long node, | ||
132 | const char *uname, int depth, | ||
133 | void *data), | ||
134 | void *data); | ||
135 | extern void* __init of_get_flat_dt_prop(unsigned long node, const char *name, | ||
136 | unsigned long *size); | ||
137 | extern int __init of_flat_dt_is_compatible(unsigned long node, const char *name); | ||
138 | extern unsigned long __init of_get_flat_dt_root(void); | ||
139 | |||
140 | /* For updating the device tree at runtime */ | 37 | /* For updating the device tree at runtime */ |
141 | extern void of_attach_node(struct device_node *); | 38 | extern void of_attach_node(struct device_node *); |
142 | extern void of_detach_node(struct device_node *); | 39 | extern void of_detach_node(struct device_node *); |
143 | 40 | ||
144 | /* Other Prototypes */ | ||
145 | extern void finish_device_tree(void); | ||
146 | extern void unflatten_device_tree(void); | ||
147 | extern void early_init_devtree(void *); | ||
148 | extern int machine_is_compatible(const char *compat); | ||
149 | extern void print_properties(struct device_node *node); | ||
150 | extern int prom_n_intr_cells(struct device_node* np); | ||
151 | extern void prom_get_irq_senses(unsigned char *senses, int off, int max); | ||
152 | extern int prom_add_property(struct device_node* np, struct property* prop); | ||
153 | extern int prom_remove_property(struct device_node *np, struct property *prop); | ||
154 | extern int prom_update_property(struct device_node *np, | ||
155 | struct property *newprop, | ||
156 | struct property *oldprop); | ||
157 | |||
158 | #ifdef CONFIG_PPC32 | 41 | #ifdef CONFIG_PPC32 |
159 | /* | 42 | /* |
160 | * PCI <-> OF matching functions | 43 | * PCI <-> OF matching functions |
@@ -178,26 +61,6 @@ extern int release_OF_resource(struct device_node* node, int index); | |||
178 | * OF address retreival & translation | 61 | * OF address retreival & translation |
179 | */ | 62 | */ |
180 | 63 | ||
181 | |||
182 | /* Helper to read a big number; size is in cells (not bytes) */ | ||
183 | static inline u64 of_read_number(const u32 *cell, int size) | ||
184 | { | ||
185 | u64 r = 0; | ||
186 | while (size--) | ||
187 | r = (r << 32) | *(cell++); | ||
188 | return r; | ||
189 | } | ||
190 | |||
191 | /* Like of_read_number, but we want an unsigned long result */ | ||
192 | #ifdef CONFIG_PPC32 | ||
193 | static inline unsigned long of_read_ulong(const u32 *cell, int size) | ||
194 | { | ||
195 | return cell[size-1]; | ||
196 | } | ||
197 | #else | ||
198 | #define of_read_ulong(cell, size) of_read_number(cell, size) | ||
199 | #endif | ||
200 | |||
201 | /* Translate an OF address block into a CPU physical address | 64 | /* Translate an OF address block into a CPU physical address |
202 | */ | 65 | */ |
203 | extern u64 of_translate_address(struct device_node *np, const u32 *addr); | 66 | extern u64 of_translate_address(struct device_node *np, const u32 *addr); |
@@ -349,11 +212,5 @@ extern int of_irq_to_resource(struct device_node *dev, int index, | |||
349 | */ | 212 | */ |
350 | extern void __iomem *of_iomap(struct device_node *device, int index); | 213 | extern void __iomem *of_iomap(struct device_node *device, int index); |
351 | 214 | ||
352 | /* | ||
353 | * NB: This is here while we transition from using asm/prom.h | ||
354 | * to linux/of.h | ||
355 | */ | ||
356 | #include <linux/of.h> | ||
357 | |||
358 | #endif /* __KERNEL__ */ | 215 | #endif /* __KERNEL__ */ |
359 | #endif /* _POWERPC_PROM_H */ | 216 | #endif /* _POWERPC_PROM_H */ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 6315edc205d8..bc8dd53f718a 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -489,6 +489,8 @@ | |||
489 | #define SPRN_MMCR1 798 | 489 | #define SPRN_MMCR1 798 |
490 | #define SPRN_MMCRA 0x312 | 490 | #define SPRN_MMCRA 0x312 |
491 | #define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */ | 491 | #define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */ |
492 | #define MMCRA_SDAR_DCACHE_MISS 0x40000000UL | ||
493 | #define MMCRA_SDAR_ERAT_MISS 0x20000000UL | ||
492 | #define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */ | 494 | #define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */ |
493 | #define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */ | 495 | #define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */ |
494 | #define MMCRA_SLOT 0x07000000UL /* SLOT bits (37-39) */ | 496 | #define MMCRA_SLOT 0x07000000UL /* SLOT bits (37-39) */ |
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h index 3ab8b3e6feb0..866f7606da68 100644 --- a/arch/powerpc/include/asm/socket.h +++ b/arch/powerpc/include/asm/socket.h | |||
@@ -67,4 +67,6 @@ | |||
67 | #define SO_PROTOCOL 38 | 67 | #define SO_PROTOCOL 38 |
68 | #define SO_DOMAIN 39 | 68 | #define SO_DOMAIN 39 |
69 | 69 | ||
70 | #define SO_RXQ_OVFL 40 | ||
71 | |||
70 | #endif /* _ASM_POWERPC_SOCKET_H */ | 72 | #endif /* _ASM_POWERPC_SOCKET_H */ |
diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h new file mode 100644 index 000000000000..cbe2297d68b6 --- /dev/null +++ b/arch/powerpc/include/asm/trace.h | |||
@@ -0,0 +1,133 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM powerpc | ||
3 | |||
4 | #if !defined(_TRACE_POWERPC_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_POWERPC_H | ||
6 | |||
7 | #include <linux/tracepoint.h> | ||
8 | |||
9 | struct pt_regs; | ||
10 | |||
11 | TRACE_EVENT(irq_entry, | ||
12 | |||
13 | TP_PROTO(struct pt_regs *regs), | ||
14 | |||
15 | TP_ARGS(regs), | ||
16 | |||
17 | TP_STRUCT__entry( | ||
18 | __field(struct pt_regs *, regs) | ||
19 | ), | ||
20 | |||
21 | TP_fast_assign( | ||
22 | __entry->regs = regs; | ||
23 | ), | ||
24 | |||
25 | TP_printk("pt_regs=%p", __entry->regs) | ||
26 | ); | ||
27 | |||
28 | TRACE_EVENT(irq_exit, | ||
29 | |||
30 | TP_PROTO(struct pt_regs *regs), | ||
31 | |||
32 | TP_ARGS(regs), | ||
33 | |||
34 | TP_STRUCT__entry( | ||
35 | __field(struct pt_regs *, regs) | ||
36 | ), | ||
37 | |||
38 | TP_fast_assign( | ||
39 | __entry->regs = regs; | ||
40 | ), | ||
41 | |||
42 | TP_printk("pt_regs=%p", __entry->regs) | ||
43 | ); | ||
44 | |||
45 | TRACE_EVENT(timer_interrupt_entry, | ||
46 | |||
47 | TP_PROTO(struct pt_regs *regs), | ||
48 | |||
49 | TP_ARGS(regs), | ||
50 | |||
51 | TP_STRUCT__entry( | ||
52 | __field(struct pt_regs *, regs) | ||
53 | ), | ||
54 | |||
55 | TP_fast_assign( | ||
56 | __entry->regs = regs; | ||
57 | ), | ||
58 | |||
59 | TP_printk("pt_regs=%p", __entry->regs) | ||
60 | ); | ||
61 | |||
62 | TRACE_EVENT(timer_interrupt_exit, | ||
63 | |||
64 | TP_PROTO(struct pt_regs *regs), | ||
65 | |||
66 | TP_ARGS(regs), | ||
67 | |||
68 | TP_STRUCT__entry( | ||
69 | __field(struct pt_regs *, regs) | ||
70 | ), | ||
71 | |||
72 | TP_fast_assign( | ||
73 | __entry->regs = regs; | ||
74 | ), | ||
75 | |||
76 | TP_printk("pt_regs=%p", __entry->regs) | ||
77 | ); | ||
78 | |||
79 | #ifdef CONFIG_PPC_PSERIES | ||
80 | extern void hcall_tracepoint_regfunc(void); | ||
81 | extern void hcall_tracepoint_unregfunc(void); | ||
82 | |||
83 | TRACE_EVENT_FN(hcall_entry, | ||
84 | |||
85 | TP_PROTO(unsigned long opcode, unsigned long *args), | ||
86 | |||
87 | TP_ARGS(opcode, args), | ||
88 | |||
89 | TP_STRUCT__entry( | ||
90 | __field(unsigned long, opcode) | ||
91 | ), | ||
92 | |||
93 | TP_fast_assign( | ||
94 | __entry->opcode = opcode; | ||
95 | ), | ||
96 | |||
97 | TP_printk("opcode=%lu", __entry->opcode), | ||
98 | |||
99 | hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc | ||
100 | ); | ||
101 | |||
102 | TRACE_EVENT_FN(hcall_exit, | ||
103 | |||
104 | TP_PROTO(unsigned long opcode, unsigned long retval, | ||
105 | unsigned long *retbuf), | ||
106 | |||
107 | TP_ARGS(opcode, retval, retbuf), | ||
108 | |||
109 | TP_STRUCT__entry( | ||
110 | __field(unsigned long, opcode) | ||
111 | __field(unsigned long, retval) | ||
112 | ), | ||
113 | |||
114 | TP_fast_assign( | ||
115 | __entry->opcode = opcode; | ||
116 | __entry->retval = retval; | ||
117 | ), | ||
118 | |||
119 | TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval), | ||
120 | |||
121 | hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc | ||
122 | ); | ||
123 | #endif | ||
124 | |||
125 | #endif /* _TRACE_POWERPC_H */ | ||
126 | |||
127 | #undef TRACE_INCLUDE_PATH | ||
128 | #undef TRACE_INCLUDE_FILE | ||
129 | |||
130 | #define TRACE_INCLUDE_PATH asm | ||
131 | #define TRACE_INCLUDE_FILE trace | ||
132 | |||
133 | #include <trace/define_trace.h> | ||
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index a5b632e52fae..3839839f83c7 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c | |||
@@ -732,7 +732,7 @@ int fix_alignment(struct pt_regs *regs) | |||
732 | 732 | ||
733 | #ifdef CONFIG_SPE | 733 | #ifdef CONFIG_SPE |
734 | if ((instr >> 26) == 0x4) { | 734 | if ((instr >> 26) == 0x4) { |
735 | PPC_WARN_EMULATED(spe); | 735 | PPC_WARN_ALIGNMENT(spe, regs); |
736 | return emulate_spe(regs, reg, instr); | 736 | return emulate_spe(regs, reg, instr); |
737 | } | 737 | } |
738 | #endif | 738 | #endif |
@@ -786,7 +786,7 @@ int fix_alignment(struct pt_regs *regs) | |||
786 | flags |= SPLT; | 786 | flags |= SPLT; |
787 | nb = 8; | 787 | nb = 8; |
788 | } | 788 | } |
789 | PPC_WARN_EMULATED(vsx); | 789 | PPC_WARN_ALIGNMENT(vsx, regs); |
790 | return emulate_vsx(addr, reg, areg, regs, flags, nb); | 790 | return emulate_vsx(addr, reg, areg, regs, flags, nb); |
791 | } | 791 | } |
792 | #endif | 792 | #endif |
@@ -794,7 +794,7 @@ int fix_alignment(struct pt_regs *regs) | |||
794 | * the exception of DCBZ which is handled as a special case here | 794 | * the exception of DCBZ which is handled as a special case here |
795 | */ | 795 | */ |
796 | if (instr == DCBZ) { | 796 | if (instr == DCBZ) { |
797 | PPC_WARN_EMULATED(dcbz); | 797 | PPC_WARN_ALIGNMENT(dcbz, regs); |
798 | return emulate_dcbz(regs, addr); | 798 | return emulate_dcbz(regs, addr); |
799 | } | 799 | } |
800 | if (unlikely(nb == 0)) | 800 | if (unlikely(nb == 0)) |
@@ -804,7 +804,7 @@ int fix_alignment(struct pt_regs *regs) | |||
804 | * function | 804 | * function |
805 | */ | 805 | */ |
806 | if (flags & M) { | 806 | if (flags & M) { |
807 | PPC_WARN_EMULATED(multiple); | 807 | PPC_WARN_ALIGNMENT(multiple, regs); |
808 | return emulate_multiple(regs, addr, reg, nb, | 808 | return emulate_multiple(regs, addr, reg, nb, |
809 | flags, instr, swiz); | 809 | flags, instr, swiz); |
810 | } | 810 | } |
@@ -825,11 +825,11 @@ int fix_alignment(struct pt_regs *regs) | |||
825 | 825 | ||
826 | /* Special case for 16-byte FP loads and stores */ | 826 | /* Special case for 16-byte FP loads and stores */ |
827 | if (nb == 16) { | 827 | if (nb == 16) { |
828 | PPC_WARN_EMULATED(fp_pair); | 828 | PPC_WARN_ALIGNMENT(fp_pair, regs); |
829 | return emulate_fp_pair(addr, reg, flags); | 829 | return emulate_fp_pair(addr, reg, flags); |
830 | } | 830 | } |
831 | 831 | ||
832 | PPC_WARN_EMULATED(unaligned); | 832 | PPC_WARN_ALIGNMENT(unaligned, regs); |
833 | 833 | ||
834 | /* If we are loading, get the data from user space, else | 834 | /* If we are loading, get the data from user space, else |
835 | * get it from register values | 835 | * get it from register values |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 9763267e38b4..bdcb557d470a 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -551,7 +551,7 @@ restore: | |||
551 | BEGIN_FW_FTR_SECTION | 551 | BEGIN_FW_FTR_SECTION |
552 | ld r5,SOFTE(r1) | 552 | ld r5,SOFTE(r1) |
553 | FW_FTR_SECTION_ELSE | 553 | FW_FTR_SECTION_ELSE |
554 | b iseries_check_pending_irqs | 554 | b .Liseries_check_pending_irqs |
555 | ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) | 555 | ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) |
556 | 2: | 556 | 2: |
557 | TRACE_AND_RESTORE_IRQ(r5); | 557 | TRACE_AND_RESTORE_IRQ(r5); |
@@ -623,7 +623,7 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) | |||
623 | 623 | ||
624 | #endif /* CONFIG_PPC_BOOK3E */ | 624 | #endif /* CONFIG_PPC_BOOK3E */ |
625 | 625 | ||
626 | iseries_check_pending_irqs: | 626 | .Liseries_check_pending_irqs: |
627 | #ifdef CONFIG_PPC_ISERIES | 627 | #ifdef CONFIG_PPC_ISERIES |
628 | ld r5,SOFTE(r1) | 628 | ld r5,SOFTE(r1) |
629 | cmpdi 0,r5,0 | 629 | cmpdi 0,r5,0 |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index fc3ead066cec..e3be98ffe2a7 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -190,14 +190,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | |||
190 | * prolog code of the PerformanceMonitor one. A little | 190 | * prolog code of the PerformanceMonitor one. A little |
191 | * trickery is thus necessary | 191 | * trickery is thus necessary |
192 | */ | 192 | */ |
193 | performance_monitor_pSeries_1: | ||
193 | . = 0xf00 | 194 | . = 0xf00 |
194 | DO_KVM 0xf00 | 195 | DO_KVM 0xf00 |
195 | b performance_monitor_pSeries | 196 | b performance_monitor_pSeries |
196 | 197 | ||
198 | altivec_unavailable_pSeries_1: | ||
197 | . = 0xf20 | 199 | . = 0xf20 |
198 | DO_KVM 0xf20 | 200 | DO_KVM 0xf20 |
199 | b altivec_unavailable_pSeries | 201 | b altivec_unavailable_pSeries |
200 | 202 | ||
203 | vsx_unavailable_pSeries_1: | ||
201 | . = 0xf40 | 204 | . = 0xf40 |
202 | DO_KVM 0xf40 | 205 | DO_KVM 0xf40 |
203 | b vsx_unavailable_pSeries | 206 | b vsx_unavailable_pSeries |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 88d9c1d5e5fb..049dda60e475 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -110,18 +110,16 @@ int powersave_nap; | |||
110 | */ | 110 | */ |
111 | static ctl_table powersave_nap_ctl_table[]={ | 111 | static ctl_table powersave_nap_ctl_table[]={ |
112 | { | 112 | { |
113 | .ctl_name = KERN_PPC_POWERSAVE_NAP, | ||
114 | .procname = "powersave-nap", | 113 | .procname = "powersave-nap", |
115 | .data = &powersave_nap, | 114 | .data = &powersave_nap, |
116 | .maxlen = sizeof(int), | 115 | .maxlen = sizeof(int), |
117 | .mode = 0644, | 116 | .mode = 0644, |
118 | .proc_handler = &proc_dointvec, | 117 | .proc_handler = proc_dointvec, |
119 | }, | 118 | }, |
120 | {} | 119 | {} |
121 | }; | 120 | }; |
122 | static ctl_table powersave_nap_sysctl_root[] = { | 121 | static ctl_table powersave_nap_sysctl_root[] = { |
123 | { | 122 | { |
124 | .ctl_name = CTL_KERN, | ||
125 | .procname = "kernel", | 123 | .procname = "kernel", |
126 | .mode = 0555, | 124 | .mode = 0555, |
127 | .child = powersave_nap_ctl_table, | 125 | .child = powersave_nap_ctl_table, |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 042a53009701..f6dca4f4b295 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -70,6 +70,8 @@ | |||
70 | #include <asm/firmware.h> | 70 | #include <asm/firmware.h> |
71 | #include <asm/lv1call.h> | 71 | #include <asm/lv1call.h> |
72 | #endif | 72 | #endif |
73 | #define CREATE_TRACE_POINTS | ||
74 | #include <asm/trace.h> | ||
73 | 75 | ||
74 | int __irq_offset_value; | 76 | int __irq_offset_value; |
75 | static int ppc_spurious_interrupts; | 77 | static int ppc_spurious_interrupts; |
@@ -340,6 +342,8 @@ void do_IRQ(struct pt_regs *regs) | |||
340 | struct pt_regs *old_regs = set_irq_regs(regs); | 342 | struct pt_regs *old_regs = set_irq_regs(regs); |
341 | unsigned int irq; | 343 | unsigned int irq; |
342 | 344 | ||
345 | trace_irq_entry(regs); | ||
346 | |||
343 | irq_enter(); | 347 | irq_enter(); |
344 | 348 | ||
345 | check_stack_overflow(); | 349 | check_stack_overflow(); |
@@ -363,6 +367,8 @@ void do_IRQ(struct pt_regs *regs) | |||
363 | timer_interrupt(regs); | 367 | timer_interrupt(regs); |
364 | } | 368 | } |
365 | #endif | 369 | #endif |
370 | |||
371 | trace_irq_exit(regs); | ||
366 | } | 372 | } |
367 | 373 | ||
368 | void __init init_IRQ(void) | 374 | void __init init_IRQ(void) |
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index 87f1663584b0..1eb85fbf53a5 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c | |||
@@ -1165,7 +1165,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
1165 | */ | 1165 | */ |
1166 | if (record) { | 1166 | if (record) { |
1167 | struct perf_sample_data data = { | 1167 | struct perf_sample_data data = { |
1168 | .addr = 0, | 1168 | .addr = ~0ULL, |
1169 | .period = event->hw.last_period, | 1169 | .period = event->hw.last_period, |
1170 | }; | 1170 | }; |
1171 | 1171 | ||
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c index 0f4c1c73a6ad..199de527d411 100644 --- a/arch/powerpc/kernel/power5+-pmu.c +++ b/arch/powerpc/kernel/power5+-pmu.c | |||
@@ -73,10 +73,6 @@ | |||
73 | #define MMCR1_PMCSEL_MSK 0x7f | 73 | #define MMCR1_PMCSEL_MSK 0x7f |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Bits in MMCRA | ||
77 | */ | ||
78 | |||
79 | /* | ||
80 | * Layout of constraint bits: | 76 | * Layout of constraint bits: |
81 | * 6666555555555544444444443333333333222222222211111111110000000000 | 77 | * 6666555555555544444444443333333333222222222211111111110000000000 |
82 | * 3210987654321098765432109876543210987654321098765432109876543210 | 78 | * 3210987654321098765432109876543210987654321098765432109876543210 |
diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c index c351b3a57fbb..98b6a729a9dd 100644 --- a/arch/powerpc/kernel/power5-pmu.c +++ b/arch/powerpc/kernel/power5-pmu.c | |||
@@ -73,10 +73,6 @@ | |||
73 | #define MMCR1_PMCSEL_MSK 0x7f | 73 | #define MMCR1_PMCSEL_MSK 0x7f |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Bits in MMCRA | ||
77 | */ | ||
78 | |||
79 | /* | ||
80 | * Layout of constraint bits: | 76 | * Layout of constraint bits: |
81 | * 6666555555555544444444443333333333222222222211111111110000000000 | 77 | * 6666555555555544444444443333333333222222222211111111110000000000 |
82 | * 3210987654321098765432109876543210987654321098765432109876543210 | 78 | * 3210987654321098765432109876543210987654321098765432109876543210 |
@@ -390,7 +386,7 @@ static int power5_compute_mmcr(u64 event[], int n_ev, | |||
390 | unsigned int hwc[], unsigned long mmcr[]) | 386 | unsigned int hwc[], unsigned long mmcr[]) |
391 | { | 387 | { |
392 | unsigned long mmcr1 = 0; | 388 | unsigned long mmcr1 = 0; |
393 | unsigned long mmcra = 0; | 389 | unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; |
394 | unsigned int pmc, unit, byte, psel; | 390 | unsigned int pmc, unit, byte, psel; |
395 | unsigned int ttm, grp; | 391 | unsigned int ttm, grp; |
396 | int i, isbus, bit, grsel; | 392 | int i, isbus, bit, grsel; |
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c index ca399ba5034c..84a607bda8fb 100644 --- a/arch/powerpc/kernel/power6-pmu.c +++ b/arch/powerpc/kernel/power6-pmu.c | |||
@@ -178,7 +178,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev, | |||
178 | unsigned int hwc[], unsigned long mmcr[]) | 178 | unsigned int hwc[], unsigned long mmcr[]) |
179 | { | 179 | { |
180 | unsigned long mmcr1 = 0; | 180 | unsigned long mmcr1 = 0; |
181 | unsigned long mmcra = 0; | 181 | unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; |
182 | int i; | 182 | int i; |
183 | unsigned int pmc, ev, b, u, s, psel; | 183 | unsigned int pmc, ev, b, u, s, psel; |
184 | unsigned int ttmset = 0; | 184 | unsigned int ttmset = 0; |
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c index 28a4daacdc02..852f7b7f6b40 100644 --- a/arch/powerpc/kernel/power7-pmu.c +++ b/arch/powerpc/kernel/power7-pmu.c | |||
@@ -51,10 +51,6 @@ | |||
51 | #define MMCR1_PMCSEL_MSK 0xff | 51 | #define MMCR1_PMCSEL_MSK 0xff |
52 | 52 | ||
53 | /* | 53 | /* |
54 | * Bits in MMCRA | ||
55 | */ | ||
56 | |||
57 | /* | ||
58 | * Layout of constraint bits: | 54 | * Layout of constraint bits: |
59 | * 6666555555555544444444443333333333222222222211111111110000000000 | 55 | * 6666555555555544444444443333333333222222222211111111110000000000 |
60 | * 3210987654321098765432109876543210987654321098765432109876543210 | 56 | * 3210987654321098765432109876543210987654321098765432109876543210 |
@@ -230,7 +226,7 @@ static int power7_compute_mmcr(u64 event[], int n_ev, | |||
230 | unsigned int hwc[], unsigned long mmcr[]) | 226 | unsigned int hwc[], unsigned long mmcr[]) |
231 | { | 227 | { |
232 | unsigned long mmcr1 = 0; | 228 | unsigned long mmcr1 = 0; |
233 | unsigned long mmcra = 0; | 229 | unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; |
234 | unsigned int pmc, unit, combine, l2sel, psel; | 230 | unsigned int pmc, unit, combine, l2sel, psel; |
235 | unsigned int pmc_inuse = 0; | 231 | unsigned int pmc_inuse = 0; |
236 | int i; | 232 | int i; |
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index 479574413a93..8eff48e20dba 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c | |||
@@ -84,10 +84,6 @@ static short mmcr1_adder_bits[8] = { | |||
84 | }; | 84 | }; |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * Bits in MMCRA | ||
88 | */ | ||
89 | |||
90 | /* | ||
91 | * Layout of constraint bits: | 87 | * Layout of constraint bits: |
92 | * 6666555555555544444444443333333333222222222211111111110000000000 | 88 | * 6666555555555544444444443333333333222222222211111111110000000000 |
93 | * 3210987654321098765432109876543210987654321098765432109876543210 | 89 | * 3210987654321098765432109876543210987654321098765432109876543210 |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index d4405b95bfaa..4ec300862466 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1317,29 +1317,6 @@ struct device_node *of_find_next_cache_node(struct device_node *np) | |||
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | /** | 1319 | /** |
1320 | * of_find_all_nodes - Get next node in global list | ||
1321 | * @prev: Previous node or NULL to start iteration | ||
1322 | * of_node_put() will be called on it | ||
1323 | * | ||
1324 | * Returns a node pointer with refcount incremented, use | ||
1325 | * of_node_put() on it when done. | ||
1326 | */ | ||
1327 | struct device_node *of_find_all_nodes(struct device_node *prev) | ||
1328 | { | ||
1329 | struct device_node *np; | ||
1330 | |||
1331 | read_lock(&devtree_lock); | ||
1332 | np = prev ? prev->allnext : allnodes; | ||
1333 | for (; np != 0; np = np->allnext) | ||
1334 | if (of_node_get(np)) | ||
1335 | break; | ||
1336 | of_node_put(prev); | ||
1337 | read_unlock(&devtree_lock); | ||
1338 | return np; | ||
1339 | } | ||
1340 | EXPORT_SYMBOL(of_find_all_nodes); | ||
1341 | |||
1342 | /** | ||
1343 | * of_node_get - Increment refcount of a node | 1320 | * of_node_get - Increment refcount of a node |
1344 | * @node: Node to inc refcount, NULL is supported to | 1321 | * @node: Node to inc refcount, NULL is supported to |
1345 | * simplify writing of callers | 1322 | * simplify writing of callers |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 4271f7a655a3..845c72ab7357 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -660,6 +660,7 @@ late_initcall(check_cache_coherency); | |||
660 | 660 | ||
661 | #ifdef CONFIG_DEBUG_FS | 661 | #ifdef CONFIG_DEBUG_FS |
662 | struct dentry *powerpc_debugfs_root; | 662 | struct dentry *powerpc_debugfs_root; |
663 | EXPORT_SYMBOL(powerpc_debugfs_root); | ||
663 | 664 | ||
664 | static int powerpc_debugfs_init(void) | 665 | static int powerpc_debugfs_init(void) |
665 | { | 666 | { |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 53bcf3d792db..b152de3e64d4 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -345,7 +345,7 @@ void __init setup_arch(char **cmdline_p) | |||
345 | 345 | ||
346 | #ifdef CONFIG_SWIOTLB | 346 | #ifdef CONFIG_SWIOTLB |
347 | if (ppc_swiotlb_enable) | 347 | if (ppc_swiotlb_enable) |
348 | swiotlb_init(); | 348 | swiotlb_init(1); |
349 | #endif | 349 | #endif |
350 | 350 | ||
351 | paging_init(); | 351 | paging_init(); |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index fd785f7a279b..6568406b2a30 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -545,7 +545,7 @@ void __init setup_arch(char **cmdline_p) | |||
545 | 545 | ||
546 | #ifdef CONFIG_SWIOTLB | 546 | #ifdef CONFIG_SWIOTLB |
547 | if (ppc_swiotlb_enable) | 547 | if (ppc_swiotlb_enable) |
548 | swiotlb_init(); | 548 | swiotlb_init(1); |
549 | #endif | 549 | #endif |
550 | 550 | ||
551 | paging_init(); | 551 | paging_init(); |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index b97c2d67f4ac..c5a4732bcc48 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -520,58 +520,6 @@ asmlinkage long compat_sys_umask(u32 mask) | |||
520 | return sys_umask((int)mask); | 520 | return sys_umask((int)mask); |
521 | } | 521 | } |
522 | 522 | ||
523 | #ifdef CONFIG_SYSCTL_SYSCALL | ||
524 | struct __sysctl_args32 { | ||
525 | u32 name; | ||
526 | int nlen; | ||
527 | u32 oldval; | ||
528 | u32 oldlenp; | ||
529 | u32 newval; | ||
530 | u32 newlen; | ||
531 | u32 __unused[4]; | ||
532 | }; | ||
533 | |||
534 | asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args) | ||
535 | { | ||
536 | struct __sysctl_args32 tmp; | ||
537 | int error; | ||
538 | size_t oldlen; | ||
539 | size_t __user *oldlenp = NULL; | ||
540 | unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; | ||
541 | |||
542 | if (copy_from_user(&tmp, args, sizeof(tmp))) | ||
543 | return -EFAULT; | ||
544 | |||
545 | if (tmp.oldval && tmp.oldlenp) { | ||
546 | /* Duh, this is ugly and might not work if sysctl_args | ||
547 | is in read-only memory, but do_sysctl does indirectly | ||
548 | a lot of uaccess in both directions and we'd have to | ||
549 | basically copy the whole sysctl.c here, and | ||
550 | glibc's __sysctl uses rw memory for the structure | ||
551 | anyway. */ | ||
552 | oldlenp = (size_t __user *)addr; | ||
553 | if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) || | ||
554 | put_user(oldlen, oldlenp)) | ||
555 | return -EFAULT; | ||
556 | } | ||
557 | |||
558 | lock_kernel(); | ||
559 | error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, | ||
560 | compat_ptr(tmp.oldval), oldlenp, | ||
561 | compat_ptr(tmp.newval), tmp.newlen); | ||
562 | unlock_kernel(); | ||
563 | if (oldlenp) { | ||
564 | if (!error) { | ||
565 | if (get_user(oldlen, oldlenp) || | ||
566 | put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp))) | ||
567 | error = -EFAULT; | ||
568 | } | ||
569 | copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); | ||
570 | } | ||
571 | return error; | ||
572 | } | ||
573 | #endif | ||
574 | |||
575 | unsigned long compat_sys_mmap2(unsigned long addr, size_t len, | 523 | unsigned long compat_sys_mmap2(unsigned long addr, size_t len, |
576 | unsigned long prot, unsigned long flags, | 524 | unsigned long prot, unsigned long flags, |
577 | unsigned long fd, unsigned long pgoff) | 525 | unsigned long fd, unsigned long pgoff) |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 6c9e20898fa7..e9af16cc7c0c 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/irq.h> | 54 | #include <linux/irq.h> |
55 | #include <linux/delay.h> | 55 | #include <linux/delay.h> |
56 | #include <linux/perf_event.h> | 56 | #include <linux/perf_event.h> |
57 | #include <asm/trace.h> | ||
57 | 58 | ||
58 | #include <asm/io.h> | 59 | #include <asm/io.h> |
59 | #include <asm/processor.h> | 60 | #include <asm/processor.h> |
@@ -572,6 +573,8 @@ void timer_interrupt(struct pt_regs * regs) | |||
572 | struct clock_event_device *evt = &decrementer->event; | 573 | struct clock_event_device *evt = &decrementer->event; |
573 | u64 now; | 574 | u64 now; |
574 | 575 | ||
576 | trace_timer_interrupt_entry(regs); | ||
577 | |||
575 | /* Ensure a positive value is written to the decrementer, or else | 578 | /* Ensure a positive value is written to the decrementer, or else |
576 | * some CPUs will continuue to take decrementer exceptions */ | 579 | * some CPUs will continuue to take decrementer exceptions */ |
577 | set_dec(DECREMENTER_MAX); | 580 | set_dec(DECREMENTER_MAX); |
@@ -591,6 +594,7 @@ void timer_interrupt(struct pt_regs * regs) | |||
591 | now = decrementer->next_tb - now; | 594 | now = decrementer->next_tb - now; |
592 | if (now <= DECREMENTER_MAX) | 595 | if (now <= DECREMENTER_MAX) |
593 | set_dec((int)now); | 596 | set_dec((int)now); |
597 | trace_timer_interrupt_exit(regs); | ||
594 | return; | 598 | return; |
595 | } | 599 | } |
596 | old_regs = set_irq_regs(regs); | 600 | old_regs = set_irq_regs(regs); |
@@ -621,6 +625,8 @@ void timer_interrupt(struct pt_regs * regs) | |||
621 | 625 | ||
622 | irq_exit(); | 626 | irq_exit(); |
623 | set_irq_regs(old_regs); | 627 | set_irq_regs(old_regs); |
628 | |||
629 | trace_timer_interrupt_exit(regs); | ||
624 | } | 630 | } |
625 | 631 | ||
626 | void wakeup_decrementer(void) | 632 | void wakeup_decrementer(void) |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index a81c7438d341..804f0f30f227 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -737,7 +737,7 @@ static int emulate_instruction(struct pt_regs *regs) | |||
737 | 737 | ||
738 | /* Emulate the mfspr rD, PVR. */ | 738 | /* Emulate the mfspr rD, PVR. */ |
739 | if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { | 739 | if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { |
740 | PPC_WARN_EMULATED(mfpvr); | 740 | PPC_WARN_EMULATED(mfpvr, regs); |
741 | rd = (instword >> 21) & 0x1f; | 741 | rd = (instword >> 21) & 0x1f; |
742 | regs->gpr[rd] = mfspr(SPRN_PVR); | 742 | regs->gpr[rd] = mfspr(SPRN_PVR); |
743 | return 0; | 743 | return 0; |
@@ -745,7 +745,7 @@ static int emulate_instruction(struct pt_regs *regs) | |||
745 | 745 | ||
746 | /* Emulating the dcba insn is just a no-op. */ | 746 | /* Emulating the dcba insn is just a no-op. */ |
747 | if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) { | 747 | if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) { |
748 | PPC_WARN_EMULATED(dcba); | 748 | PPC_WARN_EMULATED(dcba, regs); |
749 | return 0; | 749 | return 0; |
750 | } | 750 | } |
751 | 751 | ||
@@ -754,7 +754,7 @@ static int emulate_instruction(struct pt_regs *regs) | |||
754 | int shift = (instword >> 21) & 0x1c; | 754 | int shift = (instword >> 21) & 0x1c; |
755 | unsigned long msk = 0xf0000000UL >> shift; | 755 | unsigned long msk = 0xf0000000UL >> shift; |
756 | 756 | ||
757 | PPC_WARN_EMULATED(mcrxr); | 757 | PPC_WARN_EMULATED(mcrxr, regs); |
758 | regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); | 758 | regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); |
759 | regs->xer &= ~0xf0000000UL; | 759 | regs->xer &= ~0xf0000000UL; |
760 | return 0; | 760 | return 0; |
@@ -762,19 +762,19 @@ static int emulate_instruction(struct pt_regs *regs) | |||
762 | 762 | ||
763 | /* Emulate load/store string insn. */ | 763 | /* Emulate load/store string insn. */ |
764 | if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { | 764 | if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { |
765 | PPC_WARN_EMULATED(string); | 765 | PPC_WARN_EMULATED(string, regs); |
766 | return emulate_string_inst(regs, instword); | 766 | return emulate_string_inst(regs, instword); |
767 | } | 767 | } |
768 | 768 | ||
769 | /* Emulate the popcntb (Population Count Bytes) instruction. */ | 769 | /* Emulate the popcntb (Population Count Bytes) instruction. */ |
770 | if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { | 770 | if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { |
771 | PPC_WARN_EMULATED(popcntb); | 771 | PPC_WARN_EMULATED(popcntb, regs); |
772 | return emulate_popcntb_inst(regs, instword); | 772 | return emulate_popcntb_inst(regs, instword); |
773 | } | 773 | } |
774 | 774 | ||
775 | /* Emulate isel (Integer Select) instruction */ | 775 | /* Emulate isel (Integer Select) instruction */ |
776 | if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { | 776 | if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { |
777 | PPC_WARN_EMULATED(isel); | 777 | PPC_WARN_EMULATED(isel, regs); |
778 | return emulate_isel(regs, instword); | 778 | return emulate_isel(regs, instword); |
779 | } | 779 | } |
780 | 780 | ||
@@ -973,7 +973,7 @@ void SoftwareEmulation(struct pt_regs *regs) | |||
973 | #ifdef CONFIG_MATH_EMULATION | 973 | #ifdef CONFIG_MATH_EMULATION |
974 | errcode = do_mathemu(regs); | 974 | errcode = do_mathemu(regs); |
975 | if (errcode >= 0) | 975 | if (errcode >= 0) |
976 | PPC_WARN_EMULATED(math); | 976 | PPC_WARN_EMULATED(math, regs); |
977 | 977 | ||
978 | switch (errcode) { | 978 | switch (errcode) { |
979 | case 0: | 979 | case 0: |
@@ -996,7 +996,7 @@ void SoftwareEmulation(struct pt_regs *regs) | |||
996 | #elif defined(CONFIG_8XX_MINIMAL_FPEMU) | 996 | #elif defined(CONFIG_8XX_MINIMAL_FPEMU) |
997 | errcode = Soft_emulate_8xx(regs); | 997 | errcode = Soft_emulate_8xx(regs); |
998 | if (errcode >= 0) | 998 | if (errcode >= 0) |
999 | PPC_WARN_EMULATED(8xx); | 999 | PPC_WARN_EMULATED(8xx, regs); |
1000 | 1000 | ||
1001 | switch (errcode) { | 1001 | switch (errcode) { |
1002 | case 0: | 1002 | case 0: |
@@ -1107,7 +1107,7 @@ void altivec_assist_exception(struct pt_regs *regs) | |||
1107 | 1107 | ||
1108 | flush_altivec_to_thread(current); | 1108 | flush_altivec_to_thread(current); |
1109 | 1109 | ||
1110 | PPC_WARN_EMULATED(altivec); | 1110 | PPC_WARN_EMULATED(altivec, regs); |
1111 | err = emulate_altivec(regs); | 1111 | err = emulate_altivec(regs); |
1112 | if (err == 0) { | 1112 | if (err == 0) { |
1113 | regs->nip += 4; /* skip emulated instruction */ | 1113 | regs->nip += 4; /* skip emulated instruction */ |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index d82551efbfbf..f06cf93b178e 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -79,8 +79,9 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
79 | return r; | 79 | return r; |
80 | } | 80 | } |
81 | 81 | ||
82 | void kvm_arch_hardware_enable(void *garbage) | 82 | int kvm_arch_hardware_enable(void *garbage) |
83 | { | 83 | { |
84 | return 0; | ||
84 | } | 85 | } |
85 | 86 | ||
86 | void kvm_arch_hardware_disable(void *garbage) | 87 | void kvm_arch_hardware_disable(void *garbage) |
@@ -435,7 +436,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
435 | 436 | ||
436 | switch (ioctl) { | 437 | switch (ioctl) { |
437 | default: | 438 | default: |
438 | r = -EINVAL; | 439 | r = -ENOTTY; |
439 | } | 440 | } |
440 | 441 | ||
441 | return r; | 442 | return r; |
diff --git a/arch/powerpc/kvm/timing.h b/arch/powerpc/kvm/timing.h index 806ef67868bd..8167d42a776f 100644 --- a/arch/powerpc/kvm/timing.h +++ b/arch/powerpc/kvm/timing.h | |||
@@ -51,7 +51,7 @@ static inline void kvmppc_account_exit_stat(struct kvm_vcpu *vcpu, int type) | |||
51 | 51 | ||
52 | /* The BUILD_BUG_ON below breaks in funny ways, commented out | 52 | /* The BUILD_BUG_ON below breaks in funny ways, commented out |
53 | * for now ... -BenH | 53 | * for now ... -BenH |
54 | BUILD_BUG_ON(__builtin_constant_p(type)); | 54 | BUILD_BUG_ON(!__builtin_constant_p(type)); |
55 | */ | 55 | */ |
56 | switch (type) { | 56 | switch (type) { |
57 | case EXT_INTR_EXITS: | 57 | case EXT_INTR_EXITS: |
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S index 75f3267fdc30..e68beac0a171 100644 --- a/arch/powerpc/lib/copypage_64.S +++ b/arch/powerpc/lib/copypage_64.S | |||
@@ -26,11 +26,11 @@ BEGIN_FTR_SECTION | |||
26 | srd r8,r5,r11 | 26 | srd r8,r5,r11 |
27 | 27 | ||
28 | mtctr r8 | 28 | mtctr r8 |
29 | setup: | 29 | .Lsetup: |
30 | dcbt r9,r4 | 30 | dcbt r9,r4 |
31 | dcbz r9,r3 | 31 | dcbz r9,r3 |
32 | add r9,r9,r12 | 32 | add r9,r9,r12 |
33 | bdnz setup | 33 | bdnz .Lsetup |
34 | END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ) | 34 | END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ) |
35 | addi r3,r3,-8 | 35 | addi r3,r3,-8 |
36 | srdi r8,r5,7 /* page is copied in 128 byte strides */ | 36 | srdi r8,r5,7 /* page is copied in 128 byte strides */ |
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 414ca9849f23..345e2da56767 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
43 | #include <linux/timer.h> | 43 | #include <linux/timer.h> |
44 | #include <linux/mutex.h> | 44 | #include <linux/mutex.h> |
45 | #include <linux/i2c.h> | ||
45 | #include <asm/keylargo.h> | 46 | #include <asm/keylargo.h> |
46 | #include <asm/uninorth.h> | 47 | #include <asm/uninorth.h> |
47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
@@ -80,7 +81,7 @@ struct pmac_i2c_bus | |||
80 | struct device_node *busnode; | 81 | struct device_node *busnode; |
81 | int type; | 82 | int type; |
82 | int flags; | 83 | int flags; |
83 | struct i2c_adapter *adapter; | 84 | struct i2c_adapter adapter; |
84 | void *hostdata; | 85 | void *hostdata; |
85 | int channel; /* some hosts have multiple */ | 86 | int channel; /* some hosts have multiple */ |
86 | int mode; /* current mode */ | 87 | int mode; /* current mode */ |
@@ -1014,25 +1015,9 @@ int pmac_i2c_get_channel(struct pmac_i2c_bus *bus) | |||
1014 | EXPORT_SYMBOL_GPL(pmac_i2c_get_channel); | 1015 | EXPORT_SYMBOL_GPL(pmac_i2c_get_channel); |
1015 | 1016 | ||
1016 | 1017 | ||
1017 | void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus, | ||
1018 | struct i2c_adapter *adapter) | ||
1019 | { | ||
1020 | WARN_ON(bus->adapter != NULL); | ||
1021 | bus->adapter = adapter; | ||
1022 | } | ||
1023 | EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter); | ||
1024 | |||
1025 | void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus, | ||
1026 | struct i2c_adapter *adapter) | ||
1027 | { | ||
1028 | WARN_ON(bus->adapter != adapter); | ||
1029 | bus->adapter = NULL; | ||
1030 | } | ||
1031 | EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter); | ||
1032 | |||
1033 | struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus) | 1018 | struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus) |
1034 | { | 1019 | { |
1035 | return bus->adapter; | 1020 | return &bus->adapter; |
1036 | } | 1021 | } |
1037 | EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter); | 1022 | EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter); |
1038 | 1023 | ||
@@ -1041,7 +1026,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter) | |||
1041 | struct pmac_i2c_bus *bus; | 1026 | struct pmac_i2c_bus *bus; |
1042 | 1027 | ||
1043 | list_for_each_entry(bus, &pmac_i2c_busses, link) | 1028 | list_for_each_entry(bus, &pmac_i2c_busses, link) |
1044 | if (bus->adapter == adapter) | 1029 | if (&bus->adapter == adapter) |
1045 | return bus; | 1030 | return bus; |
1046 | return NULL; | 1031 | return NULL; |
1047 | } | 1032 | } |
@@ -1053,7 +1038,7 @@ int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter) | |||
1053 | 1038 | ||
1054 | if (bus == NULL) | 1039 | if (bus == NULL) |
1055 | return 0; | 1040 | return 0; |
1056 | return (bus->adapter == adapter); | 1041 | return (&bus->adapter == adapter); |
1057 | } | 1042 | } |
1058 | EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter); | 1043 | EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter); |
1059 | 1044 | ||
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index c1427b3634ec..383a5d0e9818 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S | |||
@@ -14,68 +14,94 @@ | |||
14 | 14 | ||
15 | #define STK_PARM(i) (48 + ((i)-3)*8) | 15 | #define STK_PARM(i) (48 + ((i)-3)*8) |
16 | 16 | ||
17 | #ifdef CONFIG_HCALL_STATS | 17 | #ifdef CONFIG_TRACEPOINTS |
18 | |||
19 | .section ".toc","aw" | ||
20 | |||
21 | .globl hcall_tracepoint_refcount | ||
22 | hcall_tracepoint_refcount: | ||
23 | .llong 0 | ||
24 | |||
25 | .section ".text" | ||
26 | |||
18 | /* | 27 | /* |
19 | * precall must preserve all registers. use unused STK_PARM() | 28 | * precall must preserve all registers. use unused STK_PARM() |
20 | * areas to save snapshots and opcode. | 29 | * areas to save snapshots and opcode. We branch around this |
30 | * in early init (eg when populating the MMU hashtable) by using an | ||
31 | * unconditional cpu feature. | ||
21 | */ | 32 | */ |
22 | #define HCALL_INST_PRECALL \ | 33 | #define HCALL_INST_PRECALL(FIRST_REG) \ |
23 | std r3,STK_PARM(r3)(r1); /* save opcode */ \ | ||
24 | mftb r0; /* get timebase and */ \ | ||
25 | std r0,STK_PARM(r5)(r1); /* save for later */ \ | ||
26 | BEGIN_FTR_SECTION; \ | 34 | BEGIN_FTR_SECTION; \ |
27 | mfspr r0,SPRN_PURR; /* get PURR and */ \ | 35 | b 1f; \ |
28 | std r0,STK_PARM(r6)(r1); /* save for later */ \ | 36 | END_FTR_SECTION(0, 1); \ |
29 | END_FTR_SECTION_IFSET(CPU_FTR_PURR); | 37 | ld r12,hcall_tracepoint_refcount@toc(r2); \ |
30 | 38 | cmpdi r12,0; \ | |
39 | beq+ 1f; \ | ||
40 | mflr r0; \ | ||
41 | std r3,STK_PARM(r3)(r1); \ | ||
42 | std r4,STK_PARM(r4)(r1); \ | ||
43 | std r5,STK_PARM(r5)(r1); \ | ||
44 | std r6,STK_PARM(r6)(r1); \ | ||
45 | std r7,STK_PARM(r7)(r1); \ | ||
46 | std r8,STK_PARM(r8)(r1); \ | ||
47 | std r9,STK_PARM(r9)(r1); \ | ||
48 | std r10,STK_PARM(r10)(r1); \ | ||
49 | std r0,16(r1); \ | ||
50 | addi r4,r1,STK_PARM(FIRST_REG); \ | ||
51 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ | ||
52 | bl .__trace_hcall_entry; \ | ||
53 | addi r1,r1,STACK_FRAME_OVERHEAD; \ | ||
54 | ld r0,16(r1); \ | ||
55 | ld r3,STK_PARM(r3)(r1); \ | ||
56 | ld r4,STK_PARM(r4)(r1); \ | ||
57 | ld r5,STK_PARM(r5)(r1); \ | ||
58 | ld r6,STK_PARM(r6)(r1); \ | ||
59 | ld r7,STK_PARM(r7)(r1); \ | ||
60 | ld r8,STK_PARM(r8)(r1); \ | ||
61 | ld r9,STK_PARM(r9)(r1); \ | ||
62 | ld r10,STK_PARM(r10)(r1); \ | ||
63 | mtlr r0; \ | ||
64 | 1: | ||
65 | |||
31 | /* | 66 | /* |
32 | * postcall is performed immediately before function return which | 67 | * postcall is performed immediately before function return which |
33 | * allows liberal use of volatile registers. We branch around this | 68 | * allows liberal use of volatile registers. We branch around this |
34 | * in early init (eg when populating the MMU hashtable) by using an | 69 | * in early init (eg when populating the MMU hashtable) by using an |
35 | * unconditional cpu feature. | 70 | * unconditional cpu feature. |
36 | */ | 71 | */ |
37 | #define HCALL_INST_POSTCALL \ | 72 | #define __HCALL_INST_POSTCALL \ |
38 | BEGIN_FTR_SECTION; \ | 73 | BEGIN_FTR_SECTION; \ |
39 | b 1f; \ | 74 | b 1f; \ |
40 | END_FTR_SECTION(0, 1); \ | 75 | END_FTR_SECTION(0, 1); \ |
41 | ld r4,STK_PARM(r3)(r1); /* validate opcode */ \ | 76 | ld r12,hcall_tracepoint_refcount@toc(r2); \ |
42 | cmpldi cr7,r4,MAX_HCALL_OPCODE; \ | 77 | cmpdi r12,0; \ |
43 | bgt- cr7,1f; \ | 78 | beq+ 1f; \ |
44 | \ | 79 | mflr r0; \ |
45 | /* get time and PURR snapshots after hcall */ \ | 80 | ld r6,STK_PARM(r3)(r1); \ |
46 | mftb r7; /* timebase after */ \ | 81 | std r3,STK_PARM(r3)(r1); \ |
47 | BEGIN_FTR_SECTION; \ | 82 | mr r4,r3; \ |
48 | mfspr r8,SPRN_PURR; /* PURR after */ \ | 83 | mr r3,r6; \ |
49 | ld r6,STK_PARM(r6)(r1); /* PURR before */ \ | 84 | std r0,16(r1); \ |
50 | subf r6,r6,r8; /* delta */ \ | 85 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ |
51 | END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ | 86 | bl .__trace_hcall_exit; \ |
52 | ld r5,STK_PARM(r5)(r1); /* timebase before */ \ | 87 | addi r1,r1,STACK_FRAME_OVERHEAD; \ |
53 | subf r5,r5,r7; /* time delta */ \ | 88 | ld r0,16(r1); \ |
54 | \ | 89 | ld r3,STK_PARM(r3)(r1); \ |
55 | /* calculate address of stat structure r4 = opcode */ \ | 90 | mtlr r0; \ |
56 | srdi r4,r4,2; /* index into array */ \ | ||
57 | mulli r4,r4,HCALL_STAT_SIZE; \ | ||
58 | LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \ | ||
59 | add r4,r4,r7; \ | ||
60 | ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \ | ||
61 | add r4,r4,r7; \ | ||
62 | \ | ||
63 | /* update stats */ \ | ||
64 | ld r7,HCALL_STAT_CALLS(r4); /* count */ \ | ||
65 | addi r7,r7,1; \ | ||
66 | std r7,HCALL_STAT_CALLS(r4); \ | ||
67 | ld r7,HCALL_STAT_TB(r4); /* timebase */ \ | ||
68 | add r7,r7,r5; \ | ||
69 | std r7,HCALL_STAT_TB(r4); \ | ||
70 | BEGIN_FTR_SECTION; \ | ||
71 | ld r7,HCALL_STAT_PURR(r4); /* PURR */ \ | ||
72 | add r7,r7,r6; \ | ||
73 | std r7,HCALL_STAT_PURR(r4); \ | ||
74 | END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ | ||
75 | 1: | 91 | 1: |
92 | |||
93 | #define HCALL_INST_POSTCALL_NORETS \ | ||
94 | li r5,0; \ | ||
95 | __HCALL_INST_POSTCALL | ||
96 | |||
97 | #define HCALL_INST_POSTCALL(BUFREG) \ | ||
98 | mr r5,BUFREG; \ | ||
99 | __HCALL_INST_POSTCALL | ||
100 | |||
76 | #else | 101 | #else |
77 | #define HCALL_INST_PRECALL | 102 | #define HCALL_INST_PRECALL(FIRST_ARG) |
78 | #define HCALL_INST_POSTCALL | 103 | #define HCALL_INST_POSTCALL_NORETS |
104 | #define HCALL_INST_POSTCALL(BUFREG) | ||
79 | #endif | 105 | #endif |
80 | 106 | ||
81 | .text | 107 | .text |
@@ -86,11 +112,11 @@ _GLOBAL(plpar_hcall_norets) | |||
86 | mfcr r0 | 112 | mfcr r0 |
87 | stw r0,8(r1) | 113 | stw r0,8(r1) |
88 | 114 | ||
89 | HCALL_INST_PRECALL | 115 | HCALL_INST_PRECALL(r4) |
90 | 116 | ||
91 | HVSC /* invoke the hypervisor */ | 117 | HVSC /* invoke the hypervisor */ |
92 | 118 | ||
93 | HCALL_INST_POSTCALL | 119 | HCALL_INST_POSTCALL_NORETS |
94 | 120 | ||
95 | lwz r0,8(r1) | 121 | lwz r0,8(r1) |
96 | mtcrf 0xff,r0 | 122 | mtcrf 0xff,r0 |
@@ -102,7 +128,7 @@ _GLOBAL(plpar_hcall) | |||
102 | mfcr r0 | 128 | mfcr r0 |
103 | stw r0,8(r1) | 129 | stw r0,8(r1) |
104 | 130 | ||
105 | HCALL_INST_PRECALL | 131 | HCALL_INST_PRECALL(r5) |
106 | 132 | ||
107 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ | 133 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ |
108 | 134 | ||
@@ -121,7 +147,7 @@ _GLOBAL(plpar_hcall) | |||
121 | std r6, 16(r12) | 147 | std r6, 16(r12) |
122 | std r7, 24(r12) | 148 | std r7, 24(r12) |
123 | 149 | ||
124 | HCALL_INST_POSTCALL | 150 | HCALL_INST_POSTCALL(r12) |
125 | 151 | ||
126 | lwz r0,8(r1) | 152 | lwz r0,8(r1) |
127 | mtcrf 0xff,r0 | 153 | mtcrf 0xff,r0 |
@@ -168,7 +194,7 @@ _GLOBAL(plpar_hcall9) | |||
168 | mfcr r0 | 194 | mfcr r0 |
169 | stw r0,8(r1) | 195 | stw r0,8(r1) |
170 | 196 | ||
171 | HCALL_INST_PRECALL | 197 | HCALL_INST_PRECALL(r5) |
172 | 198 | ||
173 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ | 199 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ |
174 | 200 | ||
@@ -196,7 +222,7 @@ _GLOBAL(plpar_hcall9) | |||
196 | std r11,56(r12) | 222 | std r11,56(r12) |
197 | std r0, 64(r12) | 223 | std r0, 64(r12) |
198 | 224 | ||
199 | HCALL_INST_POSTCALL | 225 | HCALL_INST_POSTCALL(r12) |
200 | 226 | ||
201 | lwz r0,8(r1) | 227 | lwz r0,8(r1) |
202 | mtcrf 0xff,r0 | 228 | mtcrf 0xff,r0 |
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index 3631a4f277eb..2f58c71b7259 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/hvcall.h> | 26 | #include <asm/hvcall.h> |
27 | #include <asm/firmware.h> | 27 | #include <asm/firmware.h> |
28 | #include <asm/cputable.h> | 28 | #include <asm/cputable.h> |
29 | #include <asm/trace.h> | ||
29 | 30 | ||
30 | DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats); | 31 | DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats); |
31 | 32 | ||
@@ -100,6 +101,35 @@ static const struct file_operations hcall_inst_seq_fops = { | |||
100 | #define HCALL_ROOT_DIR "hcall_inst" | 101 | #define HCALL_ROOT_DIR "hcall_inst" |
101 | #define CPU_NAME_BUF_SIZE 32 | 102 | #define CPU_NAME_BUF_SIZE 32 |
102 | 103 | ||
104 | |||
105 | static void probe_hcall_entry(unsigned long opcode, unsigned long *args) | ||
106 | { | ||
107 | struct hcall_stats *h; | ||
108 | |||
109 | if (opcode > MAX_HCALL_OPCODE) | ||
110 | return; | ||
111 | |||
112 | h = &get_cpu_var(hcall_stats)[opcode / 4]; | ||
113 | h->tb_start = mftb(); | ||
114 | h->purr_start = mfspr(SPRN_PURR); | ||
115 | } | ||
116 | |||
117 | static void probe_hcall_exit(unsigned long opcode, unsigned long retval, | ||
118 | unsigned long *retbuf) | ||
119 | { | ||
120 | struct hcall_stats *h; | ||
121 | |||
122 | if (opcode > MAX_HCALL_OPCODE) | ||
123 | return; | ||
124 | |||
125 | h = &__get_cpu_var(hcall_stats)[opcode / 4]; | ||
126 | h->num_calls++; | ||
127 | h->tb_total = mftb() - h->tb_start; | ||
128 | h->purr_total = mfspr(SPRN_PURR) - h->purr_start; | ||
129 | |||
130 | put_cpu_var(hcall_stats); | ||
131 | } | ||
132 | |||
103 | static int __init hcall_inst_init(void) | 133 | static int __init hcall_inst_init(void) |
104 | { | 134 | { |
105 | struct dentry *hcall_root; | 135 | struct dentry *hcall_root; |
@@ -110,6 +140,14 @@ static int __init hcall_inst_init(void) | |||
110 | if (!firmware_has_feature(FW_FEATURE_LPAR)) | 140 | if (!firmware_has_feature(FW_FEATURE_LPAR)) |
111 | return 0; | 141 | return 0; |
112 | 142 | ||
143 | if (register_trace_hcall_entry(probe_hcall_entry)) | ||
144 | return -EINVAL; | ||
145 | |||
146 | if (register_trace_hcall_exit(probe_hcall_exit)) { | ||
147 | unregister_trace_hcall_entry(probe_hcall_entry); | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | |||
113 | hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL); | 151 | hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL); |
114 | if (!hcall_root) | 152 | if (!hcall_root) |
115 | return -ENOMEM; | 153 | return -ENOMEM; |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 903eb9eec687..0707653612ba 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <asm/cputable.h> | 39 | #include <asm/cputable.h> |
40 | #include <asm/udbg.h> | 40 | #include <asm/udbg.h> |
41 | #include <asm/smp.h> | 41 | #include <asm/smp.h> |
42 | #include <asm/trace.h> | ||
42 | 43 | ||
43 | #include "plpar_wrappers.h" | 44 | #include "plpar_wrappers.h" |
44 | #include "pseries.h" | 45 | #include "pseries.h" |
@@ -661,3 +662,35 @@ void arch_free_page(struct page *page, int order) | |||
661 | EXPORT_SYMBOL(arch_free_page); | 662 | EXPORT_SYMBOL(arch_free_page); |
662 | 663 | ||
663 | #endif | 664 | #endif |
665 | |||
666 | #ifdef CONFIG_TRACEPOINTS | ||
667 | /* | ||
668 | * We optimise our hcall path by placing hcall_tracepoint_refcount | ||
669 | * directly in the TOC so we can check if the hcall tracepoints are | ||
670 | * enabled via a single load. | ||
671 | */ | ||
672 | |||
673 | /* NB: reg/unreg are called while guarded with the tracepoints_mutex */ | ||
674 | extern long hcall_tracepoint_refcount; | ||
675 | |||
676 | void hcall_tracepoint_regfunc(void) | ||
677 | { | ||
678 | hcall_tracepoint_refcount++; | ||
679 | } | ||
680 | |||
681 | void hcall_tracepoint_unregfunc(void) | ||
682 | { | ||
683 | hcall_tracepoint_refcount--; | ||
684 | } | ||
685 | |||
686 | void __trace_hcall_entry(unsigned long opcode, unsigned long *args) | ||
687 | { | ||
688 | trace_hcall_entry(opcode, args); | ||
689 | } | ||
690 | |||
691 | void __trace_hcall_exit(long opcode, unsigned long retval, | ||
692 | unsigned long *retbuf) | ||
693 | { | ||
694 | trace_hcall_exit(opcode, retval, retbuf); | ||
695 | } | ||
696 | #endif | ||