qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/6] xen-20171214-tag
@ 2017-12-15  0:27 Stefano Stabellini
  2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
  2017-12-15 11:13 ` [Qemu-devel] [PULL 0/6] xen-20171214-tag Peter Maydell
  0 siblings, 2 replies; 8+ messages in thread
From: Stefano Stabellini @ 2017-12-15  0:27 UTC (permalink / raw)
  To: peter.maydell, stefanha
  Cc: sstabellini, stefanha, anthony.perard, xen-devel, qemu-devel

The following changes since commit 0a0dc59d27527b78a195c2d838d28b7b49e5a639:

  Update version for v2.11.0 release (2017-12-13 14:31:09 +0000)

are available in the git repository at:

  git://xenbits.xen.org/people/sstabellini/qemu-dm.git tags/xen-20171214-tag

for you to fetch changes up to 2e63eb2becc228232f12a1ea30a91b2aa8c5cecd:

  xen/pt: Set is_express to avoid out-of-bounds write (2017-12-14 16:11:53 -0800)

----------------------------------------------------------------
Xen 2017/12/14

----------------------------------------------------------------
Owen Smith (4):
      ui: generate qcode to linux mappings
      xenfb: Use Input Handlers directly
      xenfb: Add [feature|request]-raw-pointer
      xenfb: activate input handlers for raw pointer devices

Paul Durrant (1):
      xen-disk: use an IOThread per instance

Simon Gaiser (1):
      xen/pt: Set is_express to avoid out-of-bounds write

 Makefile              |   1 +
 hw/block/trace-events |   7 ++
 hw/block/xen_disk.c   |  53 +++++++--
 hw/display/xenfb.c    | 294 ++++++++++++++++++++++++++------------------------
 hw/xen/xen_pt.c       |   1 +
 include/ui/input.h    |   3 +
 ui/input-keymap.c     |   1 +
 7 files changed, 215 insertions(+), 145 deletions(-)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance
  2017-12-15  0:27 [Qemu-devel] [PULL 0/6] xen-20171214-tag Stefano Stabellini
@ 2017-12-15  0:27 ` Stefano Stabellini
  2017-12-15  0:27   ` [Qemu-devel] [PULL 2/6] ui: generate qcode to linux mappings Stefano Stabellini
                     ` (4 more replies)
  2017-12-15 11:13 ` [Qemu-devel] [PULL 0/6] xen-20171214-tag Peter Maydell
  1 sibling, 5 replies; 8+ messages in thread
From: Stefano Stabellini @ 2017-12-15  0:27 UTC (permalink / raw)
  To: peter.maydell, stefanha
  Cc: sstabellini, stefanha, anthony.perard, xen-devel, qemu-devel,
	Paul Durrant

From: Paul Durrant <paul.durrant@citrix.com>

This patch allocates an IOThread object for each xen_disk instance and
sets the AIO context appropriately on connect. This allows processing
of I/O to proceed in parallel.

The patch also adds tracepoints into xen_disk to make it possible to
follow the state transtions of an instance in the log.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
 hw/block/trace-events |  7 +++++++
 hw/block/xen_disk.c   | 53 ++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index cb6767b..962a3bf 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -10,3 +10,10 @@ virtio_blk_submit_multireq(void *vdev, void *mrb, int start, int num_reqs, uint6
 # hw/block/hd-geometry.c
 hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d"
 hd_geometry_guess(void *blk, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "blk %p CHS %u %u %u trans %d"
+
+# hw/block/xen_disk.c
+xen_disk_alloc(char *name) "%s"
+xen_disk_init(char *name) "%s"
+xen_disk_connect(char *name) "%s"
+xen_disk_disconnect(char *name) "%s"
+xen_disk_free(char *name) "%s"
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index e431bd8..f74fcd4 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -27,10 +27,12 @@
 #include "hw/xen/xen_backend.h"
 #include "xen_blkif.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/iothread.h"
 #include "sysemu/block-backend.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
+#include "trace.h"
 
 /* ------------------------------------------------------------- */
 
@@ -125,6 +127,9 @@ struct XenBlkDev {
     DriveInfo           *dinfo;
     BlockBackend        *blk;
     QEMUBH              *bh;
+
+    IOThread            *iothread;
+    AioContext          *ctx;
 };
 
 /* ------------------------------------------------------------- */
@@ -596,9 +601,12 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
 static void qemu_aio_complete(void *opaque, int ret)
 {
     struct ioreq *ioreq = opaque;
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+
+    aio_context_acquire(blkdev->ctx);
 
     if (ret != 0) {
-        xen_pv_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n",
+        xen_pv_printf(&blkdev->xendev, 0, "%s I/O error\n",
                       ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
         ioreq->aio_errors++;
     }
@@ -607,10 +615,10 @@ static void qemu_aio_complete(void *opaque, int ret)
     if (ioreq->presync) {
         ioreq->presync = 0;
         ioreq_runio_qemu_aio(ioreq);
-        return;
+        goto done;
     }
     if (ioreq->aio_inflight > 0) {
-        return;
+        goto done;
     }
 
     if (xen_feature_grant_copy) {
@@ -647,16 +655,19 @@ static void qemu_aio_complete(void *opaque, int ret)
         }
     case BLKIF_OP_READ:
         if (ioreq->status == BLKIF_RSP_OKAY) {
-            block_acct_done(blk_get_stats(ioreq->blkdev->blk), &ioreq->acct);
+            block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct);
         } else {
-            block_acct_failed(blk_get_stats(ioreq->blkdev->blk), &ioreq->acct);
+            block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct);
         }
         break;
     case BLKIF_OP_DISCARD:
     default:
         break;
     }
-    qemu_bh_schedule(ioreq->blkdev->bh);
+    qemu_bh_schedule(blkdev->bh);
+
+done:
+    aio_context_release(blkdev->ctx);
 }
 
 static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
@@ -913,17 +924,29 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
 static void blk_bh(void *opaque)
 {
     struct XenBlkDev *blkdev = opaque;
+
+    aio_context_acquire(blkdev->ctx);
     blk_handle_requests(blkdev);
+    aio_context_release(blkdev->ctx);
 }
 
 static void blk_alloc(struct XenDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    Error *err = NULL;
+
+    trace_xen_disk_alloc(xendev->name);
 
     QLIST_INIT(&blkdev->inflight);
     QLIST_INIT(&blkdev->finished);
     QLIST_INIT(&blkdev->freelist);
-    blkdev->bh = qemu_bh_new(blk_bh, blkdev);
+
+    blkdev->iothread = iothread_create(xendev->name, &err);
+    assert(!err);
+
+    blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+    blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
+
     if (xen_mode != XEN_EMULATE) {
         batch_maps = 1;
     }
@@ -950,6 +973,8 @@ static int blk_init(struct XenDevice *xendev)
     int info = 0;
     char *directiosafe = NULL;
 
+    trace_xen_disk_init(xendev->name);
+
     /* read xenstore entries */
     if (blkdev->params == NULL) {
         char *h = NULL;
@@ -1062,6 +1087,8 @@ static int blk_connect(struct XenDevice *xendev)
     unsigned int i;
     uint32_t *domids;
 
+    trace_xen_disk_connect(xendev->name);
+
     /* read-only ? */
     if (blkdev->directiosafe) {
         qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;
@@ -1287,6 +1314,8 @@ static int blk_connect(struct XenDevice *xendev)
         blkdev->persistent_gnt_count = 0;
     }
 
+    blk_set_aio_context(blkdev->blk, blkdev->ctx);
+
     xen_be_bind_evtchn(&blkdev->xendev);
 
     xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, nr-ring-ref %u, "
@@ -1300,13 +1329,20 @@ static void blk_disconnect(struct XenDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
+    trace_xen_disk_disconnect(xendev->name);
+
+    aio_context_acquire(blkdev->ctx);
+
     if (blkdev->blk) {
+        blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
         blk_detach_dev(blkdev->blk, blkdev);
         blk_unref(blkdev->blk);
         blkdev->blk = NULL;
     }
     xen_pv_unbind_evtchn(&blkdev->xendev);
 
+    aio_context_release(blkdev->ctx);
+
     if (blkdev->sring) {
         xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring,
                         blkdev->nr_ring_ref);
@@ -1345,6 +1381,8 @@ static int blk_free(struct XenDevice *xendev)
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     struct ioreq *ioreq;
 
+    trace_xen_disk_free(xendev->name);
+
     blk_disconnect(xendev);
 
     while (!QLIST_EMPTY(&blkdev->freelist)) {
@@ -1360,6 +1398,7 @@ static int blk_free(struct XenDevice *xendev)
     g_free(blkdev->dev);
     g_free(blkdev->devtype);
     qemu_bh_delete(blkdev->bh);
+    iothread_destroy(blkdev->iothread);
     return 0;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 2/6] ui: generate qcode to linux mappings
  2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
@ 2017-12-15  0:27   ` Stefano Stabellini
  2017-12-15  0:28   ` [Qemu-devel] [PULL 3/6] xenfb: Use Input Handlers directly Stefano Stabellini
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Stefano Stabellini @ 2017-12-15  0:27 UTC (permalink / raw)
  To: peter.maydell, stefanha
  Cc: sstabellini, stefanha, anthony.perard, xen-devel, qemu-devel,
	Owen Smith

From: Owen Smith <owen.smith@citrix.com>

Use keycodedb to generate a qcode to linux mapping

Signed-off-by: Owen Smith <owen.smith@citrix.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
 Makefile           | 1 +
 include/ui/input.h | 3 +++
 ui/input-keymap.c  | 1 +
 3 files changed, 5 insertions(+)

diff --git a/Makefile b/Makefile
index ab0354c..0331c18 100644
--- a/Makefile
+++ b/Makefile
@@ -229,6 +229,7 @@ KEYCODEMAP_FILES = \
 		 ui/input-keymap-linux-to-qcode.c \
 		 ui/input-keymap-qcode-to-qnum.c \
 		 ui/input-keymap-qnum-to-qcode.c \
+		 ui/input-keymap-qcode-to-linux.c \
 		 $(NULL)
 
 GENERATED_FILES += $(KEYCODEMAP_FILES)
diff --git a/include/ui/input.h b/include/ui/input.h
index f8cee43..5cc76d6 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -77,4 +77,7 @@ extern const guint16 qemu_input_map_qcode_to_qnum[];
 extern const guint qemu_input_map_qnum_to_qcode_len;
 extern const guint16 qemu_input_map_qnum_to_qcode[];
 
+extern const guint qemu_input_map_qcode_to_linux_len;
+extern const guint16 qemu_input_map_qcode_to_linux[];
+
 #endif /* INPUT_H */
diff --git a/ui/input-keymap.c b/ui/input-keymap.c
index 3a19a16..663986a 100644
--- a/ui/input-keymap.c
+++ b/ui/input-keymap.c
@@ -8,6 +8,7 @@
 #include "ui/input-keymap-linux-to-qcode.c"
 #include "ui/input-keymap-qcode-to-qnum.c"
 #include "ui/input-keymap-qnum-to-qcode.c"
+#include "ui/input-keymap-qcode-to-linux.c"
 
 int qemu_input_linux_to_qcode(unsigned int lnx)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 3/6] xenfb: Use Input Handlers directly
  2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
  2017-12-15  0:27   ` [Qemu-devel] [PULL 2/6] ui: generate qcode to linux mappings Stefano Stabellini
@ 2017-12-15  0:28   ` Stefano Stabellini
  2017-12-15  0:28   ` [Qemu-devel] [PULL 4/6] xenfb: Add [feature|request]-raw-pointer Stefano Stabellini
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Stefano Stabellini @ 2017-12-15  0:28 UTC (permalink / raw)
  To: peter.maydell, stefanha
  Cc: sstabellini, stefanha, anthony.perard, xen-devel, qemu-devel,
	Owen Smith

From: Owen Smith <owen.smith@citrix.com>

Avoid the unneccessary calls through the input-legacy.c file by
using the qemu_input_handler_*() calls directly. This did require
reworking the event and sync handlers to use the reverse mapping
from qcode to linux using qemu_input_qcode_to_linux().
Removes the scancode2linux mapping, and supporting documention.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
 hw/display/xenfb.c | 274 ++++++++++++++++++++++++++---------------------------
 1 file changed, 137 insertions(+), 137 deletions(-)

diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 8e2547a..ed06efa 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -27,6 +27,7 @@
 #include "qemu/osdep.h"
 
 #include "hw/hw.h"
+#include "ui/input.h"
 #include "ui/console.h"
 #include "hw/xen/xen_backend.h"
 
@@ -51,9 +52,10 @@ struct common {
 struct XenInput {
     struct common c;
     int abs_pointer_wanted; /* Whether guest supports absolute pointer */
-    int button_state;       /* Last seen pointer button state */
-    int extended;
-    QEMUPutMouseEntry *qmouse;
+    QemuInputHandlerState *qkbd;
+    QemuInputHandlerState *qmou;
+    int axis[INPUT_AXIS__MAX];
+    int wheel;
 };
 
 #define UP_QUEUE 8
@@ -119,79 +121,6 @@ static void common_unbind(struct common *c)
 }
 
 /* -------------------------------------------------------------------- */
-
-#if 0
-/*
- * These two tables are not needed any more, but left in here
- * intentionally as documentation, to show how scancode2linux[]
- * was generated.
- *
- * Tables to map from scancode to Linux input layer keycode.
- * Scancodes are hardware-specific.  These maps assumes a
- * standard AT or PS/2 keyboard which is what QEMU feeds us.
- */
-const unsigned char atkbd_set2_keycode[512] = {
-
-     0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
-     0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
-     0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
-     0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
-     0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
-     0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
-     0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
-    82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
-
-      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
-    173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
-    159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
-    157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
-    226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
-      0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
-    110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
-
-};
-
-const unsigned char atkbd_unxlate_table[128] = {
-
-      0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
-     21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
-     35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
-     50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
-     11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
-    114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
-     71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
-     19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
-
-};
-#endif
-
-/*
- * for (i = 0; i < 128; i++) {
- *     scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
- *     scancode2linux[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
- * }
- */
-static const unsigned char scancode2linux[512] = {
-      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
-     80, 81, 82, 83, 99,  0, 86, 87, 88,117,  0,  0, 95,183,184,185,
-      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-     93,  0,  0, 89,  0,  0, 85, 91, 90, 92,  0, 94,  0,124,121,  0,
-
-      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    165,  0,  0,  0,  0,  0,  0,  0,  0,163,  0,  0, 96, 97,  0,  0,
-    113,140,164,  0,166,  0,  0,  0,  0,  0,255,  0,  0,  0,114,  0,
-    115,  0,150,  0,  0, 98,255, 99,100,  0,  0,  0,  0,  0,  0,  0,
-      0,  0,  0,  0,  0,119,119,102,103,104,  0,105,112,106,118,107,
-    108,109,110,111,  0,  0,  0,  0,  0,  0,  0,125,126,127,116,142,
-      0,  0,  0,143,  0,217,156,173,128,159,158,157,155,226,  0,112,
-      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-};
-
 /* Send an event to the keyboard frontend driver */
 static int xenfb_kbd_event(struct XenInput *xenfb,
 			   union xenkbd_in_event *event)
@@ -262,36 +191,28 @@ static int xenfb_send_position(struct XenInput *xenfb,
 
 /*
  * Send a key event from the client to the guest OS
- * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
+ * QEMU gives us a QCode.
  * We have to turn this into a Linux Input layer keycode.
  *
- * Extra complexity from the fact that with extended scancodes
- * (like those produced by arrow keys) this method gets called
- * twice, but we only want to send a single event. So we have to
- * track the '0xe0' scancode state & collapse the extended keys
- * as needed.
- *
  * Wish we could just send scancodes straight to the guest which
  * already has code for dealing with this...
  */
-static void xenfb_key_event(void *opaque, int scancode)
+static void xenfb_key_event(DeviceState *dev, QemuConsole *src,
+                            InputEvent *evt)
 {
-    struct XenInput *xenfb = opaque;
-    int down = 1;
+    struct XenInput *xenfb = (struct XenInput *)dev;
+    InputKeyEvent *key = evt->u.key.data;
+    int qcode = qemu_input_key_value_to_qcode(key->key);
+    int lnx;
 
-    if (scancode == 0xe0) {
-	xenfb->extended = 1;
-	return;
-    } else if (scancode & 0x80) {
-	scancode &= 0x7f;
-	down = 0;
-    }
-    if (xenfb->extended) {
-	scancode |= 0x80;
-	xenfb->extended = 0;
+    if (qcode < qemu_input_map_qcode_to_linux_len) {
+        lnx = qemu_input_map_qcode_to_linux[qcode];
+
+        if (lnx) {
+            trace_xenfb_key_event(xenfb, lnx, key->down);
+            xenfb_send_key(xenfb, key->down, lnx);
+        }
     }
-    trace_xenfb_key_event(opaque, scancode2linux[scancode], down);
-    xenfb_send_key(xenfb, down, scancode2linux[scancode]);
 }
 
 /*
@@ -303,45 +224,118 @@ static void xenfb_key_event(void *opaque, int scancode)
  * given any button up/down events, so have to track changes in
  * the button state.
  */
-static void xenfb_mouse_event(void *opaque,
-			      int dx, int dy, int dz, int button_state)
+static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src,
+                              InputEvent *evt)
 {
-    struct XenInput *xenfb = opaque;
-    QemuConsole *con = qemu_console_lookup_by_index(0);
+    struct XenInput *xenfb = (struct XenInput *)dev;
+    InputBtnEvent *btn;
+    InputMoveEvent *move;
+    QemuConsole *con;
     DisplaySurface *surface;
-    int dw, dh, i;
+    int scale;
+
+    switch (evt->type) {
+    case INPUT_EVENT_KIND_BTN:
+        btn = evt->u.btn.data;
+        switch (btn->button) {
+        case INPUT_BUTTON_LEFT:
+            xenfb_send_key(xenfb, btn->down, BTN_LEFT);
+            break;
+        case INPUT_BUTTON_RIGHT:
+            xenfb_send_key(xenfb, btn->down, BTN_LEFT + 1);
+            break;
+        case INPUT_BUTTON_MIDDLE:
+            xenfb_send_key(xenfb, btn->down, BTN_LEFT + 2);
+            break;
+        case INPUT_BUTTON_WHEEL_UP:
+            if (btn->down) {
+                xenfb->wheel--;
+            }
+            break;
+        case INPUT_BUTTON_WHEEL_DOWN:
+            if (btn->down) {
+                xenfb->wheel++;
+            }
+            break;
+        default:
+            break;
+        }
+        break;
 
-    if (!con) {
-        xen_pv_printf(&xenfb->c.xendev, 0, "No QEMU console available");
-        return;
+    case INPUT_EVENT_KIND_ABS:
+        move = evt->u.abs.data;
+        con = qemu_console_lookup_by_index(0);
+        if (!con) {
+            xen_pv_printf(&xenfb->c.xendev, 0, "No QEMU console available");
+            return;
+        }
+        surface = qemu_console_surface(con);
+        switch (move->axis) {
+        case INPUT_AXIS_X:
+            scale = surface_width(surface) - 1;
+            break;
+        case INPUT_AXIS_Y:
+            scale = surface_height(surface) - 1;
+            break;
+        default:
+            scale = 0x8000;
+            break;
+        }
+        xenfb->axis[move->axis] = move->value * scale / 0x7fff;
+        break;
+
+    case INPUT_EVENT_KIND_REL:
+        move = evt->u.rel.data;
+        xenfb->axis[move->axis] += move->value;
+        break;
+
+    default:
+        break;
     }
+}
 
-    surface = qemu_console_surface(con);
-    dw = surface_width(surface);
-    dh = surface_height(surface);
+static void xenfb_mouse_sync(DeviceState *dev)
+{
+    struct XenInput *xenfb = (struct XenInput *)dev;
 
-    trace_xenfb_mouse_event(opaque, dx, dy, dz, button_state,
+    trace_xenfb_mouse_event(xenfb, xenfb->axis[INPUT_AXIS_X],
+                            xenfb->axis[INPUT_AXIS_Y],
+                            xenfb->wheel, 0,
                             xenfb->abs_pointer_wanted);
-    if (xenfb->abs_pointer_wanted)
-	xenfb_send_position(xenfb,
-			    dx * (dw - 1) / 0x7fff,
-			    dy * (dh - 1) / 0x7fff,
-			    dz);
-    else
-	xenfb_send_motion(xenfb, dx, dy, dz);
-
-    for (i = 0 ; i < 8 ; i++) {
-	int lastDown = xenfb->button_state & (1 << i);
-	int down = button_state & (1 << i);
-	if (down == lastDown)
-	    continue;
-
-	if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
-	    return;
+    if (xenfb->abs_pointer_wanted) {
+        xenfb_send_position(xenfb, xenfb->axis[INPUT_AXIS_X],
+                            xenfb->axis[INPUT_AXIS_Y],
+                            xenfb->wheel);
+    } else {
+        xenfb_send_motion(xenfb, xenfb->axis[INPUT_AXIS_X],
+                          xenfb->axis[INPUT_AXIS_Y],
+                          xenfb->wheel);
+        xenfb->axis[INPUT_AXIS_X] = 0;
+        xenfb->axis[INPUT_AXIS_Y] = 0;
     }
-    xenfb->button_state = button_state;
+    xenfb->wheel = 0;
 }
 
+static QemuInputHandler xenfb_keyboard = {
+    .name  = "Xen PV Keyboard",
+    .mask  = INPUT_EVENT_MASK_KEY,
+    .event = xenfb_key_event,
+};
+
+static QemuInputHandler xenfb_abs_mouse = {
+    .name  = "Xen PV Mouse",
+    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
+    .event = xenfb_mouse_event,
+    .sync  = xenfb_mouse_sync,
+};
+
+static QemuInputHandler xenfb_rel_mouse = {
+    .name  = "Xen PV Mouse",
+    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
+    .event = xenfb_mouse_event,
+    .sync  = xenfb_mouse_sync,
+};
+
 static int input_init(struct XenDevice *xendev)
 {
     xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
@@ -357,7 +351,6 @@ static int input_initialise(struct XenDevice *xendev)
     if (rc != 0)
 	return rc;
 
-    qemu_add_kbd_event_handler(xenfb_key_event, in);
     return 0;
 }
 
@@ -370,24 +363,31 @@ static void input_connected(struct XenDevice *xendev)
         in->abs_pointer_wanted = 0;
     }
 
-    if (in->qmouse) {
-        qemu_remove_mouse_event_handler(in->qmouse);
+    if (in->qkbd) {
+        qemu_input_handler_unregister(in->qkbd);
+    }
+    if (in->qmou) {
+        qemu_input_handler_unregister(in->qmou);
     }
     trace_xenfb_input_connected(xendev, in->abs_pointer_wanted);
-    in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
-					      in->abs_pointer_wanted,
-					      "Xen PVFB Mouse");
+
+    in->qkbd = qemu_input_handler_register((DeviceState *)in, &xenfb_keyboard);
+    in->qmou = qemu_input_handler_register((DeviceState *)in,
+               in->abs_pointer_wanted ? &xenfb_abs_mouse : &xenfb_rel_mouse);
 }
 
 static void input_disconnect(struct XenDevice *xendev)
 {
     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
 
-    if (in->qmouse) {
-	qemu_remove_mouse_event_handler(in->qmouse);
-	in->qmouse = NULL;
+    if (in->qkbd) {
+        qemu_input_handler_unregister(in->qkbd);
+        in->qkbd = NULL;
+    }
+    if (in->qmou) {
+        qemu_input_handler_unregister(in->qmou);
+        in->qmou = NULL;
     }
-    qemu_add_kbd_event_handler(NULL, NULL);
     common_unbind(&in->c);
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 4/6] xenfb: Add [feature|request]-raw-pointer
  2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
  2017-12-15  0:27   ` [Qemu-devel] [PULL 2/6] ui: generate qcode to linux mappings Stefano Stabellini
  2017-12-15  0:28   ` [Qemu-devel] [PULL 3/6] xenfb: Use Input Handlers directly Stefano Stabellini
@ 2017-12-15  0:28   ` Stefano Stabellini
  2017-12-15  0:28   ` [Qemu-devel] [PULL 5/6] xenfb: activate input handlers for raw pointer devices Stefano Stabellini
  2017-12-15  0:28   ` [Qemu-devel] [PULL 6/6] xen/pt: Set is_express to avoid out-of-bounds write Stefano Stabellini
  4 siblings, 0 replies; 8+ messages in thread
From: Stefano Stabellini @ 2017-12-15  0:28 UTC (permalink / raw)
  To: peter.maydell, stefanha
  Cc: sstabellini, stefanha, anthony.perard, xen-devel, qemu-devel,
	Owen Smith

From: Owen Smith <owen.smith@citrix.com>

Writes "feature-raw-pointer" during init to indicate the backend
can pass raw unscaled values for absolute axes to the frontend.
Frontends set "request-raw-pointer" to indicate the backend should
not attempt to scale absolute values to console size.
"request-raw-pointer" is only valid if "request-abs-pointer" is
also set. Raw unscaled pointer values are in the range [0, 0x7fff]

"feature-raw-pointer" and "request-raw-pointer" added to Xen
header in commit 7868654ff7fe5e4a2eeae2b277644fa884a5031e

Signed-off-by: Owen Smith <owen.smith@citrix.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
 hw/display/xenfb.c | 47 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index ed06efa..776a2ce 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -52,6 +52,7 @@ struct common {
 struct XenInput {
     struct common c;
     int abs_pointer_wanted; /* Whether guest supports absolute pointer */
+    int raw_pointer_wanted; /* Whether guest supports raw (unscaled) pointer */
     QemuInputHandlerState *qkbd;
     QemuInputHandlerState *qmou;
     int axis[INPUT_AXIS__MAX];
@@ -264,24 +265,28 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src,
 
     case INPUT_EVENT_KIND_ABS:
         move = evt->u.abs.data;
-        con = qemu_console_lookup_by_index(0);
-        if (!con) {
-            xen_pv_printf(&xenfb->c.xendev, 0, "No QEMU console available");
-            return;
-        }
-        surface = qemu_console_surface(con);
-        switch (move->axis) {
-        case INPUT_AXIS_X:
-            scale = surface_width(surface) - 1;
-            break;
-        case INPUT_AXIS_Y:
-            scale = surface_height(surface) - 1;
-            break;
-        default:
-            scale = 0x8000;
-            break;
+        if (xenfb->raw_pointer_wanted) {
+            xenfb->axis[move->axis] = move->value;
+        } else {
+            con = qemu_console_lookup_by_index(0);
+            if (!con) {
+                xen_pv_printf(&xenfb->c.xendev, 0, "No QEMU console available");
+                return;
+            }
+            surface = qemu_console_surface(con);
+            switch (move->axis) {
+            case INPUT_AXIS_X:
+                scale = surface_width(surface) - 1;
+                break;
+            case INPUT_AXIS_Y:
+                scale = surface_height(surface) - 1;
+                break;
+            default:
+                scale = 0x8000;
+                break;
+            }
+            xenfb->axis[move->axis] = move->value * scale / 0x7fff;
         }
-        xenfb->axis[move->axis] = move->value * scale / 0x7fff;
         break;
 
     case INPUT_EVENT_KIND_REL:
@@ -339,6 +344,7 @@ static QemuInputHandler xenfb_rel_mouse = {
 static int input_init(struct XenDevice *xendev)
 {
     xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
+    xenstore_write_be_int(xendev, "feature-raw-pointer", 1);
     return 0;
 }
 
@@ -362,6 +368,13 @@ static void input_connected(struct XenDevice *xendev)
                              &in->abs_pointer_wanted) == -1) {
         in->abs_pointer_wanted = 0;
     }
+    if (xenstore_read_fe_int(xendev, "request-raw-pointer",
+                             &in->raw_pointer_wanted) == -1) {
+        in->raw_pointer_wanted = 0;
+    }
+    if (in->raw_pointer_wanted && in->abs_pointer_wanted == 0) {
+        xen_pv_printf(xendev, 0, "raw pointer set without abs pointer");
+    }
 
     if (in->qkbd) {
         qemu_input_handler_unregister(in->qkbd);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 5/6] xenfb: activate input handlers for raw pointer devices
  2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
                     ` (2 preceding siblings ...)
  2017-12-15  0:28   ` [Qemu-devel] [PULL 4/6] xenfb: Add [feature|request]-raw-pointer Stefano Stabellini
@ 2017-12-15  0:28   ` Stefano Stabellini
  2017-12-15  0:28   ` [Qemu-devel] [PULL 6/6] xen/pt: Set is_express to avoid out-of-bounds write Stefano Stabellini
  4 siblings, 0 replies; 8+ messages in thread
From: Stefano Stabellini @ 2017-12-15  0:28 UTC (permalink / raw)
  To: peter.maydell, stefanha
  Cc: sstabellini, stefanha, anthony.perard, xen-devel, qemu-devel,
	Owen Smith

From: Owen Smith <owen.smith@citrix.com>

If the frontend requests raw pointers, the input handlers must be
activated to have the input events delivered to the xenfb backend.
Without activation, the input events are delivered to handlers
registered earlier, which would be the emulated USB tablet or
emulated PS/2 mouse.
HVM xen_kbdfront can incorrectly scale absolute coordinates when
the display resolution is not 800x600.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
 hw/display/xenfb.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 776a2ce..d4fc0fa 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -387,6 +387,11 @@ static void input_connected(struct XenDevice *xendev)
     in->qkbd = qemu_input_handler_register((DeviceState *)in, &xenfb_keyboard);
     in->qmou = qemu_input_handler_register((DeviceState *)in,
                in->abs_pointer_wanted ? &xenfb_abs_mouse : &xenfb_rel_mouse);
+
+    if (in->raw_pointer_wanted) {
+        qemu_input_handler_activate(in->qkbd);
+        qemu_input_handler_activate(in->qmou);
+    }
 }
 
 static void input_disconnect(struct XenDevice *xendev)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 6/6] xen/pt: Set is_express to avoid out-of-bounds write
  2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
                     ` (3 preceding siblings ...)
  2017-12-15  0:28   ` [Qemu-devel] [PULL 5/6] xenfb: activate input handlers for raw pointer devices Stefano Stabellini
@ 2017-12-15  0:28   ` Stefano Stabellini
  4 siblings, 0 replies; 8+ messages in thread
From: Stefano Stabellini @ 2017-12-15  0:28 UTC (permalink / raw)
  To: peter.maydell, stefanha
  Cc: sstabellini, stefanha, anthony.perard, xen-devel, qemu-devel,
	Simon Gaiser

From: Simon Gaiser <hw42@ipsumj.de>

The passed-through device might be an express device. In this case the
old code allocated a too small emulated config space in
pci_config_alloc() since pci_config_size() returned the size for a
non-express device. This leads to an out-of-bound write in
xen_pt_config_reg_init(), which sometimes results in crashes. So set
is_express as already done for KVM in vfio-pci.

Shortened ASan report:

==17512==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x611000041648 at pc 0x55e0fdac51ff bp 0x7ffe4af07410 sp 0x7ffe4af07408
WRITE of size 2 at 0x611000041648 thread T0
    #0 0x55e0fdac51fe in memcpy /usr/include/x86_64-linux-gnu/bits/string3.h:53
    #1 0x55e0fdac51fe in stw_he_p include/qemu/bswap.h:330
    #2 0x55e0fdac51fe in stw_le_p include/qemu/bswap.h:379
    #3 0x55e0fdac51fe in pci_set_word include/hw/pci/pci.h:490
    #4 0x55e0fdac51fe in xen_pt_config_reg_init hw/xen/xen_pt_config_init.c:1991
    #5 0x55e0fdac51fe in xen_pt_config_init hw/xen/xen_pt_config_init.c:2067
    #6 0x55e0fdabcf4d in xen_pt_realize hw/xen/xen_pt.c:830
    #7 0x55e0fdf59666 in pci_qdev_realize hw/pci/pci.c:2034
    #8 0x55e0fdda7d3d in device_set_realized hw/core/qdev.c:914
[...]

0x611000041648 is located 8 bytes to the right of 256-byte region [0x611000041540,0x611000041640)
allocated by thread T0 here:
    #0 0x7ff596a94bb8 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xd9bb8)
    #1 0x7ff57da66580 in g_malloc0 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x50580)
    #2 0x55e0fdda7d3d in device_set_realized hw/core/qdev.c:914
[...]

Signed-off-by: Simon Gaiser <hw42@ipsumj.de>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
 hw/xen/xen_pt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index 9bba717..d57c6d3 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -946,6 +946,7 @@ static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data)
     k->exit = xen_pt_unregister_device;
     k->config_read = xen_pt_pci_read_config;
     k->config_write = xen_pt_pci_write_config;
+    k->is_express = 1; /* We might be */
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     dc->desc = "Assign an host PCI device with Xen";
     dc->props = xen_pci_passthrough_properties;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PULL 0/6] xen-20171214-tag
  2017-12-15  0:27 [Qemu-devel] [PULL 0/6] xen-20171214-tag Stefano Stabellini
  2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
@ 2017-12-15 11:13 ` Peter Maydell
  1 sibling, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2017-12-15 11:13 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Stefan Hajnoczi, Stefan Hajnoczi, Anthony PERARD, open list:X86,
	QEMU Developers

On 15 December 2017 at 00:27, Stefano Stabellini <sstabellini@kernel.org> wrote:
> The following changes since commit 0a0dc59d27527b78a195c2d838d28b7b49e5a639:
>
>   Update version for v2.11.0 release (2017-12-13 14:31:09 +0000)
>
> are available in the git repository at:
>
>   git://xenbits.xen.org/people/sstabellini/qemu-dm.git tags/xen-20171214-tag
>
> for you to fetch changes up to 2e63eb2becc228232f12a1ea30a91b2aa8c5cecd:
>
>   xen/pt: Set is_express to avoid out-of-bounds write (2017-12-14 16:11:53 -0800)
>
> ----------------------------------------------------------------
> Xen 2017/12/14
>
> ----------------------------------------------------------------
> Owen Smith (4):
>       ui: generate qcode to linux mappings
>       xenfb: Use Input Handlers directly
>       xenfb: Add [feature|request]-raw-pointer
>       xenfb: activate input handlers for raw pointer devices
>
> Paul Durrant (1):
>       xen-disk: use an IOThread per instance
>
> Simon Gaiser (1):
>       xen/pt: Set is_express to avoid out-of-bounds write

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-12-15 11:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-15  0:27 [Qemu-devel] [PULL 0/6] xen-20171214-tag Stefano Stabellini
2017-12-15  0:27 ` [Qemu-devel] [PULL 1/6] xen-disk: use an IOThread per instance Stefano Stabellini
2017-12-15  0:27   ` [Qemu-devel] [PULL 2/6] ui: generate qcode to linux mappings Stefano Stabellini
2017-12-15  0:28   ` [Qemu-devel] [PULL 3/6] xenfb: Use Input Handlers directly Stefano Stabellini
2017-12-15  0:28   ` [Qemu-devel] [PULL 4/6] xenfb: Add [feature|request]-raw-pointer Stefano Stabellini
2017-12-15  0:28   ` [Qemu-devel] [PULL 5/6] xenfb: activate input handlers for raw pointer devices Stefano Stabellini
2017-12-15  0:28   ` [Qemu-devel] [PULL 6/6] xen/pt: Set is_express to avoid out-of-bounds write Stefano Stabellini
2017-12-15 11:13 ` [Qemu-devel] [PULL 0/6] xen-20171214-tag Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).