On Wednesday, 24 January 2024 13:52:52 CST Arnd Bergmann wrote:
> On Wed, Jan 24, 2024, at 19:02, Elizabeth Figura wrote:
> > On Wednesday, 24 January 2024 01:56:52 CST Arnd Bergmann wrote:
> >> On Wed, Jan 24, 2024, at 01:40, Elizabeth Figura wrote:
> >>
> >> > + if (args->timeout) {
> >> > + struct timespec64 to;
> >> > +
> >> > + if (get_timespec64(&to, u64_to_user_ptr(args->timeout)))
> >> > + return -EFAULT;
> >> > + if (!timespec64_valid(&to))
> >> > + return -EINVAL;
> >> > +
> >> > + timeout = timespec64_to_ns(&to);
> >> > + }
> >>
> >> Have you considered just passing the nanosecond value here?
> >> Since you do not appear to write it back, that would avoid
> >> the complexities of dealing with timespec layout differences
> >> and indirection.
> >
> > That'd be nicer in general. I think there was some documentation that advised
> > using timespec64 for new ioctl interfaces but it may have been outdated or
> > misread.
>
> It's probably something I wrote. It depends a bit on
> whether you have an absolute or relative timeout. If
> the timeout is relative to the current time as I understand
> it is here, a 64-bit number seems more logical to me.
>
> For absolute times, I would usually use a __kernel_timespec,
> especially if it's CLOCK_REALTIME. In this case you would
> also need to specify the time domain.
Currently the interface does pass it as an absolute time, with the
domain implicitly being MONOTONIC. This particular choice comes from
process/botching-up-ioctls.rst, which is admittedly focused around GPU
ioctls, but the rationale of having easily restartable ioctls applies
here too.
(E.g. Wine does play games with signals, so we do want to be able to
interrupt arbitrary waits with EINTR. The "usual" fast path for ntsync
waits won't hit that, but we want to have it work.)
On the other hand, if we can pass the timeout as relative, and write it
back on exit like ppoll() does [assuming that's not proscribed], that
would presumably be slightly better for performance.
When writing the patch I just picked the recommended option, and didn't
bother doing any micro-optimizations afterward.
What's the rationale for using timespec for absolute or written-back
timeouts, instead of dealing in ns directly? I'm afraid it's not
obvious to me.
--Zeb
On Wednesday, 24 January 2024 01:42:19 CST Arnd Bergmann wrote:
> On Wed, Jan 24, 2024, at 01:40, Elizabeth Figura wrote:
> > @@ -738,6 +803,8 @@ static long ntsync_char_ioctl(struct file *file,
> > diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
> > index 26d1b3d4847f..2e44e7e77776 100644
> > --- a/include/uapi/linux/ntsync.h
> > +++ b/include/uapi/linux/ntsync.h
> > @@ -46,5 +46,7 @@ struct ntsync_wait_args {
> > struct ntsync_wait_args)
> > #define NTSYNC_IOC_CREATE_MUTEX _IOWR(NTSYNC_IOC_BASE, 5, \
> > struct ntsync_mutex_args)
> > +#define NTSYNC_IOC_PUT_MUTEX _IOWR(NTSYNC_IOC_BASE, 6, \
> > + struct ntsync_mutex_args)
> >
>
> In your implementation, this argument is not written back to
> user space, so I think this should be _IOW rather than than _IORW.
>
> Again, no practical difference here.
Hm, but there is a put_user() at the end of the function, or am I missing something?
On Wednesday, 24 January 2024 01:56:52 CST Arnd Bergmann wrote:
> On Wed, Jan 24, 2024, at 01:40, Elizabeth Figura wrote:
>
> > + if (args->timeout) {
> > + struct timespec64 to;
> > +
> > + if (get_timespec64(&to, u64_to_user_ptr(args->timeout)))
> > + return -EFAULT;
> > + if (!timespec64_valid(&to))
> > + return -EINVAL;
> > +
> > + timeout = timespec64_to_ns(&to);
> > + }
>
> Have you considered just passing the nanosecond value here?
> Since you do not appear to write it back, that would avoid
> the complexities of dealing with timespec layout differences
> and indirection.
That'd be nicer in general. I think there was some documentation that advised
using timespec64 for new ioctl interfaces but it may have been outdated or
misread.
>
> > + ids = kmalloc_array(count, sizeof(*ids), GFP_KERNEL);
> > + if (!ids)
> > + return -ENOMEM;
> > + if (copy_from_user(ids, u64_to_user_ptr(args->objs),
> > + array_size(count, sizeof(*ids)))) {
> > + kfree(ids);
> > + return -EFAULT;
> > + }
>
> This looks like memdup_user() would be slightly simpler.
That's useful, thanks.
On Wednesday, 24 January 2024 06:32:13 CST Greg Kroah-Hartman wrote:
> On Tue, Jan 23, 2024 at 09:43:09PM -0600, Elizabeth Figura wrote:
> > > Why do you need a fixed minor number? Can't your userspace handle
> > > dynamic numbers? What systems require a static value?
> >
> > I believe I added this because it's necessary for MODULE_ALIAS (and, more
> > broadly, because I was following the example of vaguely comparable devices
> > like /dev/loop-control). I suppose I could instead just remove MODULE_ALIAS
> > (or even remove the ability to compile ntsync as a module entirely).
>
> Do you really need MODULE_ALIAS()? Having it for char devices to be
> auto-loaded is not generally considered a good idea anymore as systems
> should have the module loaded before userspace goes and asks for it.
>
> It also reduces suprises when any random userspace program can cause
> kernel modules to be loaded for no real reason.
I think there's no reason we can't make loading the system's problem. I'll remove it in v2.
On Wednesday, 24 January 2024 01:38:52 CST Arnd Bergmann wrote:
> On Wed, Jan 24, 2024, at 01:40, Elizabeth Figura wrote:
> > ntsync uses a misc device as the simplest and least intrusive uAPI interface.
> >
> > Each file description on the device represents an isolated NT instance, intended
> > to correspond to a single NT virtual machine.
> >
> > Signed-off-by: Elizabeth Figura <zfigura(a)codeweavers.com>
>
> I'm looking at the ioctl interface to ensure it's well-formed.
>
> Your patches look ok from that perspective, but there are a
> few minor things I would check for consistency here:
>
> > +
> > +static const struct file_operations ntsync_fops = {
> > + .owner = THIS_MODULE,
> > + .open = ntsync_char_open,
> > + .release = ntsync_char_release,
> > + .unlocked_ioctl = ntsync_char_ioctl,
> > + .compat_ioctl = ntsync_char_ioctl,
> > + .llseek = no_llseek,
> > +};
>
> The .compat_ioctl pointer should point to compat_ptr_ioctl()
> since the actual ioctl commands all take pointers instead
> of interpreting the argument as a number.
>
> On x86 and arm64 this won't make a difference as compat_ptr()
> is a nop.
Thanks; will fix.
On Tuesday, 23 January 2024 18:54:02 CST Greg Kroah-Hartman wrote:
> On Tue, Jan 23, 2024 at 06:40:21PM -0600, Elizabeth Figura wrote:
> > Signed-off-by: Elizabeth Figura <zfigura(a)codeweavers.com>
> > ---
>
> Note, we can't take patches without any changelog text, and you don't
> want us to :)
>
> > Documentation/admin-guide/devices.txt | 3 ++-
> > Documentation/userspace-api/ioctl/ioctl-number.rst | 2 ++
> > drivers/misc/ntsync.c | 3 ++-
> > include/linux/miscdevice.h | 1 +
> > 4 files changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/admin-guide/devices.txt
> > b/Documentation/admin-guide/devices.txt index 94c98be1329a..041404397ee5
> > 100644
> > --- a/Documentation/admin-guide/devices.txt
> > +++ b/Documentation/admin-guide/devices.txt
> > @@ -376,8 +376,9 @@
> >
> > 240 = /dev/userio Serio driver testing device
> > 241 = /dev/vhost-vsock Host kernel driver for virtio
vsock
> > 242 = /dev/rfkill Turning off radio transmissions
(rfkill)
> >
> > + 243 = /dev/ntsync NT synchronization primitive
device
> >
> > - 243-254 Reserved for local use
> > + 244-254 Reserved for local use
>
> Why do you need a fixed minor number? Can't your userspace handle
> dynamic numbers? What systems require a static value?
I believe I added this because it's necessary for MODULE_ALIAS (and, more
broadly, because I was following the example of vaguely comparable devices
like /dev/loop-control). I suppose I could instead just remove MODULE_ALIAS
(or even remove the ability to compile ntsync as a module entirely).
It's a bit difficult to figure out what's the preferred way to organize things
like this (there not being a lot of precedent for this kind of driver) so I'd
appreciate any direction.
--Zeb
On Tuesday, 23 January 2024 19:14:17 CST Greg Kroah-Hartman wrote:
> On Tue, Jan 23, 2024 at 06:40:22PM -0600, Elizabeth Figura wrote:
> > +static int ntsync_create_sem(struct ntsync_device *dev, void __user
> > *argp)
> > +{
> > + struct ntsync_sem_args __user *user_args = argp;
> > + struct ntsync_sem_args args;
> > + struct ntsync_obj *sem;
> > + __u32 id;
> > + int ret;
> > +
> > + if (copy_from_user(&args, argp, sizeof(args)))
> > + return -EFAULT;
> > +
> > + if (args.count > args.max)
> > + return -EINVAL;
>
> No bounds checking on count or max?
>
> What's the relationship between count and max?
Indeed, no bounds checking. The counter is just the semaphore's internal value
and has no meaning other than that.
It's basically like an EFD_SEMAPHORE, except that the maximum is configurable
rather than always being 2**64-2.
> Some sort of real
> documentation is needed here, the changelog needs to explain this. Or
> somewhere, but as-is, this patch series is pretty unreviewable as I
> can't figure out how to review it because I don't know what it wants to
> do.
There is some comprehensive documentation in the series, but for ease of
review I will try to write a basic description of the API in each relevant
patch in v2.
On Tuesday, 23 January 2024 18:59:35 CST Greg Kroah-Hartman wrote:
> On Tue, Jan 23, 2024 at 06:40:19PM -0600, Elizabeth Figura wrote:
> > == Patches ==
> >
> > This is the first part of a 32-patch series. The series comprises 17 patches
> > which contain the actual implementation, 13 which provide self-tests, 1 to
> > update the MAINTAINERS file, and 1 to add API documentation.
>
> 32 patches? I only see 9 here, why not submit them all?
Because Documentation/process/submitting-patches.rst makes a point of asking people not to submit large patch series (and it matches the expectation of other projects I've worked with—that patches would be submitted and reviewed a few at a time). I suppose I've misunderstood that advice, though.
I'll resend with the entire series. Sorry for the noise.
Folks,
We've once again made very good progress on the regressions during this
code freeze period, thanks to everybody for your help!
It's now time for the final release. I've attached the tentative release
notes, written with help from Jacek, Rémi and Zeb, and for the first
time in Markdown format <g>. Please review these and let me know if
anything is wrong, missing, or unclear.
--
Alexandre Julliard
julliard(a)winehq.org
Would like to get disabling force feedback auto-centering working so
that trimming will work properly with force feedback devices in flight
simulators.
Currently the call to disable it is a stub
static HRESULT dinput_device_set_property( IDirectInputDevice8W
*iface, const GUID *guid,
const DIPROPHEADER *header )
{
...
case (DWORD_PTR)DIPROP_AUTOCENTER:
{
const DIPROPDWORD *value = (const DIPROPDWORD *)header;
if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return
DIERR_UNSUPPORTED;
if ( header->dwHow != DIPH_DEVICE) return DIERR_INVALIDPARAM;
impl->vtbl->set_property( iface,
FIXME( "DIPROP_AUTOCENTER stub!\n" );
impl->autocenter = value->dwData;
return DI_OK;
}
...
}
After having looked through the wine, SDL, and kernel code and read up
on the force feedback HID physical interface device (PID) usage table
reports, I am guessing this was left as a stub because it doesn't fit
in with the current design of dipnut communicating with the backend
via HID reports. The issue being that auto centering, unlike
everything else, isn't part of the PID specification, so there isn't a
predefined report that can be used for this (see table 0x0f)
https://www.usb.org/document-library/hid-usage-tables-14
Although I am no wine or Windows code expert, I am guess this leaves
the following options
- leave it disabled in the backend and emulate it via a frontend spring effect
- abuse an existing HID report to communicate it
- add a WINE specific HID report to communicate it
- add a WINE specific IOCTL to communicate it
For the first option, I mean have the winebus backends disable it via
the kernel or an SDL call and then have the dinput layer enable
simulate it by adding a default spring effect. This then lets the
dinput frontend disable it again by removing or disabling its spring
effect. For the second one I mean something like reserve an effect ID
for specifying auto centering.
Both of these are inspired by the fact that from the kernel code, it
seems auto centering for HID devices is an undocumented use of the
first effect ID for a spring effect
https://github.com/torvalds/linux/blob/610a9b8f/drivers/hid/usbhid/hid-pidf…https://github.com/torvalds/linux/blob/610a9b8f/drivers/hid/usbhid/hid-pidf…
Would be interesting in knowing what sort of implementation people
think would be best and acceptable for inclusion into wine?
Thanks! Tyson