diff options
-rw-r--r-- | Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml | 42 | ||||
-rw-r--r-- | crypto/af_alg.c | 7 | ||||
-rw-r--r-- | crypto/algif_hash.c | 4 | ||||
-rw-r--r-- | crypto/asymmetric_keys/public_key.c | 20 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c | 30 | ||||
-rw-r--r-- | drivers/hid/hid-hyperv.c | 10 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 7 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-hidpp.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-nvidia-shield.c | 12 | ||||
-rw-r--r-- | include/linux/rethook.h | 1 | ||||
-rw-r--r-- | kernel/kprobes.c | 8 | ||||
-rw-r--r-- | kernel/trace/fprobe.c | 15 | ||||
-rw-r--r-- | kernel/trace/rethook.c | 13 | ||||
-rw-r--r-- | kernel/trace/trace_eprobe.c | 18 | ||||
-rwxr-xr-x | tools/testing/selftests/hid/vmtest.sh | 1 |
15 files changed, 145 insertions, 45 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml b/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml new file mode 100644 index 000000000000..81690d4b62a6 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/loongson,ls1x-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Loongson-1 Watchdog Timer + +maintainers: + - Keguang Zhang <[email protected]> + +allOf: + - $ref: watchdog.yaml# + +properties: + compatible: + enum: + - loongson,ls1b-wdt + - loongson,ls1c-wdt + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - clocks + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/loongson,ls1x-clk.h> + watchdog: watchdog@1fe5c060 { + compatible = "loongson,ls1b-wdt"; + reg = <0x1fe5c060 0xc>; + + clocks = <&clkc LS1X_CLKID_APB>; + }; diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 6218c773d71c..06b15b9f661c 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -992,7 +992,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, ssize_t plen; /* use the existing memory in an allocated page */ - if (ctx->merge) { + if (ctx->merge && !(msg->msg_flags & MSG_SPLICE_PAGES)) { sgl = list_entry(ctx->tsgl_list.prev, struct af_alg_tsgl, list); sg = sgl->sg + sgl->cur - 1; @@ -1054,6 +1054,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, ctx->used += plen; copied += plen; size -= plen; + ctx->merge = 0; } else { do { struct page *pg; @@ -1085,12 +1086,12 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, size -= plen; sgl->cur++; } while (len && sgl->cur < MAX_SGL_ENTS); + + ctx->merge = plen & (PAGE_SIZE - 1); } if (!size) sg_mark_end(sg + sgl->cur - 1); - - ctx->merge = plen & (PAGE_SIZE - 1); } err = 0; diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 0ab43e149f0e..82c44d4899b9 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -68,13 +68,15 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg, struct hash_ctx *ctx = ask->private; ssize_t copied = 0; size_t len, max_pages, npages; - bool continuing = ctx->more, need_init = false; + bool continuing, need_init = false; int err; max_pages = min_t(size_t, ALG_MAX_PAGES, DIV_ROUND_UP(sk->sk_sndbuf, PAGE_SIZE)); lock_sock(sk); + continuing = ctx->more; + if (!continuing) { /* Discard a previous request that wasn't marked MSG_MORE. */ hash_free_result(sk, ctx); diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index e787598cb3f7..773e159dbbcb 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -185,8 +185,10 @@ static int software_key_query(const struct kernel_pkey_params *params, if (issig) { sig = crypto_alloc_sig(alg_name, 0, 0); - if (IS_ERR(sig)) + if (IS_ERR(sig)) { + ret = PTR_ERR(sig); goto error_free_key; + } if (pkey->key_is_private) ret = crypto_sig_set_privkey(sig, key, pkey->keylen); @@ -208,8 +210,10 @@ static int software_key_query(const struct kernel_pkey_params *params, } } else { tfm = crypto_alloc_akcipher(alg_name, 0, 0); - if (IS_ERR(tfm)) + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); goto error_free_key; + } if (pkey->key_is_private) ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen); @@ -300,8 +304,10 @@ static int software_key_eds_op(struct kernel_pkey_params *params, if (issig) { sig = crypto_alloc_sig(alg_name, 0, 0); - if (IS_ERR(sig)) + if (IS_ERR(sig)) { + ret = PTR_ERR(sig); goto error_free_key; + } if (pkey->key_is_private) ret = crypto_sig_set_privkey(sig, key, pkey->keylen); @@ -313,8 +319,10 @@ static int software_key_eds_op(struct kernel_pkey_params *params, ksz = crypto_sig_maxsize(sig); } else { tfm = crypto_alloc_akcipher(alg_name, 0, 0); - if (IS_ERR(tfm)) + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); goto error_free_key; + } if (pkey->key_is_private) ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen); @@ -411,8 +419,10 @@ int public_key_verify_signature(const struct public_key *pkey, key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen, GFP_KERNEL); - if (!key) + if (!key) { + ret = -ENOMEM; goto error_free_tfm; + } memcpy(key, pkey->key, pkey->keylen); ptr = key + pkey->keylen; diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c index 6f0d332ccf51..06bdcf072d10 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c @@ -132,29 +132,45 @@ static void get_common_inputs(struct common_input_property *common, int report_i common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM; } -static int float_to_int(u32 float32) +static int float_to_int(u32 flt32_val) { int fraction, shift, mantissa, sign, exp, zeropre; - mantissa = float32 & GENMASK(22, 0); - sign = (float32 & BIT(31)) ? -1 : 1; - exp = (float32 & ~BIT(31)) >> 23; + mantissa = flt32_val & GENMASK(22, 0); + sign = (flt32_val & BIT(31)) ? -1 : 1; + exp = (flt32_val & ~BIT(31)) >> 23; if (!exp && !mantissa) return 0; + /* + * Calculate the exponent and fraction part of floating + * point representation. + */ exp -= 127; if (exp < 0) { exp = -exp; + if (exp >= BITS_PER_TYPE(u32)) + return 0; zeropre = (((BIT(23) + mantissa) * 100) >> 23) >> exp; return zeropre >= 50 ? sign : 0; } shift = 23 - exp; - float32 = BIT(exp) + (mantissa >> shift); - fraction = mantissa & GENMASK(shift - 1, 0); + if (abs(shift) >= BITS_PER_TYPE(u32)) + return 0; + + if (shift < 0) { + shift = -shift; + flt32_val = BIT(exp) + (mantissa << shift); + shift = 0; + } else { + flt32_val = BIT(exp) + (mantissa >> shift); + } + + fraction = (shift == 0) ? 0 : mantissa & GENMASK(shift - 1, 0); - return (((fraction * 100) >> shift) >= 50) ? sign * (float32 + 1) : sign * float32; + return (((fraction * 100) >> shift) >= 50) ? sign * (flt32_val + 1) : sign * flt32_val; } static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id, diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 49d4a26895e7..f33485d83d24 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c @@ -258,19 +258,17 @@ static void mousevsc_on_receive(struct hv_device *device, switch (hid_msg_hdr->type) { case SYNTH_HID_PROTOCOL_RESPONSE: + len = struct_size(pipe_msg, data, pipe_msg->size); + /* * While it will be impossible for us to protect against * malicious/buggy hypervisor/host, add a check here to * ensure we don't corrupt memory. */ - if (struct_size(pipe_msg, data, pipe_msg->size) - > sizeof(struct mousevsc_prt_msg)) { - WARN_ON(1); + if (WARN_ON(len > sizeof(struct mousevsc_prt_msg))) break; - } - memcpy(&input_dev->protocol_resp, pipe_msg, - struct_size(pipe_msg, data, pipe_msg->size)); + memcpy(&input_dev->protocol_resp, pipe_msg, len); complete(&input_dev->wait_event); break; diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a1d2690a1a0d..851ee86eff32 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1093,6 +1093,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX); break; case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO); break; + case 0x076: map_key_clear(KEY_CAMERA_ACCESS_ENABLE); break; + case 0x077: map_key_clear(KEY_CAMERA_ACCESS_DISABLE); break; + case 0x078: map_key_clear(KEY_CAMERA_ACCESS_TOGGLE); break; + case 0x079: map_key_clear(KEY_KBDILLUMUP); break; case 0x07a: map_key_clear(KEY_KBDILLUMDOWN); break; case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE); break; @@ -1139,9 +1143,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break; - case 0x0d5: map_key_clear(KEY_CAMERA_ACCESS_ENABLE); break; - case 0x0d6: map_key_clear(KEY_CAMERA_ACCESS_DISABLE); break; - case 0x0d7: map_key_clear(KEY_CAMERA_ACCESS_TOGGLE); break; case 0x0d8: map_key_clear(KEY_DICTATE); break; case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break; diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index dfe8e09a18de..129b01be488d 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -4598,6 +4598,8 @@ static const struct hid_device_id hidpp_devices[] = { { /* Logitech G403 Wireless Gaming Mouse over USB */ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC082) }, + { /* Logitech G502 Lightspeed Wireless Gaming Mouse over USB */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC08D) }, { /* Logitech G703 Gaming Mouse over USB */ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC087) }, { /* Logitech G703 Hero Gaming Mouse over USB */ diff --git a/drivers/hid/hid-nvidia-shield.c b/drivers/hid/hid-nvidia-shield.c index 85700cec5eac..a928ad2be62d 100644 --- a/drivers/hid/hid-nvidia-shield.c +++ b/drivers/hid/hid-nvidia-shield.c @@ -63,12 +63,12 @@ static_assert(sizeof(enum thunderstrike_led_state) == 1); struct thunderstrike_hostcmd_board_info { __le16 revision; __le16 serial[7]; -}; +} __packed; struct thunderstrike_hostcmd_haptics { u8 motor_left; u8 motor_right; -}; +} __packed; struct thunderstrike_hostcmd_resp_report { u8 report_id; /* THUNDERSTRIKE_HOSTCMD_RESP_REPORT_ID */ @@ -81,7 +81,7 @@ struct thunderstrike_hostcmd_resp_report { __le16 fw_version; enum thunderstrike_led_state led_state; u8 payload[30]; - }; + } __packed; } __packed; static_assert(sizeof(struct thunderstrike_hostcmd_resp_report) == THUNDERSTRIKE_HOSTCMD_REPORT_SIZE); @@ -92,15 +92,15 @@ struct thunderstrike_hostcmd_req_report { u8 reserved_at_10; union { - struct { + struct __packed { u8 update; enum thunderstrike_led_state state; } led; - struct { + struct __packed { u8 update; struct thunderstrike_hostcmd_haptics motors; } haptics; - }; + } __packed; u8 reserved_at_30[27]; } __packed; static_assert(sizeof(struct thunderstrike_hostcmd_req_report) == diff --git a/include/linux/rethook.h b/include/linux/rethook.h index fdf26cd0e742..26b6f3c81a76 100644 --- a/include/linux/rethook.h +++ b/include/linux/rethook.h @@ -59,6 +59,7 @@ struct rethook_node { }; struct rethook *rethook_alloc(void *data, rethook_handler_t handler); +void rethook_stop(struct rethook *rh); void rethook_free(struct rethook *rh); void rethook_add_node(struct rethook *rh, struct rethook_node *node); struct rethook_node *rethook_try_get(struct rethook *rh); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index ce13f1a35251..1fc6095d502d 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1072,7 +1072,7 @@ static int kprobe_ftrace_enabled; static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, int *cnt) { - int ret = 0; + int ret; lockdep_assert_held(&kprobe_mutex); @@ -1110,7 +1110,7 @@ static int arm_kprobe_ftrace(struct kprobe *p) static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, int *cnt) { - int ret = 0; + int ret; lockdep_assert_held(&kprobe_mutex); @@ -2007,9 +2007,9 @@ void __weak arch_kretprobe_fixup_return(struct pt_regs *regs, unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, void *frame_pointer) { - kprobe_opcode_t *correct_ret_addr = NULL; struct kretprobe_instance *ri = NULL; struct llist_node *first, *node = NULL; + kprobe_opcode_t *correct_ret_addr; struct kretprobe *rp; /* Find correct address and all nodes for this frame. */ @@ -2693,7 +2693,7 @@ void kprobe_free_init_mem(void) static int __init init_kprobes(void) { - int i, err = 0; + int i, err; /* FIXME allocate the probe table, currently defined statically */ /* initialize all list heads */ diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index e4704ec26df7..b70de44e6d3d 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -102,12 +102,14 @@ static void fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip, if (unlikely(kprobe_running())) { fp->nmissed++; - return; + goto recursion_unlock; } kprobe_busy_begin(); __fprobe_handler(ip, parent_ip, ops, fregs); kprobe_busy_end(); + +recursion_unlock: ftrace_test_recursion_unlock(bit); } @@ -371,19 +373,16 @@ int unregister_fprobe(struct fprobe *fp) if (!fprobe_is_registered(fp)) return -EINVAL; - /* - * rethook_free() starts disabling the rethook, but the rethook handlers - * may be running on other processors at this point. To make sure that all - * current running handlers are finished, call unregister_ftrace_function() - * after this. - */ if (fp->rethook) - rethook_free(fp->rethook); + rethook_stop(fp->rethook); ret = unregister_ftrace_function(&fp->ops); if (ret < 0) return ret; + if (fp->rethook) + rethook_free(fp->rethook); + ftrace_free_filter(&fp->ops); return ret; diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c index f32ee484391a..5eb9b598f4e9 100644 --- a/kernel/trace/rethook.c +++ b/kernel/trace/rethook.c @@ -54,6 +54,19 @@ static void rethook_free_rcu(struct rcu_head *head) } /** + * rethook_stop() - Stop using a rethook. + * @rh: the struct rethook to stop. + * + * Stop using a rethook to prepare for freeing it. If you want to wait for + * all running rethook handler before calling rethook_free(), you need to + * call this first and wait RCU, and call rethook_free(). + */ +void rethook_stop(struct rethook *rh) +{ + WRITE_ONCE(rh->handler, NULL); +} + +/** * rethook_free() - Free struct rethook. * @rh: the struct rethook to be freed. * diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index cb0077ba2b49..a0a704ba27db 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -644,6 +644,7 @@ static int enable_trace_eprobe(struct trace_event_call *call, struct trace_eprobe *ep; bool enabled; int ret = 0; + int cnt = 0; tp = trace_probe_primary_from_call(call); if (WARN_ON_ONCE(!tp)) @@ -667,12 +668,25 @@ static int enable_trace_eprobe(struct trace_event_call *call, if (ret) break; enabled = true; + cnt++; } if (ret) { /* Failed to enable one of them. Roll back all */ - if (enabled) - disable_eprobe(ep, file->tr); + if (enabled) { + /* + * It's a bug if one failed for something other than memory + * not being available but another eprobe succeeded. + */ + WARN_ON_ONCE(ret != -ENOMEM); + + list_for_each_entry(pos, trace_probe_probe_list(tp), list) { + ep = container_of(pos, struct trace_eprobe, tp); + disable_eprobe(ep, file->tr); + if (!--cnt) + break; + } + } if (file) trace_probe_remove_file(tp, file); else diff --git a/tools/testing/selftests/hid/vmtest.sh b/tools/testing/selftests/hid/vmtest.sh index 681b906b4853..4da48bf6b328 100755 --- a/tools/testing/selftests/hid/vmtest.sh +++ b/tools/testing/selftests/hid/vmtest.sh @@ -79,6 +79,7 @@ recompile_kernel() cd "${kernel_checkout}" ${make_command} olddefconfig + ${make_command} headers ${make_command} } |