pon., 8 lip 2019 o 12:24 Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> napisał(a): > > Hi Bartosz, > > On Mon, Jul 8, 2019 at 11:45 AM Bartosz Golaszewski > <bgolaszewski@xxxxxxxxxxxx> wrote: > > pt., 5 lip 2019 o 18:05 Geert Uytterhoeven <geert+renesas@xxxxxxxxx> napisał(a): > > > GPIO controllers are exported to userspace using /dev/gpiochip* > > > character devices. Access control to these devices is provided by > > > standard UNIX file system permissions, on an all-or-nothing basis: > > > either a GPIO controller is accessible for a user, or it is not. > > > Currently no mechanism exists to control access to individual GPIOs. > > > > > > Hence add a virtual GPIO driver to aggregate existing GPIOs (up to 32), > > > and expose them as a new gpiochip. This is useful for implementing > > > access control, and assigning a set of GPIOs to a specific user. > > > Furthermore, it would simplify and harden exporting GPIOs to a virtual > > > machine, as the VM can just grab the full virtual GPIO controller, and > > > no longer needs to care about which GPIOs to grab and which not, > > > reducing the attack surface. > > > > > > Virtual GPIO controllers are instantiated by writing to the "new_device" > > > attribute file in sysfs: > > > > > > $ echo "<gpiochipA> <gpioA1> [<gpioA2> ...]" > > > "[, <gpiochipB> <gpioB1> [<gpioB2> ...]] ...]" > > > > /sys/bus/platform/drivers/gpio-virt-agg/new_device > > > > > > Likewise, virtual GPIO controllers can be destroyed after use: > > > > > > $ echo gpio-virt-agg.<N> \ > > > > /sys/bus/platform/drivers/gpio-virt-agg/delete_device > > > > > > Signed-off-by: Geert Uytterhoeven <geert+renesas@xxxxxxxxx> > > > I like the general idea and the interface looks mostly fine. Since > > this is new ABI I think it needs to be documented as well. > > Sure. > > > I'm having trouble building this module: > > > > CALL scripts/atomic/check-atomics.sh > > CALL scripts/checksyscalls.sh > > CHK include/generated/compile.h > > Kernel: arch/arm/boot/Image is ready > > Building modules, stage 2. > > MODPOST 235 modules > > ERROR: "gpiod_request" [drivers/gpio/gpio-virt-agg.ko] undefined! > > ERROR: "gpiochip_get_desc" [drivers/gpio/gpio-virt-agg.ko] undefined! > > ERROR: "gpiod_free" [drivers/gpio/gpio-virt-agg.ko] undefined! > > scripts/Makefile.modpost:91: recipe for target '__modpost' failed > > make[1]: *** [__modpost] Error 1 > > Makefile:1287: recipe for target 'modules' failed > > make: *** [modules] Error 2 > > make: *** Waiting for unfinished jobs.... > > > > I'm not sure what the problem is. > > Oops. As this is an RFC, I didn't bother trying to build this driver as > a module, only builtin. Apparently the 3 symbols above are not yet > exported using EXPORT_SYMBOL_GPL(). > Am I doing it right? I'm trying to create a device and am only getting this: # echo gpiochip2 23 > new_device [ 707.507039] gpio-virt-agg gpio-virt-agg.0: Cannot find gpiochip gpiochip2 gpiochip2 *does* exist in the system. > > > --- /dev/null > > > +++ b/drivers/gpio/gpio-virt-agg.c > > > @@ -0,0 +1,390 @@ > > > +// SPDX-License-Identifier: GPL-2.0-only > > > +// > > > +// GPIO Virtual Aggregator > > > +// > > > +// Copyright (C) 2019 Glider bvba > > > + > > > +#include <linux/gpio/driver.h> > > > +#include <linux/idr.h> > > > +#include <linux/kernel.h> > > > +#include <linux/module.h> > > > +#include <linux/mutex.h> > > > +#include <linux/platform_device.h> > > > + > > > +#include "gpiolib.h" > > > + > > > +#define DRV_NAME "gpio-virt-agg" > > > +#define MAX_GPIOS 32 > > > > Do we really need this limit? I see it simplifies the code, but maybe > > we can allocate the relevant arrays dynamically and not limit users? > > Sure. That limit can be lifted. > > > > +static int gpio_virt_agg_set_config(struct gpio_chip *chip, > > > + unsigned int offset, unsigned long config) > > > +{ > > > + struct gpio_virt_agg_priv *priv = gpiochip_get_data(chip); > > > + > > > + chip = priv->desc[offset]->gdev->chip; > > > + if (chip->set_config) > > > + return chip->set_config(chip, offset, config); > > > + > > > + // FIXME gpiod_set_transitory() expects success if not implemented > > BTW, do you have a comment about this FIXME? > Ha! Interesting. I'll give it a thought and respond elsewhere as it's a different subject. > > > + return -ENOTSUPP; > > > +} > > > > +static int gpio_virt_agg_probe(struct platform_device *pdev) > > > +{ > > > + struct device *dev = &pdev->dev; > > > + const char *param = dev_get_platdata(dev); > > > + struct gpio_virt_agg_priv *priv; > > > + const char *label = NULL; > > > + struct gpio_chip *chip; > > > + struct gpio_desc *desc; > > > + unsigned int offset; > > > + int error, i; > > > > This 'i' here is reported as possibly not initialized: > > > > drivers/gpio/gpio-virt-agg.c: In function ‘gpio_virt_agg_probe’: > > drivers/gpio/gpio-virt-agg.c:230:13: warning: ‘i’ may be used > > uninitialized in this function [-Wmaybe-uninitialized] > > int error, i; > > ^ > > Oops, should be preinitialized to zero. WIll fix. > > > > +static int gpio_virt_agg_remove(struct platform_device *pdev) > > > +{ > > > + struct gpio_virt_agg_priv *priv = platform_get_drvdata(pdev); > > > + unsigned int i; > > > + > > > + gpiochip_remove(&priv->chip); > > > + > > > + for (i = 0; i < priv->chip.ngpio; i++) > > > + gpiod_free(priv->desc[i]); > > Perhaps I should use gpiod_put() instead, which is exported to modules? > > > > + > > > + return 0; > > > +} > > > > You shouldn't need this function at all. It's up to users to free descriptors. > > This frees the upstream descriptors, not the descriptors used by users > of the virtual gpiochip. Shouldn't they be freed, as they are no longer > in use? > > Note that .probe() doesn't use devm_gpiochip_add_data(), as the upstream > descriptors need to be freed after the call to gpiochip_remove(). > > Thanks! I see. I'll try to review it more thoroughly once I get to play with it. So far I'm stuck on creating the virtual chip. Bart > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like that. > -- Linus Torvalds