[PATCH v2 2/3] staging: vchiq: Fix bulk transfers on 64-bit builds

2021-01-05 Thread Phil Elwell
The recent change to the bulk transfer compat function missed the fact
the relevant ioctl command is VCHIQ_IOC_QUEUE_BULK_TRANSMIT32, not
VCHIQ_IOC_QUEUE_BULK_TRANSMIT, as any attempt to send a bulk block
to the VPU would have shown.

Fixes: a4367cd2b231 ("staging: vchiq: convert compat bulk transfer")

Signed-off-by: Phil Elwell 
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 2a8883673ba1..2ca5805b2fce 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -1717,7 +1717,7 @@ vchiq_compat_ioctl_queue_bulk(struct file *file,
 {
struct vchiq_queue_bulk_transfer32 args32;
struct vchiq_queue_bulk_transfer args;
-   enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
+   enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32) ?
  VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
 
if (copy_from_user(, argp, sizeof(args32)))
-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 3/3] staging: vc04_services: Add a note to the TODO

2021-01-05 Thread Phil Elwell
Record in the TODO file that the address of ">bulk_waiter"
should never be returned to userspace.

Signed-off-by: Phil Elwell 
---
 drivers/staging/vc04_services/interface/TODO | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/staging/vc04_services/interface/TODO 
b/drivers/staging/vc04_services/interface/TODO
index fc2752bc95b2..0bcb8f158afc 100644
--- a/drivers/staging/vc04_services/interface/TODO
+++ b/drivers/staging/vc04_services/interface/TODO
@@ -91,3 +91,7 @@ The first thing one generally sees in a probe function is a 
memory allocation
 for all the device specific data. This structure is then passed all over the
 driver. This is good practice since it makes the driver work regardless of the
 number of devices probed.
+
+14) Clean up Sparse warnings from __user annotations. See
+vchiq_irq_queue_bulk_tx_rx(). Ensure that the address of ">bulk_waiter"
+is never disclosed to userspace.
-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 1/3] staging: vchiq: Fix bulk userdata handling

2021-01-05 Thread Phil Elwell
The addition of the local 'userdata' pointer to
vchiq_irq_queue_bulk_tx_rx omitted the case where neither BLOCKING nor
WAITING modes are used, in which case the value provided by the
caller is not returned to them as expected, but instead it is replaced
with a NULL. This lack of a suitable context may cause the application
to crash or otherwise malfunction.

Fixes: 4184da4f316a ("staging: vchiq: fix __user annotations")

Signed-off-by: Phil Elwell 
Tested-by: Stefan Wahren 
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index f500a7043805..2a8883673ba1 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -958,7 +958,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance 
*instance,
struct vchiq_service *service;
struct bulk_waiter_node *waiter = NULL;
bool found = false;
-   void *userdata = NULL;
+   void *userdata;
int status = 0;
int ret;
 
@@ -997,6 +997,8 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance 
*instance,
"found bulk_waiter %pK for pid %d", waiter,
current->pid);
userdata = >bulk_waiter;
+   } else {
+   userdata = args->userdata;
}
 
/*
-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 0/3] A trio of vchiq bulk transfer fixes

2021-01-05 Thread Phil Elwell
The recent batch of vchiq improvements broke bulk transfers in two ways:

1. The userdata associated with a transfer was lost in the case that a
   non-blocking mode was used.

2. The 64-bit ioctl compatibility shim for a bulk transfer used the
   wrong ioctl command.

This patch set fixes both of those bugs, and adds a security-related
note to the TODO file.

Changes in v2:
- Expand the commit message on patch 1 to clarify the impact of the
  bug, and add Tested-by.
- Add commit 3 with an additional TODO item.
- Change the name of the patch set to be numerically accurate.

Phil Elwell (3):
  staging: vchiq: Fix bulk userdata handling
  staging: vchiq: Fix bulk transfers on 64-bit builds
  staging: vc04_services: Add a note to the TODO

 drivers/staging/vc04_services/interface/TODO| 4 
 .../staging/vc04_services/interface/vchiq_arm/vchiq_arm.c   | 6 --
 2 files changed, 8 insertions(+), 2 deletions(-)

-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 1/2] staging: vchiq: Fix bulk userdata handling

2021-01-05 Thread Phil Elwell
On Tue, 5 Jan 2021 at 11:04, Dan Carpenter  wrote:
>
> On Mon, Jan 04, 2021 at 07:26:42PM +, Phil Elwell wrote:
> > On 04/01/2021 18:31, Dan Carpenter wrote:
> > > On Mon, Jan 04, 2021 at 12:09:27PM +, Phil Elwell wrote:
> > > > The addition of the local 'userdata' pointer to
> > > > vchiq_irq_queue_bulk_tx_rx omitted the case where neither BLOCKING nor
> > > > WAITING modes are used, in which case the value provided by the
> > > > caller is replaced with a NULL.
> > > >
> > > > Fixes: 4184da4f316a ("staging: vchiq: fix __user annotations")
> > > >
> > > > Signed-off-by: Phil Elwell 
> > > > ---
> > > >   drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 +++-
> > > >   1 file changed, 3 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git 
> > > > a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
> > > > b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> > > > index f500a7043805..2a8883673ba1 100644
> > > > --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> > > > +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> > > > @@ -958,7 +958,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct 
> > > > vchiq_instance *instance,
> > > >   struct vchiq_service *service;
> > > >   struct bulk_waiter_node *waiter = NULL;
> > > >   bool found = false;
> > > > - void *userdata = NULL;
> > > > + void *userdata;
> > > >   int status = 0;
> > > >   int ret;
> > > > @@ -997,6 +997,8 @@ static int vchiq_irq_queue_bulk_tx_rx(struct 
> > > > vchiq_instance *instance,
> > > >   "found bulk_waiter %pK for pid %d", waiter,
> > > >   current->pid);
> > > >   userdata = >bulk_waiter;
> > > > + } else {
> > > > + userdata = args->userdata;
> > >
> > > "args->userdata" is marked as a user pointer so we really don't want to
> > > mix user and kernel pointers here.  Presumably this opens up a large
> > > security hole.
> >
> > It's an opaque, pointer-sized token that only exists to bereturned to 
> > userspace (or not,
> > without this patch) - it's hard to see that as a security hole.
>
> I was assuming the bug here was a NULL dereference...  Apparently that's
> not the case?  The commit message needs to be updated to be more clear
> about how the bug looks like to the user.
>
> Are we using the ">bulk_waiter" as a "token to be returned to
> userspace" as well?  It looks like maybe it is in vchiq_put_completion().
> That defeats KASLR and is a different sort of security problem.
>
> Mixing __user pointers and regular pointers is dangerous and has lead to
> security problems in this driver in the past.  But also mixing mixing
> tokens with pointers just makes the code hard to read.  Instead of
> undoing Arnd's work where he split the user space and kernel pointers
> apart we should go ahead and spit it up even more.  At least add a giant
> FIXME comment and an item in the TODO list so we don't forget to do this
> before removing the code from staging.

Those all sound like valid comments to have made against the original
patch, but that seems to have received little attention.

I'll just leave this here - perhaps Arnd has the patience to finish the job.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 1/2] staging: vchiq: Fix bulk userdata handling

2021-01-04 Thread Phil Elwell

On 04/01/2021 18:31, Dan Carpenter wrote:

On Mon, Jan 04, 2021 at 12:09:27PM +, Phil Elwell wrote:

The addition of the local 'userdata' pointer to
vchiq_irq_queue_bulk_tx_rx omitted the case where neither BLOCKING nor
WAITING modes are used, in which case the value provided by the
caller is replaced with a NULL.

Fixes: 4184da4f316a ("staging: vchiq: fix __user annotations")

Signed-off-by: Phil Elwell 
---
  drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index f500a7043805..2a8883673ba1 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -958,7 +958,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance 
*instance,
struct vchiq_service *service;
struct bulk_waiter_node *waiter = NULL;
bool found = false;
-   void *userdata = NULL;
+   void *userdata;
int status = 0;
int ret;
  
@@ -997,6 +997,8 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,

"found bulk_waiter %pK for pid %d", waiter,
current->pid);
userdata = >bulk_waiter;
+   } else {
+   userdata = args->userdata;


"args->userdata" is marked as a user pointer so we really don't want to
mix user and kernel pointers here.  Presumably this opens up a large
security hole.


It's an opaque, pointer-sized token that only exists to bereturned to userspace 
(or not,
without this patch) - it's hard to see that as a security hole.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] staging: vchiq: Fix bulk transfers on 64-bit builds

2021-01-04 Thread Phil Elwell
The recent change to the bulk transfer compat function missed the fact
the relevant ioctl command is VCHIQ_IOC_QUEUE_BULK_TRANSMIT32, not
VCHIQ_IOC_QUEUE_BULK_TRANSMIT, as any attempt to send a bulk block
to the VPU would have shown.

Fixes: a4367cd2b231 ("staging: vchiq: convert compat bulk transfer")

Signed-off-by: Phil Elwell 
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 2a8883673ba1..2ca5805b2fce 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -1717,7 +1717,7 @@ vchiq_compat_ioctl_queue_bulk(struct file *file,
 {
struct vchiq_queue_bulk_transfer32 args32;
struct vchiq_queue_bulk_transfer args;
-   enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
+   enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32) ?
  VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
 
if (copy_from_user(, argp, sizeof(args32)))
-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] A brace of vchiq bulk transfer fixes

2021-01-04 Thread Phil Elwell
The recent batch of vchiq improvements broke bulk transfers in two ways:

1. The userdata associated with a transfer was lost in the case that a
   non-blocking mode was used.

2. The 64-bit ioctl compatibility shim for a bulk transfer used the
   wrong ioctl command.

This patch set fixes both of those bugs.

Phil Elwell (2):
  staging: vchiq: Fix bulk userdata handling
  staging: vchiq: Fix bulk transfers on 64-bit builds

 .../staging/vc04_services/interface/vchiq_arm/vchiq_arm.c   | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] staging: vchiq: Fix bulk userdata handling

2021-01-04 Thread Phil Elwell
The addition of the local 'userdata' pointer to
vchiq_irq_queue_bulk_tx_rx omitted the case where neither BLOCKING nor
WAITING modes are used, in which case the value provided by the
caller is replaced with a NULL.

Fixes: 4184da4f316a ("staging: vchiq: fix __user annotations")

Signed-off-by: Phil Elwell 
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index f500a7043805..2a8883673ba1 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -958,7 +958,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance 
*instance,
struct vchiq_service *service;
struct bulk_waiter_node *waiter = NULL;
bool found = false;
-   void *userdata = NULL;
+   void *userdata;
int status = 0;
int ret;
 
@@ -997,6 +997,8 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance 
*instance,
"found bulk_waiter %pK for pid %d", waiter,
current->pid);
userdata = >bulk_waiter;
+   } else {
+   userdata = args->userdata;
}
 
/*
-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: vchiq: Fix local event signalling

2019-01-11 Thread Phil Elwell
Prior to the recent event reworking (see Fixes), thread synchronisation
was implemented using completions, the worker thread being woken with
a call to complete(). The replacement uses waitqueues, which are more
like condition variables in that the waiting thread is only woken if
the condition is true.

When the VPU signals the ARM, it first sets the event's fired flag to
indicate which event is being signalled, but the places in the
ARM-side code where the worker thread is being woken -
remote_event_signal_local via request_poll - did not do so as it
wasn't previously necessary, and since the armed flag was being
cleared this lead to a deadlock.

Fixes: 852b2876a8a8 ("staging: vchiq: rework remove_event handling")
Signed-off-by: Phil Elwell 
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 9e17ec6..53f5a1c 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -446,6 +446,7 @@ remote_event_wait(wait_queue_head_t *wq, struct 
remote_event *event)
 static inline void
 remote_event_signal_local(wait_queue_head_t *wq, struct remote_event *event)
 {
+   event->fired = 1;
event->armed = 0;
wake_up_all(wq);
 }
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 0/4] Improve VCHIQ cache line size handling

2018-09-17 Thread Phil Elwell

On 17/09/2018 18:51, Florian Fainelli wrote:

On 09/17/2018 04:47 AM, Phil Elwell wrote:

Hi Stefan,

On 17/09/2018 12:39, Stefan Wahren wrote:

Hi Phil,

Am 17.09.2018 um 10:22 schrieb Phil Elwell:

Both sides of the VCHIQ communications mechanism need to agree on the cache
line size. Using an incorrect value can lead to data corruption, but having the
two sides using different values is usually worse.

In the absence of an obvious convenient run-time method to determine the
correct value in the ARCH=arm world, the downstream Raspberry Pi trees used a
Device Tree property, written by the firmware, to configure the kernel driver.
This method was vetoed during the upstreaming process, so a fixed value of 32
was used instead, and some corruptions ensued. This is take 2 at arriving at
the correct value.

Add a new compatible string - "brcm,bcm2836-vchiq" - to indicate an SoC with
a 64-byte cache line. Document the new string in the binding, and use it on
the appropriate platforms.

The final patch is a (seemingly cosmetic) correction of the Device Tree "reg"
declaration for the device node, but it doubles as an indication to the
Raspberry Pi firmware that the kernel driver is running a recent kernel driver
that chooses the correct value. As such it would help if the DT patches are
not merged before the driver patch.

v3: Builds without errors, tested on multiple Raspberry Pi models.
v2: Replaced ARM-specific logic used to determine cache line size with
 a new compatible string for BCM2836 and BCM2837.

Phil Elwell (4):
   staging/vc04_services: Use correct cache line size
   dt-bindings: soc: Document "brcm,bcm2836-vchiq"
   ARM: dts: bcm283x: Correct vchiq compatible string
   ARM: dts: bcm283x: Correct mailbox register sizes


since my pull requests are out, would it be okay to apply patch #1 for
4.20 and the DT stuff for 4.21 (with the assumption Rob is okay with
these patches)?


Patch 4 is the only one I'd like to be delayed, but delaying 2-4 is fine with 
me.


Humm, did you mean you would like not to be delayed? In any case Stefan,
you can send an additional pull request, and I will merge it and send a
second pull request towards ARM SoC maintainers, that's not a problem.


No, I meant what I wrote - I would prefer patch 1 to be merged before patch 4 
(or at least
in the same release) to avoid the need for another firmware change, hence 
delaying patch
4 is good. It makes sense for the other commits to be merged in that order, but 
the
normal compatible-string fallback mechanism means there is no hard dependency 
there.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 0/4] Improve VCHIQ cache line size handling

2018-09-17 Thread Phil Elwell
Hi Stefan,

On 17/09/2018 12:39, Stefan Wahren wrote:
> Hi Phil,
> 
> Am 17.09.2018 um 10:22 schrieb Phil Elwell:
>> Both sides of the VCHIQ communications mechanism need to agree on the cache
>> line size. Using an incorrect value can lead to data corruption, but having 
>> the
>> two sides using different values is usually worse.
>>
>> In the absence of an obvious convenient run-time method to determine the
>> correct value in the ARCH=arm world, the downstream Raspberry Pi trees used a
>> Device Tree property, written by the firmware, to configure the kernel 
>> driver.
>> This method was vetoed during the upstreaming process, so a fixed value of 32
>> was used instead, and some corruptions ensued. This is take 2 at arriving at
>> the correct value.
>>
>> Add a new compatible string - "brcm,bcm2836-vchiq" - to indicate an SoC with
>> a 64-byte cache line. Document the new string in the binding, and use it on
>> the appropriate platforms.
>>
>> The final patch is a (seemingly cosmetic) correction of the Device Tree "reg"
>> declaration for the device node, but it doubles as an indication to the
>> Raspberry Pi firmware that the kernel driver is running a recent kernel 
>> driver
>> that chooses the correct value. As such it would help if the DT patches are
>> not merged before the driver patch.
>>
>> v3: Builds without errors, tested on multiple Raspberry Pi models.
>> v2: Replaced ARM-specific logic used to determine cache line size with
>> a new compatible string for BCM2836 and BCM2837.
>>
>> Phil Elwell (4):
>>   staging/vc04_services: Use correct cache line size
>>   dt-bindings: soc: Document "brcm,bcm2836-vchiq"
>>   ARM: dts: bcm283x: Correct vchiq compatible string
>>   ARM: dts: bcm283x: Correct mailbox register sizes
> 
> since my pull requests are out, would it be okay to apply patch #1 for
> 4.20 and the DT stuff for 4.21 (with the assumption Rob is okay with
> these patches)?

Patch 4 is the only one I'd like to be delayed, but delaying 2-4 is fine with 
me.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 2/4] dt-bindings: soc: Document "brcm,bcm2836-vchiq"

2018-09-17 Thread Phil Elwell
"brcm,bcm2836-vchiq" should be used on BCM2836 and BCM2837 to ensure
correct operation.

Signed-off-by: Phil Elwell 
Acked-by: Stefan Wahren 
---
 Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt 
b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt
index 8dd7b3a..f331316 100644
--- a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt
+++ b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt
@@ -2,7 +2,8 @@ Broadcom VCHIQ firmware services
 
 Required properties:
 
-- compatible:  Should be "brcm,bcm2835-vchiq"
+- compatible:  Should be "brcm,bcm2835-vchiq" on BCM2835, otherwise
+   "brcm,bcm2836-vchiq".
 - reg: Physical base address and length of the doorbell register pair
 - interrupts:  The interrupt number
  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 4/4] ARM: dts: bcm283x: Correct mailbox register sizes

2018-09-17 Thread Phil Elwell
The size field in a Device Tree "reg" property is encoded in bytes, not
words.

Fixes: 614fa22119d6 ("ARM: dts: bcm2835: Add VCHIQ node to the Raspberry Pi 
boards. (v3)")
Signed-off-by: Phil Elwell 
Acked-by: Stefan Wahren 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 215d8cc..29f970f 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -32,7 +32,7 @@
 
vchiq: mailbox@7e00b840 {
compatible = "brcm,bcm2835-vchiq";
-   reg = <0x7e00b840 0xf>;
+   reg = <0x7e00b840 0x3c>;
interrupts = <0 2>;
};
};
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 3/4] ARM: dts: bcm283x: Correct vchiq compatible string

2018-09-17 Thread Phil Elwell
To allow VCHIQ to determine the correct cache line size, use the new
"brcm,bcm2836-vchiq" compatible string on BCM2836 and BCM2837.

Signed-off-by: Phil Elwell 
Acked-by: Stefan Wahren 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +-
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts  | 2 +-
 arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 ++
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +-
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts  | 2 +-
 arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 2 +-
 6 files changed, 11 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index cb2d6d7..215d8cc 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -30,7 +30,7 @@
#power-domain-cells = <1>;
};
 
-   mailbox@7e00b840 {
+   vchiq: mailbox@7e00b840 {
compatible = "brcm,bcm2835-vchiq";
reg = <0x7e00b840 0xf>;
interrupts = <0 2>;
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts 
b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index 2fef70a..ac4408b 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2836.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-smsc9514.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
 
diff --git a/arch/arm/boot/dts/bcm2836-rpi.dtsi 
b/arch/arm/boot/dts/bcm2836-rpi.dtsi
new file mode 100644
index 000..c4c858b
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "bcm2835-rpi.dtsi"
+
+ {
+   compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
+};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts 
b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
index 4adb85e..eca36e3 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2837.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-lan7515.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
 
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts 
b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
index c318bcb..a0ba0f6 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2837.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-smsc9514.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
 
diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi 
b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
index 7b7ab6a..4a89a18 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2837.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 
 / {
memory {
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 1/4] staging/vc04_services: Use correct cache line size

2018-09-17 Thread Phil Elwell
Use the compatible string in the DTB to select the correct cache line
size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837.

Signed-off-by: Phil Elwell 
---
 .../interface/vchiq_arm/vchiq_2835_arm.c   |  4 ++-
 .../vc04_services/interface/vchiq_arm/vchiq_arm.c  | 35 +++---
 .../vc04_services/interface/vchiq_arm/vchiq_arm.h  |  5 
 3 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index e767209..83d740f 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
 int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
 {
struct device *dev = >dev;
-   struct rpi_firmware *fw = platform_get_drvdata(pdev);
+   struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev);
+   struct rpi_firmware *fw = drvdata->fw;
VCHIQ_SLOT_ZERO_T *vchiq_slot_zero;
struct resource *res;
void *slot_mem;
@@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, 
VCHIQ_STATE_T *state)
if (err < 0)
return err;
 
+   g_cache_line_size = drvdata->cache_line_size;
g_fragments_size = 2 * g_cache_line_size;
 
/* Allocate space for the channels in coherent memory */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index bc05c69..ea78937 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -170,6 +170,14 @@ static struct device *vchiq_dev;
 static DEFINE_SPINLOCK(msg_queue_spinlock);
 static struct platform_device *bcm2835_camera;
 
+static struct vchiq_drvdata bcm2835_drvdata = {
+   .cache_line_size = 32,
+};
+
+static struct vchiq_drvdata bcm2836_drvdata = {
+   .cache_line_size = 64,
+};
+
 static const char *const ioctl_names[] = {
"CONNECT",
"SHUTDOWN",
@@ -3573,12 +3581,25 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T 
*state,
}
 }
 
+static const struct of_device_id vchiq_of_match[] = {
+   { .compatible = "brcm,bcm2835-vchiq", .data = _drvdata },
+   { .compatible = "brcm,bcm2836-vchiq", .data = _drvdata },
+   {},
+};
+MODULE_DEVICE_TABLE(of, vchiq_of_match);
+
 static int vchiq_probe(struct platform_device *pdev)
 {
struct device_node *fw_node;
-   struct rpi_firmware *fw;
+   const struct of_device_id *of_id;
+   struct vchiq_drvdata *drvdata;
int err;
 
+   of_id = of_match_node(vchiq_of_match, pdev->dev.of_node);
+   drvdata = (struct vchiq_drvdata *)of_id->data;
+   if (!drvdata)
+   return -EINVAL;
+
fw_node = of_find_compatible_node(NULL, NULL,
  "raspberrypi,bcm2835-firmware");
if (!fw_node) {
@@ -3586,12 +3607,12 @@ static int vchiq_probe(struct platform_device *pdev)
return -ENOENT;
}
 
-   fw = rpi_firmware_get(fw_node);
+   drvdata->fw = rpi_firmware_get(fw_node);
of_node_put(fw_node);
-   if (!fw)
+   if (!drvdata->fw)
return -EPROBE_DEFER;
 
-   platform_set_drvdata(pdev, fw);
+   platform_set_drvdata(pdev, drvdata);
 
err = vchiq_platform_init(pdev, _state);
if (err != 0)
@@ -3661,12 +3682,6 @@ static int vchiq_remove(struct platform_device *pdev)
return 0;
 }
 
-static const struct of_device_id vchiq_of_match[] = {
-   { .compatible = "brcm,bcm2835-vchiq", },
-   {},
-};
-MODULE_DEVICE_TABLE(of, vchiq_of_match);
-
 static struct platform_driver vchiq_driver = {
.driver = {
.name = "bcm2835_vchiq",
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
index 40bb0c6..2f3ebc9 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct {
 
 } VCHIQ_ARM_STATE_T;
 
+struct vchiq_drvdata {
+   const unsigned int cache_line_size;
+   struct rpi_firmware *fw;
+};
+
 extern int vchiq_arm_log_level;
 extern int vchiq_susp_log_level;
 
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 0/4] Improve VCHIQ cache line size handling

2018-09-17 Thread Phil Elwell
Both sides of the VCHIQ communications mechanism need to agree on the cache
line size. Using an incorrect value can lead to data corruption, but having the
two sides using different values is usually worse.

In the absence of an obvious convenient run-time method to determine the
correct value in the ARCH=arm world, the downstream Raspberry Pi trees used a
Device Tree property, written by the firmware, to configure the kernel driver.
This method was vetoed during the upstreaming process, so a fixed value of 32
was used instead, and some corruptions ensued. This is take 2 at arriving at
the correct value.

Add a new compatible string - "brcm,bcm2836-vchiq" - to indicate an SoC with
a 64-byte cache line. Document the new string in the binding, and use it on
the appropriate platforms.

The final patch is a (seemingly cosmetic) correction of the Device Tree "reg"
declaration for the device node, but it doubles as an indication to the
Raspberry Pi firmware that the kernel driver is running a recent kernel driver
that chooses the correct value. As such it would help if the DT patches are
not merged before the driver patch.

v3: Builds without errors, tested on multiple Raspberry Pi models.
v2: Replaced ARM-specific logic used to determine cache line size with
a new compatible string for BCM2836 and BCM2837.

Phil Elwell (4):
  staging/vc04_services: Use correct cache line size
  dt-bindings: soc: Document "brcm,bcm2836-vchiq"
  ARM: dts: bcm283x: Correct vchiq compatible string
  ARM: dts: bcm283x: Correct mailbox register sizes

 .../bindings/soc/bcm/brcm,bcm2835-vchiq.txt|  3 +-
 arch/arm/boot/dts/bcm2835-rpi.dtsi |  4 +--
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts  |  2 +-
 arch/arm/boot/dts/bcm2836-rpi.dtsi |  6 
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts |  2 +-
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts  |  2 +-
 arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi |  2 +-
 .../interface/vchiq_arm/vchiq_2835_arm.c   |  4 ++-
 .../vc04_services/interface/vchiq_arm/vchiq_arm.c  | 35 +++---
 .../vc04_services/interface/vchiq_arm/vchiq_arm.h  |  5 
 10 files changed, 47 insertions(+), 18 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi

-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/4] staging/vc04_services: Use correct cache line size

2018-09-14 Thread Phil Elwell

On 14/09/2018 18:03, Florian Fainelli wrote:

On 09/14/2018 06:22 AM, Phil Elwell wrote:

Use the compatible string in the DTB to select the correct cache line
size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837.

Signed-off-by: Phil Elwell 
---


[snip]


@@ -170,6 +170,14 @@ static struct device *vchiq_dev;
  static DEFINE_SPINLOCK(msg_queue_spinlock);
  static struct platform_device *bcm2835_camera;
  
+static struct vchiq_drvdata bcm2835_drvdata = {

+   .cache_line_size = 32,
+};
+
+static struct vchiq_drvdata bcm2836_drvdata = {
+   .cache_line_size = 64,
+};


Those two structures could probably be marked const. Other than that,
the approach definitively looks good to me.


The mutability is intentional - the structure pointer to the firmware is also
stored there. This isn't the only piece of mutable static data in a driver
that will only have a single instance, so allocating and initialising a
per-instance structure seems needlessly complicated.

Thanks for the feedback.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/4] staging/vc04_services: Use correct cache line size

2018-09-14 Thread Phil Elwell

On 14/09/2018 14:22, Phil Elwell wrote:

Use the compatible string in the DTB to select the correct cache line
size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837.

Signed-off-by: Phil Elwell 
---
  .../interface/vchiq_arm/vchiq_2835_arm.c   |  4 ++-
  .../vc04_services/interface/vchiq_arm/vchiq_arm.c  | 36 --
  .../vc04_services/interface/vchiq_arm/vchiq_arm.h  |  5 +++
  3 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index e767209..83d740f 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
  int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
  {
struct device *dev = >dev;
-   struct rpi_firmware *fw = platform_get_drvdata(pdev);
+   struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev);
+   struct rpi_firmware *fw = drvdata->fw;
VCHIQ_SLOT_ZERO_T *vchiq_slot_zero;
struct resource *res;
void *slot_mem;
@@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, 
VCHIQ_STATE_T *state)
if (err < 0)
return err;
  
+	g_cache_line_size = drvdata->cache_line_size;

g_fragments_size = 2 * g_cache_line_size;
  
  	/* Allocate space for the channels in coherent memory */

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index bc05c69..b2ae9259 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -170,6 +170,14 @@ static struct device *vchiq_dev;
  static DEFINE_SPINLOCK(msg_queue_spinlock);
  static struct platform_device *bcm2835_camera;
  
+static struct vchiq_drvdata bcm2835_drvdata = {

+   .cache_line_size = 32,
+};
+
+static struct vchiq_drvdata bcm2836_drvdata = {
+   .cache_line_size = 64,
+};
+
  static const char *const ioctl_names[] = {
"CONNECT",
"SHUTDOWN",
@@ -3573,12 +3581,26 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T 
*state,
}
  }
  
+static const struct of_device_id vchiq_of_match[] = {

+   { .compatible = "brcm,bcm2835-vchiq", .data = _drvdata },
+   { .compatible = "brcm,bcm2836-vchiq", .data = _drvdata },
+   {},
+};
+MODULE_DEVICE_TABLE(of, vchiq_of_match);
+
  static int vchiq_probe(struct platform_device *pdev)
  {
struct device_node *fw_node;
-   struct rpi_firmware *fw;
+   const struct of_device_id *of_id;
+   struct vchiq_drvdata *drvdata;
int err;
  
+	snd_rpi_simple.dev = >dev;

+   of_id = of_match_node(vchiq_of_match, pdev->dev.of_node);
+   drvdata = of_id->data;
+   if (!drvdata)
+   return -EINVAL;
+
fw_node = of_find_compatible_node(NULL, NULL,
  "raspberrypi,bcm2835-firmware");
if (!fw_node) {
@@ -3586,12 +3608,12 @@ static int vchiq_probe(struct platform_device *pdev)
return -ENOENT;
}
  
-	fw = rpi_firmware_get(fw_node);

+   drvdata->fw = rpi_firmware_get(fw_node);
of_node_put(fw_node);
-   if (!fw)
+   if (!drvdata->fw)
return -EPROBE_DEFER;
  
-	platform_set_drvdata(pdev, fw);

+   platform_set_drvdata(pdev, drvdata);
  
  	err = vchiq_platform_init(pdev, _state);

if (err != 0)
@@ -3661,12 +3683,6 @@ static int vchiq_remove(struct platform_device *pdev)
return 0;
  }
  
-static const struct of_device_id vchiq_of_match[] = {

-   { .compatible = "brcm,bcm2835-vchiq", },
-   {},
-};
-MODULE_DEVICE_TABLE(of, vchiq_of_match);
-
  static struct platform_driver vchiq_driver = {
.driver = {
.name = "bcm2835_vchiq",
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
index 40bb0c6..2f3ebc9 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct {
  
  } VCHIQ_ARM_STATE_T;
  
+struct vchiq_drvdata {

+   const unsigned int cache_line_size;
+   struct rpi_firmware *fw;
+};
+
  extern int vchiq_arm_log_level;
  extern int vchiq_susp_log_level;
  



This version doesn't compile (wrong defconfig used when building), but any 
criticism of the
approach before v3 is welcome.

Phil

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 2/4] dt-bindings: soc: Document "brcm,bcm2836-vchiq"

2018-09-14 Thread Phil Elwell
"brcm,bcm2836-vchiq" should be used on BCM2836 and BCM2837 to ensure
correct operation.

Signed-off-by: Phil Elwell 
---
 Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt 
b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt
index 8dd7b3a..f331316 100644
--- a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt
+++ b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt
@@ -2,7 +2,8 @@ Broadcom VCHIQ firmware services
 
 Required properties:
 
-- compatible:  Should be "brcm,bcm2835-vchiq"
+- compatible:  Should be "brcm,bcm2835-vchiq" on BCM2835, otherwise
+   "brcm,bcm2836-vchiq".
 - reg: Physical base address and length of the doorbell register pair
 - interrupts:  The interrupt number
  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 3/4] ARM: dts: bcm283x: Correct vchiq compatible string

2018-09-14 Thread Phil Elwell
To allow VCHIQ to determine the correct cache line size, use the new
"brcm,bcm2836-vchiq" compatible string on BCM2836 and BCM2837.

Signed-off-by: Phil Elwell 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +-
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts  | 2 +-
 arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 ++
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +-
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts  | 2 +-
 arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 2 +-
 6 files changed, 11 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index cb2d6d7..215d8cc 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -30,7 +30,7 @@
#power-domain-cells = <1>;
};
 
-   mailbox@7e00b840 {
+   vchiq: mailbox@7e00b840 {
compatible = "brcm,bcm2835-vchiq";
reg = <0x7e00b840 0xf>;
interrupts = <0 2>;
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts 
b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index 2fef70a..ac4408b 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2836.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-smsc9514.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
 
diff --git a/arch/arm/boot/dts/bcm2836-rpi.dtsi 
b/arch/arm/boot/dts/bcm2836-rpi.dtsi
new file mode 100644
index 000..c4c858b
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "bcm2835-rpi.dtsi"
+
+ {
+   compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
+};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts 
b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
index 4adb85e..eca36e3 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2837.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-lan7515.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
 
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts 
b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
index c318bcb..a0ba0f6 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2837.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-smsc9514.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
 
diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi 
b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
index 7b7ab6a..4a89a18 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 #include "bcm2837.dtsi"
-#include "bcm2835-rpi.dtsi"
+#include "bcm2836-rpi.dtsi"
 
 / {
memory {
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 1/4] staging/vc04_services: Use correct cache line size

2018-09-14 Thread Phil Elwell
Use the compatible string in the DTB to select the correct cache line
size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837.

Signed-off-by: Phil Elwell 
---
 .../interface/vchiq_arm/vchiq_2835_arm.c   |  4 ++-
 .../vc04_services/interface/vchiq_arm/vchiq_arm.c  | 36 --
 .../vc04_services/interface/vchiq_arm/vchiq_arm.h  |  5 +++
 3 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index e767209..83d740f 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
 int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
 {
struct device *dev = >dev;
-   struct rpi_firmware *fw = platform_get_drvdata(pdev);
+   struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev);
+   struct rpi_firmware *fw = drvdata->fw;
VCHIQ_SLOT_ZERO_T *vchiq_slot_zero;
struct resource *res;
void *slot_mem;
@@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, 
VCHIQ_STATE_T *state)
if (err < 0)
return err;
 
+   g_cache_line_size = drvdata->cache_line_size;
g_fragments_size = 2 * g_cache_line_size;
 
/* Allocate space for the channels in coherent memory */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index bc05c69..b2ae9259 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -170,6 +170,14 @@ static struct device *vchiq_dev;
 static DEFINE_SPINLOCK(msg_queue_spinlock);
 static struct platform_device *bcm2835_camera;
 
+static struct vchiq_drvdata bcm2835_drvdata = {
+   .cache_line_size = 32,
+};
+
+static struct vchiq_drvdata bcm2836_drvdata = {
+   .cache_line_size = 64,
+};
+
 static const char *const ioctl_names[] = {
"CONNECT",
"SHUTDOWN",
@@ -3573,12 +3581,26 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T 
*state,
}
 }
 
+static const struct of_device_id vchiq_of_match[] = {
+   { .compatible = "brcm,bcm2835-vchiq", .data = _drvdata },
+   { .compatible = "brcm,bcm2836-vchiq", .data = _drvdata },
+   {},
+};
+MODULE_DEVICE_TABLE(of, vchiq_of_match);
+
 static int vchiq_probe(struct platform_device *pdev)
 {
struct device_node *fw_node;
-   struct rpi_firmware *fw;
+   const struct of_device_id *of_id;
+   struct vchiq_drvdata *drvdata;
int err;
 
+   snd_rpi_simple.dev = >dev;
+   of_id = of_match_node(vchiq_of_match, pdev->dev.of_node);
+   drvdata = of_id->data;
+   if (!drvdata)
+   return -EINVAL;
+
fw_node = of_find_compatible_node(NULL, NULL,
  "raspberrypi,bcm2835-firmware");
if (!fw_node) {
@@ -3586,12 +3608,12 @@ static int vchiq_probe(struct platform_device *pdev)
return -ENOENT;
}
 
-   fw = rpi_firmware_get(fw_node);
+   drvdata->fw = rpi_firmware_get(fw_node);
of_node_put(fw_node);
-   if (!fw)
+   if (!drvdata->fw)
return -EPROBE_DEFER;
 
-   platform_set_drvdata(pdev, fw);
+   platform_set_drvdata(pdev, drvdata);
 
err = vchiq_platform_init(pdev, _state);
if (err != 0)
@@ -3661,12 +3683,6 @@ static int vchiq_remove(struct platform_device *pdev)
return 0;
 }
 
-static const struct of_device_id vchiq_of_match[] = {
-   { .compatible = "brcm,bcm2835-vchiq", },
-   {},
-};
-MODULE_DEVICE_TABLE(of, vchiq_of_match);
-
 static struct platform_driver vchiq_driver = {
.driver = {
.name = "bcm2835_vchiq",
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
index 40bb0c6..2f3ebc9 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct {
 
 } VCHIQ_ARM_STATE_T;
 
+struct vchiq_drvdata {
+   const unsigned int cache_line_size;
+   struct rpi_firmware *fw;
+};
+
 extern int vchiq_arm_log_level;
 extern int vchiq_susp_log_level;
 
-- 
2.7.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 resend] staging: bcm2835-audio: Fix memory corruption

2017-09-24 Thread Phil Elwell
The previous commit (0adbfd46) fixed a memory leak but also freed a
block in the success case, causing a stale pointer to be used with
potentially fatal results. Only free the vchi_instance block in the
case that vchi_connect fails; once connected, the instance is
retained for subsequent connections.

Simplifying the code by removing a bunch of gotos and returning errors
directly.

Signed-off-by: Phil Elwell <p...@raspberrypi.org>
Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in 
bcm2835_audio_open_connection()")
---
v2: Simplified following feedback from Dan Carpenter.
---
 .../vc04_services/bcm2835-audio/bcm2835-vchiq.c   | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c 
b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
index 5f3d8f2..4be864d 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
@@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
__func__, instance);
instance->alsa_stream = alsa_stream;
alsa_stream->instance = instance;
-   ret = 0; // xxx todo -1;
-   goto err_free_mem;
+   return 0;
}
 
/* Initialize and create a VCHI connection */
@@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
LOG_ERR("%s: failed to initialise VCHI instance 
(ret=%d)\n",
__func__, ret);
 
-   ret = -EIO;
-   goto err_free_mem;
+   return -EIO;
}
ret = vchi_connect(NULL, 0, vchi_instance);
if (ret) {
LOG_ERR("%s: failed to connect VCHI instance 
(ret=%d)\n",
__func__, ret);
 
-   ret = -EIO;
-   goto err_free_mem;
+   kfree(vchi_instance);
+   return -EIO;
}
initted = 1;
}
@@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
if (IS_ERR(instance)) {
LOG_ERR("%s: failed to initialize audio service\n", __func__);
 
-   ret = PTR_ERR(instance);
-   goto err_free_mem;
+   /* vchi_instance is retained for use the next time. */
+   return PTR_ERR(instance);
}
 
instance->alsa_stream = alsa_stream;
alsa_stream->instance = instance;
 
LOG_DBG(" success !\n");
-   ret = 0;
-err_free_mem:
-   kfree(vchi_instance);
 
-   return ret;
+   return 0;
 }
 
 int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2] staging: bcm2835-audio: Fix memory corruption

2017-08-11 Thread Phil Elwell
The previous commit (0adbfd46) fixed a memory leak but also freed a
block in the success case, causing a stale pointer to be used with
potentially fatal results. Only free the vchi_instance block in the
case that vchi_connect fails; once connected, the instance is
retained for subsequent connections.

Simplifying the code by removing a bunch of gotos and returning errors
directly.

Signed-off-by: Phil Elwell <p...@raspberrypi.org>
Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in 
bcm2835_audio_open_connection()")
---
[Resend with v2 in subject]
v2: Simplified following feedback from Dan Carpenter.
---
 .../vc04_services/bcm2835-audio/bcm2835-vchiq.c   | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c 
b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
index 5f3d8f2..4be864d 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
@@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
__func__, instance);
instance->alsa_stream = alsa_stream;
alsa_stream->instance = instance;
-   ret = 0; // xxx todo -1;
-   goto err_free_mem;
+   return 0;
}
 
/* Initialize and create a VCHI connection */
@@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
LOG_ERR("%s: failed to initialise VCHI instance 
(ret=%d)\n",
__func__, ret);
 
-   ret = -EIO;
-   goto err_free_mem;
+   return -EIO;
}
ret = vchi_connect(NULL, 0, vchi_instance);
if (ret) {
LOG_ERR("%s: failed to connect VCHI instance 
(ret=%d)\n",
__func__, ret);
 
-   ret = -EIO;
-   goto err_free_mem;
+   kfree(vchi_instance);
+   return -EIO;
}
initted = 1;
}
@@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
if (IS_ERR(instance)) {
LOG_ERR("%s: failed to initialize audio service\n", __func__);
 
-   ret = PTR_ERR(instance);
-   goto err_free_mem;
+   /* vchi_instance is retained for use the next time. */
+   return PTR_ERR(instance);
}
 
instance->alsa_stream = alsa_stream;
alsa_stream->instance = instance;
 
LOG_DBG(" success !\n");
-   ret = 0;
-err_free_mem:
-   kfree(vchi_instance);
 
-   return ret;
+   return 0;
 }
 
 int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: bcm2835-audio: Fix memory corruption

2017-08-11 Thread Phil Elwell
The previous commit (0adbfd46) fixed a memory leak but also freed a
block in the success case, causing a stale pointer to be used with
potentially fatal results. Only free the vchi_instance block in the
case that vchi_connect fails; once connected, the instance is
retained for subsequent connections.

Simplifying the code by removing a bunch of gotos and returning errors
directly.

Signed-off-by: Phil Elwell <p...@raspberrypi.org>
Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in 
bcm2835_audio_open_connection()")
---
v2: Simplified following feedback from Dan Carpenter.
---
 .../vc04_services/bcm2835-audio/bcm2835-vchiq.c   | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c 
b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
index 5f3d8f2..4be864d 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
@@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
__func__, instance);
instance->alsa_stream = alsa_stream;
alsa_stream->instance = instance;
-   ret = 0; // xxx todo -1;
-   goto err_free_mem;
+   return 0;
}
 
/* Initialize and create a VCHI connection */
@@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
LOG_ERR("%s: failed to initialise VCHI instance 
(ret=%d)\n",
__func__, ret);
 
-   ret = -EIO;
-   goto err_free_mem;
+   return -EIO;
}
ret = vchi_connect(NULL, 0, vchi_instance);
if (ret) {
LOG_ERR("%s: failed to connect VCHI instance 
(ret=%d)\n",
__func__, ret);
 
-   ret = -EIO;
-   goto err_free_mem;
+   kfree(vchi_instance);
+   return -EIO;
}
initted = 1;
}
@@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
if (IS_ERR(instance)) {
LOG_ERR("%s: failed to initialize audio service\n", __func__);
 
-   ret = PTR_ERR(instance);
-   goto err_free_mem;
+   /* vchi_instance is retained for use the next time. */
+   return PTR_ERR(instance);
}
 
instance->alsa_stream = alsa_stream;
alsa_stream->instance = instance;
 
LOG_DBG(" success !\n");
-   ret = 0;
-err_free_mem:
-   kfree(vchi_instance);
 
-   return ret;
+   return 0;
 }
 
 int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: bcm2835-audio: Fix memory corruption

2017-08-10 Thread Phil Elwell


On 10/08/2017 12:24, Dan Carpenter wrote:
> On Thu, Aug 10, 2017 at 11:52:42AM +0100, Phil Elwell wrote:
>> On 10/08/2017 11:21, Dan Carpenter wrote:
>>> The original patch did not go through the normal review process...
>>>
>>> On Tue, Aug 08, 2017 at 01:05:02PM +0100, Phil Elwell wrote:
>>>> I'm all for fixing memory leaks, but freeing a block while it is still
>>>> being used is a recipe for hard-to-debug kernel exceptions.
>>>>
>>>
>>> This bug completely breaks the driver doesn't it?  It's not very subtle
>>> so it should be easy to diagnose with git bisect.
>>
>> It's more subtle than that - the failure isn't consistent, sometimes crashing
>> and sometimes not depending on how and when memory is reused.
>>
>>>> 1) There is already a vchi method for freeing the instance, so use it.
>>>> 2) Only call it on error, and then only before initted is false.
>>>>
>>>> Signed-off-by: Phil Elwell <p...@raspberrypi.org>
>>>> Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in 
>>>> bcm2835_audio_open_connection()")
>>>> ---
>>>>  drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 2 +-
>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c 
>>>> b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
>>>> index 5f3d8f2..89f96f3 100644
>>>> --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
>>>> +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
>>>> @@ -409,6 +409,7 @@ static int bcm2835_audio_open_connection(struct 
>>>> bcm2835_alsa_stream *alsa_stream
>>>>LOG_ERR("%s: failed to connect VCHI instance 
>>>> (ret=%d)\n",
>>>>__func__, ret);
>>>>  
>>>> +  vchi_disconnect(vchi_instance);
>>>
>>> This is ugly because why are we calling disconnect() if connect() fails?
>>> These functions should be symetric so disconnect only disconnects and
>>> we call a different function to undo vchi_initialise().
>>
>> Agreed - I'm not going to change the API, but I can add a comment.
>>
> 
> Nah...  Please don't do that.  Just create a function:
> 
> void vchiq_free(VCHIQ_INSTANCE_T *vchi_instance)
> {
>   kfree(vchi_instance);
> }
> 
> Really vchi_initialise() is badly named and it's just a wrapper around
> vchiq_initialise().  It should be deleted and vchiq_initialise() should
> be renamed to allocate instead of initialize...  But that's for a
> separate patch.
> 
> And also we should move the kfree() out of disconnect() like I said
> and instead call vchiq_free().  But again, that's for a separate patch.
> 
> Change the goto to "return -EIO."  Leave the last error path as-is.
> Eventually we will want to break this into two functions, one that
> allocates the first vchi_instance and one that calls vc_vchi_audio_init().
> But again, there are many patches needed to fix this code.

[ static removed ]

Shouldn't that be:

void vchi_uninitialise(VCHI_INSTANCE_T instance_handle)
{
vchiq_shutdown((VCHIQ_INSTANCE_T)instance_handle);
}
EXPORT_SYMBOL(vchi_uninitialise);

Yes, in this case the instance is just a block of memory with no users,
but if this is a general API call then you want it to work in all cases,
and calling vchiq_shutdown is the right way to free an instance. Calling
a VCHIQ method when all the other calls are to the VCHI API is grubby,
so make it a VCHI method instead.

If instead this is just another hack - a kfree with a comment in code form -
then lets keep it static within the audio driver (which is what I thought you
were initially suggesting).

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: bcm2835-audio: Fix memory corruption

2017-08-10 Thread Phil Elwell
On 10/08/2017 11:21, Dan Carpenter wrote:
> The original patch did not go through the normal review process...
> 
> On Tue, Aug 08, 2017 at 01:05:02PM +0100, Phil Elwell wrote:
>> I'm all for fixing memory leaks, but freeing a block while it is still
>> being used is a recipe for hard-to-debug kernel exceptions.
>>
> 
> This bug completely breaks the driver doesn't it?  It's not very subtle
> so it should be easy to diagnose with git bisect.

It's more subtle than that - the failure isn't consistent, sometimes crashing
and sometimes not depending on how and when memory is reused.

>> 1) There is already a vchi method for freeing the instance, so use it.
>> 2) Only call it on error, and then only before initted is false.
>>
>> Signed-off-by: Phil Elwell <p...@raspberrypi.org>
>> Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in 
>> bcm2835_audio_open_connection()")
>> ---
>>  drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c 
>> b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
>> index 5f3d8f2..89f96f3 100644
>> --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
>> +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
>> @@ -409,6 +409,7 @@ static int bcm2835_audio_open_connection(struct 
>> bcm2835_alsa_stream *alsa_stream
>>  LOG_ERR("%s: failed to connect VCHI instance 
>> (ret=%d)\n",
>>  __func__, ret);
>>  
>> +vchi_disconnect(vchi_instance);
> 
> This is ugly because why are we calling disconnect() if connect() fails?
> These functions should be symetric so disconnect only disconnects and
> we call a different function to undo vchi_initialise().

Agreed - I'm not going to change the API, but I can add a comment.

>>  ret = -EIO;
>>  goto err_free_mem;
> 
> This label name is out of date.  There is a later error path where
> vc_vchi_audio_init() fails and we leak on that path.

Also agreed. I'll rework it.

> Also why is
> vchi_instance a static variable?  Arglebargleblargleblah...

You may well think that. I couldn't possibly comment.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: bcm2835-audio: Fix memory corruption

2017-08-08 Thread Phil Elwell
I'm all for fixing memory leaks, but freeing a block while it is still
being used is a recipe for hard-to-debug kernel exceptions.

1) There is already a vchi method for freeing the instance, so use it.
2) Only call it on error, and then only before initted is false.

Signed-off-by: Phil Elwell <p...@raspberrypi.org>
Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in 
bcm2835_audio_open_connection()")
---
 drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c 
b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
index 5f3d8f2..89f96f3 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
@@ -409,6 +409,7 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
LOG_ERR("%s: failed to connect VCHI instance 
(ret=%d)\n",
__func__, ret);
 
+   vchi_disconnect(vchi_instance);
ret = -EIO;
goto err_free_mem;
}
@@ -431,7 +432,6 @@ static int bcm2835_audio_open_connection(struct 
bcm2835_alsa_stream *alsa_stream
LOG_DBG(" success !\n");
ret = 0;
 err_free_mem:
-   kfree(vchi_instance);
 
return ret;
 }
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [Bug] VCHIQ functional test broken

2017-05-15 Thread Phil Elwell
On 15/05/2017 15:54, Stefan Wahren wrote:
> Am 15.05.2017 um 16:29 schrieb Phil Elwell:
>> On 13/05/2017 10:30, Russell King - ARM Linux wrote:
>>> On Sat, May 13, 2017 at 11:07:28AM +0200, Stefan Wahren wrote:
>>>> In the meantime this issue has been fixed by Phil [1].
>>> Right - definitely a driver bug.  Mapping more memory for DMA than is
>>> actually going to be DMA'd to and expecting data to be preserved is
>>> really horrid.
>> That feature was added during the upstreaming process, and as Stefan says
>> there is an outstanding patch for it.
>>
>>>> Unfortunately i found another issue. If i enable CONFIG_HIGHMEM in
>>>> the kernel config, the data during functional test gets corrupted.
>>>> Phil said it's caused by the usage of get_user_pages() [2].
>>> Without knowing who "Phil" is in that thread, but...
>>>
>>>HIGHMEM is a problem because you can't use get_user_pages on pages in
>>>HIGHMEM.
>>>
>>> is an interesting statement, and without any reasoning or evidence.
>>>
>>> I also believe it to be incorrect.  get_user_pages() returns an array
>>> of struct page pointers for the user memory, calling flush_dcache_page()
>>> and flush_anon_page() on them to ensure that any kernel mapping is
>>> coherent with what is in userspace.
>>>
>>> As far as returning the array of page pointers, get_user_pages() doesn't
>>> care whether they're lowmem or highmem.
>>>
>>> flush_dcache_page() doesn't care either - if it wants to flush the page
>>> and the page is a highmem page, it will temporarily map it before
>>> flushing it.
>>>
>>> flush_anon_page() is a no-op for all non-aliasing caches.
>>>
>>> get_user_pages() works fine for whatever memory on other platforms and
>>> drivers such as etnaviv, so I think this comes down to the vchip driver
>>> doing things in ways that the kernel interfaces its using don't expect -
>>> exactly like the "lets pass full pages to the DMA API" broken-ness.
>> See previous comment.
>>
>>> I would like to hear the justification for that statement, but without
>>> any justification, I assert that the statement is false.
>> I am the Phil in question, and the off-the-cuff comment was the result of
>> a hazy memory of issues encountered with VCHIQ bulk transfers as a Broadcom
>> employee (which would have been on a 2.6 kernel). I suspect there may have
>> been some use of kernel virtual addresses as an intermediate representation,
>> but I no longer have access to that code.
>>
>> If get_user_pages is HIGHMEM-safe (and I can see why it would be), then the
>> cause of the corruption Stefan saw is probably the special handling of
>> unaligned reads, specifically:
>>
>>  memcpy((char *)page_address(pages[0]) +
>>  pagelist->offset,
>>  fragments,
>>  head_bytes);
> 
> 
> Btw shouldn't we use copy_from_user() at this place?

I'm sure you mean copy_to_user(), and the answer is "it's complicated". 
Depending
on the relative timing, this code can also be called from a kernel thread, so I
doubt that would work.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [Bug] VCHIQ functional test broken

2017-05-15 Thread Phil Elwell
On 13/05/2017 10:30, Russell King - ARM Linux wrote:
> On Sat, May 13, 2017 at 11:07:28AM +0200, Stefan Wahren wrote:
>> In the meantime this issue has been fixed by Phil [1].
> 
> Right - definitely a driver bug.  Mapping more memory for DMA than is
> actually going to be DMA'd to and expecting data to be preserved is
> really horrid.

That feature was added during the upstreaming process, and as Stefan says
there is an outstanding patch for it.

>> Unfortunately i found another issue. If i enable CONFIG_HIGHMEM in
>> the kernel config, the data during functional test gets corrupted.
>> Phil said it's caused by the usage of get_user_pages() [2].
> 
> Without knowing who "Phil" is in that thread, but...
> 
>HIGHMEM is a problem because you can't use get_user_pages on pages in
>HIGHMEM.
> 
> is an interesting statement, and without any reasoning or evidence.
> 
> I also believe it to be incorrect.  get_user_pages() returns an array
> of struct page pointers for the user memory, calling flush_dcache_page()
> and flush_anon_page() on them to ensure that any kernel mapping is
> coherent with what is in userspace.
> 
> As far as returning the array of page pointers, get_user_pages() doesn't
> care whether they're lowmem or highmem.
> 
> flush_dcache_page() doesn't care either - if it wants to flush the page
> and the page is a highmem page, it will temporarily map it before
> flushing it.
> 
> flush_anon_page() is a no-op for all non-aliasing caches.
> 
> get_user_pages() works fine for whatever memory on other platforms and
> drivers such as etnaviv, so I think this comes down to the vchip driver
> doing things in ways that the kernel interfaces its using don't expect -
> exactly like the "lets pass full pages to the DMA API" broken-ness.

See previous comment.

> I would like to hear the justification for that statement, but without
> any justification, I assert that the statement is false.

I am the Phil in question, and the off-the-cuff comment was the result of
a hazy memory of issues encountered with VCHIQ bulk transfers as a Broadcom
employee (which would have been on a 2.6 kernel). I suspect there may have
been some use of kernel virtual addresses as an intermediate representation,
but I no longer have access to that code.

If get_user_pages is HIGHMEM-safe (and I can see why it would be), then the
cause of the corruption Stefan saw is probably the special handling of
unaligned reads, specifically:

memcpy((char *)page_address(pages[0]) +
pagelist->offset,
fragments,
head_bytes);

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: vc04_services: Fix bulk cache maintenance

2017-05-10 Thread Phil Elwell
On 10/05/2017 10:06, Greg Kroah-Hartman wrote:
> On Wed, May 10, 2017 at 09:42:43AM +0100, Phil Elwell wrote:
>> On 04/05/2017 18:51, Stefan Wahren wrote:
>>>
>>>> Phil Elwell <p...@raspberrypi.org> hat am 4. Mai 2017 um 11:58 geschrieben:
>>>>
>>>>
>>>> vchiq_arm supports transfers less than one page and at arbitrary
>>>> alignment, using the dma-mapping API to perform its cache maintenance
>>>> (even though the VPU drives the DMA hardware). Read (DMA_FROM_DEVICE)
>>>> operations use cache invalidation for speed, falling back to
>>>> clean+invalidate on partial cache lines, with writes (DMA_TO_DEVICE)
>>>> using flushes.
>>>>
>>>> If a read transfer has ends which aren't page-aligned, performing cache
>>>> maintenance as if they were whole pages can lead to memory corruption
>>>> since the partial cache lines at the ends (and any cache lines before or
>>>> after the transfer area) will be invalidated. This bug was masked until
>>>> the disabling of the cache flush in flush_dcache_page().
>>>>
>>>> Honouring the requested transfer start- and end-points prevents the
>>>> corruption.
>>>>
>>>> Fixes: cf9caf192988 ("staging: vc04_services: Replace dmac_map_area with 
>>>> dmac_map_sg")
>>>> Signed-off-by: Phil Elwell <p...@raspberrypi.org>
>>>
>>> Reported-by: Stefan Wahren <stefan.wah...@i2se.com>
>>> Tested-by: Stefan Wahren <stefan.wah...@i2se.com>
>>>
>>> In order to clarify the context of this issue:
>>>
>>> http://lists.infradead.org/pipermail/linux-rpi-kernel/2017-April/006149.html
>>
>> Thanks, Stefan.
>>
>> Is there no feedback other on this patch? It's been in the rpi-4.11.y 
>> downstream
>> branch for a week now with favourable results - see issue
>> https://github.com/raspberrypi/linux/issues/1977 and pr
>> https://github.com/raspberrypi/linux/pull/1987.
> 
> It's the middle of the merge window, I can't do anything with this
> until after 4.12-rc1 comes out.  Please be patient...

Yes, of course - that's the kind of feedback I was looking for.

Thanks,

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: vc04_services: Fix bulk cache maintenance

2017-05-10 Thread Phil Elwell
On 04/05/2017 18:51, Stefan Wahren wrote:
> 
>> Phil Elwell <p...@raspberrypi.org> hat am 4. Mai 2017 um 11:58 geschrieben:
>>
>>
>> vchiq_arm supports transfers less than one page and at arbitrary
>> alignment, using the dma-mapping API to perform its cache maintenance
>> (even though the VPU drives the DMA hardware). Read (DMA_FROM_DEVICE)
>> operations use cache invalidation for speed, falling back to
>> clean+invalidate on partial cache lines, with writes (DMA_TO_DEVICE)
>> using flushes.
>>
>> If a read transfer has ends which aren't page-aligned, performing cache
>> maintenance as if they were whole pages can lead to memory corruption
>> since the partial cache lines at the ends (and any cache lines before or
>> after the transfer area) will be invalidated. This bug was masked until
>> the disabling of the cache flush in flush_dcache_page().
>>
>> Honouring the requested transfer start- and end-points prevents the
>> corruption.
>>
>> Fixes: cf9caf192988 ("staging: vc04_services: Replace dmac_map_area with 
>> dmac_map_sg")
>> Signed-off-by: Phil Elwell <p...@raspberrypi.org>
> 
> Reported-by: Stefan Wahren <stefan.wah...@i2se.com>
> Tested-by: Stefan Wahren <stefan.wah...@i2se.com>
> 
> In order to clarify the context of this issue:
> 
> http://lists.infradead.org/pipermail/linux-rpi-kernel/2017-April/006149.html

Thanks, Stefan.

Is there no feedback other on this patch? It's been in the rpi-4.11.y downstream
branch for a week now with favourable results - see issue
https://github.com/raspberrypi/linux/issues/1977 and pr
https://github.com/raspberrypi/linux/pull/1987.

Phil
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: vc04_services: Fix bulk cache maintenance

2017-05-04 Thread Phil Elwell
vchiq_arm supports transfers less than one page and at arbitrary
alignment, using the dma-mapping API to perform its cache maintenance
(even though the VPU drives the DMA hardware). Read (DMA_FROM_DEVICE)
operations use cache invalidation for speed, falling back to
clean+invalidate on partial cache lines, with writes (DMA_TO_DEVICE)
using flushes.

If a read transfer has ends which aren't page-aligned, performing cache
maintenance as if they were whole pages can lead to memory corruption
since the partial cache lines at the ends (and any cache lines before or
after the transfer area) will be invalidated. This bug was masked until
the disabling of the cache flush in flush_dcache_page().

Honouring the requested transfer start- and end-points prevents the
corruption.

Fixes: cf9caf192988 ("staging: vc04_services: Replace dmac_map_area with 
dmac_map_sg")
Signed-off-by: Phil Elwell <p...@raspberrypi.org>
---
 .../interface/vchiq_arm/vchiq_2835_arm.c   | 31 +-
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index 3aeffcb..02e9736 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -501,8 +501,15 @@ int vchiq_platform_init(struct platform_device *pdev, 
VCHIQ_STATE_T *state)
 */
sg_init_table(scatterlist, num_pages);
/* Now set the pages for each scatterlist */
-   for (i = 0; i < num_pages; i++)
-   sg_set_page(scatterlist + i, pages[i], PAGE_SIZE, 0);
+   for (i = 0; i < num_pages; i++) {
+   unsigned int len = PAGE_SIZE - offset;
+
+   if (len > count)
+   len = count;
+   sg_set_page(scatterlist + i, pages[i], len, offset);
+   offset = 0;
+   count -= len;
+   }
 
dma_buffers = dma_map_sg(g_dev,
 scatterlist,
@@ -523,20 +530,20 @@ int vchiq_platform_init(struct platform_device *pdev, 
VCHIQ_STATE_T *state)
u32 addr = sg_dma_address(sg);
 
/* Note: addrs is the address + page_count - 1
-* The firmware expects the block to be page
+* The firmware expects blocks after the first to be page-
 * aligned and a multiple of the page size
 */
WARN_ON(len == 0);
-   WARN_ON(len & ~PAGE_MASK);
-   WARN_ON(addr & ~PAGE_MASK);
+   WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK));
+   WARN_ON(i && (addr & ~PAGE_MASK));
if (k > 0 &&
-   ((addrs[k - 1] & PAGE_MASK) |
-   ((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT)
-   == addr) {
-   addrs[k - 1] += (len >> PAGE_SHIFT);
-   } else {
-   addrs[k++] = addr | ((len >> PAGE_SHIFT) - 1);
-   }
+   ((addrs[k - 1] & PAGE_MASK) +
+(((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT))
+   == (addr & PAGE_MASK))
+   addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT);
+   else
+   addrs[k++] = (addr & PAGE_MASK) |
+   (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1);
}
 
/* Partial cache lines (fragments) require special measures */
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [bug report] staging: add bcm2708 vchiq driver

2016-11-16 Thread Phil Elwell
On 16/11/2016 10:21, Dan Carpenter wrote:
> On Tue, Nov 15, 2016 at 10:04:05PM -0500, Vince Weaver wrote:
>> On Tue, 15 Nov 2016, Michael Zoran wrote:
>>
>>> I'm still interested to know more about the MMU statement.  I would
>>> think at least some of the RPI models have one because swapping appears
>>> to be at least somewhat functional on the later models.
>> All Raspberry Pi models have an MMU.  I'm not sure why anyone thinks
>> otherwise.
> No idea.  Someone told me that when I complained about a different
> security bug on RPI.
The ARM cores have MMUs between them and the SoC bus, but the VC4 VPU
and its peripherals do not, leading to the need for contiguous
allocations. Some VPU peripherals can only address 256MB of RAM, which
further constrains allocations.

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel