* [PATCH v2 1/4] input: Add FF_TRIGGER_RUMBLE effect type
2026-07-30 13:40 ` [PATCH v2 0/4] input: force feedback for trigger rumble motors Guillaume Casal
@ 2026-07-30 13:40 ` Guillaume Casal
2026-07-30 13:53 ` sashiko-bot
2026-07-30 13:40 ` [PATCH v2 2/4] input: ff-memless: Handle FF_TRIGGER_RUMBLE Guillaume Casal
` (3 subsequent siblings)
4 siblings, 1 reply; 19+ messages in thread
From: Guillaume Casal @ 2026-07-30 13:40 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
Some gamepads carry rumble motors behind their triggers, in addition to
the ones in the grips that FF_RUMBLE drives: Xbox controllers call them
impulse triggers, and handhelds such as the ASUS ROG Xbox Ally X have
them too. The force feedback API cannot reach those motors.
Add FF_TRIGGER_RUMBLE as a new effect type carrying its own
struct ff_trigger_rumble_effect, and move FF_EFFECT_MIN down to it, in
the same way FF_HAPTIC was added.
v1 took the approach of the 2022 series and added two members to
struct ff_rumble_effect instead:
https://lore.kernel.org/linux-input/20260730095317.767418-1-guillaume.casal.42@gmail.com/
That is not safe. EVIOCSFF copies the whole struct ff_effect from
userspace, and an application that leaves the tail of the union
uninitialised, which is common when only strong_magnitude and
weak_magnitude are set, would have had that stack content interpreted as
trigger magnitudes. Working programs would start buzzing their triggers
at random. Keeping the size of the union unchanged makes the ABI
compatible in layout, not in meaning.
A distinct effect type has no such problem: no existing application ever
emits it, so no uninitialised byte can be mistaken for a magnitude. It
also removes the need for a separate capability bit, since userspace
discovers the type in the EVIOCGBIT(EV_FF) bitmap exactly as it does for
FF_RUMBLE.
Based on an earlier attempt by Daniel Bomar:
https://lore.kernel.org/lkml/20220410220449.5071-1-dbdaniel42@gmail.com/
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -438,6 +438,20 @@
* @repeat_count: number of times to retrigger effect
* @retrigger_period: time before effect is retriggered (in ms)
*/
+/**
+ * struct ff_trigger_rumble_effect - parameters of a trigger rumble effect
+ * @left_magnitude: magnitude of the motor behind the left trigger
+ * @right_magnitude: magnitude of the motor behind the right trigger
+ *
+ * Some gamepads carry rumble motors behind their triggers, in addition to
+ * the ones in the grips that FF_RUMBLE drives. Xbox controllers call them
+ * impulse triggers.
+ */
+struct ff_trigger_rumble_effect {
+ __u16 left_magnitude;
+ __u16 right_magnitude;
+};
+
struct ff_haptic_effect {
__u16 hid_usage;
__u16 vendor_id;
@@ -483,6 +497,7 @@
struct ff_periodic_effect periodic;
struct ff_condition_effect condition[2]; /* One for each axis */
struct ff_rumble_effect rumble;
+ struct ff_trigger_rumble_effect trigger_rumble;
struct ff_haptic_effect haptic;
} u;
};
@@ -491,6 +506,7 @@
* Force feedback effect types
*/
+#define FF_TRIGGER_RUMBLE 0x4e
#define FF_HAPTIC 0x4f
#define FF_RUMBLE 0x50
#define FF_PERIODIC 0x51
@@ -501,7 +517,7 @@
#define FF_INERTIA 0x56
#define FF_RAMP 0x57
-#define FF_EFFECT_MIN FF_HAPTIC
+#define FF_EFFECT_MIN FF_TRIGGER_RUMBLE
#define FF_EFFECT_MAX FF_RAMP
/*
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 1/4] input: Add FF_TRIGGER_RUMBLE effect type
2026-07-30 13:40 ` [PATCH v2 1/4] input: Add FF_TRIGGER_RUMBLE effect type Guillaume Casal
@ 2026-07-30 13:53 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-07-30 13:53 UTC (permalink / raw)
To: Guillaume Casal; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Kernel stack memory leak via `evdev` compat IOCTL and `uinput`.
--
--- Patch [1]: [PATCH v2 1/4] input: Add FF_TRIGGER_RUMBLE effect type ---
commit 2bed919a335670e21f97b67d6c9c64308176a631
Author: Guillaume Casal <guillaume.casal.42@gmail.com>
Subject: input: Add FF_TRIGGER_RUMBLE effect type
This commit adds a new FF_TRIGGER_RUMBLE force feedback effect type to support
impulse triggers found on modern gamepads. It introduces the
ff_trigger_rumble_effect structure and adds it to the ff_effect union. This
avoids ABI compatibility issues that could arise from reusing existing structs
with uninitialized tail bytes.
> diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
> index 6aa703fcfcfb7..1d172489f8bc5 100644
> --- a/include/uapi/linux/input.h
> +++ b/include/uapi/linux/input.h
[ ... ]
> @@ -483,6 +497,7 @@ struct ff_effect {
> struct ff_periodic_effect periodic;
> struct ff_condition_effect condition[2]; /* One for each axis */
> struct ff_rumble_effect rumble;
> + struct ff_trigger_rumble_effect trigger_rumble;
> struct ff_haptic_effect haptic;
> } u;
> };
[Severity: High]
This is a pre-existing issue, but could the handling of EVIOCSFF via compat
ioctl lead to a kernel stack memory leak when used with uinput?
When a 32-bit userspace client calls the EVIOCSFF ioctl on an evdev device
backed by a uinput device, evdev_do_ioctl() allocates a 48-byte
struct ff_effect on the kernel stack without initialization:
drivers/input/evdev.c:evdev_do_ioctl() {
struct ff_effect effect;
...
case EVIOC_MASK_SIZE(EVIOCSFF):
if (input_ff_effect_from_user(p, size, &effect))
return -EFAULT;
error = input_ff_upload(dev, &effect, file);
...
}
For compat applications, input_ff_effect_from_user() only copies 44 bytes
(sizeof(struct ff_effect_compat)), leaving the last 4 bytes of the effect
struct uninitialized:
drivers/input/input-compat.c:input_ff_effect_from_user() {
compat_effect = (struct ff_effect_compat *)effect;
if (copy_from_user(compat_effect, buffer,
sizeof(struct ff_effect_compat)))
...
}
If a 64-bit userspace daemon retrieves the force-feedback effect using the
UI_BEGIN_FF_UPLOAD ioctl, uinput_ioctl_handler() copies the full 48-byte
structure back to userspace:
drivers/input/misc/uinput.c:uinput_ioctl_handler() {
ff_up.effect = *req->u.upload.effect;
...
retval = uinput_ff_upload_to_user(p, &ff_up);
...
}
Does this sequence allow the 64-bit uinput daemon to read 4 bytes of
uninitialized kernel stack data?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730134004.1118476-1-guillaume.casal.42@gmail.com?part=1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 2/4] input: ff-memless: Handle FF_TRIGGER_RUMBLE
2026-07-30 13:40 ` [PATCH v2 0/4] input: force feedback for trigger rumble motors Guillaume Casal
2026-07-30 13:40 ` [PATCH v2 1/4] input: Add FF_TRIGGER_RUMBLE effect type Guillaume Casal
@ 2026-07-30 13:40 ` Guillaume Casal
2026-07-30 13:40 ` [PATCH v2 3/4] HID: debug: Add FF_TRIGGER_RUMBLE name Guillaume Casal
` (2 subsequent siblings)
4 siblings, 0 replies; 19+ messages in thread
From: Guillaume Casal @ 2026-07-30 13:40 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
Combine trigger rumble effects the way the other types are combined, so
that drivers using input_ff_create_memless() receive them.
Because ml_get_combo_effect() groups playing effects by type, a trigger
rumble effect forms its own combo and reaches the driver in its own
play_effect() call, leaving FF_RUMBLE untouched. An effect that has
finished still contributes its type to the combo with zero magnitudes,
so the existing stop path works unchanged.
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -289,6 +289,15 @@
min(weak + effect->u.rumble.weak_magnitude, 0xffffU);
break;
+ case FF_TRIGGER_RUMBLE:
+ effect->u.trigger_rumble.left_magnitude =
+ min((u32)new->u.trigger_rumble.left_magnitude * gain / 0xffff +
+ effect->u.trigger_rumble.left_magnitude, 0xffffU);
+ effect->u.trigger_rumble.right_magnitude =
+ min((u32)new->u.trigger_rumble.right_magnitude * gain / 0xffff +
+ effect->u.trigger_rumble.right_magnitude, 0xffffU);
+ break;
+
case FF_PERIODIC:
i = apply_envelope(state, abs(new->u.periodic.magnitude),
&new->u.periodic.envelope);
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v2 3/4] HID: debug: Add FF_TRIGGER_RUMBLE name
2026-07-30 13:40 ` [PATCH v2 0/4] input: force feedback for trigger rumble motors Guillaume Casal
2026-07-30 13:40 ` [PATCH v2 1/4] input: Add FF_TRIGGER_RUMBLE effect type Guillaume Casal
2026-07-30 13:40 ` [PATCH v2 2/4] input: ff-memless: Handle FF_TRIGGER_RUMBLE Guillaume Casal
@ 2026-07-30 13:40 ` Guillaume Casal
2026-07-30 13:40 ` [PATCH v2 4/4] Documentation: input: Document FF_TRIGGER_RUMBLE Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 0/4] input: force feedback for trigger rumble motors Guillaume Casal
4 siblings, 0 replies; 19+ messages in thread
From: Guillaume Casal @ 2026-07-30 13:40 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
Without an entry in the force[] array, hid_resolv_event() prints the raw
hex code instead of the name in debugfs.
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -3583,6 +3583,7 @@
};
static const char *force[FF_CNT] = {
+ [FF_TRIGGER_RUMBLE] = "FF_TRIGGER_RUMBLE",
[FF_RUMBLE] = "FF_RUMBLE",
[FF_PERIODIC] = "FF_PERIODIC",
[FF_CONSTANT] = "FF_CONSTANT",
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v2 4/4] Documentation: input: Document FF_TRIGGER_RUMBLE
2026-07-30 13:40 ` [PATCH v2 0/4] input: force feedback for trigger rumble motors Guillaume Casal
` (2 preceding siblings ...)
2026-07-30 13:40 ` [PATCH v2 3/4] HID: debug: Add FF_TRIGGER_RUMBLE name Guillaume Casal
@ 2026-07-30 13:40 ` Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 0/4] input: force feedback for trigger rumble motors Guillaume Casal
4 siblings, 0 replies; 19+ messages in thread
From: Guillaume Casal @ 2026-07-30 13:40 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
List the new effect type alongside the others so that userspace
developers can find it when querying device capabilities.
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/Documentation/input/ff.rst b/Documentation/input/ff.rst
--- a/Documentation/input/ff.rst
+++ b/Documentation/input/ff.rst
@@ -85,6 +85,7 @@
- FF_FRICTION can simulate friction
- FF_DAMPER can simulate damper effects
- FF_RUMBLE rumble effects
+- FF_TRIGGER_RUMBLE rumble effects in the triggers
- FF_INERTIA can simulate inertia
- FF_GAIN gain is adjustable
- FF_AUTOCENTER autocenter is adjustable
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v3 0/4] input: force feedback for trigger rumble motors
2026-07-30 13:40 ` [PATCH v2 0/4] input: force feedback for trigger rumble motors Guillaume Casal
` (3 preceding siblings ...)
2026-07-30 13:40 ` [PATCH v2 4/4] Documentation: input: Document FF_TRIGGER_RUMBLE Guillaume Casal
@ 2026-07-31 5:41 ` Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 1/4] input: Add FF_TRIGGER_RUMBLE effect type Guillaume Casal
` (3 more replies)
4 siblings, 4 replies; 19+ messages in thread
From: Guillaume Casal @ 2026-07-31 5:41 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
Some gamepads carry rumble motors behind their triggers, in addition to
the usual two in the grips: Xbox controllers call them impulse triggers,
and handhelds such as the ASUS ROG Xbox Ally X have them too. The force
feedback API cannot reach those motors.
v1: https://lore.kernel.org/linux-input/20260730095317.767418-1-guillaume.casal.42@gmail.com/
v2: https://lore.kernel.org/linux-input/20260730134004.1118476-1-guillaume.casal.42@gmail.com/
Changes since v2
================
Patch 1: the new structure was inserted between the kernel-doc block of
struct ff_haptic_effect and the structure itself, leaving that block
orphaned and stripping ff_haptic_effect of its documentation. It now goes
after ff_haptic_effect, before the kernel-doc of struct ff_effect. No
code change.
Patch 4: the description column no longer relies on a tab that overshoots
for a name this long.
Patches 2 and 3 are unchanged.
A fifth patch ratelimiting the pr_err() in get_compatible_type() was
prepared and dropped before sending: input_ff_upload() rejects any type
absent from dev->ffbit before storing the effect, and input_ff_create()
copies dev->ffbit into ff->ffbit, so the path it was meant to protect is
not reachable for an in-tree driver.
Changes since v1
================
v1 followed the 2022 series by Daniel Bomar and added trigger_left and
trigger_right to struct ff_rumble_effect. That was wrong, and I am
grateful the problem was pointed out on the list before it went any
further.
EVIOCSFF copies the whole struct ff_effect from userspace. An
application that sets only strong_magnitude and weak_magnitude, and does
not clear the rest of the union, passes uninitialised stack content in
the bytes that v1 gave meaning to. ff-memless would then scale that
content and hand it to the driver, so a program that works today would
start buzzing the triggers at random. Keeping the size of the union
unchanged makes the layout compatible, not the meaning. This is likely
why the 2022 series never went anywhere.
v2 therefore uses a distinct effect type, FF_TRIGGER_RUMBLE, with its own
struct ff_trigger_rumble_effect, following what was done for FF_HAPTIC.
No existing application emits this type, so no uninitialised byte can be
mistaken for a magnitude. The capability bit of v1 is dropped: userspace
discovers the type in the EVIOCGBIT(EV_FF) bitmap, as it does for
FF_RUMBLE.
Two smaller points raised on v1 are fixed here as well: the missing entry
in the force[] array of hid-debug.c, and the missing line in
Documentation/input/ff.rst.
No in-tree user yet
===================
I want to be upfront about this, since it is the obvious objection: at
the tip of this series, git grep FF_TRIGGER_RUMBLE matches only the four
files it touches. No driver advertises the type, so the new arm in
ml_combine_effects() cannot run yet.
The driver that does drive it exists and is tested, on the handheld
described below, but it lives in hid-asus, which is not in mainline. Its
maintainers carry the gamepad support out of tree and upstream it in
steps. Sending its patch with this series would mean sending a patch
against a file that does not contain the code it modifies.
So the order is deliberate: settle the API here, then the driver patch
goes to its maintainers, then the SDL side. If you would rather see a
user in the same series, I can hold this until the gamepad part of
hid-asus lands upstream, but that is not under my control.
Design notes
============
ml_get_combo_effect() groups playing effects by type, so a trigger rumble
effect forms its own combo and reaches the driver in its own
play_effect() call, without disturbing FF_RUMBLE. An effect that has
finished still contributes its type with zero magnitudes, so the stop
path needs no change.
Testing
=======
checkpatch.pl reports no warnings on any of the four patches.
I booted v7.2-rc5 with this series applied under QEMU, with a small
memless driver compiled in that advertises both types and logs the
magnitudes it is handed. Userspace side, a static init issues the
EVIOCSFF ioctls. Output, kernel lines interleaved with userspace ones:
capabilities advertised : FF_RUMBLE yes, FF_TRIGGER_RUMBLE yes
triggers only -> FF_TRIGGER_RUMBLE left=65535 right=65535
grips only -> FF_RUMBLE strong=65535 weak=65535
left trigger only -> FF_TRIGGER_RUMBLE left=65535 right= 0
right trigger only -> FF_TRIGGER_RUMBLE left= 0 right=65535
Each effect is followed by a call with zero magnitudes when it expires,
so the existing stop path needs no change.
The last case is the one that matters for the concern raised on v1. The
test fills the whole struct ff_effect with 0xAA, sets only type,
replay.length and the two rumble magnitudes, and uploads it, which is
what a careless application does today:
old-style app, dirty union
-> FF_RUMBLE strong=32768 weak=32768
and no FF_TRIGGER_RUMBLE call at all
The dirty bytes cannot be mistaken for trigger magnitudes, because they
never carry that meaning for an FF_RUMBLE effect. With v1 they would have
been scaled and sent to the hardware.
The same was then run against real hardware. The vendor kernel of my
handheld cannot be rebuilt, its sources are not published, so I booted
the patched kernel in a VM on the same machine and handed it the gamepad
by USB passthrough. The driver bound it as usual and the device came up
advertising both types:
peripheral: /dev/input/event8 (ASUS ROG Ally X Gamepad)
capabilities advertised : FF_RUMBLE yes, FF_TRIGGER_RUMBLE yes
Capturing the physical bus from the host with usbmon while the VM drove
the pad gives the reports the firmware actually received:
triggers: L=100 R=100 grips: L= 0 R= 0 triggers only
triggers: L= 0 R= 0 grips: L=100 R=100 grips only
triggers: L=100 R= 0 grips: L= 0 R= 0 left trigger only
triggers: L= 0 R=100 grips: L= 0 R= 0 right trigger only
triggers: L= 0 R= 0 grips: L= 50 R= 50 old-style app, dirty union
The four actuators are driven independently, and the careless
application gets its 50% in the grips with nothing in the triggers,
which is the whole point of the change in shape since v1.
The driver patch that fills those two magnitudes is not part of this
series: that driver is not in mainline, and I will send it to its
maintainers once the API here settles.
Guillaume Casal (4):
input: Add FF_TRIGGER_RUMBLE effect type
input: ff-memless: Handle FF_TRIGGER_RUMBLE
HID: debug: Add FF_TRIGGER_RUMBLE name
Documentation: input: Document FF_TRIGGER_RUMBLE
Documentation/input/ff.rst | 1 +
drivers/hid/hid-debug.c | 1 +
drivers/input/ff-memless.c | 9 +++++++++
include/uapi/linux/input.h | 18 +++++++++++++++++-
4 files changed, 29 insertions(+), 1 deletion(-)
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v3 1/4] input: Add FF_TRIGGER_RUMBLE effect type
2026-07-31 5:41 ` [PATCH v3 0/4] input: force feedback for trigger rumble motors Guillaume Casal
@ 2026-07-31 5:41 ` Guillaume Casal
2026-07-31 7:57 ` sashiko-bot
2026-07-31 5:41 ` [PATCH v3 2/4] input: ff-memless: Handle FF_TRIGGER_RUMBLE Guillaume Casal
` (2 subsequent siblings)
3 siblings, 1 reply; 19+ messages in thread
From: Guillaume Casal @ 2026-07-31 5:41 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
Some gamepads carry rumble motors behind their triggers, in addition to
the ones in the grips that FF_RUMBLE drives: Xbox controllers call them
impulse triggers, and handhelds such as the ASUS ROG Xbox Ally X have
them too. The force feedback API cannot reach those motors.
Add FF_TRIGGER_RUMBLE as a new effect type carrying its own
struct ff_trigger_rumble_effect, and move FF_EFFECT_MIN down to it, in
the same way FF_HAPTIC was added.
v1 took the approach of the 2022 series and added two members to
struct ff_rumble_effect instead:
https://lore.kernel.org/linux-input/20260730095317.767418-1-guillaume.casal.42@gmail.com/
That is not safe. EVIOCSFF copies the whole struct ff_effect from
userspace, and an application that leaves the tail of the union
uninitialised, which is common when only strong_magnitude and
weak_magnitude are set, would have had that stack content interpreted as
trigger magnitudes. Working programs would start buzzing their triggers
at random. Keeping the size of the union unchanged makes the ABI
compatible in layout, not in meaning.
A distinct effect type has no such problem: no existing application ever
emits it, so no uninitialised byte can be mistaken for a magnitude. It
also removes the need for a separate capability bit, since userspace
discovers the type in the EVIOCGBIT(EV_FF) bitmap exactly as it does for
FF_RUMBLE.
Based on an earlier attempt by Daniel Bomar:
https://lore.kernel.org/lkml/20220410220449.5071-1-dbdaniel42@gmail.com/
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -448,9 +448,27 @@
};
/**
+ * struct ff_trigger_rumble_effect - parameters of a trigger rumble effect
+ * @left_magnitude: magnitude of the motor behind the left trigger
+ * @right_magnitude: magnitude of the motor behind the right trigger
+ *
+ * Some gamepads carry rumble motors behind their triggers, in addition to
+ * the ones in the grips that FF_RUMBLE drives. Xbox controllers call them
+ * impulse triggers.
+ *
+ * Magnitudes span 0 to 0xffff, as for struct ff_rumble_effect. The effect
+ * has no direction: each magnitude addresses one fixed actuator.
+ */
+struct ff_trigger_rumble_effect {
+ __u16 left_magnitude;
+ __u16 right_magnitude;
+};
+
+/**
* struct ff_effect - defines force feedback effect
* @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
- * FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
+ * FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_TRIGGER_RUMBLE, FF_INERTIA, or
+ * FF_CUSTOM)
* @id: an unique id assigned to an effect
* @direction: direction of the effect
* @trigger: trigger conditions (struct ff_trigger)
@@ -483,6 +501,7 @@
struct ff_periodic_effect periodic;
struct ff_condition_effect condition[2]; /* One for each axis */
struct ff_rumble_effect rumble;
+ struct ff_trigger_rumble_effect trigger_rumble;
struct ff_haptic_effect haptic;
} u;
};
@@ -491,6 +510,7 @@
* Force feedback effect types
*/
+#define FF_TRIGGER_RUMBLE 0x4e
#define FF_HAPTIC 0x4f
#define FF_RUMBLE 0x50
#define FF_PERIODIC 0x51
@@ -501,7 +521,7 @@
#define FF_INERTIA 0x56
#define FF_RAMP 0x57
-#define FF_EFFECT_MIN FF_HAPTIC
+#define FF_EFFECT_MIN FF_TRIGGER_RUMBLE
#define FF_EFFECT_MAX FF_RAMP
/*
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v3 1/4] input: Add FF_TRIGGER_RUMBLE effect type
2026-07-31 5:41 ` [PATCH v3 1/4] input: Add FF_TRIGGER_RUMBLE effect type Guillaume Casal
@ 2026-07-31 7:57 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-07-31 7:57 UTC (permalink / raw)
To: Guillaume Casal; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Medium] The memoryless force-feedback core (`ff-memless.c`) lacks support for the newly added `FF_TRIGGER_RUMBLE` effect, causing trigger rumble effects to be silently discarded.
- [Low] The `FF_TRIGGER_RUMBLE` effect is missing from the HID debug subsystem's string mapping array.
Pre-existing issues:
- [High] Pre-existing 4-byte kernel stack memory leak to userspace in 32-bit compat EVIOCSFF ioctl via partially uninitialized struct ff_effect.
--
--- Patch [1]: [PATCH v3 1/4] input: Add FF_TRIGGER_RUMBLE effect type ---
commit 3d2db8431a4c26c55eb87cf71c1052fd6e1eefd5
Author: Guillaume Casal <guillaume.casal.42@gmail.com>
input: Add FF_TRIGGER_RUMBLE effect type
Some gamepads carry rumble motors behind their triggers, in addition to
the ones in the grips that FF_RUMBLE drives: Xbox controllers call them
impulse triggers, and handhelds such as the ASUS ROG Xbox Ally X have
them too. The force feedback API cannot reach those motors.
[ ... ]
Based on an earlier attempt by Daniel Bomar:
https://lore.kernel.org/lkml/20220410220449.5071-1-dbdaniel42@gmail.com/
> diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
> index 6aa703fcfcfb7..e63d19d9a093d 100644
> --- a/include/uapi/linux/input.h
> +++ b/include/uapi/linux/input.h
[ ... ]
> @@ -483,6 +501,7 @@ struct ff_effect {
> struct ff_periodic_effect periodic;
> struct ff_condition_effect condition[2]; /* One for each axis */
> struct ff_rumble_effect rumble;
> + struct ff_trigger_rumble_effect trigger_rumble;
[Severity: High]
This is a pre-existing issue and was not introduced by this patch, but does
adding to this union highlight a potential kernel stack memory leak when
struct ff_effect is used in the 32-bit compat EVIOCSFF ioctl?
When evdev_do_ioctl() in drivers/input/evdev.c declares the struct on
the stack without zero-initializing it:
drivers/input/evdev.c:evdev_do_ioctl() {
struct ff_effect effect;
...
case EVIOC_MASK_SIZE(EVIOCSFF):
if (input_ff_effect_from_user(p, size, &effect))
Does the compat handler in drivers/input/input-compat.c leave the last
4 bytes of the 48-byte struct uninitialized by only copying 44 bytes?
drivers/input/input-compat.c:input_ff_effect_from_user() {
compat_effect = (struct ff_effect_compat *)effect;
if (copy_from_user(compat_effect, buffer,
sizeof(struct ff_effect_compat)))
If the evdev device is backed by uinput, can those uninitialized stack
bytes then be copied to the 64-bit uinput daemon?
drivers/input/misc/uinput.c:uinput_ff_upload_to_user() {
if (copy_to_user(buffer, ff_up, sizeof(struct uinput_ff_upload)))
> struct ff_haptic_effect haptic;
> } u;
> };
> @@ -491,6 +510,7 @@ struct ff_effect {
> * Force feedback effect types
> */
>
> +#define FF_TRIGGER_RUMBLE 0x4e
[Severity: Medium]
Does the memoryless force-feedback core need to be updated to support
this new effect?
Looking at ml_combine_effects() in drivers/input/ff-memless.c, it
appears FF_TRIGGER_RUMBLE will fall through to the default case and log
an error instead of populating the combined effect magnitudes:
drivers/input/ff-memless.c:ml_combine_effects() {
switch (new->type) {
case FF_CONSTANT:
...
default:
pr_err("invalid type in ml_combine_effects()\n");
[Severity: Low]
Should this new effect type also be added to the string mapping array in
the HID debug subsystem?
Looking at drivers/hid/hid-debug.c, debugfs reads will fail to display
the string name for FF_TRIGGER_RUMBLE without it:
drivers/hid/hid-debug.c:
static const char *force[FF_CNT] = {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260731054159.1982164-1-guillaume.casal.42@gmail.com?part=1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 2/4] input: ff-memless: Handle FF_TRIGGER_RUMBLE
2026-07-31 5:41 ` [PATCH v3 0/4] input: force feedback for trigger rumble motors Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 1/4] input: Add FF_TRIGGER_RUMBLE effect type Guillaume Casal
@ 2026-07-31 5:41 ` Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 3/4] HID: debug: Add FF_TRIGGER_RUMBLE name Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 4/4] Documentation: input: Document FF_TRIGGER_RUMBLE Guillaume Casal
3 siblings, 0 replies; 19+ messages in thread
From: Guillaume Casal @ 2026-07-31 5:41 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
Combine trigger rumble effects the way the other types are combined, so
that drivers using input_ff_create_memless() receive them.
Because ml_get_combo_effect() groups playing effects by type, a trigger
rumble effect forms its own combo and reaches the driver in its own
play_effect() call, leaving FF_RUMBLE untouched. An effect that has
finished still contributes its type to the combo with zero magnitudes,
so the existing stop path works unchanged.
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -289,6 +289,15 @@
min(weak + effect->u.rumble.weak_magnitude, 0xffffU);
break;
+ case FF_TRIGGER_RUMBLE:
+ effect->u.trigger_rumble.left_magnitude =
+ min((u32)new->u.trigger_rumble.left_magnitude * gain / 0xffff +
+ effect->u.trigger_rumble.left_magnitude, 0xffffU);
+ effect->u.trigger_rumble.right_magnitude =
+ min((u32)new->u.trigger_rumble.right_magnitude * gain / 0xffff +
+ effect->u.trigger_rumble.right_magnitude, 0xffffU);
+ break;
+
case FF_PERIODIC:
i = apply_envelope(state, abs(new->u.periodic.magnitude),
&new->u.periodic.envelope);
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 3/4] HID: debug: Add FF_TRIGGER_RUMBLE name
2026-07-31 5:41 ` [PATCH v3 0/4] input: force feedback for trigger rumble motors Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 1/4] input: Add FF_TRIGGER_RUMBLE effect type Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 2/4] input: ff-memless: Handle FF_TRIGGER_RUMBLE Guillaume Casal
@ 2026-07-31 5:41 ` Guillaume Casal
2026-07-31 5:41 ` [PATCH v3 4/4] Documentation: input: Document FF_TRIGGER_RUMBLE Guillaume Casal
3 siblings, 0 replies; 19+ messages in thread
From: Guillaume Casal @ 2026-07-31 5:41 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
Without an entry in the force[] array, hid_resolv_event() prints the raw
hex code instead of the name in debugfs.
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -3583,6 +3583,7 @@
};
static const char *force[FF_CNT] = {
+ [FF_TRIGGER_RUMBLE] = "FF_TRIGGER_RUMBLE",
[FF_RUMBLE] = "FF_RUMBLE",
[FF_PERIODIC] = "FF_PERIODIC",
[FF_CONSTANT] = "FF_CONSTANT",
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v3 4/4] Documentation: input: Document FF_TRIGGER_RUMBLE
2026-07-31 5:41 ` [PATCH v3 0/4] input: force feedback for trigger rumble motors Guillaume Casal
` (2 preceding siblings ...)
2026-07-31 5:41 ` [PATCH v3 3/4] HID: debug: Add FF_TRIGGER_RUMBLE name Guillaume Casal
@ 2026-07-31 5:41 ` Guillaume Casal
3 siblings, 0 replies; 19+ messages in thread
From: Guillaume Casal @ 2026-07-31 5:41 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, dbdaniel42
List the new effect type alongside the others so that userspace
developers can find it when querying device capabilities.
Signed-off-by: Guillaume Casal <guillaume.casal.42@gmail.com>
---
diff --git a/Documentation/input/ff.rst b/Documentation/input/ff.rst
--- a/Documentation/input/ff.rst
+++ b/Documentation/input/ff.rst
@@ -85,6 +85,7 @@
- FF_FRICTION can simulate friction
- FF_DAMPER can simulate damper effects
- FF_RUMBLE rumble effects
+- FF_TRIGGER_RUMBLE rumble effects in the triggers
- FF_INERTIA can simulate inertia
- FF_GAIN gain is adjustable
- FF_AUTOCENTER autocenter is adjustable
^ permalink raw reply [flat|nested] 19+ messages in thread