You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have tried this PR via this NixOS Hardware PR. I had no issue on a Surface Laptop Studio but the touchscreen functionalities ceased to function.
When touching the screen I get this kernel error :
kernel: ipts 0000:00:16.4-3e8d0870-271a-4208-8eb5-9acb9402ae04: Failed to process buffer: -22
All I can get so far is 'EINVAL 22 Invalid argument'
But this leaves the questions: invalid argument for what call? What parameter? It might only be invalid under a certain context for that call, so what was the context?
I don't want to mislead you, all I can so is collaborate to collect more info with you as an interested party. I'm not a developer.
But my take is either we can help, or leave it to someone else. So that said, if you want,
Its not a good idea to dump a whole -b log.
But can you provide the following.
Do a reboot, and then as quickly as possible (so that the log is minimal in terms of both the info to sift and disclosure)
Generate the error, and then as a wheel or admin user (not root) do a journalctl -b -o short-precise | grep -iE 'ipts|0000:00:16\.4' > /tmp/ipts.log (the current boot, clarify event order, filter for ipts and its PCI address, redirect to file)
Have a look at the log first and check there isn't anything you don't want uploading here but I think it should be manageable.
There is a good chance that this won't be the end either, but its just not an option to dump a less filtered log like adding all hid/eds I don't think. So I'd rather suggest as little as possible. It could be if you investigate the log it will identify important other info to minimally grep for immediately.
I will do the log this evening as I don't have the computer with me right now.
and yes the 6.X kernel worked perfectly (and as I use nixos I was hable to rollback to it very easely)
I've included the below for record for reasoning in case @ fault doesn't yield fruit, and for anyone else looking at the issue, but you might want to skip to @ dirty-test-dirty-fix
From the log
Surface-Book-1 kernel: ipts 0000:00:16.4-3e8d0870-271a-4208-8eb5-9acb9402ae04: IPTS EDS Version: 1
So we've got a particular part of the patches to look at, 0005-ipts.patch, and if we look at that drivers/modules created by the patches then within that also we've got a path, EDS 1.
There in we get three hits on EINVAL , but one seems to be ipts_control_hid2me_feedback which only seems to be called when getting and setting eds2 features. So that's EDS 2 not 1, and doesn't seem to be part of a loop or polling like what appears to be trying to perhaps consume the buffer (the stream of errors as you presumably touch the screen Surface-Book-1 kernel: ipts 0000:00:16.4-3e8d0870-271a-4208-8eb5-9acb9402ae04: Failed to process buffer: -22 ) . So I don't think that's it.
We've got one in ipts_eds1_raw_request, so thats promising. Only called in ipts_hid_raw_request (I think) Which as far as I can see is only leveraged by a struct/datastructure ipts_hid_driver? So it could be that but frankly I've no idea how to trace everywhere a data structure gets referenced (see not a developer), to see if it explains the issue. That is also called in ipts_hid_init and being called driver feels like a one off, not something repeating over a buffer.
Then we have a third in 'ipts_receiver_start' but that seems to lead back to another data structure 'ipts_driver' which only seems to come once as part of the setup in main. So again it doesn't feel like the thing erroring over our buffer.
At that point I'm stuck as far as I can without more logging. I'd start with adding 'hid' to your filter log. However, beyond that I can only suggest kernel dynamic debugging, which doesn't seem unreasonable given that it does look like this is something originating both not immediately within the ipts module, and also started with a kernel change.
@ fault
But that leaves us with another option, which is worth it given that its not comfortable throwing huge logs up in public, and that's to ask ai to do a static analysis traversal on the code paths to rule out and find sources for the error, and it has thrown the following up which checks out as very coherent.
NOTE: the following is a dirty test, because it comes in the form of a dirty fix. Its dirty, because I don't have the expertise to know what nuances I'm overlooking when checking the proposal. So this might work for you, or work for all, but... I have no idea what buts I don't know about.
drivers/hid/ipts/receiver.c:171 ipts_receiver_poll_loop >
drivers/hid/ipts/hid.c:171 ipts_hid_input_data [FRAME branch] >
drivers/hid/hid-core.c:2167 hid_input_report >
drivers/hid/hid-core.c:2148 __hid_input_report >
drivers/hid/hid-core.c:2062 hid_report_raw_event if (csize < rsize ) >
drivers/hid/hid-core.c:2065 -EINVAL >
passing back up to be logged at drivers/hid/ipts/receiver.c:172
if (ret)
dev_err(ipts->dev, "Failed to process buffer: %d\n", ret);
So we've got both an EINVAL and the observed string "Failed to process buffer:"
And we've got when csize (current passed data) is less than rsize (the expected defined report size)
Where this code correlates to a change in strictness only introduced in time for 7.0rc torvalds/linux@0a3fe97
"...simply return if the incoming event buffer size is not large enough to fill the associated report"
This is a change from previously just log a debug error, pad the shortfall, and carry on.
The issue is that an HID structure descriptor of the report 65 data that the ipst hid device is initialised with, does not agree with size that hid_input_report is told that data is when its actually passed. The size that hid_input_report is told to expect is taken from the constant IPTS_HID_REPORT_DATA_SIZE. However, that constant failed to include the the report ID byte and the scan time
IPTS_HID_REPORT_DATA_SIZE is referenced in two other locations, but one uses it in the same way (so it still needs the same compliance), and the other uses the same thing in a more primitive form. So as a correction it still holds. Essentially the old kernel was padding something it is no longer prepared to, and was allowing something it shouldn't have been. The padding issue isn't an issue though becuawe of how ipts appears to allocate the memory and then fill it, it will simply now allocate the correct amount.
@ dirty-test-dirty-fix
I call this a dirty test because it's a dirty fix. I call it a dirty fix because while I have thoroughly checked and traced the assertions, I do not have the experience to know what nuances could exist that I could be missing.
Fortunately because you are using NixOS I understand that the patch I attach here is actually far easier for you to leverage than would be the case for just about any other distro? I understand you can configure to build and configure with your own patches? As long as this patch is applied anywhere after the linux 7.0.x patches there should be no conflicts.
I recommend you apply to 7.0.9, that being successful since last time (barring the fault.)
It it works do please let me know. Same for if you have any questions?
Can you do journalctl -b -o short-precise | grep -iE 'ipts|Event data for report|eds' > /tmp/ipts.log , as an admin or wheel user.
Ideally upload the logs, but you should check the logs for anything you don't want uploading first.
Otherwise just check the results for, we are interested in:
... IPTS EDS Version: 1 (or maybe 2?)
Do you see a HID warning Event data for report (probably 65) was too short ... ?
How did did you install/build for 7.0.x for fedora? Are you using your own build of the linux-surface kernel? Or perhaps this is a COPR project? (this linux-surface org doesn't appear to have released 7.0.x yet. cfouche3005 is able to be ahead because their NixOS is using sort of a separately maintained fork at the end of the day.
@orthogonaleety Thank you for your help. I'm quite new to this kind of stuff and i can produce a log-file, but there is no info about your questions.
I downloaded the kernel on here, not build it myself and updated it automatically last week.
Hi @ErnstHarder
In that case it sounds like there is something that is not as it seems RE: linux-surface vs 7.0.x
This org has not released the 7.0.x kernel yet sadly. cfouche has 7.0.x because their distro has done their own work so they weren't fully reliant on upstream here.
If your fedora is showing 7.0.x its likely because it is still downloading the official fedora kernel when they release a new update, and has switched over to that automatically. (It's exactly what happens on my Fedora.)
execute uname -a .
Unless the kerenel 'clearly' shows "linux-surface" in the name, then you have switched back to the non surface kernel. I'd also add it should probably show 6.19.8 as this is the latest linux-surface kernel https://github.com/linux-surface/linux-surface/releases
If it doesn't show linux-surface in the name, then provided you installed the linux-surface package you should have the kernel-watchdog python script available which if you run it will automatically switch you back to that as the default. sudo linux-surface-default-watchdog.py
More info lower down at https://github.com/linux-surface/linux-surface/wiki/Installation-and-Setup#Fedora
If you need more assistance, then as its probably not directly related to cfouche's issue, in which case I recommend you open the matter as a Q&A discussion here https://github.com/linux-surface/linux-surface/discussions/categories/q-a , with your problem and the latest info from my comment above.
If you paste in a 'link' to 'this' issue,https://github.com/linux-surface/linux-surface/issues/2150 , I'll see it pop up in this thread as a tidy mention.
Thanks to nixos, I was able to easily test this kernel patch with the 7.0.9 kernel and I can report that the problem is fix, touchscreen and stylus are working
I am not closing the issue until the fix is merged
Thanks cfouche,
I agree it's not appropriate to 'answer' = close the issue until a solution is accepted into the repo.
I would issue PR if there was a test branch to commend it to, but I don't feel its appropriate for me to commend this directly to master (production) without mandating a certain level of review.
I'll give the PR for the 7.0 patches a nudge since they haven't been merged, and the author is a past contributor.
Thanks for your collaboration cfouche, its been very interesting.
hid_report_raw_event() subtracts one for the report ID, so csize comes out at 7484 against an rsize of 7487. Three bytes short.
The driver's own layout shows 7488 is what was meant. It writes the report ID at temp[0] and the frame at temp[3], which leaves temp[1..2] for the scan time. The +3 just never made it into the size handed to HID core, or into the buffer allocation in resources.c.
Why it only shows up on 7.0
hid_report_raw_event() used to zero pad short reports. v6.19:
if (csize<rsize) {
dbg_hid("report %d is too short, (%d < %d)\n", report->id,
csize, rsize);
memset(cdata+csize, 0, rsize-csize);
}
v7.0 rejects them instead:
if (csize<rsize) {
hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
report->id, rsize, csize);
ret=-EINVAL;
goto out;
}
ipts was relying on that padding. I didn't chase down which commit changed it, it's somewhere in v6.19..v7.0.
Why EDS v1 only
EDS v1 is the path that synthesises a report using ipts_fallback_descriptor. EDS v2 devices send native HID reports and take the header->type == IPTS_DATA_TYPE_HID branch, which passes header->size, so they never hit this. That lines up with the original report here of a working Surface Laptop Studio and a broken Surface Book 1.
Patch
--- a/drivers/hid/ipts/resources.c+++ b/drivers/hid/ipts/resources.c@@ -88,7 +88,13 @@
goto err;
if (!res->report.address) {
- res->report.size = IPTS_HID_REPORT_DATA_SIZE;+ /*+ * Report 65 is declared by ipts_fallback_descriptor as+ * 2 bytes scan time + IPTS_HID_REPORT_DATA_SIZE bytes of data,+ * plus 1 byte report ID = IPTS_HID_REPORT_DATA_SIZE + 3.+ * hid_report_raw_event() rejects anything shorter with -EINVAL.+ */+ res->report.size = IPTS_HID_REPORT_DATA_SIZE + 3;
res->report.address = kzalloc(res->report.size, GFP_KERNEL);
if (!res->report.address) {
--- a/drivers/hid/ipts/hid.c+++ b/drivers/hid/ipts/hid.c@@ -168,7 +168,7 @@
memcpy(frame->data, header->data, header->size);
- return hid_input_report(ipts->hid, HID_INPUT_REPORT, temp, IPTS_HID_REPORT_DATA_SIZE, 1);+ return hid_input_report(ipts->hid, HID_INPUT_REPORT, temp, ipts->resources.report.size, 1);
}
int ipts_hid_init(struct ipts_context *ipts, struct ipts_device_info info)
I left the -ERANGE check in ipts_hid_input_data() alone deliberately. It caps header->size so the last write lands at offset 7484, still inside the bigger buffer. Writes don't change, only the allocation and the length that gets reported.
This should be safe on older kernels too. It just makes the reported length match what the descriptor says, and the old padding path turns into a no-op.
Testing
Built out of tree with DKMS against the stock Ubuntu 7.0.0 kernel. Worth noting the driver needs no other changes to build on 7.0, everything compiles clean and all symbols resolve.
Before the patch: continuous Failed to process buffer: -22, 1412 of them in one test, and nothing at all on the iptsd virtual touchscreen.
After: no errors, and 3059 events off IPTSD Virtual Touchscreen, including ABS_MT_SLOT and ABS_MT_TRACKING_ID, so multi-finger tracking works and not just single touch. Confirmed across several clean reboots with the module loading automatically at boot.
I don't have a pen, so the stylus path is untested. It goes through the same buffer processing.
Environment
Surface Book 2, BIOS 394.779.768
Ubuntu 24.04.4, kernel 7.0.0-28-generic
IPTS device at 00:16.4, 8086:9d3e rev 21
MEI client 3e8d0870-271a-4208-8eb5-9acb9402ae04
EDS version 1
ipts from patches/6.19/0005-ipts.patch at bf1921f (arch-6.19.8-3)
iptsd 3.1.0-1
Two other things worth knowing
If anyone else is testing this out of tree, the IOMMU quirk from 0005-ipts.patch still matters. Without an identity domain SET_MEM_WINDOW times out with -EAGAIN. You can get the same effect at runtime by setting the IPTS device's own iommu group to identity via /sys/kernel/iommu_groups/<n>/type, which means unbinding the drivers in that group, setting the type, then rebinding. iommu.passthrough=1 also works but it applies to everything, and on my machine it broke the NVIDIA dGPU with RmInitAdapter failed! (0x23:0x65:1587).
The other one cost me a fair bit of time. Once SET_MEM_WINDOW fails, the ME firmware stays wedged. Everything after that fails earlier, at GET_DEVICE_INFO with -11, and reloading ipts or even mei_me doesn't clear it. Only a full power cycle does. It looks convincingly like a second unrelated bug while you're iterating.
Activity
orthogonaleety commentedon May 28, 2026
Hi cfouche thanks for this.
All I can get so far is 'EINVAL 22 Invalid argument'
But this leaves the questions: invalid argument for what call? What parameter? It might only be invalid under a certain context for that call, so what was the context?
I don't want to mislead you, all I can so is collaborate to collect more info with you as an interested party. I'm not a developer.
But my take is either we can help, or leave it to someone else. So that said, if you want,
Its not a good idea to dump a whole -b log.
But can you provide the following.
Do a reboot, and then as quickly as possible (so that the log is minimal in terms of both the info to sift and disclosure)
Generate the error, and then as a wheel or admin user (not root) do a
journalctl -b -o short-precise | grep -iE 'ipts|0000:00:16\.4' > /tmp/ipts.log(the current boot, clarify event order, filter for ipts and its PCI address, redirect to file)Have a look at the log first and check there isn't anything you don't want uploading here but I think it should be manageable.
There is a good chance that this won't be the end either, but its just not an option to dump a less filtered log like adding all hid/eds I don't think. So I'd rather suggest as little as possible. It could be if you investigate the log it will identify important other info to minimally grep for immediately.
orthogonaleety commentedon May 28, 2026
(I should also ask, this was definitely working NixOS unstable 6.x surface patched kernel yes?)
cfouche3005 commentedon May 28, 2026
I will do the log this evening as I don't have the computer with me right now.
and yes the 6.X kernel worked perfectly (and as I use nixos I was hable to rollback to it very easely)
cfouche3005 commentedon May 28, 2026
ipts.log
Here are my logs like you wanted
ErnstHarder commentedon Jun 1, 2026
Hi, for me the touchscreen stopped working on a Surface Book 2.
On Fedora.
cfouche3005 commentedon Jun 1, 2026
kernel 7.0.x ?
orthogonaleety commentedon Jun 1, 2026
Hi @cfouche3005 , I think I've found the issue
Hi cfouche
I've included the below for record for reasoning in case @ fault doesn't yield fruit, and for anyone else looking at the issue, but you might want to skip to @ dirty-test-dirty-fix
From the log
Surface-Book-1 kernel: ipts 0000:00:16.4-3e8d0870-271a-4208-8eb5-9acb9402ae04: IPTS EDS Version: 1
So we've got a particular part of the patches to look at, 0005-ipts.patch, and if we look at that drivers/modules created by the patches then within that also we've got a path, EDS 1.
There in we get three hits on EINVAL , but one seems to be ipts_control_hid2me_feedback which only seems to be called when getting and setting eds2 features. So that's EDS 2 not 1, and doesn't seem to be part of a loop or polling like what appears to be trying to perhaps consume the buffer (the stream of errors as you presumably touch the screen
Surface-Book-1 kernel: ipts 0000:00:16.4-3e8d0870-271a-4208-8eb5-9acb9402ae04: Failed to process buffer: -22) . So I don't think that's it.We've got one in ipts_eds1_raw_request, so thats promising. Only called in ipts_hid_raw_request (I think) Which as far as I can see is only leveraged by a struct/datastructure ipts_hid_driver? So it could be that but frankly I've no idea how to trace everywhere a data structure gets referenced (see not a developer), to see if it explains the issue. That is also called in ipts_hid_init and being called driver feels like a one off, not something repeating over a buffer.
Then we have a third in 'ipts_receiver_start' but that seems to lead back to another data structure 'ipts_driver' which only seems to come once as part of the setup in main. So again it doesn't feel like the thing erroring over our buffer.
At that point I'm stuck as far as I can without more logging. I'd start with adding 'hid' to your filter log. However, beyond that I can only suggest kernel dynamic debugging, which doesn't seem unreasonable given that it does look like this is something originating both not immediately within the ipts module, and also started with a kernel change.
@ fault
But that leaves us with another option, which is worth it given that its not comfortable throwing huge logs up in public, and that's to ask ai to do a static analysis traversal on the code paths to rule out and find sources for the error, and it has thrown the following up which checks out as very coherent.
NOTE: the following is a dirty test, because it comes in the form of a dirty fix. Its dirty, because I don't have the expertise to know what nuances I'm overlooking when checking the proposal. So this might work for you, or work for all, but... I have no idea what buts I don't know about.
drivers/hid/ipts/receiver.c:171 ipts_receiver_poll_loop >
drivers/hid/ipts/hid.c:171 ipts_hid_input_data [FRAME branch] >
drivers/hid/hid-core.c:2167 hid_input_report >
drivers/hid/hid-core.c:2148 __hid_input_report >
drivers/hid/hid-core.c:2062 hid_report_raw_event if (csize < rsize ) >
drivers/hid/hid-core.c:2065 -EINVAL >
passing back up to be logged at drivers/hid/ipts/receiver.c:172
if (ret)
dev_err(ipts->dev, "Failed to process buffer: %d\n", ret);
So we've got both an EINVAL and the observed string "Failed to process buffer:"
And we've got when csize (current passed data) is less than rsize (the expected defined report size)
Where this code correlates to a change in strictness only introduced in time for 7.0rc
torvalds/linux@0a3fe97
"...simply return if the incoming event buffer size is not large enough to fill the associated report"
This is a change from previously just log a debug error, pad the shortfall, and carry on.
The issue is that an HID structure descriptor of the report 65 data that the ipst hid device is initialised with, does not agree with size that hid_input_report is told that data is when its actually passed. The size that hid_input_report is told to expect is taken from the constant IPTS_HID_REPORT_DATA_SIZE. However, that constant failed to include the the report ID byte and the scan time
( https://docs.kernel.org/hid/hidintro.html#collections-report-ids-and-evdev-events )
IPTS_HID_REPORT_DATA_SIZE is referenced in two other locations, but one uses it in the same way (so it still needs the same compliance), and the other uses the same thing in a more primitive form. So as a correction it still holds. Essentially the old kernel was padding something it is no longer prepared to, and was allowing something it shouldn't have been. The padding issue isn't an issue though becuawe of how ipts appears to allocate the memory and then fill it, it will simply now allocate the correct amount.
@ dirty-test-dirty-fix
I call this a dirty test because it's a dirty fix. I call it a dirty fix because while I have thoroughly checked and traced the assertions, I do not have the experience to know what nuances could exist that I could be missing.
Fortunately because you are using NixOS I understand that the patch I attach here is actually far easier for you to leverage than would be the case for just about any other distro? I understand you can configure to build and configure with your own patches? As long as this patch is applied anywhere after the linux 7.0.x patches there should be no conflicts.
I recommend you apply to 7.0.9, that being successful since last time (barring the fault.)
It it works do please let me know. Same for if you have any questions?
0017-ipts-fix-hid-report-data-size.patch
orthogonaleety commentedon Jun 1, 2026
orthogonaleety commentedon Jun 1, 2026
@ErnstHarder
Can you do
journalctl -b -o short-precise | grep -iE 'ipts|Event data for report|eds' > /tmp/ipts.log, as an admin or wheel user.Ideally upload the logs, but you should check the logs for anything you don't want uploading first.
Otherwise just check the results for, we are interested in:
... IPTS EDS Version: 1(or maybe 2?)Event data for report(probably 65)was too short... ?How did did you install/build for 7.0.x for fedora? Are you using your own build of the linux-surface kernel? Or perhaps this is a COPR project? (this linux-surface org doesn't appear to have released 7.0.x yet. cfouche3005 is able to be ahead because their NixOS is using sort of a separately maintained fork at the end of the day.
ErnstHarder commentedon Jun 2, 2026
@orthogonaleety Thank you for your help. I'm quite new to this kind of stuff and i can produce a log-file, but there is no info about your questions.
I downloaded the kernel on here, not build it myself and updated it automatically last week.
orthogonaleety commentedon Jun 2, 2026
Hi @ErnstHarder
In that case it sounds like there is something that is not as it seems RE: linux-surface vs 7.0.x
This org has not released the 7.0.x kernel yet sadly. cfouche has 7.0.x because their distro has done their own work so they weren't fully reliant on upstream here.
If your fedora is showing 7.0.x its likely because it is still downloading the official fedora kernel when they release a new update, and has switched over to that automatically. (It's exactly what happens on my Fedora.)
execute
uname -a.Unless the kerenel 'clearly' shows "linux-surface" in the name, then you have switched back to the non surface kernel. I'd also add it should probably show 6.19.8 as this is the latest linux-surface kernel https://github.com/linux-surface/linux-surface/releases
If it doesn't show linux-surface in the name, then provided you installed the linux-surface package you should have the kernel-watchdog python script available which if you run it will automatically switch you back to that as the default.
sudo linux-surface-default-watchdog.pyMore info lower down at https://github.com/linux-surface/linux-surface/wiki/Installation-and-Setup#Fedora
If you need more assistance, then as its probably not directly related to cfouche's issue, in which case I recommend you open the matter as a Q&A discussion here https://github.com/linux-surface/linux-surface/discussions/categories/q-a , with your problem and the latest info from my comment above.
If you paste in a 'link' to 'this' issue,
https://github.com/linux-surface/linux-surface/issues/2150, I'll see it pop up in this thread as a tidy mention.cfouche3005 commentedon Jun 3, 2026
Thanks to nixos, I was able to easily test this kernel patch with the 7.0.9 kernel and I can report that the problem is fix, touchscreen and stylus are working
I am not closing the issue until the fix is merged
orthogonaleety commentedon Jun 3, 2026
Thanks cfouche,
I agree it's not appropriate to 'answer' = close the issue until a solution is accepted into the repo.
I would issue PR if there was a test branch to commend it to, but I don't feel its appropriate for me to commend this directly to master (production) without mandating a certain level of review.
I'll give the PR for the 7.0 patches a nudge since they haven't been merged, and the author is a past contributor.
Thanks for your collaboration cfouche, its been very interesting.
correct IPTS_HID_REPORT_DATA_SIZE out by 3 bytes
Correct IPTS_HID_REPORT_DATA_SIZE out by 3 bytes
Correct IPTS_HID_REPORT_DATA_SIZE out by 3 bytes
rgregg commentedon Jul 24, 2026
I hit this on a Surface Book 2 and think I found the cause. It's an off-by-3 in ipts that was harmless until 7.0.
What happens
The driver loads, gets into poll mode, and then drops every data buffer:
No touch events ever make it to userspace.
The message that actually explains it
The useful one isn't logged under
ipts, it's underhid-generic, so it doesn't show up if you're grepping dmesg for ipts:That's
(rsize vs csize)fromhid_report_raw_event().Cause
ipts_fallback_descriptordeclares report 65 as:That's a 7487 byte payload, or 7488 including the report ID.
hid_compute_report_size()returns 7487.But
ipts_hid_input_data()passesIPTS_HID_REPORT_DATA_SIZE, which is 7485:hid_report_raw_event()subtracts one for the report ID, so csize comes out at 7484 against an rsize of 7487. Three bytes short.The driver's own layout shows 7488 is what was meant. It writes the report ID at
temp[0]and the frame attemp[3], which leavestemp[1..2]for the scan time. The +3 just never made it into the size handed to HID core, or into the buffer allocation inresources.c.Why it only shows up on 7.0
hid_report_raw_event()used to zero pad short reports. v6.19:v7.0 rejects them instead:
ipts was relying on that padding. I didn't chase down which commit changed it, it's somewhere in v6.19..v7.0.
Why EDS v1 only
EDS v1 is the path that synthesises a report using
ipts_fallback_descriptor. EDS v2 devices send native HID reports and take theheader->type == IPTS_DATA_TYPE_HIDbranch, which passesheader->size, so they never hit this. That lines up with the original report here of a working Surface Laptop Studio and a broken Surface Book 1.Patch
I left the
-ERANGEcheck inipts_hid_input_data()alone deliberately. It capsheader->sizeso the last write lands at offset 7484, still inside the bigger buffer. Writes don't change, only the allocation and the length that gets reported.This should be safe on older kernels too. It just makes the reported length match what the descriptor says, and the old padding path turns into a no-op.
Testing
Built out of tree with DKMS against the stock Ubuntu 7.0.0 kernel. Worth noting the driver needs no other changes to build on 7.0, everything compiles clean and all symbols resolve.
Before the patch: continuous
Failed to process buffer: -22, 1412 of them in one test, and nothing at all on the iptsd virtual touchscreen.After: no errors, and 3059 events off
IPTSD Virtual Touchscreen, includingABS_MT_SLOTandABS_MT_TRACKING_ID, so multi-finger tracking works and not just single touch. Confirmed across several clean reboots with the module loading automatically at boot.I don't have a pen, so the stylus path is untested. It goes through the same buffer processing.
Environment
8086:9d3erev 213e8d0870-271a-4208-8eb5-9acb9402ae04patches/6.19/0005-ipts.patchat bf1921f (arch-6.19.8-3)Two other things worth knowing
If anyone else is testing this out of tree, the IOMMU quirk from
0005-ipts.patchstill matters. Without an identity domainSET_MEM_WINDOWtimes out with-EAGAIN. You can get the same effect at runtime by setting the IPTS device's own iommu group to identity via/sys/kernel/iommu_groups/<n>/type, which means unbinding the drivers in that group, setting the type, then rebinding.iommu.passthrough=1also works but it applies to everything, and on my machine it broke the NVIDIA dGPU withRmInitAdapter failed! (0x23:0x65:1587).The other one cost me a fair bit of time. Once
SET_MEM_WINDOWfails, the ME firmware stays wedged. Everything after that fails earlier, atGET_DEVICE_INFOwith-11, and reloading ipts or even mei_me doesn't clear it. Only a full power cycle does. It looks convincingly like a second unrelated bug while you're iterating.Correct IPTS_HID_REPORT_DATA_SIZE out by 3 bytes