Re: [PATCH v9 17/17] tools/wmi: add a sample for dell smbios communication over WMI

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Just my 2c, I like this simplification Mario.
Reviewed-by: Edward O'Callaghan <quasisec@xxxxxxxxxx>

On Thu, Oct 19, 2017 at 9:27 AM,  <Mario.Limonciello@xxxxxxxx> wrote:
>> -----Original Message-----
>> From: Limonciello, Mario
>> Sent: Wednesday, October 18, 2017 8:56 AM
>> To: 'Pali Rohár' <pali.rohar@xxxxxxxxx>; Greg KH <greg@xxxxxxxxx>; Alan Cox
>> <gnomes@xxxxxxxxxxxxxxxxxxx>
>> Cc: dvhart@xxxxxxxxxxxxx; Andy Shevchenko <andy.shevchenko@xxxxxxxxx>;
>> LKML <linux-kernel@xxxxxxxxxxxxxxx>; platform-driver-x86@xxxxxxxxxxxxxxx; Andy
>> Lutomirski <luto@xxxxxxxxxx>; quasisec@xxxxxxxxxx; rjw@xxxxxxxxxxxxx;
>> mjg59@xxxxxxxxxx; hch@xxxxxx
>> Subject: RE: [PATCH v9 17/17] tools/wmi: add a sample for dell smbios
>> communication over WMI
>>
>> > -----Original Message-----
>> > From: Pali Rohár [mailto:pali.rohar@xxxxxxxxx]
>> > Sent: Wednesday, October 18, 2017 2:29 AM
>> > To: Greg KH <greg@xxxxxxxxx>; Alan Cox <gnomes@xxxxxxxxxxxxxxxxxxx>
>> > Cc: dvhart@xxxxxxxxxxxxx; Andy Shevchenko <andy.shevchenko@xxxxxxxxx>;
>> > LKML <linux-kernel@xxxxxxxxxxxxxxx>; platform-driver-x86@xxxxxxxxxxxxxxx;
>> Andy
>> > Lutomirski <luto@xxxxxxxxxx>; quasisec@xxxxxxxxxx; rjw@xxxxxxxxxxxxx;
>> > mjg59@xxxxxxxxxx; hch@xxxxxx; Limonciello, Mario
>> > <Mario_Limonciello@xxxxxxxx>
>> > Subject: Re: [PATCH v9 17/17] tools/wmi: add a sample for dell smbios
>> > communication over WMI
>> >
>> > On Tuesday 17 October 2017 13:22:01 Mario Limonciello wrote:
>> > > diff --git a/tools/wmi/dell-smbios-example.c b/tools/wmi/dell-smbios-
>> example.c
>> > > new file mode 100644
>> > > index 000000000000..69c4dd9c6056
>> > > --- /dev/null
>> > > +++ b/tools/wmi/dell-smbios-example.c
>> > > @@ -0,0 +1,214 @@
>> > > +/*
>> > > + *  Sample application for SMBIOS communication over WMI interface
>> > > + *  Performs the following:
>> > > + *  - Simple class/select lookup for TPM information
>> > > + *  - Simple query of known tokens and their values
>> > > + *  - Simple activation of a token
>> > > + *
>> > > + *  Copyright (C) 2017 Dell, Inc.
>> > > + *
>> > > + *  This program is free software; you can redistribute it and/or modify
>> > > + *  it under the terms of the GNU General Public License version 2 as
>> > > + *  published by the Free Software Foundation.
>> > > + */
>> > > +
>> > > +#include <errno.h>
>> > > +#include <fcntl.h>
>> > > +#include <stdio.h>
>> > > +#include <stdlib.h>
>> > > +#include <sys/ioctl.h>
>> > > +#include <unistd.h>
>> > > +
>> > > +/* if uapi header isn't installed, this might not yet exist */
>> > > +#ifndef __packed
>> > > +#define __packed __attribute__((packed))
>> > > +#endif
>> > > +#include <linux/wmi.h>
>> > > +
>> > > +/* It would be better to discover these using udev, but for a simple
>> > > + * application they're hardcoded
>> > > + */
>> > > +static const char *ioctl_devfs = "/dev/wmi/dell-smbios";
>> > > +static const char *token_sysfs =
>> > > +                 "/sys/bus/platform/devices/dell-smbios.0/tokens";
>> > > +static const char *buffer_sysfs =
>> > > +                 "/sys/bus/wmi/devices/A80593CE-A997-11DA-B012-
>> > B622A1EF5492/required_buffer_size";
>> >
>> > Greg, Alan, could userspace expects those paths to be part of kernel
>> > <--> userspace ABI? Looking e.g. at "dell-smbios.0" name and I'm not
>> > sure if this is something which is going to be stable between kernel
>> > versions and forever as part of ABI.
>>
>> In my sample application to be distributed with the kernel these are
>> hardcoded paths, but if more dependencies were used, I would
>> expect all 3 of these paths to be discovered using udev.
>> I do include a comment for that point specifically.
>>
>> >
>> > Also if everything is part of smbios API, would not it better to provide
>> > everything via IOCTL over /dev/wmi/dell-smbios? I think this code is too
>> > complicated, just because for correct IOCTL buffer size it needs to read
>> > other properties via sysfs, etc... For me it looks like that it is not a
>> > good API for userspace developers.
>> >
>> > --
>>
>> This does give me an idea, how about a read on the character device
>> will return required buffer size instead of needing to find a sysfs
>> attribute?  This seems more intuitive to me.
>
> So as to not send the whole series again only to get this idea shot down,
> this is what it looks like (minus documentation updates).
> Thoughts?
>
> diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
> index c7de80f96183..922a87d7cf34 100644
> --- a/drivers/platform/x86/wmi.c
> +++ b/drivers/platform/x86/wmi.c
> @@ -799,23 +799,12 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
>
>         return 0;
>  }
> -
> -static long match_ioctl(struct file *filp, unsigned int cmd, unsigned long arg,
> -                       int compat)
> +static int wmi_char_open(struct inode *inode, struct file *filp)
>  {
> -       struct wmi_ioctl_buffer __user *input =
> -               (struct wmi_ioctl_buffer __user *) arg;
> +       const char *driver_name = filp->f_path.dentry->d_iname;
>         struct wmi_driver *wdriver = NULL;
>         struct wmi_block *wblock = NULL;
>         struct wmi_block *next = NULL;
> -       const char *driver_name;
> -       u64 size;
> -       int ret;
> -
> -       if (_IOC_TYPE(cmd) != WMI_IOC)
> -               return -ENOTTY;
> -
> -       driver_name = filp->f_path.dentry->d_iname;
>
>         list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
>                 wdriver = container_of(wblock->dev.dev.driver,
> @@ -826,6 +815,52 @@ static long match_ioctl(struct file *filp, unsigned int cmd, unsigned long arg,
>                         break;
>         }
>
> +       if (!wdriver)
> +               return -ENODEV;
> +
> +       filp->private_data = wblock;
> +       nonseekable_open(inode, filp);
> +       return 0;
> +}
> +
> +static int wmi_char_release(struct inode *inode, struct file *filp)
> +{
> +       return 0;
> +}
> +
> +static ssize_t wmi_char_read(struct file *filp, char __user *buffer,
> +       size_t length, loff_t *offset)
> +{
> +       struct wmi_block *wblock = filp->private_data;
> +       size_t count;
> +
> +       if (*offset != 0)
> +               return 0;
> +
> +       count = sizeof(wblock->req_buf_size);
> +       if (copy_to_user(buffer, &wblock->req_buf_size, count))
> +               return -EFAULT;
> +
> +       *offset = count;
> +       return count;
> +}
> +
> +static long match_ioctl(struct file *filp, unsigned int cmd, unsigned long arg,
> +                       int compat)
> +{
> +       struct wmi_ioctl_buffer __user *input =
> +               (struct wmi_ioctl_buffer __user *) arg;
> +       struct wmi_block *wblock = filp->private_data;
> +       struct wmi_driver *wdriver = NULL;
> +       u64 size;
> +       int ret;
> +
> +       if (_IOC_TYPE(cmd) != WMI_IOC)
> +               return -ENOTTY;
> +
> +       wdriver = container_of(wblock->dev.dev.driver,
> +               struct wmi_driver, driver);
> +
>         if (!wdriver)
>                 return -ENODEV;
>
> @@ -886,6 +921,9 @@ static long wmi_compat_ioctl(struct file *filp, unsigned int cmd,
>
>  static const struct file_operations wmi_fops = {
>         .owner          = THIS_MODULE,
> +       .read           = wmi_char_read,
> +       .open           = wmi_char_open,
> +       .release        = wmi_char_release,
>         .unlocked_ioctl = wmi_unlocked_ioctl,
>  #ifdef CONFIG_COMPAT
>         .compat_ioctl = wmi_compat_ioctl,
> diff --git a/tools/wmi/dell-smbios-example.c b/tools/wmi/dell-smbios-example.c
> index 69c4dd9c6056..a5f97647c9c5 100644
> --- a/tools/wmi/dell-smbios-example.c
> +++ b/tools/wmi/dell-smbios-example.c
> @@ -31,8 +31,6 @@
>  static const char *ioctl_devfs = "/dev/wmi/dell-smbios";
>  static const char *token_sysfs =
>                         "/sys/bus/platform/devices/dell-smbios.0/tokens";
> -static const char *buffer_sysfs =
> -                       "/sys/bus/wmi/devices/A80593CE-A997-11DA-B012-B622A1EF5492/required_buffer_size";
>
>  static void show_buffer(struct dell_wmi_smbios_buffer *buffer)
>  {
> @@ -147,15 +145,13 @@ static int activate_token(struct dell_wmi_smbios_buffer *buffer,
>
>  static int query_buffer_size(__u64 *buffer_size)
>  {
> -       char buf[4096];
>         FILE *f;
>
> -       f = fopen(buffer_sysfs, "rb");
> +       f = fopen(ioctl_devfs, "rb");
>         if (!f)
>                 return -EINVAL;
> -       fread(buf, 1, 4096, f);
> +       fread(buffer_size, sizeof(__u64), 1, f);
>         fclose(f);
> -       *buffer_size = strtol(buf, NULL, 10);
>         return EXIT_SUCCESS;
>  }
>
>
>>
>> Token information is provided over sysfs for multiple reasons.
>> 1) It's applicable to all dispatchers.  Even if the WMI dispatcher wasn't
>> used it's useful for userspace to query through.  For example the SMI call
>> to get tokens in libsmbios can be simplified to just read sysfs files.
>>
>> 2) it's information not coming from ACPI-WMI.  This series is setting
>> precedent for how to interact with ACPI-WMI methods in userspace.
>> putting in random data on the IOCTL that is not used in the ACPI-WMI
>> method or provided by the WMI bus doesn't fit.
>>
>> 3) It is static information that won't change until you reboot.




[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux