Re: [PATCHv7 07/26] driver core: amba: add device binding path 'driver_override'

2014-10-08 Thread Antonios Motakis
On Fri, Sep 26, 2014 at 5:37 PM, Russell King - ARM Linux
 wrote:
>
> On Tue, Sep 23, 2014 at 04:46:06PM +0200, Antonios Motakis wrote:
> > As already demonstrated with PCI [1] and the platform bus [2], a
> > driver_override property in sysfs can be used to bypass the id matching
> > of a device to a AMBA driver. This can be used by VFIO to bind to any AMBA
> > device requested by the user.
> >
> > [1] 
> > http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html
> > [2] https://www.redhat.com/archives/libvir-list/2014-April/msg00382.html
> >
> > Signed-off-by: Antonios Motakis 
>
> I have to ask why this is even needed in the first place.  To take the
> example in [2], what's wrong with:
>
> echo fff51000.ethernet > 
> /sys/bus/platform/devices/fff51000.ethernet/driver/unbind
> echo fff51000.ethernet > /sys/bus/platform/drivers/vfio-platform/bind
>
> and similar for AMBA.
>
> All we would need to do is to introduce a way of having a driver accept
> explicit bind requests.
>
> In any case:
>
> > +static ssize_t driver_override_store(struct device *_dev,
> > +  struct device_attribute *attr,
> > +  const char *buf, size_t count)
> > +{
> > + struct amba_device *dev = to_amba_device(_dev);
> > + char *driver_override, *old = dev->driver_override, *cp;
> > +
> > + if (count > PATH_MAX)
> > + return -EINVAL;
> > +
> > + driver_override = kstrndup(buf, count, GFP_KERNEL);
> > + if (!driver_override)
> > + return -ENOMEM;
> > +
> > + cp = strchr(driver_override, '\n');
> > + if (cp)
> > + *cp = '\0';
>
> I hope that is not replicated everywhere.  This allows up to a page to be
> allocated, even when the first byte may be a newline.  This is wasteful.
>
> How about:
>
> if (count > PATH_MAX)
> return -EINVAL;
>
> cp = strnchr(buf, count, '\n');
> if (cp)
> count = cp - buf - 1;
>
> if (count) {
> driver_override = kstrndup(buf, count, GFP_KERNEL);
> if (!driver_override)
> return -ENOMEM;
> } else {
> driver_override = NULL;
> }
>
> kfree(dev->driver_override);
> dev->driver_override = driver_override;

I implemented something along this lines and tested it a bit. The
kernel already splits the input by newlines, and the function is being
called for each one separately; so this change doesn't save any
memory.

>
> Also:
>
> > +static ssize_t driver_override_show(struct device *_dev,
> > + struct device_attribute *attr, char *buf)
> > +{
> > + struct amba_device *dev = to_amba_device(_dev);
> > +
> > + return sprintf(buf, "%s\n", dev->driver_override);
> > +}
>
> Do we really want to do a NULL pointer dereference here?
>
> --
> FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
> according to speedtest.net.




-- 
Antonios Motakis
Virtual Open Systems
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv7 07/26] driver core: amba: add device binding path 'driver_override'

2014-09-29 Thread Antonios Motakis
On Fri, Sep 26, 2014 at 5:37 PM, Russell King - ARM Linux
 wrote:
> On Tue, Sep 23, 2014 at 04:46:06PM +0200, Antonios Motakis wrote:
>> As already demonstrated with PCI [1] and the platform bus [2], a
>> driver_override property in sysfs can be used to bypass the id matching
>> of a device to a AMBA driver. This can be used by VFIO to bind to any AMBA
>> device requested by the user.
>>
>> [1] 
>> http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html
>> [2] https://www.redhat.com/archives/libvir-list/2014-April/msg00382.html
>>
>> Signed-off-by: Antonios Motakis 
>
> I have to ask why this is even needed in the first place.  To take the
> example in [2], what's wrong with:
>
> echo fff51000.ethernet > 
> /sys/bus/platform/devices/fff51000.ethernet/driver/unbind
> echo fff51000.ethernet > /sys/bus/platform/drivers/vfio-platform/bind
>
> and similar for AMBA.
>
> All we would need to do is to introduce a way of having a driver accept
> explicit bind requests.

I don't have strong feelings on whether it should be done one way or
the other, however the approach proposed here is identical to the one
already accepted in mainline for PCI and platform devices. Should we
do something different for AMBA?

>
> In any case:
>
>> +static ssize_t driver_override_store(struct device *_dev,
>> +  struct device_attribute *attr,
>> +  const char *buf, size_t count)
>> +{
>> + struct amba_device *dev = to_amba_device(_dev);
>> + char *driver_override, *old = dev->driver_override, *cp;
>> +
>> + if (count > PATH_MAX)
>> + return -EINVAL;
>> +
>> + driver_override = kstrndup(buf, count, GFP_KERNEL);
>> + if (!driver_override)
>> + return -ENOMEM;
>> +
>> + cp = strchr(driver_override, '\n');
>> + if (cp)
>> + *cp = '\0';
>
> I hope that is not replicated everywhere.  This allows up to a page to be
> allocated, even when the first byte may be a newline.  This is wasteful.
>
> How about:
>
> if (count > PATH_MAX)
> return -EINVAL;
>
> cp = strnchr(buf, count, '\n');
> if (cp)
> count = cp - buf - 1;
>
> if (count) {
> driver_override = kstrndup(buf, count, GFP_KERNEL);
> if (!driver_override)
> return -ENOMEM;
> } else {
> driver_override = NULL;
> }
>
> kfree(dev->driver_override);
> dev->driver_override = driver_override;

Ack.

>
> Also:
>
>> +static ssize_t driver_override_show(struct device *_dev,
>> + struct device_attribute *attr, char *buf)
>> +{
>> + struct amba_device *dev = to_amba_device(_dev);
>> +
>> + return sprintf(buf, "%s\n", dev->driver_override);
>> +}
>
> Do we really want to do a NULL pointer dereference here?

I'll add a check here.

Thanks

-- 
Antonios Motakis
Virtual Open Systems
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv7 07/26] driver core: amba: add device binding path 'driver_override'

2014-09-26 Thread Russell King - ARM Linux
On Tue, Sep 23, 2014 at 04:46:06PM +0200, Antonios Motakis wrote:
> As already demonstrated with PCI [1] and the platform bus [2], a
> driver_override property in sysfs can be used to bypass the id matching
> of a device to a AMBA driver. This can be used by VFIO to bind to any AMBA
> device requested by the user.
> 
> [1] 
> http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html
> [2] https://www.redhat.com/archives/libvir-list/2014-April/msg00382.html
> 
> Signed-off-by: Antonios Motakis 

I have to ask why this is even needed in the first place.  To take the
example in [2], what's wrong with:

echo fff51000.ethernet > 
/sys/bus/platform/devices/fff51000.ethernet/driver/unbind
echo fff51000.ethernet > /sys/bus/platform/drivers/vfio-platform/bind

and similar for AMBA.

All we would need to do is to introduce a way of having a driver accept
explicit bind requests.

In any case:

> +static ssize_t driver_override_store(struct device *_dev,
> +  struct device_attribute *attr,
> +  const char *buf, size_t count)
> +{
> + struct amba_device *dev = to_amba_device(_dev);
> + char *driver_override, *old = dev->driver_override, *cp;
> +
> + if (count > PATH_MAX)
> + return -EINVAL;
> +
> + driver_override = kstrndup(buf, count, GFP_KERNEL);
> + if (!driver_override)
> + return -ENOMEM;
> +
> + cp = strchr(driver_override, '\n');
> + if (cp)
> + *cp = '\0';

I hope that is not replicated everywhere.  This allows up to a page to be
allocated, even when the first byte may be a newline.  This is wasteful.

How about:

if (count > PATH_MAX)
return -EINVAL;

cp = strnchr(buf, count, '\n');
if (cp)
count = cp - buf - 1;

if (count) {
driver_override = kstrndup(buf, count, GFP_KERNEL);
if (!driver_override)
return -ENOMEM;
} else {
driver_override = NULL;
}

kfree(dev->driver_override);
dev->driver_override = driver_override;

Also:

> +static ssize_t driver_override_show(struct device *_dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct amba_device *dev = to_amba_device(_dev);
> +
> + return sprintf(buf, "%s\n", dev->driver_override);
> +}

Do we really want to do a NULL pointer dereference here?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv7 07/26] driver core: amba: add device binding path 'driver_override'

2014-09-26 Thread Antonios Motakis
Ok, they will be posted separately.

Thanks

On Wed, Sep 24, 2014 at 12:45 AM, Alex Williamson
 wrote:
> On Tue, 2014-09-23 at 16:46 +0200, Antonios Motakis wrote:
>> As already demonstrated with PCI [1] and the platform bus [2], a
>> driver_override property in sysfs can be used to bypass the id matching
>> of a device to a AMBA driver. This can be used by VFIO to bind to any AMBA
>> device requested by the user.
>>
>> [1] 
>> http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html
>> [2] https://www.redhat.com/archives/libvir-list/2014-April/msg00382.html
>>
>> Signed-off-by: Antonios Motakis 
>> ---
>>  drivers/amba/bus.c   | 44 
>>  include/linux/amba/bus.h |  1 +
>>  2 files changed, 45 insertions(+)
>
> Why are 7 & 8 being dragged into this series?  Combine them into a
> single patch and post it separately.
>
>>
>> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
>> index 3cf61a1..473177c 100644
>> --- a/drivers/amba/bus.c
>> +++ b/drivers/amba/bus.c
>> @@ -17,6 +17,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  #include 
>>
>> @@ -42,6 +43,10 @@ static int amba_match(struct device *dev, struct 
>> device_driver *drv)
>>   struct amba_device *pcdev = to_amba_device(dev);
>>   struct amba_driver *pcdrv = to_amba_driver(drv);
>>
>> + /* When driver_override is set, only bind to the matching driver */
>> + if (pcdev->driver_override)
>> + return !strcmp(pcdev->driver_override, drv->name);
>> +
>>   return amba_lookup(pcdrv->id_table, pcdev) != NULL;
>>  }
>>
>> @@ -58,6 +63,44 @@ static int amba_uevent(struct device *dev, struct 
>> kobj_uevent_env *env)
>>   return retval;
>>  }
>>
>> +static ssize_t driver_override_show(struct device *_dev,
>> + struct device_attribute *attr, char *buf)
>> +{
>> + struct amba_device *dev = to_amba_device(_dev);
>> +
>> + return sprintf(buf, "%s\n", dev->driver_override);
>> +}
>> +
>> +static ssize_t driver_override_store(struct device *_dev,
>> +  struct device_attribute *attr,
>> +  const char *buf, size_t count)
>> +{
>> + struct amba_device *dev = to_amba_device(_dev);
>> + char *driver_override, *old = dev->driver_override, *cp;
>> +
>> + if (count > PATH_MAX)
>> + return -EINVAL;
>> +
>> + driver_override = kstrndup(buf, count, GFP_KERNEL);
>> + if (!driver_override)
>> + return -ENOMEM;
>> +
>> + cp = strchr(driver_override, '\n');
>> + if (cp)
>> + *cp = '\0';
>> +
>> + if (strlen(driver_override)) {
>> + dev->driver_override = driver_override;
>> + } else {
>> +kfree(driver_override);
>> +dev->driver_override = NULL;
>> + }
>> +
>> + kfree(old);
>> +
>> + return count;
>> +}
>> +
>>  #define amba_attr_func(name,fmt,arg...) 
>>  \
>>  static ssize_t name##_show(struct device *_dev, 
>>  \
>>  struct device_attribute *attr, char *buf)\
>> @@ -80,6 +123,7 @@ amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
>>  static struct device_attribute amba_dev_attrs[] = {
>>   __ATTR_RO(id),
>>   __ATTR_RO(resource),
>> + __ATTR_RW(driver_override),
>>   __ATTR_NULL,
>>  };
>>
>> diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
>> index fdd7e1b..7c011e7 100644
>> --- a/include/linux/amba/bus.h
>> +++ b/include/linux/amba/bus.h
>> @@ -32,6 +32,7 @@ struct amba_device {
>>   struct clk  *pclk;
>>   unsigned intperiphid;
>>   unsigned intirq[AMBA_NR_IRQS];
>> + char*driver_override;
>>  };
>>
>>  struct amba_driver {
>
>
>



-- 
Antonios Motakis
Virtual Open Systems
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv7 07/26] driver core: amba: add device binding path 'driver_override'

2014-09-23 Thread Alex Williamson
On Tue, 2014-09-23 at 16:46 +0200, Antonios Motakis wrote:
> As already demonstrated with PCI [1] and the platform bus [2], a
> driver_override property in sysfs can be used to bypass the id matching
> of a device to a AMBA driver. This can be used by VFIO to bind to any AMBA
> device requested by the user.
> 
> [1] 
> http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html
> [2] https://www.redhat.com/archives/libvir-list/2014-April/msg00382.html
> 
> Signed-off-by: Antonios Motakis 
> ---
>  drivers/amba/bus.c   | 44 
>  include/linux/amba/bus.h |  1 +
>  2 files changed, 45 insertions(+)

Why are 7 & 8 being dragged into this series?  Combine them into a
single patch and post it separately.

> 
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index 3cf61a1..473177c 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -17,6 +17,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  
> @@ -42,6 +43,10 @@ static int amba_match(struct device *dev, struct 
> device_driver *drv)
>   struct amba_device *pcdev = to_amba_device(dev);
>   struct amba_driver *pcdrv = to_amba_driver(drv);
>  
> + /* When driver_override is set, only bind to the matching driver */
> + if (pcdev->driver_override)
> + return !strcmp(pcdev->driver_override, drv->name);
> +
>   return amba_lookup(pcdrv->id_table, pcdev) != NULL;
>  }
>  
> @@ -58,6 +63,44 @@ static int amba_uevent(struct device *dev, struct 
> kobj_uevent_env *env)
>   return retval;
>  }
>  
> +static ssize_t driver_override_show(struct device *_dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct amba_device *dev = to_amba_device(_dev);
> +
> + return sprintf(buf, "%s\n", dev->driver_override);
> +}
> +
> +static ssize_t driver_override_store(struct device *_dev,
> +  struct device_attribute *attr,
> +  const char *buf, size_t count)
> +{
> + struct amba_device *dev = to_amba_device(_dev);
> + char *driver_override, *old = dev->driver_override, *cp;
> +
> + if (count > PATH_MAX)
> + return -EINVAL;
> +
> + driver_override = kstrndup(buf, count, GFP_KERNEL);
> + if (!driver_override)
> + return -ENOMEM;
> +
> + cp = strchr(driver_override, '\n');
> + if (cp)
> + *cp = '\0';
> +
> + if (strlen(driver_override)) {
> + dev->driver_override = driver_override;
> + } else {
> +kfree(driver_override);
> +dev->driver_override = NULL;
> + }
> +
> + kfree(old);
> +
> + return count;
> +}
> +
>  #define amba_attr_func(name,fmt,arg...)  
> \
>  static ssize_t name##_show(struct device *_dev,  
> \
>  struct device_attribute *attr, char *buf)\
> @@ -80,6 +123,7 @@ amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
>  static struct device_attribute amba_dev_attrs[] = {
>   __ATTR_RO(id),
>   __ATTR_RO(resource),
> + __ATTR_RW(driver_override),
>   __ATTR_NULL,
>  };
>  
> diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
> index fdd7e1b..7c011e7 100644
> --- a/include/linux/amba/bus.h
> +++ b/include/linux/amba/bus.h
> @@ -32,6 +32,7 @@ struct amba_device {
>   struct clk  *pclk;
>   unsigned intperiphid;
>   unsigned intirq[AMBA_NR_IRQS];
> + char*driver_override;
>  };
>  
>  struct amba_driver {



--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv7 07/26] driver core: amba: add device binding path 'driver_override'

2014-09-23 Thread Antonios Motakis
As already demonstrated with PCI [1] and the platform bus [2], a
driver_override property in sysfs can be used to bypass the id matching
of a device to a AMBA driver. This can be used by VFIO to bind to any AMBA
device requested by the user.

[1] 
http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html
[2] https://www.redhat.com/archives/libvir-list/2014-April/msg00382.html

Signed-off-by: Antonios Motakis 
---
 drivers/amba/bus.c   | 44 
 include/linux/amba/bus.h |  1 +
 2 files changed, 45 insertions(+)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 3cf61a1..473177c 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -42,6 +43,10 @@ static int amba_match(struct device *dev, struct 
device_driver *drv)
struct amba_device *pcdev = to_amba_device(dev);
struct amba_driver *pcdrv = to_amba_driver(drv);
 
+   /* When driver_override is set, only bind to the matching driver */
+   if (pcdev->driver_override)
+   return !strcmp(pcdev->driver_override, drv->name);
+
return amba_lookup(pcdrv->id_table, pcdev) != NULL;
 }
 
@@ -58,6 +63,44 @@ static int amba_uevent(struct device *dev, struct 
kobj_uevent_env *env)
return retval;
 }
 
+static ssize_t driver_override_show(struct device *_dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct amba_device *dev = to_amba_device(_dev);
+
+   return sprintf(buf, "%s\n", dev->driver_override);
+}
+
+static ssize_t driver_override_store(struct device *_dev,
+struct device_attribute *attr,
+const char *buf, size_t count)
+{
+   struct amba_device *dev = to_amba_device(_dev);
+   char *driver_override, *old = dev->driver_override, *cp;
+
+   if (count > PATH_MAX)
+   return -EINVAL;
+
+   driver_override = kstrndup(buf, count, GFP_KERNEL);
+   if (!driver_override)
+   return -ENOMEM;
+
+   cp = strchr(driver_override, '\n');
+   if (cp)
+   *cp = '\0';
+
+   if (strlen(driver_override)) {
+   dev->driver_override = driver_override;
+   } else {
+  kfree(driver_override);
+  dev->driver_override = NULL;
+   }
+
+   kfree(old);
+
+   return count;
+}
+
 #define amba_attr_func(name,fmt,arg...)
\
 static ssize_t name##_show(struct device *_dev,
\
   struct device_attribute *attr, char *buf)\
@@ -80,6 +123,7 @@ amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
 static struct device_attribute amba_dev_attrs[] = {
__ATTR_RO(id),
__ATTR_RO(resource),
+   __ATTR_RW(driver_override),
__ATTR_NULL,
 };
 
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index fdd7e1b..7c011e7 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -32,6 +32,7 @@ struct amba_device {
struct clk  *pclk;
unsigned intperiphid;
unsigned intirq[AMBA_NR_IRQS];
+   char*driver_override;
 };
 
 struct amba_driver {
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html