Re: [PATCH 8/9] qspinlock: Generic paravirt support

2015-03-19 Thread Waiman Long

On 03/19/2015 08:25 AM, Peter Zijlstra wrote:

On Thu, Mar 19, 2015 at 11:12:42AM +0100, Peter Zijlstra wrote:

So I was now thinking of hashing the lock pointer; let me go and quickly
put something together.

A little something like so; ideally we'd allocate the hashtable since
NR_CPUS is kinda bloated, but it shows the idea I think.

And while this has loops in (the rehashing thing) their fwd progress
does not depend on other CPUs.

And I suspect that for the typical lock contention scenarios its
unlikely we ever really get into long rehashing chains.

---
  include/linux/lfsr.h|   49 
  kernel/locking/qspinlock_paravirt.h |  143 

  2 files changed, 178 insertions(+), 14 deletions(-)


This is a much better alternative.


--- /dev/null
+++ b/include/linux/lfsr.h
@@ -0,0 +1,49 @@
+#ifndef _LINUX_LFSR_H
+#define _LINUX_LFSR_H
+
+/*
+ * Simple Binary Galois Linear Feedback Shift Register
+ *
+ * http://en.wikipedia.org/wiki/Linear_feedback_shift_register
+ *
+ */
+
+extern void __lfsr_needs_more_taps(void);
+
+static __always_inline u32 lfsr_taps(int bits)
+{
+   if (bits ==  1) return 0x0001;
+   if (bits ==  2) return 0x0001;
+   if (bits ==  3) return 0x0003;
+   if (bits ==  4) return 0x0009;
+   if (bits ==  5) return 0x0012;
+   if (bits ==  6) return 0x0021;
+   if (bits ==  7) return 0x0041;
+   if (bits ==  8) return 0x008E;
+   if (bits ==  9) return 0x0108;
+   if (bits == 10) return 0x0204;
+   if (bits == 11) return 0x0402;
+   if (bits == 12) return 0x0829;
+   if (bits == 13) return 0x100D;
+   if (bits == 14) return 0x2015;
+
+   /*
+* For more taps see:
+*   http://users.ece.cmu.edu/~koopman/lfsr/index.html
+*/
+   __lfsr_needs_more_taps();
+
+   return 0;
+}
+
+static inline u32 lfsr(u32 val, int bits)
+{
+   u32 bit = val  1;
+
+   val= 1;
+   if (bit)
+   val ^= lfsr_taps(bits);
+   return val;
+}
+
+#endif /* _LINUX_LFSR_H */
--- a/kernel/locking/qspinlock_paravirt.h
+++ b/kernel/locking/qspinlock_paravirt.h
@@ -2,6 +2,9 @@
  #error do not include this file
  #endif

+#includelinux/hash.h
+#includelinux/lfsr.h
+
  /*
   * Implement paravirt qspinlocks; the general idea is to halt the vcpus 
instead
   * of spinning them.
@@ -107,7 +110,120 @@ static void pv_kick_node(struct mcs_spin
pv_kick(pn-cpu);
  }

-static DEFINE_PER_CPU(struct qspinlock *, __pv_lock_wait);
+/*
+ * Hash table using open addressing with an LFSR probe sequence.
+ *
+ * Since we should not be holding locks from NMI context (very rare indeed) the
+ * max load factor is 0.75, which is around the point where open addressing
+ * breaks down.
+ *
+ * Instead of probing just the immediate bucket we probe all buckets in the
+ * same cacheline.
+ *
+ * http://en.wikipedia.org/wiki/Hash_table#Open_addressing
+ *
+ */
+
+#define HB_RESERVED((struct qspinlock *)1)
+
+struct pv_hash_bucket {
+   struct qspinlock *lock;
+   int cpu;
+};
+
+/*
+ * XXX dynamic allocate using nr_cpu_ids instead...
+ */
+#define PV_LOCK_HASH_BITS  (2 + NR_CPUS_BITS)
+


As said here, we should make it dynamically allocated depending on 
num_possible_cpus().



+#if PV_LOCK_HASH_BITS  6
+#undef PV_LOCK_HASH_BITS
+#define PB_LOCK_HASH_BITS  6
+#endif
+
+#define PV_LOCK_HASH_SIZE  (1  PV_LOCK_HASH_BITS)
+
+static struct pv_hash_bucket __pv_lock_hash[PV_LOCK_HASH_SIZE] 
cacheline_aligned;
+
+#define PV_HB_PER_LINE (SMP_CACHE_BYTES / sizeof(struct 
pv_hash_bucket))
+
+static inline u32 hash_align(u32 hash)
+{
+   return hash  ~(PV_HB_PER_LINE - 1);
+}
+
+static struct qspinlock **pv_hash(struct qspinlock *lock)
+{
+   u32 hash = hash_ptr(lock, PV_LOCK_HASH_BITS);
+   struct pv_hash_bucket *hb, *end;
+
+   if (!hash)
+   hash = 1;
+
+   hb =__pv_lock_hash[hash_align(hash)];
+   for (;;) {
+   for (end = hb + PV_HB_PER_LINE; hb  end; hb++) {
+   if (cmpxchg(hb-lock, NULL, HB_RESERVED)) {
+   WRITE_ONCE(hb-cpu, smp_processor_id());
+   /*
+* Since we must read lock first and cpu
+* second, we must write cpu first and lock
+* second, therefore use HB_RESERVE to mark an
+* entry in use before writing the values.
+*
+* This can cause hb_hash_find() to not find a
+* cpu even though _Q_SLOW_VAL, this is not a
+* problem since we re-check l-locked before
+* going to sleep and the unlock will have
+* cleared l-locked already.
+*/
+   

[PATCH 1/1] Add virtio-input driver.

2015-03-19 Thread Gerd Hoffmann
virtio-input is basically evdev-events-over-virtio, so this driver isn't
much more than reading configuration from config space and forwarding
incoming events to the linux input layer.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 drivers/virtio/Kconfig|  10 ++
 drivers/virtio/Makefile   |   1 +
 drivers/virtio/virtio_input.c | 313 ++
 include/uapi/linux/virtio_ids.h   |   1 +
 include/uapi/linux/virtio_input.h |  65 
 5 files changed, 390 insertions(+)
 create mode 100644 drivers/virtio/virtio_input.c
 create mode 100644 include/uapi/linux/virtio_input.h

diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index b546da5..cab9f3f 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -48,6 +48,16 @@ config VIRTIO_BALLOON
 
 If unsure, say M.
 
+config VIRTIO_INPUT
+   tristate Virtio input driver
+   depends on VIRTIO
+   depends on INPUT
+   ---help---
+This driver supports virtio input devices such as
+keyboards, mice and tablets.
+
+If unsure, say M.
+
  config VIRTIO_MMIO
tristate Platform bus driver for memory mapped virtio devices
depends on HAS_IOMEM
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index d85565b..41e30e3 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
 virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
 virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
 obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
+obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
new file mode 100644
index 000..2d425cf
--- /dev/null
+++ b/drivers/virtio/virtio_input.c
@@ -0,0 +1,313 @@
+#include linux/module.h
+#include linux/virtio.h
+#include linux/input.h
+
+#include uapi/linux/virtio_ids.h
+#include uapi/linux/virtio_input.h
+
+struct virtio_input {
+   struct virtio_device   *vdev;
+   struct input_dev   *idev;
+   char   name[64];
+   char   serial[64];
+   char   phys[64];
+   struct virtqueue   *evt, *sts;
+   struct virtio_input_event  evts[64];
+};
+
+static ssize_t serial_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct input_dev *idev = to_input_dev(dev);
+   struct virtio_input *vi = input_get_drvdata(idev);
+   return sprintf(buf, %s\n, vi-serial);
+}
+static DEVICE_ATTR_RO(serial);
+
+static struct attribute *dev_attrs[] = {
+   dev_attr_serial.attr,
+   NULL
+};
+
+static umode_t dev_attrs_are_visible(struct kobject *kobj,
+struct attribute *a, int n)
+{
+   struct device *dev = container_of(kobj, struct device, kobj);
+   struct input_dev *idev = to_input_dev(dev);
+   struct virtio_input *vi = input_get_drvdata(idev);
+
+   if (a == dev_attr_serial.attr  !strlen(vi-serial))
+   return 0;
+
+   return a-mode;
+}
+
+static struct attribute_group dev_attr_grp = {
+   .attrs =dev_attrs,
+   .is_visible =   dev_attrs_are_visible,
+};
+
+static const struct attribute_group *dev_attr_groups[] = {
+   dev_attr_grp,
+   NULL
+};
+
+static void virtinput_queue_evtbuf(struct virtio_input *vi,
+  struct virtio_input_event *evtbuf)
+{
+   struct scatterlist sg[1];
+
+   sg_init_one(sg, evtbuf, sizeof(*evtbuf));
+   virtqueue_add_inbuf(vi-evt, sg, 1, evtbuf, GFP_ATOMIC);
+}
+
+static void virtinput_recv_events(struct virtqueue *vq)
+{
+   struct virtio_input *vi = vq-vdev-priv;
+   struct virtio_input_event *event;
+   unsigned int len;
+
+   while ((event = virtqueue_get_buf(vi-evt, len)) != NULL) {
+   input_event(vi-idev,
+   le16_to_cpu(event-type),
+   le16_to_cpu(event-code),
+   le32_to_cpu(event-value));
+   virtinput_queue_evtbuf(vi, event);
+   }
+   virtqueue_kick(vq);
+}
+
+static int virtinput_send_status(struct virtio_input *vi,
+u16 type, u16 code, s32 value)
+{
+   struct virtio_input_event *stsbuf;
+   struct scatterlist sg[1];
+
+   stsbuf = kzalloc(sizeof(*stsbuf), GFP_ATOMIC);
+   if (!stsbuf)
+   return -ENOMEM;
+
+   stsbuf-type  = cpu_to_le16(type);
+   stsbuf-code  = cpu_to_le16(code);
+   stsbuf-value = cpu_to_le32(value);
+   sg_init_one(sg, stsbuf, sizeof(*stsbuf));
+   virtqueue_add_outbuf(vi-sts, sg, 1, stsbuf, GFP_ATOMIC);
+   virtqueue_kick(vi-sts);
+   return 0;
+}
+
+static void virtinput_recv_status(struct virtqueue *vq)
+{
+   struct virtio_input *vi = vq-vdev-priv;
+   struct virtio_input_event *stsbuf;
+   

[PATCH 0/1] Add virtio-input driver.

2015-03-19 Thread Gerd Hoffmann
  Hi,

This patch adds a virtio driver for input devices.

Specification:
  https://www.kraxel.org/cgit/virtio-spec/log/?h=virtio-input
  https://www.kraxel.org/virtio/virtio-v1.0-csprd03-virtio-input.html#x1-2640007

Qemu patches;
  https://lists.gnu.org/archive/html/qemu-devel/2015-03/threads.html#03973

Gerd Hoffmann (1):
  Add virtio-input driver.

 drivers/virtio/Kconfig|  10 ++
 drivers/virtio/Makefile   |   1 +
 drivers/virtio/virtio_input.c | 313 ++
 include/uapi/linux/virtio_ids.h   |   1 +
 include/uapi/linux/virtio_input.h |  65 
 5 files changed, 390 insertions(+)
 create mode 100644 drivers/virtio/virtio_input.c
 create mode 100644 include/uapi/linux/virtio_input.h

-- 
1.8.3.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 9/9] qspinlock,x86,kvm: Implement KVM support for paravirt qspinlock

2015-03-19 Thread Peter Zijlstra
On Wed, Mar 18, 2015 at 10:45:55PM -0400, Waiman Long wrote:
 On 03/16/2015 09:16 AM, Peter Zijlstra wrote:
 I do have some concern about this call site patching mechanism as the
 modification is not atomic. The spin_unlock() calls are in many places in
 the kernel. There is a possibility that a thread is calling a certain
 spin_unlock call site while it is being patched by another one with the
 alternative() function call.
 
 So far, I don't see any problem with bare metal where paravirt_patch_insns()
 is used to patch it to the move instruction. However, in a virtual guest
 enivornment where paravirt_patch_call() was used, there were situations
 where the system panic because of page fault on some invalid memory in the
 kthread. If you look at the paravirt_patch_call(), you will see:
 
 :
 b-opcode = 0xe8; /* call */
 b-delta = delta;
 
 If another CPU reads the instruction at the call site at the right moment,
 it will get the modified call instruction, but not the new delta value. It
 will then jump to a random location. I believe that was causing the system
 panic that I saw.
 
 So I think it is kind of risky to use it here unless we can guarantee that
 call site patching is atomic wrt other CPUs.

Just look at where the patching is done:

init/main.c:start_kernel()
  check_bugs()
alternative_instructions()
  apply_paravirt()

We're UP and not holding any locks, disable IRQs (see text_poke_early())
and have NMIs 'disabled'.
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 0/1] Add virtio-input driver.

2015-03-19 Thread Paolo Bonzini


On 19/03/2015 17:33, Michael S. Tsirkin wrote:
 On Thu, Mar 19, 2015 at 03:46:44PM +0100, Gerd Hoffmann wrote:
 Latest.  As far I know there never ever have been incompatible changes
 to the interface, and given this is userspace/kernel abi I don't expect
 that to happen in the future.
 
 More events are added though, are they not? And distros backport rundom
 subsets.
 So I worry: what happens e.g. if you migrate between hosts which expose
 slightly different subsets of events?
 Might e.g. a button get stuck because button-press event was
 sent but button-release wasn't?

I think this is the same as SCSI.  You can migrate between hosts which
expose slightly different command sets.

Paolo
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 8/9] qspinlock: Generic paravirt support

2015-03-19 Thread Peter Zijlstra
On Thu, Mar 19, 2015 at 01:25:36PM +0100, Peter Zijlstra wrote:
 +static struct qspinlock **pv_hash(struct qspinlock *lock)
 +{
 + u32 hash = hash_ptr(lock, PV_LOCK_HASH_BITS);
 + struct pv_hash_bucket *hb, *end;
 +
 + if (!hash)
 + hash = 1;
 +
 + hb = __pv_lock_hash[hash_align(hash)];
 + for (;;) {
 + for (end = hb + PV_HB_PER_LINE; hb  end; hb++) {
 + if (cmpxchg(hb-lock, NULL, HB_RESERVED)) {

That should be: !cmpxchg(), bit disturbing that that booted.

 + WRITE_ONCE(hb-cpu, smp_processor_id());
 + /*
 +  * Since we must read lock first and cpu
 +  * second, we must write cpu first and lock
 +  * second, therefore use HB_RESERVE to mark an
 +  * entry in use before writing the values.
 +  *
 +  * This can cause hb_hash_find() to not find a
 +  * cpu even though _Q_SLOW_VAL, this is not a
 +  * problem since we re-check l-locked before
 +  * going to sleep and the unlock will have
 +  * cleared l-locked already.
 +  */
 + smp_wmb(); /* matches rmb from pv_hash_find */
 + WRITE_ONCE(hb-lock, lock);
 + goto done;
 + }
 + }
 +
 + hash = lfsr(hash, PV_LOCK_HASH_BITS);
 + hb = __pv_lock_hash[hash_align(hash)];
 + }
 +
 +done:
 + return hb-lock;
 +}
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 0/1] Add virtio-input driver.

2015-03-19 Thread Michael S. Tsirkin
On Thu, Mar 19, 2015 at 10:13:10AM +0100, Gerd Hoffmann wrote:
   Hi,
 
 This patch adds a virtio driver for input devices.
 
 Specification:
   https://www.kraxel.org/cgit/virtio-spec/log/?h=virtio-input
   
 https://www.kraxel.org/virtio/virtio-v1.0-csprd03-virtio-input.html#x1-2640007


OK, I don't know which thread should I use for spec discussions.
Referring to that:

See file:///usr/include/linux/input.h.

Is likely not present on many systems, or might not include
the info you refer to.

 type, code and value are filled according to the linux input layer
 (evdev) interface

Which version?  How will non-linux guests know what to implement?


 
 Qemu patches;
   https://lists.gnu.org/archive/html/qemu-devel/2015-03/threads.html#03973
 
 Gerd Hoffmann (1):
   Add virtio-input driver.
 
  drivers/virtio/Kconfig|  10 ++
  drivers/virtio/Makefile   |   1 +
  drivers/virtio/virtio_input.c | 313 
 ++
  include/uapi/linux/virtio_ids.h   |   1 +
  include/uapi/linux/virtio_input.h |  65 
  5 files changed, 390 insertions(+)
  create mode 100644 drivers/virtio/virtio_input.c
  create mode 100644 include/uapi/linux/virtio_input.h
 
 -- 
 1.8.3.1
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [Xen-devel] [PATCH 0/9] qspinlock stuff -v15

2015-03-19 Thread Peter Zijlstra
On Thu, Mar 19, 2015 at 06:01:34PM +, David Vrabel wrote:
 This seems work for me, but I've not got time to give it a more thorough
 testing.
 
 You can fold this into your series.

Thanks!

 There doesn't seem to be a way to disable QUEUE_SPINLOCKS when supported by
 the arch, is this intentional?  If so, the existing ticketlock code could go.

Yeah, its left as a rudiment such that if we find issues with the
qspinlock code we can 'revert' with a trivial patch. If no issues show
up we can rip out all the old code in a subsequent release.
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 0/1] Add virtio-input driver.

2015-03-19 Thread Gerd Hoffmann
On Do, 2015-03-19 at 14:35 +0100, Michael S. Tsirkin wrote:
 On Thu, Mar 19, 2015 at 10:13:10AM +0100, Gerd Hoffmann wrote:
Hi,
  
  This patch adds a virtio driver for input devices.
  
  Specification:
https://www.kraxel.org/cgit/virtio-spec/log/?h=virtio-input

  https://www.kraxel.org/virtio/virtio-v1.0-csprd03-virtio-input.html#x1-2640007
 
 
 OK, I don't know which thread should I use for spec discussions.
 Referring to that:
 
   See file:///usr/include/linux/input.h.
 
 Is likely not present on many systems, or might not include
 the info you refer to.

Dunno what the best way to deal with it is.  Link to the version online
@ kernel.org instead maybe?

  type, code and value are filled according to the linux input layer
  (evdev) interface
 
 Which version?

Latest.  As far I know there never ever have been incompatible changes
to the interface, and given this is userspace/kernel abi I don't expect
that to happen in the future.

   How will non-linux guests know what to implement?

There are some docs on the linux input layer and evdev events in
Documentation/input/ in the kernel tree.

cheers,
  Gerd


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 4/4] virtio_pci: drop msi_off on probe

2015-03-19 Thread Michael S. Tsirkin
pci core now disables msi on probe automatically,
drop this from device-specific code.

Cc: Bjorn Helgaas bhelg...@google.com
Cc: linux-...@vger.kernel.org
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/virtio/virtio_pci_common.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/virtio/virtio_pci_common.c 
b/drivers/virtio/virtio_pci_common.c
index e894eb2..806bb2c 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -501,9 +501,6 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
INIT_LIST_HEAD(vp_dev-virtqueues);
spin_lock_init(vp_dev-lock);
 
-   /* Disable MSI/MSIX to bring device to a known good state. */
-   pci_msi_off(pci_dev);
-
/* enable the device */
rc = pci_enable_device(pci_dev);
if (rc)
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 9/9] qspinlock, x86, kvm: Implement KVM support for paravirt qspinlock

2015-03-19 Thread Waiman Long

On 03/19/2015 06:01 AM, Peter Zijlstra wrote:

On Wed, Mar 18, 2015 at 10:45:55PM -0400, Waiman Long wrote:

On 03/16/2015 09:16 AM, Peter Zijlstra wrote:
I do have some concern about this call site patching mechanism as the
modification is not atomic. The spin_unlock() calls are in many places in
the kernel. There is a possibility that a thread is calling a certain
spin_unlock call site while it is being patched by another one with the
alternative() function call.

So far, I don't see any problem with bare metal where paravirt_patch_insns()
is used to patch it to the move instruction. However, in a virtual guest
enivornment where paravirt_patch_call() was used, there were situations
where the system panic because of page fault on some invalid memory in the
kthread. If you look at the paravirt_patch_call(), you will see:

 :
b-opcode = 0xe8; /* call */
b-delta = delta;

If another CPU reads the instruction at the call site at the right moment,
it will get the modified call instruction, but not the new delta value. It
will then jump to a random location. I believe that was causing the system
panic that I saw.

So I think it is kind of risky to use it here unless we can guarantee that
call site patching is atomic wrt other CPUs.

Just look at where the patching is done:

init/main.c:start_kernel()
   check_bugs()
 alternative_instructions()
   apply_paravirt()

We're UP and not holding any locks, disable IRQs (see text_poke_early())
and have NMIs 'disabled'.


You are probably right. The initial apply_paravirt() was done before the 
SMP boot. Subsequent ones were at kernel module load time. I put a 
counter in the __native_queue_spin_unlock() and it registered 26949 
unlock calls in a 16-cpu guest before it got patched out.


The panic that I observed before might be due to some coding error of my 
own.


-Longman
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 1/1] Add virtio-input driver.

2015-03-19 Thread Dmitry Torokhov
On Thu, Mar 19, 2015 at 01:29:49PM +0100, David Herrmann wrote:
 Hi
 
 (CC: Dmitry)
 
 On Thu, Mar 19, 2015 at 10:13 AM, Gerd Hoffmann kra...@redhat.com wrote:
  virtio-input is basically evdev-events-over-virtio, so this driver isn't
  much more than reading configuration from config space and forwarding
  incoming events to the linux input layer.
 
  Signed-off-by: Gerd Hoffmann kra...@redhat.com
  ---
   drivers/virtio/Kconfig|  10 ++
   drivers/virtio/Makefile   |   1 +
   drivers/virtio/virtio_input.c | 313 
  ++
   include/uapi/linux/virtio_ids.h   |   1 +
   include/uapi/linux/virtio_input.h |  65 
   5 files changed, 390 insertions(+)
   create mode 100644 drivers/virtio/virtio_input.c
   create mode 100644 include/uapi/linux/virtio_input.h
 
  diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
  index b546da5..cab9f3f 100644
  --- a/drivers/virtio/Kconfig
  +++ b/drivers/virtio/Kconfig
  @@ -48,6 +48,16 @@ config VIRTIO_BALLOON
 
   If unsure, say M.
 
  +config VIRTIO_INPUT
  +   tristate Virtio input driver
  +   depends on VIRTIO
  +   depends on INPUT
  +   ---help---
  +This driver supports virtio input devices such as
  +keyboards, mice and tablets.
  +
  +If unsure, say M.
  +
config VIRTIO_MMIO
  tristate Platform bus driver for memory mapped virtio devices
  depends on HAS_IOMEM
  diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
  index d85565b..41e30e3 100644
  --- a/drivers/virtio/Makefile
  +++ b/drivers/virtio/Makefile
  @@ -4,3 +4,4 @@ obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
   virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
   virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
   obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
  +obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
  diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
  new file mode 100644
  index 000..2d425cf
  --- /dev/null
  +++ b/drivers/virtio/virtio_input.c
  @@ -0,0 +1,313 @@
  +#include linux/module.h
  +#include linux/virtio.h
  +#include linux/input.h
  +
  +#include uapi/linux/virtio_ids.h
  +#include uapi/linux/virtio_input.h
  +
  +struct virtio_input {
  +   struct virtio_device   *vdev;
  +   struct input_dev   *idev;
  +   char   name[64];
  +   char   serial[64];
  +   char   phys[64];
  +   struct virtqueue   *evt, *sts;
  +   struct virtio_input_event  evts[64];
  +};
  +
  +static ssize_t serial_show(struct device *dev,
  +  struct device_attribute *attr, char *buf)
  +{
  +   struct input_dev *idev = to_input_dev(dev);
  +   struct virtio_input *vi = input_get_drvdata(idev);
  +   return sprintf(buf, %s\n, vi-serial);
  +}
  +static DEVICE_ATTR_RO(serial);

What is serial? Serial number?

  +
  +static struct attribute *dev_attrs[] = {
  +   dev_attr_serial.attr,
  +   NULL
  +};
  +
  +static umode_t dev_attrs_are_visible(struct kobject *kobj,
  +struct attribute *a, int n)
  +{
  +   struct device *dev = container_of(kobj, struct device, kobj);
  +   struct input_dev *idev = to_input_dev(dev);
  +   struct virtio_input *vi = input_get_drvdata(idev);
  +
  +   if (a == dev_attr_serial.attr  !strlen(vi-serial))
  +   return 0;
  +
  +   return a-mode;
  +}
  +
  +static struct attribute_group dev_attr_grp = {
  +   .attrs =dev_attrs,
  +   .is_visible =   dev_attrs_are_visible,
  +};
  +
  +static const struct attribute_group *dev_attr_groups[] = {
  +   dev_attr_grp,
  +   NULL
  +};
  +
  +static void virtinput_queue_evtbuf(struct virtio_input *vi,
  +  struct virtio_input_event *evtbuf)
  +{
  +   struct scatterlist sg[1];
  +
  +   sg_init_one(sg, evtbuf, sizeof(*evtbuf));
  +   virtqueue_add_inbuf(vi-evt, sg, 1, evtbuf, GFP_ATOMIC);
  +}
  +
  +static void virtinput_recv_events(struct virtqueue *vq)
  +{
  +   struct virtio_input *vi = vq-vdev-priv;
  +   struct virtio_input_event *event;
  +   unsigned int len;
  +
  +   while ((event = virtqueue_get_buf(vi-evt, len)) != NULL) {
  +   input_event(vi-idev,
  +   le16_to_cpu(event-type),
  +   le16_to_cpu(event-code),
  +   le32_to_cpu(event-value));
  +   virtinput_queue_evtbuf(vi, event);
  +   }
  +   virtqueue_kick(vq);
  +}
  +
  +static int virtinput_send_status(struct virtio_input *vi,
  +u16 type, u16 code, s32 value)
  +{
  +   struct virtio_input_event *stsbuf;
  +   struct scatterlist sg[1];
  +
  +   stsbuf = kzalloc(sizeof(*stsbuf), GFP_ATOMIC);
  +   if (!stsbuf)
  +   

Re: [PATCH 1/1] Add virtio-input driver.

2015-03-19 Thread David Herrmann
Hi

(CC: Dmitry)

On Thu, Mar 19, 2015 at 10:13 AM, Gerd Hoffmann kra...@redhat.com wrote:
 virtio-input is basically evdev-events-over-virtio, so this driver isn't
 much more than reading configuration from config space and forwarding
 incoming events to the linux input layer.

 Signed-off-by: Gerd Hoffmann kra...@redhat.com
 ---
  drivers/virtio/Kconfig|  10 ++
  drivers/virtio/Makefile   |   1 +
  drivers/virtio/virtio_input.c | 313 
 ++
  include/uapi/linux/virtio_ids.h   |   1 +
  include/uapi/linux/virtio_input.h |  65 
  5 files changed, 390 insertions(+)
  create mode 100644 drivers/virtio/virtio_input.c
  create mode 100644 include/uapi/linux/virtio_input.h

 diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
 index b546da5..cab9f3f 100644
 --- a/drivers/virtio/Kconfig
 +++ b/drivers/virtio/Kconfig
 @@ -48,6 +48,16 @@ config VIRTIO_BALLOON

  If unsure, say M.

 +config VIRTIO_INPUT
 +   tristate Virtio input driver
 +   depends on VIRTIO
 +   depends on INPUT
 +   ---help---
 +This driver supports virtio input devices such as
 +keyboards, mice and tablets.
 +
 +If unsure, say M.
 +
   config VIRTIO_MMIO
 tristate Platform bus driver for memory mapped virtio devices
 depends on HAS_IOMEM
 diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
 index d85565b..41e30e3 100644
 --- a/drivers/virtio/Makefile
 +++ b/drivers/virtio/Makefile
 @@ -4,3 +4,4 @@ obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
  virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
  virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
  obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
 +obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
 diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
 new file mode 100644
 index 000..2d425cf
 --- /dev/null
 +++ b/drivers/virtio/virtio_input.c
 @@ -0,0 +1,313 @@
 +#include linux/module.h
 +#include linux/virtio.h
 +#include linux/input.h
 +
 +#include uapi/linux/virtio_ids.h
 +#include uapi/linux/virtio_input.h
 +
 +struct virtio_input {
 +   struct virtio_device   *vdev;
 +   struct input_dev   *idev;
 +   char   name[64];
 +   char   serial[64];
 +   char   phys[64];
 +   struct virtqueue   *evt, *sts;
 +   struct virtio_input_event  evts[64];
 +};
 +
 +static ssize_t serial_show(struct device *dev,
 +  struct device_attribute *attr, char *buf)
 +{
 +   struct input_dev *idev = to_input_dev(dev);
 +   struct virtio_input *vi = input_get_drvdata(idev);
 +   return sprintf(buf, %s\n, vi-serial);
 +}
 +static DEVICE_ATTR_RO(serial);
 +
 +static struct attribute *dev_attrs[] = {
 +   dev_attr_serial.attr,
 +   NULL
 +};
 +
 +static umode_t dev_attrs_are_visible(struct kobject *kobj,
 +struct attribute *a, int n)
 +{
 +   struct device *dev = container_of(kobj, struct device, kobj);
 +   struct input_dev *idev = to_input_dev(dev);
 +   struct virtio_input *vi = input_get_drvdata(idev);
 +
 +   if (a == dev_attr_serial.attr  !strlen(vi-serial))
 +   return 0;
 +
 +   return a-mode;
 +}
 +
 +static struct attribute_group dev_attr_grp = {
 +   .attrs =dev_attrs,
 +   .is_visible =   dev_attrs_are_visible,
 +};
 +
 +static const struct attribute_group *dev_attr_groups[] = {
 +   dev_attr_grp,
 +   NULL
 +};
 +
 +static void virtinput_queue_evtbuf(struct virtio_input *vi,
 +  struct virtio_input_event *evtbuf)
 +{
 +   struct scatterlist sg[1];
 +
 +   sg_init_one(sg, evtbuf, sizeof(*evtbuf));
 +   virtqueue_add_inbuf(vi-evt, sg, 1, evtbuf, GFP_ATOMIC);
 +}
 +
 +static void virtinput_recv_events(struct virtqueue *vq)
 +{
 +   struct virtio_input *vi = vq-vdev-priv;
 +   struct virtio_input_event *event;
 +   unsigned int len;
 +
 +   while ((event = virtqueue_get_buf(vi-evt, len)) != NULL) {
 +   input_event(vi-idev,
 +   le16_to_cpu(event-type),
 +   le16_to_cpu(event-code),
 +   le32_to_cpu(event-value));
 +   virtinput_queue_evtbuf(vi, event);
 +   }
 +   virtqueue_kick(vq);
 +}
 +
 +static int virtinput_send_status(struct virtio_input *vi,
 +u16 type, u16 code, s32 value)
 +{
 +   struct virtio_input_event *stsbuf;
 +   struct scatterlist sg[1];
 +
 +   stsbuf = kzalloc(sizeof(*stsbuf), GFP_ATOMIC);
 +   if (!stsbuf)
 +   return -ENOMEM;
 +
 +   stsbuf-type  = cpu_to_le16(type);
 +   stsbuf-code  = cpu_to_le16(code);
 +   stsbuf-value = cpu_to_le32(value);
 +   sg_init_one(sg, stsbuf, sizeof(*stsbuf));
 +   virtqueue_add_outbuf(vi-sts, sg, 

Re: [PATCH 0/1] Add virtio-input driver.

2015-03-19 Thread Michael S. Tsirkin
On Thu, Mar 19, 2015 at 03:46:44PM +0100, Gerd Hoffmann wrote:
 On Do, 2015-03-19 at 14:35 +0100, Michael S. Tsirkin wrote:
  On Thu, Mar 19, 2015 at 10:13:10AM +0100, Gerd Hoffmann wrote:
 Hi,
   
   This patch adds a virtio driver for input devices.
   
   Specification:
 https://www.kraxel.org/cgit/virtio-spec/log/?h=virtio-input
 
   https://www.kraxel.org/virtio/virtio-v1.0-csprd03-virtio-input.html#x1-2640007
  
  
  OK, I don't know which thread should I use for spec discussions.
  Referring to that:
  
  See file:///usr/include/linux/input.h.
  
  Is likely not present on many systems, or might not include
  the info you refer to.
 
 Dunno what the best way to deal with it is.  Link to the version online
 @ kernel.org instead maybe?
 
   type, code and value are filled according to the linux input layer
   (evdev) interface
  
  Which version?
 
 Latest.  As far I know there never ever have been incompatible changes
 to the interface, and given this is userspace/kernel abi I don't expect
 that to happen in the future.
 
How will non-linux guests know what to implement?
 
 There are some docs on the linux input layer and evdev events in
 Documentation/input/ in the kernel tree.
 
 cheers,
   Gerd


Also, the spec needs to be rewritten a bit more formally,
with conformance clauses separated from freetext description,
and linked to from appropriate section.

 motion events are send from the device send-sent

-- 
MST
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization