Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc

Pull sparc fixes from David Miller:

1) System call tracing doesn't handle register contents properly across
the trace. From Mike Frysinger.

2) Hook up copy_file_range

3) Build fix for 32-bit with newer tools.

4) New sun4v watchdog driver, from Wim Coekaerts.

5) Set context system call has to allow for servicable faults when we
flush the register windows to memory

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc64: Fix sparc64_set_context stack handling.
sparc32: Add -Wa,-Av8 to KBUILD_CFLAGS.
Add sun4v_wdt watchdog driver
sparc: Fix system call tracing register handling.
sparc: Hook up copy_file_range syscall.

+275 -6
+4
Documentation/watchdog/watchdog-parameters.txt
··· 400 400 nowayout: Watchdog cannot be stopped once started 401 401 (default=kernel config parameter) 402 402 ------------------------------------------------- 403 + sun4v_wdt: 404 + timeout_ms: Watchdog timeout in milliseconds 1..180000, default=60000) 405 + nowayout: Watchdog cannot be stopped once started 406 + -------------------------------------------------
+6
arch/sparc/Makefile
··· 24 24 export BITS := 32 25 25 UTS_MACHINE := sparc 26 26 27 + # We are adding -Wa,-Av8 to KBUILD_CFLAGS to deal with a specs bug in some 28 + # versions of gcc. Some gcc versions won't pass -Av8 to binutils when you 29 + # give -mcpu=v8. This silently worked with older bintutils versions but 30 + # does not any more. 27 31 KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 32 + KBUILD_CFLAGS += -Wa,-Av8 33 + 28 34 KBUILD_AFLAGS += -m32 -Wa,-Av8 29 35 30 36 else
+2 -1
arch/sparc/include/uapi/asm/unistd.h
··· 422 422 #define __NR_listen 354 423 423 #define __NR_setsockopt 355 424 424 #define __NR_mlock2 356 425 + #define __NR_copy_file_range 357 425 426 426 - #define NR_syscalls 357 427 + #define NR_syscalls 358 427 428 428 429 /* Bitmask values returned from kern_features system call. */ 429 430 #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
+17
arch/sparc/kernel/entry.S
··· 948 948 cmp %o0, 0 949 949 bne 3f 950 950 mov -ENOSYS, %o0 951 + 952 + /* Syscall tracing can modify the registers. */ 953 + ld [%sp + STACKFRAME_SZ + PT_G1], %g1 954 + sethi %hi(sys_call_table), %l7 955 + ld [%sp + STACKFRAME_SZ + PT_I0], %i0 956 + or %l7, %lo(sys_call_table), %l7 957 + ld [%sp + STACKFRAME_SZ + PT_I1], %i1 958 + ld [%sp + STACKFRAME_SZ + PT_I2], %i2 959 + ld [%sp + STACKFRAME_SZ + PT_I3], %i3 960 + ld [%sp + STACKFRAME_SZ + PT_I4], %i4 961 + ld [%sp + STACKFRAME_SZ + PT_I5], %i5 962 + cmp %g1, NR_syscalls 963 + bgeu 3f 964 + mov -ENOSYS, %o0 965 + 966 + sll %g1, 2, %l4 951 967 mov %i0, %o0 968 + ld [%l7 + %l4], %l7 952 969 mov %i1, %o1 953 970 mov %i2, %o2 954 971 mov %i3, %o3
+2 -1
arch/sparc/kernel/hvcalls.S
··· 338 338 mov %o1, %o4 339 339 mov HV_FAST_MACH_SET_WATCHDOG, %o5 340 340 ta HV_FAST_TRAP 341 + brnz,a,pn %o4, 0f 341 342 stx %o1, [%o4] 342 - retl 343 + 0: retl 343 344 nop 344 345 ENDPROC(sun4v_mach_set_watchdog) 345 346
+1 -1
arch/sparc/kernel/signal_64.c
··· 52 52 unsigned char fenab; 53 53 int err; 54 54 55 - flush_user_windows(); 55 + synchronize_user_stack(); 56 56 if (get_thread_wsaved() || 57 57 (((unsigned long)ucp) & (sizeof(unsigned long)-1)) || 58 58 (!__access_ok(ucp, sizeof(*ucp))))
+1
arch/sparc/kernel/sparc_ksyms_64.c
··· 37 37 EXPORT_SYMBOL(sun4v_niagara_setperf); 38 38 EXPORT_SYMBOL(sun4v_niagara2_getperf); 39 39 EXPORT_SYMBOL(sun4v_niagara2_setperf); 40 + EXPORT_SYMBOL(sun4v_mach_set_watchdog); 40 41 41 42 /* from hweight.S */ 42 43 EXPORT_SYMBOL(__arch_hweight8);
+36
arch/sparc/kernel/syscalls.S
··· 158 158 add %sp, PTREGS_OFF, %o0 159 159 brnz,pn %o0, 3f 160 160 mov -ENOSYS, %o0 161 + 162 + /* Syscall tracing can modify the registers. */ 163 + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 164 + sethi %hi(sys_call_table32), %l7 165 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 166 + or %l7, %lo(sys_call_table32), %l7 167 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 168 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 169 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 170 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 171 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 172 + 173 + cmp %g1, NR_syscalls 174 + bgeu,pn %xcc, 3f 175 + mov -ENOSYS, %o0 176 + 177 + sll %g1, 2, %l4 161 178 srl %i0, 0, %o0 179 + lduw [%l7 + %l4], %l7 162 180 srl %i4, 0, %o4 163 181 srl %i1, 0, %o1 164 182 srl %i2, 0, %o2 ··· 188 170 add %sp, PTREGS_OFF, %o0 189 171 brnz,pn %o0, 3f 190 172 mov -ENOSYS, %o0 173 + 174 + /* Syscall tracing can modify the registers. */ 175 + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 176 + sethi %hi(sys_call_table64), %l7 177 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 178 + or %l7, %lo(sys_call_table64), %l7 179 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 180 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 181 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 182 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 183 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 184 + 185 + cmp %g1, NR_syscalls 186 + bgeu,pn %xcc, 3f 187 + mov -ENOSYS, %o0 188 + 189 + sll %g1, 2, %l4 191 190 mov %i0, %o0 191 + lduw [%l7 + %l4], %l7 192 192 mov %i1, %o1 193 193 mov %i2, %o2 194 194 mov %i3, %o3
+1 -1
arch/sparc/kernel/systbls_32.S
··· 88 88 /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr 89 89 /*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf 90 90 /*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen 91 - /*355*/ .long sys_setsockopt, sys_mlock2 91 + /*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range
+2 -2
arch/sparc/kernel/systbls_64.S
··· 89 89 /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr 90 90 .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf 91 91 /*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen 92 - .word compat_sys_setsockopt, sys_mlock2 92 + .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range 93 93 94 94 #endif /* CONFIG_COMPAT */ 95 95 ··· 170 170 /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr 171 171 .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf 172 172 /*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen 173 - .word sys_setsockopt, sys_mlock2 173 + .word sys_setsockopt, sys_mlock2, sys_copy_file_range
+11
drivers/watchdog/Kconfig
··· 1569 1569 machines. The watchdog timeout period is normally one minute but 1570 1570 can be changed with a boot-time parameter. 1571 1571 1572 + config WATCHDOG_SUN4V 1573 + tristate "Sun4v Watchdog support" 1574 + select WATCHDOG_CORE 1575 + depends on SPARC64 1576 + help 1577 + Say Y here to support the hypervisor watchdog capability embedded 1578 + in the SPARC sun4v architecture. 1579 + 1580 + To compile this driver as a module, choose M here. The module will 1581 + be called sun4v_wdt. 1582 + 1572 1583 # XTENSA Architecture 1573 1584 1574 1585 # Xen Architecture
+1
drivers/watchdog/Makefile
··· 179 179 180 180 obj-$(CONFIG_WATCHDOG_RIO) += riowd.o 181 181 obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o 182 + obj-$(CONFIG_WATCHDOG_SUN4V) += sun4v_wdt.o 182 183 183 184 # XTENSA Architecture 184 185
+191
drivers/watchdog/sun4v_wdt.c
··· 1 + /* 2 + * sun4v watchdog timer 3 + * (c) Copyright 2016 Oracle Corporation 4 + * 5 + * Implement a simple watchdog driver using the built-in sun4v hypervisor 6 + * watchdog support. If time expires, the hypervisor stops or bounces 7 + * the guest domain. 8 + * 9 + * This program is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License 11 + * as published by the Free Software Foundation; either version 12 + * 2 of the License, or (at your option) any later version. 13 + */ 14 + 15 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 16 + 17 + #include <linux/errno.h> 18 + #include <linux/init.h> 19 + #include <linux/kernel.h> 20 + #include <linux/module.h> 21 + #include <linux/moduleparam.h> 22 + #include <linux/watchdog.h> 23 + #include <asm/hypervisor.h> 24 + #include <asm/mdesc.h> 25 + 26 + #define WDT_TIMEOUT 60 27 + #define WDT_MAX_TIMEOUT 31536000 28 + #define WDT_MIN_TIMEOUT 1 29 + #define WDT_DEFAULT_RESOLUTION_MS 1000 /* 1 second */ 30 + 31 + static unsigned int timeout; 32 + module_param(timeout, uint, 0); 33 + MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" 34 + __MODULE_STRING(WDT_TIMEOUT) ")"); 35 + 36 + static bool nowayout = WATCHDOG_NOWAYOUT; 37 + module_param(nowayout, bool, S_IRUGO); 38 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 39 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 40 + 41 + static int sun4v_wdt_stop(struct watchdog_device *wdd) 42 + { 43 + sun4v_mach_set_watchdog(0, NULL); 44 + 45 + return 0; 46 + } 47 + 48 + static int sun4v_wdt_ping(struct watchdog_device *wdd) 49 + { 50 + int hverr; 51 + 52 + /* 53 + * HV watchdog timer will round up the timeout 54 + * passed in to the nearest multiple of the 55 + * watchdog resolution in milliseconds. 56 + */ 57 + hverr = sun4v_mach_set_watchdog(wdd->timeout * 1000, NULL); 58 + if (hverr == HV_EINVAL) 59 + return -EINVAL; 60 + 61 + return 0; 62 + } 63 + 64 + static int sun4v_wdt_set_timeout(struct watchdog_device *wdd, 65 + unsigned int timeout) 66 + { 67 + wdd->timeout = timeout; 68 + 69 + return 0; 70 + } 71 + 72 + static const struct watchdog_info sun4v_wdt_ident = { 73 + .options = WDIOF_SETTIMEOUT | 74 + WDIOF_MAGICCLOSE | 75 + WDIOF_KEEPALIVEPING, 76 + .identity = "sun4v hypervisor watchdog", 77 + .firmware_version = 0, 78 + }; 79 + 80 + static struct watchdog_ops sun4v_wdt_ops = { 81 + .owner = THIS_MODULE, 82 + .start = sun4v_wdt_ping, 83 + .stop = sun4v_wdt_stop, 84 + .ping = sun4v_wdt_ping, 85 + .set_timeout = sun4v_wdt_set_timeout, 86 + }; 87 + 88 + static struct watchdog_device wdd = { 89 + .info = &sun4v_wdt_ident, 90 + .ops = &sun4v_wdt_ops, 91 + .min_timeout = WDT_MIN_TIMEOUT, 92 + .max_timeout = WDT_MAX_TIMEOUT, 93 + .timeout = WDT_TIMEOUT, 94 + }; 95 + 96 + static int __init sun4v_wdt_init(void) 97 + { 98 + struct mdesc_handle *handle; 99 + u64 node; 100 + const u64 *value; 101 + int err = 0; 102 + unsigned long major = 1, minor = 1; 103 + 104 + /* 105 + * There are 2 properties that can be set from the control 106 + * domain for the watchdog. 107 + * watchdog-resolution 108 + * watchdog-max-timeout 109 + * 110 + * We can expect a handle to be returned otherwise something 111 + * serious is wrong. Correct to return -ENODEV here. 112 + */ 113 + 114 + handle = mdesc_grab(); 115 + if (!handle) 116 + return -ENODEV; 117 + 118 + node = mdesc_node_by_name(handle, MDESC_NODE_NULL, "platform"); 119 + err = -ENODEV; 120 + if (node == MDESC_NODE_NULL) 121 + goto out_release; 122 + 123 + /* 124 + * This is a safe way to validate if we are on the right 125 + * platform. 126 + */ 127 + if (sun4v_hvapi_register(HV_GRP_CORE, major, &minor)) 128 + goto out_hv_unreg; 129 + 130 + /* Allow value of watchdog-resolution up to 1s (default) */ 131 + value = mdesc_get_property(handle, node, "watchdog-resolution", NULL); 132 + err = -EINVAL; 133 + if (value) { 134 + if (*value == 0 || 135 + *value > WDT_DEFAULT_RESOLUTION_MS) 136 + goto out_hv_unreg; 137 + } 138 + 139 + value = mdesc_get_property(handle, node, "watchdog-max-timeout", NULL); 140 + if (value) { 141 + /* 142 + * If the property value (in ms) is smaller than 143 + * min_timeout, return -EINVAL. 144 + */ 145 + if (*value < wdd.min_timeout * 1000) 146 + goto out_hv_unreg; 147 + 148 + /* 149 + * If the property value is smaller than 150 + * default max_timeout then set watchdog max_timeout to 151 + * the value of the property in seconds. 152 + */ 153 + if (*value < wdd.max_timeout * 1000) 154 + wdd.max_timeout = *value / 1000; 155 + } 156 + 157 + watchdog_init_timeout(&wdd, timeout, NULL); 158 + 159 + watchdog_set_nowayout(&wdd, nowayout); 160 + 161 + err = watchdog_register_device(&wdd); 162 + if (err) 163 + goto out_hv_unreg; 164 + 165 + pr_info("initialized (timeout=%ds, nowayout=%d)\n", 166 + wdd.timeout, nowayout); 167 + 168 + mdesc_release(handle); 169 + 170 + return 0; 171 + 172 + out_hv_unreg: 173 + sun4v_hvapi_unregister(HV_GRP_CORE); 174 + 175 + out_release: 176 + mdesc_release(handle); 177 + return err; 178 + } 179 + 180 + static void __exit sun4v_wdt_exit(void) 181 + { 182 + sun4v_hvapi_unregister(HV_GRP_CORE); 183 + watchdog_unregister_device(&wdd); 184 + } 185 + 186 + module_init(sun4v_wdt_init); 187 + module_exit(sun4v_wdt_exit); 188 + 189 + MODULE_AUTHOR("Wim Coekaerts <wim.coekaerts@oracle.com>"); 190 + MODULE_DESCRIPTION("sun4v watchdog driver"); 191 + MODULE_LICENSE("GPL");