From: Tim Sell <timothy.s...@unisys.com>

Ensure we properly lock between visorinput_channel_interrupt() and
devdata_create().  We now guarantee that interrupts will be disabled and
we will be holding lock_visor_dev at the time input_register_device() is
called (from register_client_keyboard() or register_client_mouse()), after
which we may quickly find ourselves in visorinput_open(), where we enable
interrupts, and hence may call visorinput_channel_interrupt().

Signed-off-by: Tim Sell <timothy.s...@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.ro...@unisys.com>

---
v2: the patch was resubmitted.
---
 drivers/staging/unisys/visorinput/visorinput.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/unisys/visorinput/visorinput.c 
b/drivers/staging/unisys/visorinput/visorinput.c
index 4620a49..8c22e0f 100644
--- a/drivers/staging/unisys/visorinput/visorinput.c
+++ b/drivers/staging/unisys/visorinput/visorinput.c
@@ -415,6 +415,8 @@ devdata_create(struct visor_device *dev, enum 
visorinput_device_type devtype)
        if (!devdata)
                return NULL;
        devdata->dev = dev;
+       init_rwsem(&devdata->lock_visor_dev);
+       down_write(&devdata->lock_visor_dev);
 
        /*
         * This is an input device in a client guest partition,
@@ -453,12 +455,14 @@ devdata_create(struct visor_device *dev, enum 
visorinput_device_type devtype)
                break;
        }
 
-       init_rwsem(&devdata->lock_visor_dev);
        kref_init(&devdata->kref);
+       dev_set_drvdata(&dev->device, devdata);
+       up_write(&devdata->lock_visor_dev);
 
        return devdata;
 
 cleanups_register:
+       up_write(&devdata->lock_visor_dev);
        kfree(devdata);
        return NULL;
 }
@@ -466,7 +470,6 @@ cleanups_register:
 static int
 visorinput_probe(struct visor_device *dev)
 {
-       struct visorinput_devdata *devdata = NULL;
        uuid_le guid;
        enum visorinput_device_type devtype;
 
@@ -477,10 +480,9 @@ visorinput_probe(struct visor_device *dev)
                devtype = visorinput_keyboard;
        else
                return -ENODEV;
-       devdata = devdata_create(dev, devtype);
-       if (!devdata)
+       visorbus_disable_channel_interrupts(dev);
+       if (!devdata_create(dev, devtype))
                return -ENOMEM;
-       dev_set_drvdata(&dev->device, devdata);
        return 0;
 }
 
-- 
2.5.0

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

Reply via email to