diff options
Diffstat (limited to 'arch/powerpc')
38 files changed, 422 insertions, 305 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 4c0cedf4e2c7..ce4c68a4a823 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -150,7 +150,9 @@ endif | |||
150 | 150 | ||
151 | CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell) | 151 | CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell) |
152 | 152 | ||
153 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) | 153 | asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) |
154 | |||
155 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr) | ||
154 | KBUILD_AFLAGS += -Iarch/$(ARCH) | 156 | KBUILD_AFLAGS += -Iarch/$(ARCH) |
155 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) | 157 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) |
156 | CPP = $(CC) -E $(KBUILD_CFLAGS) | 158 | CPP = $(CC) -E $(KBUILD_CFLAGS) |
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index a28f02165e97..d367a0aece2a 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c | |||
@@ -139,18 +139,18 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, | |||
139 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). | 139 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). |
140 | * The buffer is put in it's own section so that tools may locate it easier. | 140 | * The buffer is put in it's own section so that tools may locate it easier. |
141 | */ | 141 | */ |
142 | static char cmdline[COMMAND_LINE_SIZE] | 142 | static char cmdline[BOOT_COMMAND_LINE_SIZE] |
143 | __attribute__((__section__("__builtin_cmdline"))); | 143 | __attribute__((__section__("__builtin_cmdline"))); |
144 | 144 | ||
145 | static void prep_cmdline(void *chosen) | 145 | static void prep_cmdline(void *chosen) |
146 | { | 146 | { |
147 | if (cmdline[0] == '\0') | 147 | if (cmdline[0] == '\0') |
148 | getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); | 148 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); |
149 | 149 | ||
150 | printf("\n\rLinux/PowerPC load: %s", cmdline); | 150 | printf("\n\rLinux/PowerPC load: %s", cmdline); |
151 | /* If possible, edit the command line */ | 151 | /* If possible, edit the command line */ |
152 | if (console_ops.edit_cmdline) | 152 | if (console_ops.edit_cmdline) |
153 | console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); | 153 | console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE); |
154 | printf("\n\r"); | 154 | printf("\n\r"); |
155 | 155 | ||
156 | /* Put the command line back into the devtree for the kernel */ | 156 | /* Put the command line back into the devtree for the kernel */ |
@@ -174,7 +174,7 @@ void start(void) | |||
174 | * built-in command line wasn't set by an external tool */ | 174 | * built-in command line wasn't set by an external tool */ |
175 | if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) | 175 | if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) |
176 | memmove(cmdline, loader_info.cmdline, | 176 | memmove(cmdline, loader_info.cmdline, |
177 | min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1)); | 177 | min(loader_info.cmdline_len, BOOT_COMMAND_LINE_SIZE-1)); |
178 | 178 | ||
179 | if (console_ops.open && (console_ops.open() < 0)) | 179 | if (console_ops.open && (console_ops.open() < 0)) |
180 | exit(); | 180 | exit(); |
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index b3218ce451bb..8aad3c55aeda 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "types.h" | 15 | #include "types.h" |
16 | #include "string.h" | 16 | #include "string.h" |
17 | 17 | ||
18 | #define COMMAND_LINE_SIZE 512 | 18 | #define BOOT_COMMAND_LINE_SIZE 2048 |
19 | #define MAX_PATH_LEN 256 | 19 | #define MAX_PATH_LEN 256 |
20 | #define MAX_PROP_LEN 256 /* What should this be? */ | 20 | #define MAX_PROP_LEN 256 /* What should this be? */ |
21 | 21 | ||
diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c index 9954d98871d0..4ec2d86d3c50 100644 --- a/arch/powerpc/boot/ps3.c +++ b/arch/powerpc/boot/ps3.c | |||
@@ -47,13 +47,13 @@ BSS_STACK(4096); | |||
47 | * The buffer is put in it's own section so that tools may locate it easier. | 47 | * The buffer is put in it's own section so that tools may locate it easier. |
48 | */ | 48 | */ |
49 | 49 | ||
50 | static char cmdline[COMMAND_LINE_SIZE] | 50 | static char cmdline[BOOT_COMMAND_LINE_SIZE] |
51 | __attribute__((__section__("__builtin_cmdline"))); | 51 | __attribute__((__section__("__builtin_cmdline"))); |
52 | 52 | ||
53 | static void prep_cmdline(void *chosen) | 53 | static void prep_cmdline(void *chosen) |
54 | { | 54 | { |
55 | if (cmdline[0] == '\0') | 55 | if (cmdline[0] == '\0') |
56 | getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); | 56 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); |
57 | else | 57 | else |
58 | setprop_str(chosen, "bootargs", cmdline); | 58 | setprop_str(chosen, "bootargs", cmdline); |
59 | 59 | ||
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a2efdaa020b0..66ad7a74116f 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -41,14 +41,14 @@ struct opal_takeover_args { | |||
41 | * size except the last one in the list to be as well. | 41 | * size except the last one in the list to be as well. |
42 | */ | 42 | */ |
43 | struct opal_sg_entry { | 43 | struct opal_sg_entry { |
44 | void *data; | 44 | __be64 data; |
45 | long length; | 45 | __be64 length; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | /* sg list */ | 48 | /* SG list */ |
49 | struct opal_sg_list { | 49 | struct opal_sg_list { |
50 | unsigned long num_entries; | 50 | __be64 length; |
51 | struct opal_sg_list *next; | 51 | __be64 next; |
52 | struct opal_sg_entry entry[]; | 52 | struct opal_sg_entry entry[]; |
53 | }; | 53 | }; |
54 | 54 | ||
@@ -858,8 +858,8 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type, | |||
858 | int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type, | 858 | int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type, |
859 | uint32_t addr, __be32 *data, uint32_t sz); | 859 | uint32_t addr, __be32 *data, uint32_t sz); |
860 | 860 | ||
861 | int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id); | 861 | int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id); |
862 | int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type); | 862 | int64_t opal_get_elog_size(__be64 *log_id, __be64 *size, __be64 *elog_type); |
863 | int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset); | 863 | int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset); |
864 | int64_t opal_send_ack_elog(uint64_t log_id); | 864 | int64_t opal_send_ack_elog(uint64_t log_id); |
865 | void opal_resend_pending_logs(void); | 865 | void opal_resend_pending_logs(void); |
@@ -868,23 +868,24 @@ int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result); | |||
868 | int64_t opal_manage_flash(uint8_t op); | 868 | int64_t opal_manage_flash(uint8_t op); |
869 | int64_t opal_update_flash(uint64_t blk_list); | 869 | int64_t opal_update_flash(uint64_t blk_list); |
870 | int64_t opal_dump_init(uint8_t dump_type); | 870 | int64_t opal_dump_init(uint8_t dump_type); |
871 | int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size); | 871 | int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size); |
872 | int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type); | 872 | int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type); |
873 | int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer); | 873 | int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer); |
874 | int64_t opal_dump_ack(uint32_t dump_id); | 874 | int64_t opal_dump_ack(uint32_t dump_id); |
875 | int64_t opal_dump_resend_notification(void); | 875 | int64_t opal_dump_resend_notification(void); |
876 | 876 | ||
877 | int64_t opal_get_msg(uint64_t buffer, size_t size); | 877 | int64_t opal_get_msg(uint64_t buffer, uint64_t size); |
878 | int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token); | 878 | int64_t opal_check_completion(uint64_t buffer, uint64_t size, uint64_t token); |
879 | int64_t opal_sync_host_reboot(void); | 879 | int64_t opal_sync_host_reboot(void); |
880 | int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer, | 880 | int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer, |
881 | size_t length); | 881 | uint64_t length); |
882 | int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, | 882 | int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, |
883 | size_t length); | 883 | uint64_t length); |
884 | int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); | 884 | int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); |
885 | 885 | ||
886 | /* Internal functions */ | 886 | /* Internal functions */ |
887 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); | 887 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, |
888 | int depth, void *data); | ||
888 | extern int early_init_dt_scan_recoverable_ranges(unsigned long node, | 889 | extern int early_init_dt_scan_recoverable_ranges(unsigned long node, |
889 | const char *uname, int depth, void *data); | 890 | const char *uname, int depth, void *data); |
890 | 891 | ||
@@ -893,10 +894,6 @@ extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); | |||
893 | 894 | ||
894 | extern void hvc_opal_init_early(void); | 895 | extern void hvc_opal_init_early(void); |
895 | 896 | ||
896 | /* Internal functions */ | ||
897 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, | ||
898 | int depth, void *data); | ||
899 | |||
900 | extern int opal_notifier_register(struct notifier_block *nb); | 897 | extern int opal_notifier_register(struct notifier_block *nb); |
901 | extern int opal_notifier_unregister(struct notifier_block *nb); | 898 | extern int opal_notifier_unregister(struct notifier_block *nb); |
902 | 899 | ||
@@ -906,9 +903,6 @@ extern void opal_notifier_enable(void); | |||
906 | extern void opal_notifier_disable(void); | 903 | extern void opal_notifier_disable(void); |
907 | extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val); | 904 | extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val); |
908 | 905 | ||
909 | extern int opal_get_chars(uint32_t vtermno, char *buf, int count); | ||
910 | extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); | ||
911 | |||
912 | extern int __opal_async_get_token(void); | 906 | extern int __opal_async_get_token(void); |
913 | extern int opal_async_get_token_interruptible(void); | 907 | extern int opal_async_get_token_interruptible(void); |
914 | extern int __opal_async_release_token(int token); | 908 | extern int __opal_async_release_token(int token); |
@@ -916,8 +910,6 @@ extern int opal_async_release_token(int token); | |||
916 | extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg); | 910 | extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg); |
917 | extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data); | 911 | extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data); |
918 | 912 | ||
919 | extern void hvc_opal_init_early(void); | ||
920 | |||
921 | struct rtc_time; | 913 | struct rtc_time; |
922 | extern int opal_set_rtc_time(struct rtc_time *tm); | 914 | extern int opal_set_rtc_time(struct rtc_time *tm); |
923 | extern void opal_get_rtc_time(struct rtc_time *tm); | 915 | extern void opal_get_rtc_time(struct rtc_time *tm); |
@@ -937,6 +929,10 @@ extern int opal_resync_timebase(void); | |||
937 | 929 | ||
938 | extern void opal_lpc_init(void); | 930 | extern void opal_lpc_init(void); |
939 | 931 | ||
932 | struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, | ||
933 | unsigned long vmalloc_size); | ||
934 | void opal_free_sg_list(struct opal_sg_list *sg); | ||
935 | |||
940 | #endif /* __ASSEMBLY__ */ | 936 | #endif /* __ASSEMBLY__ */ |
941 | 937 | ||
942 | #endif /* __OPAL_H */ | 938 | #endif /* __OPAL_H */ |
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 6586a40a46ce..cded7c1278ef 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -318,11 +318,16 @@ n: | |||
318 | addi reg,reg,(name - 0b)@l; | 318 | addi reg,reg,(name - 0b)@l; |
319 | 319 | ||
320 | #ifdef __powerpc64__ | 320 | #ifdef __powerpc64__ |
321 | #ifdef HAVE_AS_ATHIGH | ||
322 | #define __AS_ATHIGH high | ||
323 | #else | ||
324 | #define __AS_ATHIGH h | ||
325 | #endif | ||
321 | #define LOAD_REG_IMMEDIATE(reg,expr) \ | 326 | #define LOAD_REG_IMMEDIATE(reg,expr) \ |
322 | lis reg,(expr)@highest; \ | 327 | lis reg,(expr)@highest; \ |
323 | ori reg,reg,(expr)@higher; \ | 328 | ori reg,reg,(expr)@higher; \ |
324 | rldicr reg,reg,32,31; \ | 329 | rldicr reg,reg,32,31; \ |
325 | oris reg,reg,(expr)@h; \ | 330 | oris reg,reg,(expr)@__AS_ATHIGH; \ |
326 | ori reg,reg,(expr)@l; | 331 | ori reg,reg,(expr)@l; |
327 | 332 | ||
328 | #define LOAD_REG_ADDR(reg,name) \ | 333 | #define LOAD_REG_ADDR(reg,name) \ |
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index d0e784e0ff48..521790330672 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h | |||
@@ -39,6 +39,17 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end) | |||
39 | (unsigned long)_stext < end; | 39 | (unsigned long)_stext < end; |
40 | } | 40 | } |
41 | 41 | ||
42 | static inline int overlaps_kvm_tmp(unsigned long start, unsigned long end) | ||
43 | { | ||
44 | #ifdef CONFIG_KVM_GUEST | ||
45 | extern char kvm_tmp[]; | ||
46 | return start < (unsigned long)kvm_tmp && | ||
47 | (unsigned long)&kvm_tmp[1024 * 1024] < end; | ||
48 | #else | ||
49 | return 0; | ||
50 | #endif | ||
51 | } | ||
52 | |||
42 | #undef dereference_function_descriptor | 53 | #undef dereference_function_descriptor |
43 | static inline void *dereference_function_descriptor(void *ptr) | 54 | static inline void *dereference_function_descriptor(void *ptr) |
44 | { | 55 | { |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 3ddf70276706..ea4dc3a89c1f 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -361,3 +361,4 @@ SYSCALL(finit_module) | |||
361 | SYSCALL(ni_syscall) /* sys_kcmp */ | 361 | SYSCALL(ni_syscall) /* sys_kcmp */ |
362 | SYSCALL_SPU(sched_setattr) | 362 | SYSCALL_SPU(sched_setattr) |
363 | SYSCALL_SPU(sched_getattr) | 363 | SYSCALL_SPU(sched_getattr) |
364 | SYSCALL_SPU(renameat2) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 4494f029b632..9b892bbd9d84 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <uapi/asm/unistd.h> | 12 | #include <uapi/asm/unistd.h> |
13 | 13 | ||
14 | 14 | ||
15 | #define __NR_syscalls 357 | 15 | #define __NR_syscalls 358 |
16 | 16 | ||
17 | #define __NR__exit __NR_exit | 17 | #define __NR__exit __NR_exit |
18 | #define NR_syscalls __NR_syscalls | 18 | #define NR_syscalls __NR_syscalls |
diff --git a/arch/powerpc/include/uapi/asm/setup.h b/arch/powerpc/include/uapi/asm/setup.h index 552df83f1a49..ae3fb68cb28e 100644 --- a/arch/powerpc/include/uapi/asm/setup.h +++ b/arch/powerpc/include/uapi/asm/setup.h | |||
@@ -1 +1,6 @@ | |||
1 | #include <asm-generic/setup.h> | 1 | #ifndef _UAPI_ASM_POWERPC_SETUP_H |
2 | #define _UAPI_ASM_POWERPC_SETUP_H | ||
3 | |||
4 | #define COMMAND_LINE_SIZE 2048 | ||
5 | |||
6 | #endif /* _UAPI_ASM_POWERPC_SETUP_H */ | ||
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 881bf2e2560d..2d526f7b48da 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h | |||
@@ -379,5 +379,6 @@ | |||
379 | #define __NR_kcmp 354 | 379 | #define __NR_kcmp 354 |
380 | #define __NR_sched_setattr 355 | 380 | #define __NR_sched_setattr 355 |
381 | #define __NR_sched_getattr 356 | 381 | #define __NR_sched_getattr 356 |
382 | #define __NR_renameat2 357 | ||
382 | 383 | ||
383 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ | 384 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ |
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 6a0175297b0d..dd8695f6cb6d 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c | |||
@@ -74,7 +74,7 @@ | |||
74 | #define KVM_INST_MTSRIN 0x7c0001e4 | 74 | #define KVM_INST_MTSRIN 0x7c0001e4 |
75 | 75 | ||
76 | static bool kvm_patching_worked = true; | 76 | static bool kvm_patching_worked = true; |
77 | static char kvm_tmp[1024 * 1024]; | 77 | char kvm_tmp[1024 * 1024]; |
78 | static int kvm_tmp_index; | 78 | static int kvm_tmp_index; |
79 | 79 | ||
80 | static inline void kvm_patch_ins(u32 *inst, u32 new_inst) | 80 | static inline void kvm_patch_ins(u32 *inst, u32 new_inst) |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 59d229a2a3e0..879b3aacac32 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -237,7 +237,7 @@ static void wake_offline_cpus(void) | |||
237 | if (!cpu_online(cpu)) { | 237 | if (!cpu_online(cpu)) { |
238 | printk(KERN_INFO "kexec: Waking offline cpu %d.\n", | 238 | printk(KERN_INFO "kexec: Waking offline cpu %d.\n", |
239 | cpu); | 239 | cpu); |
240 | cpu_up(cpu); | 240 | WARN_ON(cpu_up(cpu)); |
241 | } | 241 | } |
242 | } | 242 | } |
243 | } | 243 | } |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 2a4779091a58..155013da27e0 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -208,7 +208,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, | |||
208 | unsigned long in_devfn) | 208 | unsigned long in_devfn) |
209 | { | 209 | { |
210 | struct pci_controller* hose; | 210 | struct pci_controller* hose; |
211 | struct pci_bus *bus = NULL; | 211 | struct pci_bus *tmp_bus, *bus = NULL; |
212 | struct device_node *hose_node; | 212 | struct device_node *hose_node; |
213 | 213 | ||
214 | /* Argh ! Please forgive me for that hack, but that's the | 214 | /* Argh ! Please forgive me for that hack, but that's the |
@@ -229,10 +229,12 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, | |||
229 | * used on pre-domains setup. We return the first match | 229 | * used on pre-domains setup. We return the first match |
230 | */ | 230 | */ |
231 | 231 | ||
232 | list_for_each_entry(bus, &pci_root_buses, node) { | 232 | list_for_each_entry(tmp_bus, &pci_root_buses, node) { |
233 | if (in_bus >= bus->number && in_bus <= bus->busn_res.end) | 233 | if (in_bus >= tmp_bus->number && |
234 | in_bus <= tmp_bus->busn_res.end) { | ||
235 | bus = tmp_bus; | ||
234 | break; | 236 | break; |
235 | bus = NULL; | 237 | } |
236 | } | 238 | } |
237 | if (bus == NULL || bus->dev.of_node == NULL) | 239 | if (bus == NULL || bus->dev.of_node == NULL) |
238 | return -ENODEV; | 240 | return -ENODEV; |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 3bd77edd7610..450850a49dce 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -120,6 +120,7 @@ EXPORT_SYMBOL(giveup_spe); | |||
120 | EXPORT_SYMBOL(flush_instruction_cache); | 120 | EXPORT_SYMBOL(flush_instruction_cache); |
121 | #endif | 121 | #endif |
122 | EXPORT_SYMBOL(flush_dcache_range); | 122 | EXPORT_SYMBOL(flush_dcache_range); |
123 | EXPORT_SYMBOL(flush_icache_range); | ||
123 | 124 | ||
124 | #ifdef CONFIG_SMP | 125 | #ifdef CONFIG_SMP |
125 | #ifdef CONFIG_PPC32 | 126 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 2f3cdb01506d..658e89d2025b 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
@@ -705,7 +705,7 @@ static int __init rtas_flash_init(void) | |||
705 | if (rtas_token("ibm,update-flash-64-and-reboot") == | 705 | if (rtas_token("ibm,update-flash-64-and-reboot") == |
706 | RTAS_UNKNOWN_SERVICE) { | 706 | RTAS_UNKNOWN_SERVICE) { |
707 | pr_info("rtas_flash: no firmware flash support\n"); | 707 | pr_info("rtas_flash: no firmware flash support\n"); |
708 | return 1; | 708 | return -EINVAL; |
709 | } | 709 | } |
710 | 710 | ||
711 | rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); | 711 | rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 122a580f7322..7e711bdcc6da 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -813,9 +813,6 @@ static void __init clocksource_init(void) | |||
813 | static int decrementer_set_next_event(unsigned long evt, | 813 | static int decrementer_set_next_event(unsigned long evt, |
814 | struct clock_event_device *dev) | 814 | struct clock_event_device *dev) |
815 | { | 815 | { |
816 | /* Don't adjust the decrementer if some irq work is pending */ | ||
817 | if (test_irq_work_pending()) | ||
818 | return 0; | ||
819 | __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt; | 816 | __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt; |
820 | set_dec(evt); | 817 | set_dec(evt); |
821 | 818 | ||
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 94e597e6f15c..7af190a266b3 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -886,7 +886,7 @@ static int kvmppc_book3s_init(void) | |||
886 | r = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); | 886 | r = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); |
887 | if (r) | 887 | if (r) |
888 | return r; | 888 | return r; |
889 | #ifdef CONFIG_KVM_BOOK3S_32 | 889 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
890 | r = kvmppc_book3s_init_pr(); | 890 | r = kvmppc_book3s_init_pr(); |
891 | #endif | 891 | #endif |
892 | return r; | 892 | return r; |
@@ -895,7 +895,7 @@ static int kvmppc_book3s_init(void) | |||
895 | 895 | ||
896 | static void kvmppc_book3s_exit(void) | 896 | static void kvmppc_book3s_exit(void) |
897 | { | 897 | { |
898 | #ifdef CONFIG_KVM_BOOK3S_32 | 898 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
899 | kvmppc_book3s_exit_pr(); | 899 | kvmppc_book3s_exit_pr(); |
900 | #endif | 900 | #endif |
901 | kvm_exit(); | 901 | kvm_exit(); |
@@ -905,7 +905,7 @@ module_init(kvmppc_book3s_init); | |||
905 | module_exit(kvmppc_book3s_exit); | 905 | module_exit(kvmppc_book3s_exit); |
906 | 906 | ||
907 | /* On 32bit this is our one and only kernel module */ | 907 | /* On 32bit this is our one and only kernel module */ |
908 | #ifdef CONFIG_KVM_BOOK3S_32 | 908 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
909 | MODULE_ALIAS_MISCDEV(KVM_MINOR); | 909 | MODULE_ALIAS_MISCDEV(KVM_MINOR); |
910 | MODULE_ALIAS("devname:kvm"); | 910 | MODULE_ALIAS("devname:kvm"); |
911 | #endif | 911 | #endif |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 1d6c56ad5b60..8fcc36306a02 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -234,7 +234,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
234 | pte_size = psize; | 234 | pte_size = psize; |
235 | pte = lookup_linux_pte_and_update(pgdir, hva, writing, | 235 | pte = lookup_linux_pte_and_update(pgdir, hva, writing, |
236 | &pte_size); | 236 | &pte_size); |
237 | if (pte_present(pte)) { | 237 | if (pte_present(pte) && !pte_numa(pte)) { |
238 | if (writing && !pte_write(pte)) | 238 | if (writing && !pte_write(pte)) |
239 | /* make the actual HPTE be read-only */ | 239 | /* make the actual HPTE be read-only */ |
240 | ptel = hpte_make_readonly(ptel); | 240 | ptel = hpte_make_readonly(ptel); |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index ffbb871c2bd8..07c8b5b0f9d2 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -242,6 +242,12 @@ kvm_novcpu_exit: | |||
242 | */ | 242 | */ |
243 | .globl kvm_start_guest | 243 | .globl kvm_start_guest |
244 | kvm_start_guest: | 244 | kvm_start_guest: |
245 | |||
246 | /* Set runlatch bit the minute you wake up from nap */ | ||
247 | mfspr r1, SPRN_CTRLF | ||
248 | ori r1, r1, 1 | ||
249 | mtspr SPRN_CTRLT, r1 | ||
250 | |||
245 | ld r2,PACATOC(r13) | 251 | ld r2,PACATOC(r13) |
246 | 252 | ||
247 | li r0,KVM_HWTHREAD_IN_KVM | 253 | li r0,KVM_HWTHREAD_IN_KVM |
@@ -309,6 +315,11 @@ kvm_no_guest: | |||
309 | li r0, KVM_HWTHREAD_IN_NAP | 315 | li r0, KVM_HWTHREAD_IN_NAP |
310 | stb r0, HSTATE_HWTHREAD_STATE(r13) | 316 | stb r0, HSTATE_HWTHREAD_STATE(r13) |
311 | kvm_do_nap: | 317 | kvm_do_nap: |
318 | /* Clear the runlatch bit before napping */ | ||
319 | mfspr r2, SPRN_CTRLF | ||
320 | clrrdi r2, r2, 1 | ||
321 | mtspr SPRN_CTRLT, r2 | ||
322 | |||
312 | li r3, LPCR_PECE0 | 323 | li r3, LPCR_PECE0 |
313 | mfspr r4, SPRN_LPCR | 324 | mfspr r4, SPRN_LPCR |
314 | rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 | 325 | rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 |
@@ -1312,6 +1323,110 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | |||
1312 | mr r3, r9 | 1323 | mr r3, r9 |
1313 | bl kvmppc_save_fp | 1324 | bl kvmppc_save_fp |
1314 | 1325 | ||
1326 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
1327 | BEGIN_FTR_SECTION | ||
1328 | b 2f | ||
1329 | END_FTR_SECTION_IFCLR(CPU_FTR_TM) | ||
1330 | /* Turn on TM. */ | ||
1331 | mfmsr r8 | ||
1332 | li r0, 1 | ||
1333 | rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG | ||
1334 | mtmsrd r8 | ||
1335 | |||
1336 | ld r5, VCPU_MSR(r9) | ||
1337 | rldicl. r5, r5, 64 - MSR_TS_S_LG, 62 | ||
1338 | beq 1f /* TM not active in guest. */ | ||
1339 | |||
1340 | li r3, TM_CAUSE_KVM_RESCHED | ||
1341 | |||
1342 | /* Clear the MSR RI since r1, r13 are all going to be foobar. */ | ||
1343 | li r5, 0 | ||
1344 | mtmsrd r5, 1 | ||
1345 | |||
1346 | /* All GPRs are volatile at this point. */ | ||
1347 | TRECLAIM(R3) | ||
1348 | |||
1349 | /* Temporarily store r13 and r9 so we have some regs to play with */ | ||
1350 | SET_SCRATCH0(r13) | ||
1351 | GET_PACA(r13) | ||
1352 | std r9, PACATMSCRATCH(r13) | ||
1353 | ld r9, HSTATE_KVM_VCPU(r13) | ||
1354 | |||
1355 | /* Get a few more GPRs free. */ | ||
1356 | std r29, VCPU_GPRS_TM(29)(r9) | ||
1357 | std r30, VCPU_GPRS_TM(30)(r9) | ||
1358 | std r31, VCPU_GPRS_TM(31)(r9) | ||
1359 | |||
1360 | /* Save away PPR and DSCR soon so don't run with user values. */ | ||
1361 | mfspr r31, SPRN_PPR | ||
1362 | HMT_MEDIUM | ||
1363 | mfspr r30, SPRN_DSCR | ||
1364 | ld r29, HSTATE_DSCR(r13) | ||
1365 | mtspr SPRN_DSCR, r29 | ||
1366 | |||
1367 | /* Save all but r9, r13 & r29-r31 */ | ||
1368 | reg = 0 | ||
1369 | .rept 29 | ||
1370 | .if (reg != 9) && (reg != 13) | ||
1371 | std reg, VCPU_GPRS_TM(reg)(r9) | ||
1372 | .endif | ||
1373 | reg = reg + 1 | ||
1374 | .endr | ||
1375 | /* ... now save r13 */ | ||
1376 | GET_SCRATCH0(r4) | ||
1377 | std r4, VCPU_GPRS_TM(13)(r9) | ||
1378 | /* ... and save r9 */ | ||
1379 | ld r4, PACATMSCRATCH(r13) | ||
1380 | std r4, VCPU_GPRS_TM(9)(r9) | ||
1381 | |||
1382 | /* Reload stack pointer and TOC. */ | ||
1383 | ld r1, HSTATE_HOST_R1(r13) | ||
1384 | ld r2, PACATOC(r13) | ||
1385 | |||
1386 | /* Set MSR RI now we have r1 and r13 back. */ | ||
1387 | li r5, MSR_RI | ||
1388 | mtmsrd r5, 1 | ||
1389 | |||
1390 | /* Save away checkpinted SPRs. */ | ||
1391 | std r31, VCPU_PPR_TM(r9) | ||
1392 | std r30, VCPU_DSCR_TM(r9) | ||
1393 | mflr r5 | ||
1394 | mfcr r6 | ||
1395 | mfctr r7 | ||
1396 | mfspr r8, SPRN_AMR | ||
1397 | mfspr r10, SPRN_TAR | ||
1398 | std r5, VCPU_LR_TM(r9) | ||
1399 | stw r6, VCPU_CR_TM(r9) | ||
1400 | std r7, VCPU_CTR_TM(r9) | ||
1401 | std r8, VCPU_AMR_TM(r9) | ||
1402 | std r10, VCPU_TAR_TM(r9) | ||
1403 | |||
1404 | /* Restore r12 as trap number. */ | ||
1405 | lwz r12, VCPU_TRAP(r9) | ||
1406 | |||
1407 | /* Save FP/VSX. */ | ||
1408 | addi r3, r9, VCPU_FPRS_TM | ||
1409 | bl .store_fp_state | ||
1410 | addi r3, r9, VCPU_VRS_TM | ||
1411 | bl .store_vr_state | ||
1412 | mfspr r6, SPRN_VRSAVE | ||
1413 | stw r6, VCPU_VRSAVE_TM(r9) | ||
1414 | 1: | ||
1415 | /* | ||
1416 | * We need to save these SPRs after the treclaim so that the software | ||
1417 | * error code is recorded correctly in the TEXASR. Also the user may | ||
1418 | * change these outside of a transaction, so they must always be | ||
1419 | * context switched. | ||
1420 | */ | ||
1421 | mfspr r5, SPRN_TFHAR | ||
1422 | mfspr r6, SPRN_TFIAR | ||
1423 | mfspr r7, SPRN_TEXASR | ||
1424 | std r5, VCPU_TFHAR(r9) | ||
1425 | std r6, VCPU_TFIAR(r9) | ||
1426 | std r7, VCPU_TEXASR(r9) | ||
1427 | 2: | ||
1428 | #endif | ||
1429 | |||
1315 | /* Increment yield count if they have a VPA */ | 1430 | /* Increment yield count if they have a VPA */ |
1316 | ld r8, VCPU_VPA(r9) /* do they have a VPA? */ | 1431 | ld r8, VCPU_VPA(r9) /* do they have a VPA? */ |
1317 | cmpdi r8, 0 | 1432 | cmpdi r8, 0 |
@@ -1999,8 +2114,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) | |||
1999 | 2114 | ||
2000 | /* | 2115 | /* |
2001 | * Take a nap until a decrementer or external or doobell interrupt | 2116 | * Take a nap until a decrementer or external or doobell interrupt |
2002 | * occurs, with PECE1, PECE0 and PECEDP set in LPCR | 2117 | * occurs, with PECE1, PECE0 and PECEDP set in LPCR. Also clear the |
2118 | * runlatch bit before napping. | ||
2003 | */ | 2119 | */ |
2120 | mfspr r2, SPRN_CTRLF | ||
2121 | clrrdi r2, r2, 1 | ||
2122 | mtspr SPRN_CTRLT, r2 | ||
2123 | |||
2004 | li r0,1 | 2124 | li r0,1 |
2005 | stb r0,HSTATE_HWTHREAD_REQ(r13) | 2125 | stb r0,HSTATE_HWTHREAD_REQ(r13) |
2006 | mfspr r5,SPRN_LPCR | 2126 | mfspr r5,SPRN_LPCR |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index c5c052a9729c..02f1defd8bb9 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -1153,7 +1153,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_pr(struct kvm *kvm, | |||
1153 | goto free_vcpu; | 1153 | goto free_vcpu; |
1154 | vcpu->arch.book3s = vcpu_book3s; | 1154 | vcpu->arch.book3s = vcpu_book3s; |
1155 | 1155 | ||
1156 | #ifdef CONFIG_KVM_BOOK3S_32 | 1156 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
1157 | vcpu->arch.shadow_vcpu = | 1157 | vcpu->arch.shadow_vcpu = |
1158 | kzalloc(sizeof(*vcpu->arch.shadow_vcpu), GFP_KERNEL); | 1158 | kzalloc(sizeof(*vcpu->arch.shadow_vcpu), GFP_KERNEL); |
1159 | if (!vcpu->arch.shadow_vcpu) | 1159 | if (!vcpu->arch.shadow_vcpu) |
@@ -1198,7 +1198,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_pr(struct kvm *kvm, | |||
1198 | uninit_vcpu: | 1198 | uninit_vcpu: |
1199 | kvm_vcpu_uninit(vcpu); | 1199 | kvm_vcpu_uninit(vcpu); |
1200 | free_shadow_vcpu: | 1200 | free_shadow_vcpu: |
1201 | #ifdef CONFIG_KVM_BOOK3S_32 | 1201 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
1202 | kfree(vcpu->arch.shadow_vcpu); | 1202 | kfree(vcpu->arch.shadow_vcpu); |
1203 | free_vcpu3s: | 1203 | free_vcpu3s: |
1204 | #endif | 1204 | #endif |
@@ -1215,7 +1215,7 @@ static void kvmppc_core_vcpu_free_pr(struct kvm_vcpu *vcpu) | |||
1215 | 1215 | ||
1216 | free_page((unsigned long)vcpu->arch.shared & PAGE_MASK); | 1216 | free_page((unsigned long)vcpu->arch.shared & PAGE_MASK); |
1217 | kvm_vcpu_uninit(vcpu); | 1217 | kvm_vcpu_uninit(vcpu); |
1218 | #ifdef CONFIG_KVM_BOOK3S_32 | 1218 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
1219 | kfree(vcpu->arch.shadow_vcpu); | 1219 | kfree(vcpu->arch.shadow_vcpu); |
1220 | #endif | 1220 | #endif |
1221 | vfree(vcpu_book3s); | 1221 | vfree(vcpu_book3s); |
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 3ea26c25590b..cf1d325eae8b 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -82,17 +82,14 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize) | |||
82 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); | 82 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); |
83 | va |= penc << 12; | 83 | va |= penc << 12; |
84 | va |= ssize << 8; | 84 | va |= ssize << 8; |
85 | /* Add AVAL part */ | 85 | /* |
86 | if (psize != apsize) { | 86 | * AVAL bits: |
87 | /* | 87 | * We don't need all the bits, but rest of the bits |
88 | * MPSS, 64K base page size and 16MB parge page size | 88 | * must be ignored by the processor. |
89 | * We don't need all the bits, but rest of the bits | 89 | * vpn cover upto 65 bits of va. (0...65) and we need |
90 | * must be ignored by the processor. | 90 | * 58..64 bits of va. |
91 | * vpn cover upto 65 bits of va. (0...65) and we need | 91 | */ |
92 | * 58..64 bits of va. | 92 | va |= (vpn & 0xfe); /* AVAL */ |
93 | */ | ||
94 | va |= (vpn & 0xfe); | ||
95 | } | ||
96 | va |= 1; /* L */ | 93 | va |= 1; /* L */ |
97 | asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2) | 94 | asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2) |
98 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) | 95 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) |
@@ -133,17 +130,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize) | |||
133 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); | 130 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); |
134 | va |= penc << 12; | 131 | va |= penc << 12; |
135 | va |= ssize << 8; | 132 | va |= ssize << 8; |
136 | /* Add AVAL part */ | 133 | /* |
137 | if (psize != apsize) { | 134 | * AVAL bits: |
138 | /* | 135 | * We don't need all the bits, but rest of the bits |
139 | * MPSS, 64K base page size and 16MB parge page size | 136 | * must be ignored by the processor. |
140 | * We don't need all the bits, but rest of the bits | 137 | * vpn cover upto 65 bits of va. (0...65) and we need |
141 | * must be ignored by the processor. | 138 | * 58..64 bits of va. |
142 | * vpn cover upto 65 bits of va. (0...65) and we need | 139 | */ |
143 | * 58..64 bits of va. | 140 | va |= (vpn & 0xfe); |
144 | */ | ||
145 | va |= (vpn & 0xfe); | ||
146 | } | ||
147 | va |= 1; /* L */ | 141 | va |= 1; /* L */ |
148 | asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)" | 142 | asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)" |
149 | : : "r"(va) : "memory"); | 143 | : : "r"(va) : "memory"); |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index d766d6ee33fe..06ba83b036d3 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -207,6 +207,10 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
207 | if (overlaps_kernel_text(vaddr, vaddr + step)) | 207 | if (overlaps_kernel_text(vaddr, vaddr + step)) |
208 | tprot &= ~HPTE_R_N; | 208 | tprot &= ~HPTE_R_N; |
209 | 209 | ||
210 | /* Make kvm guest trampolines executable */ | ||
211 | if (overlaps_kvm_tmp(vaddr, vaddr + step)) | ||
212 | tprot &= ~HPTE_R_N; | ||
213 | |||
210 | /* | 214 | /* |
211 | * If relocatable, check if it overlaps interrupt vectors that | 215 | * If relocatable, check if it overlaps interrupt vectors that |
212 | * are copied down to real 0. For relocatable kernel | 216 | * are copied down to real 0. For relocatable kernel |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 4ebbb9e99286..3b181b22cd46 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -232,6 +232,7 @@ int __node_distance(int a, int b) | |||
232 | 232 | ||
233 | return distance; | 233 | return distance; |
234 | } | 234 | } |
235 | EXPORT_SYMBOL(__node_distance); | ||
235 | 236 | ||
236 | static void initialize_distance_lookup_table(int nid, | 237 | static void initialize_distance_lookup_table(int nid, |
237 | const __be32 *associativity) | 238 | const __be32 *associativity) |
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 297c91051413..e0766b82e165 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c | |||
@@ -155,16 +155,28 @@ static ssize_t read_offset_data(void *dest, size_t dest_len, | |||
155 | return copy_len; | 155 | return copy_len; |
156 | } | 156 | } |
157 | 157 | ||
158 | static unsigned long h_get_24x7_catalog_page(char page[static 4096], | 158 | static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096, |
159 | u32 version, u32 index) | 159 | unsigned long version, |
160 | unsigned long index) | ||
160 | { | 161 | { |
161 | WARN_ON(!IS_ALIGNED((unsigned long)page, 4096)); | 162 | pr_devel("h_get_24x7_catalog_page(0x%lx, %lu, %lu)", |
163 | phys_4096, | ||
164 | version, | ||
165 | index); | ||
166 | WARN_ON(!IS_ALIGNED(phys_4096, 4096)); | ||
162 | return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE, | 167 | return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE, |
163 | virt_to_phys(page), | 168 | phys_4096, |
164 | version, | 169 | version, |
165 | index); | 170 | index); |
166 | } | 171 | } |
167 | 172 | ||
173 | static unsigned long h_get_24x7_catalog_page(char page[], | ||
174 | u64 version, u32 index) | ||
175 | { | ||
176 | return h_get_24x7_catalog_page_(virt_to_phys(page), | ||
177 | version, index); | ||
178 | } | ||
179 | |||
168 | static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | 180 | static ssize_t catalog_read(struct file *filp, struct kobject *kobj, |
169 | struct bin_attribute *bin_attr, char *buf, | 181 | struct bin_attribute *bin_attr, char *buf, |
170 | loff_t offset, size_t count) | 182 | loff_t offset, size_t count) |
@@ -173,7 +185,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | |||
173 | ssize_t ret = 0; | 185 | ssize_t ret = 0; |
174 | size_t catalog_len = 0, catalog_page_len = 0, page_count = 0; | 186 | size_t catalog_len = 0, catalog_page_len = 0, page_count = 0; |
175 | loff_t page_offset = 0; | 187 | loff_t page_offset = 0; |
176 | uint32_t catalog_version_num = 0; | 188 | uint64_t catalog_version_num = 0; |
177 | void *page = kmem_cache_alloc(hv_page_cache, GFP_USER); | 189 | void *page = kmem_cache_alloc(hv_page_cache, GFP_USER); |
178 | struct hv_24x7_catalog_page_0 *page_0 = page; | 190 | struct hv_24x7_catalog_page_0 *page_0 = page; |
179 | if (!page) | 191 | if (!page) |
@@ -185,7 +197,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | |||
185 | goto e_free; | 197 | goto e_free; |
186 | } | 198 | } |
187 | 199 | ||
188 | catalog_version_num = be32_to_cpu(page_0->version); | 200 | catalog_version_num = be64_to_cpu(page_0->version); |
189 | catalog_page_len = be32_to_cpu(page_0->length); | 201 | catalog_page_len = be32_to_cpu(page_0->length); |
190 | catalog_len = catalog_page_len * 4096; | 202 | catalog_len = catalog_page_len * 4096; |
191 | 203 | ||
@@ -208,8 +220,9 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | |||
208 | page, 4096, page_offset * 4096); | 220 | page, 4096, page_offset * 4096); |
209 | e_free: | 221 | e_free: |
210 | if (hret) | 222 | if (hret) |
211 | pr_err("h_get_24x7_catalog_page(ver=%d, page=%lld) failed: rc=%ld\n", | 223 | pr_err("h_get_24x7_catalog_page(ver=%lld, page=%lld) failed:" |
212 | catalog_version_num, page_offset, hret); | 224 | " rc=%ld\n", |
225 | catalog_version_num, page_offset, hret); | ||
213 | kfree(page); | 226 | kfree(page); |
214 | 227 | ||
215 | pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n", | 228 | pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n", |
@@ -243,7 +256,7 @@ e_free: \ | |||
243 | static DEVICE_ATTR_RO(_name) | 256 | static DEVICE_ATTR_RO(_name) |
244 | 257 | ||
245 | PAGE_0_ATTR(catalog_version, "%lld\n", | 258 | PAGE_0_ATTR(catalog_version, "%lld\n", |
246 | (unsigned long long)be32_to_cpu(page_0->version)); | 259 | (unsigned long long)be64_to_cpu(page_0->version)); |
247 | PAGE_0_ATTR(catalog_len, "%lld\n", | 260 | PAGE_0_ATTR(catalog_len, "%lld\n", |
248 | (unsigned long long)be32_to_cpu(page_0->length) * 4096); | 261 | (unsigned long long)be32_to_cpu(page_0->length) * 4096); |
249 | static BIN_ATTR_RO(catalog, 0/* real length varies */); | 262 | static BIN_ATTR_RO(catalog, 0/* real length varies */); |
@@ -485,13 +498,13 @@ static int hv_24x7_init(void) | |||
485 | struct hv_perf_caps caps; | 498 | struct hv_perf_caps caps; |
486 | 499 | ||
487 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { | 500 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { |
488 | pr_info("not a virtualized system, not enabling\n"); | 501 | pr_debug("not a virtualized system, not enabling\n"); |
489 | return -ENODEV; | 502 | return -ENODEV; |
490 | } | 503 | } |
491 | 504 | ||
492 | hret = hv_perf_caps_get(&caps); | 505 | hret = hv_perf_caps_get(&caps); |
493 | if (hret) { | 506 | if (hret) { |
494 | pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n", | 507 | pr_debug("could not obtain capabilities, not enabling, rc=%ld\n", |
495 | hret); | 508 | hret); |
496 | return -ENODEV; | 509 | return -ENODEV; |
497 | } | 510 | } |
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 278ba7b9c2b5..c9d399a2df82 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c | |||
@@ -78,7 +78,7 @@ static ssize_t kernel_version_show(struct device *dev, | |||
78 | return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT); | 78 | return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT); |
79 | } | 79 | } |
80 | 80 | ||
81 | DEVICE_ATTR_RO(kernel_version); | 81 | static DEVICE_ATTR_RO(kernel_version); |
82 | HV_CAPS_ATTR(version, "0x%x\n"); | 82 | HV_CAPS_ATTR(version, "0x%x\n"); |
83 | HV_CAPS_ATTR(ga, "%d\n"); | 83 | HV_CAPS_ATTR(ga, "%d\n"); |
84 | HV_CAPS_ATTR(expanded, "%d\n"); | 84 | HV_CAPS_ATTR(expanded, "%d\n"); |
@@ -273,13 +273,13 @@ static int hv_gpci_init(void) | |||
273 | struct hv_perf_caps caps; | 273 | struct hv_perf_caps caps; |
274 | 274 | ||
275 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { | 275 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { |
276 | pr_info("not a virtualized system, not enabling\n"); | 276 | pr_debug("not a virtualized system, not enabling\n"); |
277 | return -ENODEV; | 277 | return -ENODEV; |
278 | } | 278 | } |
279 | 279 | ||
280 | hret = hv_perf_caps_get(&caps); | 280 | hret = hv_perf_caps_get(&caps); |
281 | if (hret) { | 281 | if (hret) { |
282 | pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n", | 282 | pr_debug("could not obtain capabilities, not enabling, rc=%ld\n", |
283 | hret); | 283 | hret); |
284 | return -ENODEV; | 284 | return -ENODEV; |
285 | } | 285 | } |
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 253fefe3d1a0..5b51079f3e3b 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
@@ -549,7 +549,8 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) | |||
549 | ret = ioda_eeh_phb_reset(hose, option); | 549 | ret = ioda_eeh_phb_reset(hose, option); |
550 | } else { | 550 | } else { |
551 | bus = eeh_pe_bus_get(pe); | 551 | bus = eeh_pe_bus_get(pe); |
552 | if (pci_is_root_bus(bus)) | 552 | if (pci_is_root_bus(bus) || |
553 | pci_is_root_bus(bus->parent)) | ||
553 | ret = ioda_eeh_root_reset(hose, option); | 554 | ret = ioda_eeh_root_reset(hose, option); |
554 | else | 555 | else |
555 | ret = ioda_eeh_bridge_reset(hose, bus->self, option); | 556 | ret = ioda_eeh_bridge_reset(hose, bus->self, option); |
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index b9827b0d87e4..788a1977b9a5 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c | |||
@@ -209,89 +209,20 @@ static struct kobj_type dump_ktype = { | |||
209 | .default_attrs = dump_default_attrs, | 209 | .default_attrs = dump_default_attrs, |
210 | }; | 210 | }; |
211 | 211 | ||
212 | static void free_dump_sg_list(struct opal_sg_list *list) | 212 | static int64_t dump_read_info(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type) |
213 | { | ||
214 | struct opal_sg_list *sg1; | ||
215 | while (list) { | ||
216 | sg1 = list->next; | ||
217 | kfree(list); | ||
218 | list = sg1; | ||
219 | } | ||
220 | list = NULL; | ||
221 | } | ||
222 | |||
223 | static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump) | ||
224 | { | ||
225 | struct opal_sg_list *sg1, *list = NULL; | ||
226 | void *addr; | ||
227 | int64_t size; | ||
228 | |||
229 | addr = dump->buffer; | ||
230 | size = dump->size; | ||
231 | |||
232 | sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
233 | if (!sg1) | ||
234 | goto nomem; | ||
235 | |||
236 | list = sg1; | ||
237 | sg1->num_entries = 0; | ||
238 | while (size > 0) { | ||
239 | /* Translate virtual address to physical address */ | ||
240 | sg1->entry[sg1->num_entries].data = | ||
241 | (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT); | ||
242 | |||
243 | if (size > PAGE_SIZE) | ||
244 | sg1->entry[sg1->num_entries].length = PAGE_SIZE; | ||
245 | else | ||
246 | sg1->entry[sg1->num_entries].length = size; | ||
247 | |||
248 | sg1->num_entries++; | ||
249 | if (sg1->num_entries >= SG_ENTRIES_PER_NODE) { | ||
250 | sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
251 | if (!sg1->next) | ||
252 | goto nomem; | ||
253 | |||
254 | sg1 = sg1->next; | ||
255 | sg1->num_entries = 0; | ||
256 | } | ||
257 | addr += PAGE_SIZE; | ||
258 | size -= PAGE_SIZE; | ||
259 | } | ||
260 | return list; | ||
261 | |||
262 | nomem: | ||
263 | pr_err("%s : Failed to allocate memory\n", __func__); | ||
264 | free_dump_sg_list(list); | ||
265 | return NULL; | ||
266 | } | ||
267 | |||
268 | static void sglist_to_phy_addr(struct opal_sg_list *list) | ||
269 | { | ||
270 | struct opal_sg_list *sg, *next; | ||
271 | |||
272 | for (sg = list; sg; sg = next) { | ||
273 | next = sg->next; | ||
274 | /* Don't translate NULL pointer for last entry */ | ||
275 | if (sg->next) | ||
276 | sg->next = (struct opal_sg_list *)__pa(sg->next); | ||
277 | else | ||
278 | sg->next = NULL; | ||
279 | |||
280 | /* Convert num_entries to length */ | ||
281 | sg->num_entries = | ||
282 | sg->num_entries * sizeof(struct opal_sg_entry) + 16; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type) | ||
287 | { | 213 | { |
214 | __be32 id, size, type; | ||
288 | int rc; | 215 | int rc; |
289 | *type = 0xffffffff; | ||
290 | 216 | ||
291 | rc = opal_dump_info2(id, size, type); | 217 | type = cpu_to_be32(0xffffffff); |
292 | 218 | ||
219 | rc = opal_dump_info2(&id, &size, &type); | ||
293 | if (rc == OPAL_PARAMETER) | 220 | if (rc == OPAL_PARAMETER) |
294 | rc = opal_dump_info(id, size); | 221 | rc = opal_dump_info(&id, &size); |
222 | |||
223 | *dump_id = be32_to_cpu(id); | ||
224 | *dump_size = be32_to_cpu(size); | ||
225 | *dump_type = be32_to_cpu(type); | ||
295 | 226 | ||
296 | if (rc) | 227 | if (rc) |
297 | pr_warn("%s: Failed to get dump info (%d)\n", | 228 | pr_warn("%s: Failed to get dump info (%d)\n", |
@@ -314,15 +245,12 @@ static int64_t dump_read_data(struct dump_obj *dump) | |||
314 | } | 245 | } |
315 | 246 | ||
316 | /* Generate SG list */ | 247 | /* Generate SG list */ |
317 | list = dump_data_to_sglist(dump); | 248 | list = opal_vmalloc_to_sg_list(dump->buffer, dump->size); |
318 | if (!list) { | 249 | if (!list) { |
319 | rc = -ENOMEM; | 250 | rc = -ENOMEM; |
320 | goto out; | 251 | goto out; |
321 | } | 252 | } |
322 | 253 | ||
323 | /* Translate sg list addr to real address */ | ||
324 | sglist_to_phy_addr(list); | ||
325 | |||
326 | /* First entry address */ | 254 | /* First entry address */ |
327 | addr = __pa(list); | 255 | addr = __pa(list); |
328 | 256 | ||
@@ -341,7 +269,7 @@ static int64_t dump_read_data(struct dump_obj *dump) | |||
341 | __func__, dump->id); | 269 | __func__, dump->id); |
342 | 270 | ||
343 | /* Free SG list */ | 271 | /* Free SG list */ |
344 | free_dump_sg_list(list); | 272 | opal_free_sg_list(list); |
345 | 273 | ||
346 | out: | 274 | out: |
347 | return rc; | 275 | return rc; |
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index ef7bc2a97862..10268c41d830 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c | |||
@@ -238,18 +238,25 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) | |||
238 | 238 | ||
239 | static void elog_work_fn(struct work_struct *work) | 239 | static void elog_work_fn(struct work_struct *work) |
240 | { | 240 | { |
241 | size_t elog_size; | 241 | __be64 size; |
242 | __be64 id; | ||
243 | __be64 type; | ||
244 | uint64_t elog_size; | ||
242 | uint64_t log_id; | 245 | uint64_t log_id; |
243 | uint64_t elog_type; | 246 | uint64_t elog_type; |
244 | int rc; | 247 | int rc; |
245 | char name[2+16+1]; | 248 | char name[2+16+1]; |
246 | 249 | ||
247 | rc = opal_get_elog_size(&log_id, &elog_size, &elog_type); | 250 | rc = opal_get_elog_size(&id, &size, &type); |
248 | if (rc != OPAL_SUCCESS) { | 251 | if (rc != OPAL_SUCCESS) { |
249 | pr_err("ELOG: Opal log read failed\n"); | 252 | pr_err("ELOG: Opal log read failed\n"); |
250 | return; | 253 | return; |
251 | } | 254 | } |
252 | 255 | ||
256 | elog_size = be64_to_cpu(size); | ||
257 | log_id = be64_to_cpu(id); | ||
258 | elog_type = be64_to_cpu(type); | ||
259 | |||
253 | BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE); | 260 | BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE); |
254 | 261 | ||
255 | if (elog_size >= OPAL_MAX_ERRLOG_SIZE) | 262 | if (elog_size >= OPAL_MAX_ERRLOG_SIZE) |
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c index 714ef972406b..dc487ff04704 100644 --- a/arch/powerpc/platforms/powernv/opal-flash.c +++ b/arch/powerpc/platforms/powernv/opal-flash.c | |||
@@ -79,9 +79,6 @@ | |||
79 | /* XXX: Assume candidate image size is <= 1GB */ | 79 | /* XXX: Assume candidate image size is <= 1GB */ |
80 | #define MAX_IMAGE_SIZE 0x40000000 | 80 | #define MAX_IMAGE_SIZE 0x40000000 |
81 | 81 | ||
82 | /* Flash sg list version */ | ||
83 | #define SG_LIST_VERSION (1UL) | ||
84 | |||
85 | /* Image status */ | 82 | /* Image status */ |
86 | enum { | 83 | enum { |
87 | IMAGE_INVALID, | 84 | IMAGE_INVALID, |
@@ -131,11 +128,15 @@ static DEFINE_MUTEX(image_data_mutex); | |||
131 | */ | 128 | */ |
132 | static inline void opal_flash_validate(void) | 129 | static inline void opal_flash_validate(void) |
133 | { | 130 | { |
134 | struct validate_flash_t *args_buf = &validate_flash_data; | 131 | long ret; |
132 | void *buf = validate_flash_data.buf; | ||
133 | __be32 size, result; | ||
135 | 134 | ||
136 | args_buf->status = opal_validate_flash(__pa(args_buf->buf), | 135 | ret = opal_validate_flash(__pa(buf), &size, &result); |
137 | &(args_buf->buf_size), | 136 | |
138 | &(args_buf->result)); | 137 | validate_flash_data.status = ret; |
138 | validate_flash_data.buf_size = be32_to_cpu(size); | ||
139 | validate_flash_data.result = be32_to_cpu(result); | ||
139 | } | 140 | } |
140 | 141 | ||
141 | /* | 142 | /* |
@@ -268,93 +269,11 @@ static ssize_t manage_store(struct kobject *kobj, | |||
268 | } | 269 | } |
269 | 270 | ||
270 | /* | 271 | /* |
271 | * Free sg list | ||
272 | */ | ||
273 | static void free_sg_list(struct opal_sg_list *list) | ||
274 | { | ||
275 | struct opal_sg_list *sg1; | ||
276 | while (list) { | ||
277 | sg1 = list->next; | ||
278 | kfree(list); | ||
279 | list = sg1; | ||
280 | } | ||
281 | list = NULL; | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Build candidate image scatter gather list | ||
286 | * | ||
287 | * list format: | ||
288 | * ----------------------------------- | ||
289 | * | VER (8) | Entry length in bytes | | ||
290 | * ----------------------------------- | ||
291 | * | Pointer to next entry | | ||
292 | * ----------------------------------- | ||
293 | * | Address of memory area 1 | | ||
294 | * ----------------------------------- | ||
295 | * | Length of memory area 1 | | ||
296 | * ----------------------------------- | ||
297 | * | ......... | | ||
298 | * ----------------------------------- | ||
299 | * | ......... | | ||
300 | * ----------------------------------- | ||
301 | * | Address of memory area N | | ||
302 | * ----------------------------------- | ||
303 | * | Length of memory area N | | ||
304 | * ----------------------------------- | ||
305 | */ | ||
306 | static struct opal_sg_list *image_data_to_sglist(void) | ||
307 | { | ||
308 | struct opal_sg_list *sg1, *list = NULL; | ||
309 | void *addr; | ||
310 | int size; | ||
311 | |||
312 | addr = image_data.data; | ||
313 | size = image_data.size; | ||
314 | |||
315 | sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
316 | if (!sg1) | ||
317 | return NULL; | ||
318 | |||
319 | list = sg1; | ||
320 | sg1->num_entries = 0; | ||
321 | while (size > 0) { | ||
322 | /* Translate virtual address to physical address */ | ||
323 | sg1->entry[sg1->num_entries].data = | ||
324 | (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT); | ||
325 | |||
326 | if (size > PAGE_SIZE) | ||
327 | sg1->entry[sg1->num_entries].length = PAGE_SIZE; | ||
328 | else | ||
329 | sg1->entry[sg1->num_entries].length = size; | ||
330 | |||
331 | sg1->num_entries++; | ||
332 | if (sg1->num_entries >= SG_ENTRIES_PER_NODE) { | ||
333 | sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
334 | if (!sg1->next) { | ||
335 | pr_err("%s : Failed to allocate memory\n", | ||
336 | __func__); | ||
337 | goto nomem; | ||
338 | } | ||
339 | |||
340 | sg1 = sg1->next; | ||
341 | sg1->num_entries = 0; | ||
342 | } | ||
343 | addr += PAGE_SIZE; | ||
344 | size -= PAGE_SIZE; | ||
345 | } | ||
346 | return list; | ||
347 | nomem: | ||
348 | free_sg_list(list); | ||
349 | return NULL; | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * OPAL update flash | 272 | * OPAL update flash |
354 | */ | 273 | */ |
355 | static int opal_flash_update(int op) | 274 | static int opal_flash_update(int op) |
356 | { | 275 | { |
357 | struct opal_sg_list *sg, *list, *next; | 276 | struct opal_sg_list *list; |
358 | unsigned long addr; | 277 | unsigned long addr; |
359 | int64_t rc = OPAL_PARAMETER; | 278 | int64_t rc = OPAL_PARAMETER; |
360 | 279 | ||
@@ -364,30 +283,13 @@ static int opal_flash_update(int op) | |||
364 | goto flash; | 283 | goto flash; |
365 | } | 284 | } |
366 | 285 | ||
367 | list = image_data_to_sglist(); | 286 | list = opal_vmalloc_to_sg_list(image_data.data, image_data.size); |
368 | if (!list) | 287 | if (!list) |
369 | goto invalid_img; | 288 | goto invalid_img; |
370 | 289 | ||
371 | /* First entry address */ | 290 | /* First entry address */ |
372 | addr = __pa(list); | 291 | addr = __pa(list); |
373 | 292 | ||
374 | /* Translate sg list address to absolute */ | ||
375 | for (sg = list; sg; sg = next) { | ||
376 | next = sg->next; | ||
377 | /* Don't translate NULL pointer for last entry */ | ||
378 | if (sg->next) | ||
379 | sg->next = (struct opal_sg_list *)__pa(sg->next); | ||
380 | else | ||
381 | sg->next = NULL; | ||
382 | |||
383 | /* | ||
384 | * Convert num_entries to version/length format | ||
385 | * to satisfy OPAL. | ||
386 | */ | ||
387 | sg->num_entries = (SG_LIST_VERSION << 56) | | ||
388 | (sg->num_entries * sizeof(struct opal_sg_entry) + 16); | ||
389 | } | ||
390 | |||
391 | pr_alert("FLASH: Image is %u bytes\n", image_data.size); | 293 | pr_alert("FLASH: Image is %u bytes\n", image_data.size); |
392 | pr_alert("FLASH: Image update requested\n"); | 294 | pr_alert("FLASH: Image update requested\n"); |
393 | pr_alert("FLASH: Image will be updated during system reboot\n"); | 295 | pr_alert("FLASH: Image will be updated during system reboot\n"); |
diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index 6b614726baf2..d202f9bc3683 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c | |||
@@ -39,10 +39,11 @@ struct param_attr { | |||
39 | struct kobj_attribute kobj_attr; | 39 | struct kobj_attribute kobj_attr; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static int opal_get_sys_param(u32 param_id, u32 length, void *buffer) | 42 | static ssize_t opal_get_sys_param(u32 param_id, u32 length, void *buffer) |
43 | { | 43 | { |
44 | struct opal_msg msg; | 44 | struct opal_msg msg; |
45 | int ret, token; | 45 | ssize_t ret; |
46 | int token; | ||
46 | 47 | ||
47 | token = opal_async_get_token_interruptible(); | 48 | token = opal_async_get_token_interruptible(); |
48 | if (token < 0) { | 49 | if (token < 0) { |
@@ -59,7 +60,7 @@ static int opal_get_sys_param(u32 param_id, u32 length, void *buffer) | |||
59 | 60 | ||
60 | ret = opal_async_wait_response(token, &msg); | 61 | ret = opal_async_wait_response(token, &msg); |
61 | if (ret) { | 62 | if (ret) { |
62 | pr_err("%s: Failed to wait for the async response, %d\n", | 63 | pr_err("%s: Failed to wait for the async response, %zd\n", |
63 | __func__, ret); | 64 | __func__, ret); |
64 | goto out_token; | 65 | goto out_token; |
65 | } | 66 | } |
@@ -111,7 +112,7 @@ static ssize_t sys_param_show(struct kobject *kobj, | |||
111 | { | 112 | { |
112 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, | 113 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, |
113 | kobj_attr); | 114 | kobj_attr); |
114 | int ret; | 115 | ssize_t ret; |
115 | 116 | ||
116 | mutex_lock(&opal_sysparam_mutex); | 117 | mutex_lock(&opal_sysparam_mutex); |
117 | ret = opal_get_sys_param(attr->param_id, attr->param_size, | 118 | ret = opal_get_sys_param(attr->param_id, attr->param_size, |
@@ -121,9 +122,10 @@ static ssize_t sys_param_show(struct kobject *kobj, | |||
121 | 122 | ||
122 | memcpy(buf, param_data_buf, attr->param_size); | 123 | memcpy(buf, param_data_buf, attr->param_size); |
123 | 124 | ||
125 | ret = attr->param_size; | ||
124 | out: | 126 | out: |
125 | mutex_unlock(&opal_sysparam_mutex); | 127 | mutex_unlock(&opal_sysparam_mutex); |
126 | return ret ? ret : attr->param_size; | 128 | return ret; |
127 | } | 129 | } |
128 | 130 | ||
129 | static ssize_t sys_param_store(struct kobject *kobj, | 131 | static ssize_t sys_param_store(struct kobject *kobj, |
@@ -131,14 +133,20 @@ static ssize_t sys_param_store(struct kobject *kobj, | |||
131 | { | 133 | { |
132 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, | 134 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, |
133 | kobj_attr); | 135 | kobj_attr); |
134 | int ret; | 136 | ssize_t ret; |
137 | |||
138 | /* MAX_PARAM_DATA_LEN is sizeof(param_data_buf) */ | ||
139 | if (count > MAX_PARAM_DATA_LEN) | ||
140 | count = MAX_PARAM_DATA_LEN; | ||
135 | 141 | ||
136 | mutex_lock(&opal_sysparam_mutex); | 142 | mutex_lock(&opal_sysparam_mutex); |
137 | memcpy(param_data_buf, buf, count); | 143 | memcpy(param_data_buf, buf, count); |
138 | ret = opal_set_sys_param(attr->param_id, attr->param_size, | 144 | ret = opal_set_sys_param(attr->param_id, attr->param_size, |
139 | param_data_buf); | 145 | param_data_buf); |
140 | mutex_unlock(&opal_sysparam_mutex); | 146 | mutex_unlock(&opal_sysparam_mutex); |
141 | return ret ? ret : count; | 147 | if (!ret) |
148 | ret = count; | ||
149 | return ret; | ||
142 | } | 150 | } |
143 | 151 | ||
144 | void __init opal_sys_param_init(void) | 152 | void __init opal_sys_param_init(void) |
@@ -214,13 +222,13 @@ void __init opal_sys_param_init(void) | |||
214 | } | 222 | } |
215 | 223 | ||
216 | if (of_property_read_u32_array(sysparam, "param-len", size, count)) { | 224 | if (of_property_read_u32_array(sysparam, "param-len", size, count)) { |
217 | pr_err("SYSPARAM: Missing propery param-len in the DT\n"); | 225 | pr_err("SYSPARAM: Missing property param-len in the DT\n"); |
218 | goto out_free_perm; | 226 | goto out_free_perm; |
219 | } | 227 | } |
220 | 228 | ||
221 | 229 | ||
222 | if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) { | 230 | if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) { |
223 | pr_err("SYSPARAM: Missing propery param-perm in the DT\n"); | 231 | pr_err("SYSPARAM: Missing property param-perm in the DT\n"); |
224 | goto out_free_perm; | 232 | goto out_free_perm; |
225 | } | 233 | } |
226 | 234 | ||
@@ -233,6 +241,12 @@ void __init opal_sys_param_init(void) | |||
233 | 241 | ||
234 | /* For each of the parameters, populate the parameter attributes */ | 242 | /* For each of the parameters, populate the parameter attributes */ |
235 | for (i = 0; i < count; i++) { | 243 | for (i = 0; i < count; i++) { |
244 | if (size[i] > MAX_PARAM_DATA_LEN) { | ||
245 | pr_warn("SYSPARAM: Not creating parameter %d as size " | ||
246 | "exceeds buffer length\n", i); | ||
247 | continue; | ||
248 | } | ||
249 | |||
236 | sysfs_attr_init(&attr[i].kobj_attr.attr); | 250 | sysfs_attr_init(&attr[i].kobj_attr.attr); |
237 | attr[i].param_id = id[i]; | 251 | attr[i].param_id = id[i]; |
238 | attr[i].param_size = size[i]; | 252 | attr[i].param_size = size[i]; |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 49d2f00019e5..360ad80c754c 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -242,14 +242,14 @@ void opal_notifier_update_evt(uint64_t evt_mask, | |||
242 | void opal_notifier_enable(void) | 242 | void opal_notifier_enable(void) |
243 | { | 243 | { |
244 | int64_t rc; | 244 | int64_t rc; |
245 | uint64_t evt = 0; | 245 | __be64 evt = 0; |
246 | 246 | ||
247 | atomic_set(&opal_notifier_hold, 0); | 247 | atomic_set(&opal_notifier_hold, 0); |
248 | 248 | ||
249 | /* Process pending events */ | 249 | /* Process pending events */ |
250 | rc = opal_poll_events(&evt); | 250 | rc = opal_poll_events(&evt); |
251 | if (rc == OPAL_SUCCESS && evt) | 251 | if (rc == OPAL_SUCCESS && evt) |
252 | opal_do_notifier(evt); | 252 | opal_do_notifier(be64_to_cpu(evt)); |
253 | } | 253 | } |
254 | 254 | ||
255 | void opal_notifier_disable(void) | 255 | void opal_notifier_disable(void) |
@@ -529,7 +529,7 @@ static irqreturn_t opal_interrupt(int irq, void *data) | |||
529 | 529 | ||
530 | opal_handle_interrupt(virq_to_hw(irq), &events); | 530 | opal_handle_interrupt(virq_to_hw(irq), &events); |
531 | 531 | ||
532 | opal_do_notifier(events); | 532 | opal_do_notifier(be64_to_cpu(events)); |
533 | 533 | ||
534 | return IRQ_HANDLED; | 534 | return IRQ_HANDLED; |
535 | } | 535 | } |
@@ -638,3 +638,66 @@ void opal_shutdown(void) | |||
638 | 638 | ||
639 | /* Export this so that test modules can use it */ | 639 | /* Export this so that test modules can use it */ |
640 | EXPORT_SYMBOL_GPL(opal_invalid_call); | 640 | EXPORT_SYMBOL_GPL(opal_invalid_call); |
641 | |||
642 | /* Convert a region of vmalloc memory to an opal sg list */ | ||
643 | struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, | ||
644 | unsigned long vmalloc_size) | ||
645 | { | ||
646 | struct opal_sg_list *sg, *first = NULL; | ||
647 | unsigned long i = 0; | ||
648 | |||
649 | sg = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
650 | if (!sg) | ||
651 | goto nomem; | ||
652 | |||
653 | first = sg; | ||
654 | |||
655 | while (vmalloc_size > 0) { | ||
656 | uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT; | ||
657 | uint64_t length = min(vmalloc_size, PAGE_SIZE); | ||
658 | |||
659 | sg->entry[i].data = cpu_to_be64(data); | ||
660 | sg->entry[i].length = cpu_to_be64(length); | ||
661 | i++; | ||
662 | |||
663 | if (i >= SG_ENTRIES_PER_NODE) { | ||
664 | struct opal_sg_list *next; | ||
665 | |||
666 | next = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
667 | if (!next) | ||
668 | goto nomem; | ||
669 | |||
670 | sg->length = cpu_to_be64( | ||
671 | i * sizeof(struct opal_sg_entry) + 16); | ||
672 | i = 0; | ||
673 | sg->next = cpu_to_be64(__pa(next)); | ||
674 | sg = next; | ||
675 | } | ||
676 | |||
677 | vmalloc_addr += length; | ||
678 | vmalloc_size -= length; | ||
679 | } | ||
680 | |||
681 | sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16); | ||
682 | |||
683 | return first; | ||
684 | |||
685 | nomem: | ||
686 | pr_err("%s : Failed to allocate memory\n", __func__); | ||
687 | opal_free_sg_list(first); | ||
688 | return NULL; | ||
689 | } | ||
690 | |||
691 | void opal_free_sg_list(struct opal_sg_list *sg) | ||
692 | { | ||
693 | while (sg) { | ||
694 | uint64_t next = be64_to_cpu(sg->next); | ||
695 | |||
696 | kfree(sg); | ||
697 | |||
698 | if (next) | ||
699 | sg = __va(next); | ||
700 | else | ||
701 | sg = NULL; | ||
702 | } | ||
703 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3b2b4fb3585b..98824aa99173 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -343,7 +343,6 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) | |||
343 | pci_name(dev)); | 343 | pci_name(dev)); |
344 | continue; | 344 | continue; |
345 | } | 345 | } |
346 | pci_dev_get(dev); | ||
347 | pdn->pcidev = dev; | 346 | pdn->pcidev = dev; |
348 | pdn->pe_number = pe->pe_number; | 347 | pdn->pe_number = pe->pe_number; |
349 | pe->dma_weight += pnv_ioda_dma_weight(dev); | 348 | pe->dma_weight += pnv_ioda_dma_weight(dev); |
@@ -462,7 +461,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev | |||
462 | 461 | ||
463 | pe = &phb->ioda.pe_array[pdn->pe_number]; | 462 | pe = &phb->ioda.pe_array[pdn->pe_number]; |
464 | WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); | 463 | WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); |
465 | set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table); | 464 | set_iommu_table_base(&pdev->dev, &pe->tce32_table); |
466 | } | 465 | } |
467 | 466 | ||
468 | static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, | 467 | static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, |
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 61cf8fa9c61b..8723d32632f5 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c | |||
@@ -162,18 +162,62 @@ static void pnv_shutdown(void) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | #ifdef CONFIG_KEXEC | 164 | #ifdef CONFIG_KEXEC |
165 | static void pnv_kexec_wait_secondaries_down(void) | ||
166 | { | ||
167 | int my_cpu, i, notified = -1; | ||
168 | |||
169 | my_cpu = get_cpu(); | ||
170 | |||
171 | for_each_online_cpu(i) { | ||
172 | uint8_t status; | ||
173 | int64_t rc; | ||
174 | |||
175 | if (i == my_cpu) | ||
176 | continue; | ||
177 | |||
178 | for (;;) { | ||
179 | rc = opal_query_cpu_status(get_hard_smp_processor_id(i), | ||
180 | &status); | ||
181 | if (rc != OPAL_SUCCESS || status != OPAL_THREAD_STARTED) | ||
182 | break; | ||
183 | barrier(); | ||
184 | if (i != notified) { | ||
185 | printk(KERN_INFO "kexec: waiting for cpu %d " | ||
186 | "(physical %d) to enter OPAL\n", | ||
187 | i, paca[i].hw_cpu_id); | ||
188 | notified = i; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | |||
165 | static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) | 194 | static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) |
166 | { | 195 | { |
167 | xics_kexec_teardown_cpu(secondary); | 196 | xics_kexec_teardown_cpu(secondary); |
168 | 197 | ||
169 | /* Return secondary CPUs to firmware on OPAL v3 */ | 198 | /* On OPAL v3, we return all CPUs to firmware */ |
170 | if (firmware_has_feature(FW_FEATURE_OPALv3) && secondary) { | 199 | |
200 | if (!firmware_has_feature(FW_FEATURE_OPALv3)) | ||
201 | return; | ||
202 | |||
203 | if (secondary) { | ||
204 | /* Return secondary CPUs to firmware on OPAL v3 */ | ||
171 | mb(); | 205 | mb(); |
172 | get_paca()->kexec_state = KEXEC_STATE_REAL_MODE; | 206 | get_paca()->kexec_state = KEXEC_STATE_REAL_MODE; |
173 | mb(); | 207 | mb(); |
174 | 208 | ||
175 | /* Return the CPU to OPAL */ | 209 | /* Return the CPU to OPAL */ |
176 | opal_return_cpu(); | 210 | opal_return_cpu(); |
211 | } else if (crash_shutdown) { | ||
212 | /* | ||
213 | * On crash, we don't wait for secondaries to go | ||
214 | * down as they might be unreachable or hung, so | ||
215 | * instead we just wait a bit and move on. | ||
216 | */ | ||
217 | mdelay(1); | ||
218 | } else { | ||
219 | /* Primary waits for the secondaries to have reached OPAL */ | ||
220 | pnv_kexec_wait_secondaries_down(); | ||
177 | } | 221 | } |
178 | } | 222 | } |
179 | #endif /* CONFIG_KEXEC */ | 223 | #endif /* CONFIG_KEXEC */ |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 908672bdcea6..bf5fcd452168 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/cputhreads.h> | 30 | #include <asm/cputhreads.h> |
31 | #include <asm/xics.h> | 31 | #include <asm/xics.h> |
32 | #include <asm/opal.h> | 32 | #include <asm/opal.h> |
33 | #include <asm/runlatch.h> | ||
33 | 34 | ||
34 | #include "powernv.h" | 35 | #include "powernv.h" |
35 | 36 | ||
@@ -156,7 +157,9 @@ static void pnv_smp_cpu_kill_self(void) | |||
156 | */ | 157 | */ |
157 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); | 158 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); |
158 | while (!generic_check_cpu_restart(cpu)) { | 159 | while (!generic_check_cpu_restart(cpu)) { |
160 | ppc64_runlatch_off(); | ||
159 | power7_nap(); | 161 | power7_nap(); |
162 | ppc64_runlatch_on(); | ||
160 | if (!generic_check_cpu_restart(cpu)) { | 163 | if (!generic_check_cpu_restart(cpu)) { |
161 | DBG("CPU%d Unexpected exit while offline !\n", cpu); | 164 | DBG("CPU%d Unexpected exit while offline !\n", cpu); |
162 | /* We may be getting an IPI, so we re-enable | 165 | /* We may be getting an IPI, so we re-enable |
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 9b8e05078a63..20d62975856f 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -88,13 +88,14 @@ void set_default_offline_state(int cpu) | |||
88 | 88 | ||
89 | static void rtas_stop_self(void) | 89 | static void rtas_stop_self(void) |
90 | { | 90 | { |
91 | struct rtas_args args = { | 91 | static struct rtas_args args = { |
92 | .token = cpu_to_be32(rtas_stop_self_token), | ||
93 | .nargs = 0, | 92 | .nargs = 0, |
94 | .nret = 1, | 93 | .nret = 1, |
95 | .rets = &args.args[0], | 94 | .rets = &args.args[0], |
96 | }; | 95 | }; |
97 | 96 | ||
97 | args.token = cpu_to_be32(rtas_stop_self_token); | ||
98 | |||
98 | local_irq_disable(); | 99 | local_irq_disable(); |
99 | 100 | ||
100 | BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); | 101 | BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); |
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 573b488fc48b..7f75c94af822 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
@@ -100,10 +100,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz | |||
100 | 100 | ||
101 | start_pfn = base >> PAGE_SHIFT; | 101 | start_pfn = base >> PAGE_SHIFT; |
102 | 102 | ||
103 | if (!pfn_valid(start_pfn)) { | 103 | lock_device_hotplug(); |
104 | memblock_remove(base, memblock_size); | 104 | |
105 | return 0; | 105 | if (!pfn_valid(start_pfn)) |
106 | } | 106 | goto out; |
107 | 107 | ||
108 | block_sz = memory_block_size_bytes(); | 108 | block_sz = memory_block_size_bytes(); |
109 | sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; | 109 | sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; |
@@ -114,8 +114,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz | |||
114 | base += MIN_MEMORY_BLOCK_SIZE; | 114 | base += MIN_MEMORY_BLOCK_SIZE; |
115 | } | 115 | } |
116 | 116 | ||
117 | out: | ||
117 | /* Update memory regions for memory remove */ | 118 | /* Update memory regions for memory remove */ |
118 | memblock_remove(base, memblock_size); | 119 | memblock_remove(base, memblock_size); |
120 | unlock_device_hotplug(); | ||
119 | return 0; | 121 | return 0; |
120 | } | 122 | } |
121 | 123 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 64603a10b863..4914fd3f41ec 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -1058,7 +1058,7 @@ static int __init apm821xx_pciex_core_init(struct device_node *np) | |||
1058 | return 1; | 1058 | return 1; |
1059 | } | 1059 | } |
1060 | 1060 | ||
1061 | static int apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1061 | static int __init apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1062 | { | 1062 | { |
1063 | u32 val; | 1063 | u32 val; |
1064 | 1064 | ||