[PATCH v2 04/18] drm/qxl: change the way slot is detected

2018-12-13 Thread Gerd Hoffmann
From: Frediano Ziglio 

Instead of relaying on surface type use the actual placement.
This allow to have different placement for a single type of
surface.

Signed-off-by: Frediano Ziglio 

[ kraxel: rebased, adapted to upstream changes ]

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index f9dddfe7d9..d015d4fff1 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -311,7 +311,8 @@ static inline uint64_t
 qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
unsigned long offset)
 {
-   struct qxl_memslot *slot = bo->type == QXL_GEM_DOMAIN_VRAM
+   struct qxl_memslot *slot =
+   (bo->tbo.mem.mem_type == TTM_PL_VRAM)
? >main_slot : >surfaces_slot;
 
/* TODO - need to hold one of the locks to read tbo.offset */
-- 
2.9.3

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


[PATCH v2 13/18] drm/qxl: use shadow bo directly

2018-12-13 Thread Gerd Hoffmann
Pass the shadow bo to qxl_io_create_primary() instead of expecting
qxl_io_create_primary to check bo->shadow.  Set is_primary flag on the
shadow bo.  Move the is_primary tracking into qxl_io_create_primary()
and qxl_io_destroy_primary() functions.

That simplifies primary surface tracking and the workflow in
qxl_primary_atomic_update().

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_cmd.c |  8 +++-
 drivers/gpu/drm/qxl/qxl_display.c | 33 +++--
 2 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index aed0242e11..fd9725bacb 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -372,6 +372,7 @@ void qxl_io_flush_surfaces(struct qxl_device *qdev)
 void qxl_io_destroy_primary(struct qxl_device *qdev)
 {
wait_for_io_cmd(qdev, 0, QXL_IO_DESTROY_PRIMARY_ASYNC);
+   qdev->primary_bo->is_primary = false;
qdev->primary_bo = NULL;
 }
 
@@ -388,11 +389,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, struct 
qxl_bo *bo)
create->width = bo->surf.width;
create->height = bo->surf.height;
create->stride = bo->surf.stride;
-   if (bo->shadow) {
-   create->mem = qxl_bo_physical_address(qdev, bo->shadow, 0);
-   } else {
-   create->mem = qxl_bo_physical_address(qdev, bo, 0);
-   }
+   create->mem = qxl_bo_physical_address(qdev, bo, 0);
 
DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr);
 
@@ -401,6 +398,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, struct 
qxl_bo *bo)
 
wait_for_io_cmd(qdev, 0, QXL_IO_CREATE_PRIMARY_ASYNC);
qdev->primary_bo = bo;
+   qdev->primary_bo->is_primary = true;
 }
 
 void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id)
diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 828e4f773c..204ae46c62 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -401,13 +401,15 @@ static int qxl_framebuffer_surface_dirty(struct 
drm_framebuffer *fb,
struct qxl_device *qdev = fb->dev->dev_private;
struct drm_clip_rect norect;
struct qxl_bo *qobj;
+   bool is_primary;
int inc = 1;
 
drm_modeset_lock_all(fb->dev);
 
qobj = gem_to_qxl_bo(fb->obj[0]);
/* if we aren't primary surface ignore this */
-   if (!qobj->is_primary) {
+   is_primary = qobj->shadow ? qobj->shadow->is_primary : qobj->is_primary;
+   if (!is_primary) {
drm_modeset_unlock_all(fb->dev);
return 0;
}
@@ -526,14 +528,13 @@ static void qxl_primary_atomic_update(struct drm_plane 
*plane,
 {
struct qxl_device *qdev = plane->dev->dev_private;
struct qxl_bo *bo = gem_to_qxl_bo(plane->state->fb->obj[0]);
-   struct qxl_bo *bo_old;
+   struct qxl_bo *bo_old, *primary;
struct drm_clip_rect norect = {
.x1 = 0,
.y1 = 0,
.x2 = plane->state->fb->width,
.y2 = plane->state->fb->height
};
-   bool same_shadow = false;
 
if (old_state->fb) {
bo_old = gem_to_qxl_bo(old_state->fb->obj[0]);
@@ -541,26 +542,13 @@ static void qxl_primary_atomic_update(struct drm_plane 
*plane,
bo_old = NULL;
}
 
-   if (bo == bo_old)
-   return;
+   primary = bo->shadow ? bo->shadow : bo;
 
-   if (bo_old && bo_old->shadow && bo->shadow &&
-   bo_old->shadow == bo->shadow) {
-   same_shadow = true;
-   }
-
-   if (bo_old && bo_old->is_primary) {
-   if (!same_shadow)
+   if (!primary->is_primary) {
+   if (qdev->primary_bo)
qxl_io_destroy_primary(qdev);
-   bo_old->is_primary = false;
-   }
-
-   if (!bo->is_primary) {
-   if (!same_shadow) {
-   qxl_io_create_primary(qdev, bo);
-   qxl_primary_apply_cursor(plane);
-   }
-   bo->is_primary = true;
+   qxl_io_create_primary(qdev, primary);
+   qxl_primary_apply_cursor(plane);
}
 
qxl_draw_dirty_fb(qdev, plane->state->fb, bo, 0, 0, , 1, 1);
@@ -756,6 +744,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane,
qxl_bo_create(qdev, user_bo->gem_base.size,
  true, true, QXL_GEM_DOMAIN_SURFACE, NULL,
  _bo->shadow);
+   user_bo->shadow->surf = user_bo->surf;
}
}
 
@@ -784,7 +773,7 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane,
user_bo = gem_to_qxl_bo(obj);
qxl_bo_unpin(user_bo);
 
-   if (user_bo->shadow && !user_bo->is_primary) {
+   if (user_bo->shadow && !user_bo->shadow->is_primary) {

[PATCH v2 02/18] drm/qxl: drop unused qxl_fb_virtual_address

2018-12-13 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 38c5a8b1df..7eabf4a9ed 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -308,13 +308,6 @@ void qxl_ring_free(struct qxl_ring *ring);
 void qxl_ring_init_hdr(struct qxl_ring *ring);
 int qxl_check_idle(struct qxl_ring *ring);
 
-static inline void *
-qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical)
-{
-   DRM_DEBUG_DRIVER("not implemented (%lu)\n", physical);
-   return 0;
-}
-
 static inline uint64_t
 qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
unsigned long offset)
-- 
2.9.3

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


[PATCH v2 18/18] drm/qxl: remove dead qxl fbdev emulation code

2018-12-13 Thread Gerd Hoffmann
Lovely diffstat, thanks to the new generic fbdev emulation.

 drm/qxl/Makefile   |2
 drm/qxl/qxl_draw.c |  232 
 drm/qxl/qxl_drv.h  |   21 ---
 drm/qxl/qxl_fb.c   |  300 -

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h  |  21 ---
 drivers/gpu/drm/qxl/qxl_draw.c | 232 ---
 drivers/gpu/drm/qxl/qxl_fb.c   | 300 -
 drivers/gpu/drm/qxl/Makefile   |   2 +-
 4 files changed, 1 insertion(+), 554 deletions(-)
 delete mode 100644 drivers/gpu/drm/qxl/qxl_fb.c

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 8c3af1cdbe..4a0331b3ff 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -220,8 +220,6 @@ struct qxl_device {
struct qxl_mman mman;
struct qxl_gem  gem;
 
-   struct drm_fb_helperfb_helper;
-
void *ram_physical;
 
struct qxl_ring *release_ring;
@@ -322,12 +320,6 @@ qxl_bo_physical_address(struct qxl_device *qdev, struct 
qxl_bo *bo,
return slot->high_bits | (bo->tbo.offset - slot->gpu_offset + offset);
 }
 
-/* qxl_fb.c */
-#define QXLFB_CONN_LIMIT 1
-
-int qxl_fbdev_init(struct qxl_device *qdev);
-void qxl_fbdev_fini(struct qxl_device *qdev);
-
 /* qxl_display.c */
 void qxl_display_read_client_monitors_config(struct qxl_device *qdev);
 int qxl_create_monitors_object(struct qxl_device *qdev);
@@ -432,9 +424,6 @@ int qxl_alloc_bo_reserved(struct qxl_device *qdev,
  struct qxl_bo **_bo);
 /* qxl drawing commands */
 
-void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image,
-   int stride /* filled in if 0 */);
-
 void qxl_draw_dirty_fb(struct qxl_device *qdev,
   struct drm_framebuffer *fb,
   struct qxl_bo *bo,
@@ -443,13 +432,6 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
   unsigned int num_clips, int inc,
   uint32_t dumb_shadow_offset);
 
-void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec);
-
-void qxl_draw_copyarea(struct qxl_device *qdev,
-  u32 width, u32 height,
-  u32 sx, u32 sy,
-  u32 dx, u32 dy);
-
 void qxl_release_free(struct qxl_device *qdev,
  struct qxl_release *release);
 
@@ -481,9 +463,6 @@ int qxl_gem_prime_mmap(struct drm_gem_object *obj,
 int qxl_irq_init(struct qxl_device *qdev);
 irqreturn_t qxl_irq_handler(int irq, void *arg);
 
-/* qxl_fb.c */
-bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj);
-
 int qxl_debugfs_add_files(struct qxl_device *qdev,
  struct drm_info_list *files,
  unsigned int nfiles);
diff --git a/drivers/gpu/drm/qxl/qxl_draw.c b/drivers/gpu/drm/qxl/qxl_draw.c
index 5313ad21c1..97c3f1a95a 100644
--- a/drivers/gpu/drm/qxl/qxl_draw.c
+++ b/drivers/gpu/drm/qxl/qxl_draw.c
@@ -109,152 +109,6 @@ make_drawable(struct qxl_device *qdev, int surface, 
uint8_t type,
return 0;
 }
 
-static int alloc_palette_object(struct qxl_device *qdev,
-   struct qxl_release *release,
-   struct qxl_bo **palette_bo)
-{
-   return qxl_alloc_bo_reserved(qdev, release,
-sizeof(struct qxl_palette) + 
sizeof(uint32_t) * 2,
-palette_bo);
-}
-
-static int qxl_palette_create_1bit(struct qxl_bo *palette_bo,
-  struct qxl_release *release,
-  const struct qxl_fb_image *qxl_fb_image)
-{
-   const struct fb_image *fb_image = _fb_image->fb_image;
-   uint32_t visual = qxl_fb_image->visual;
-   const uint32_t *pseudo_palette = qxl_fb_image->pseudo_palette;
-   struct qxl_palette *pal;
-   int ret;
-   uint32_t fgcolor, bgcolor;
-   static uint64_t unique; /* we make no attempt to actually set this
-* correctly globaly, since that would require
-* tracking all of our palettes. */
-   ret = qxl_bo_kmap(palette_bo, (void **));
-   if (ret)
-   return ret;
-   pal->num_ents = 2;
-   pal->unique = unique++;
-   if (visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) {
-   /* NB: this is the only used branch currently. */
-   fgcolor = pseudo_palette[fb_image->fg_color];
-   bgcolor = pseudo_palette[fb_image->bg_color];
-   } else {
-   fgcolor = fb_image->fg_color;
-   bgcolor = fb_image->bg_color;
-   }
-   pal->ents[0] = bgcolor;
-   pal->ents[1] = fgcolor;
-   qxl_bo_kunmap(palette_bo);
-   return 0;
-}
-
-void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image,
-   

[PATCH v2 14/18] drm/qxl: cover all crtcs in shadow bo.

2018-12-13 Thread Gerd Hoffmann
The qxl device supports only a single active framebuffer ("primary
surface" in spice terminology).  In multihead configurations are handled
by defining rectangles within the primary surface for each head/crtc.

Userspace which uses the qxl ioctl interface (xorg qxl driver) is aware
of this limitation and will setup framebuffers and crtcs accordingly.

Userspace which uses dumb framebuffers (xorg modesetting driver,
wayland) is not aware of this limitation and tries to use two
framebuffers (one for each crtc) instead.

The qxl kms driver already has the dumb bo separated from the primary
surface, by using a (shared) shadow bo as primary surface.  This is
needed to support pageflips without having to re-create the primary
surface.  The qxl driver will blit from the dumb bo to the shadow bo
instead.

So we can extend the shadow logic:  Maintain a global shadow bo (aka
primary surface), make it big enough that dumb bo's for all crtcs fit in
side-by-side.  Adjust the pageflip blits to place the heads next to each
other in the shadow.

With this patch in place multihead qxl works with wayland.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h |   5 +-
 drivers/gpu/drm/qxl/qxl_display.c | 120 +-
 drivers/gpu/drm/qxl/qxl_draw.c|   9 ++-
 3 files changed, 105 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 150b1a4f66..43c6df9cf9 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -230,6 +230,8 @@ struct qxl_device {
struct qxl_ram_header *ram_header;
 
struct qxl_bo *primary_bo;
+   struct qxl_bo *dumb_shadow_bo;
+   struct qxl_head *dumb_heads;
 
struct qxl_memslot main_slot;
struct qxl_memslot surfaces_slot;
@@ -437,7 +439,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
   struct qxl_bo *bo,
   unsigned int flags, unsigned int color,
   struct drm_clip_rect *clips,
-  unsigned int num_clips, int inc);
+  unsigned int num_clips, int inc,
+  uint32_t dumb_shadow_offset);
 
 void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec);
 
diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 204ae46c62..fc88826b69 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -323,6 +323,8 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc 
*crtc,
head.y = crtc->y;
if (qdev->monitors_config->count < i + 1)
qdev->monitors_config->count = i + 1;
+   if (qdev->primary_bo == qdev->dumb_shadow_bo)
+   head.x += qdev->dumb_heads[i].x;
} else if (i > 0) {
head.width = 0;
head.height = 0;
@@ -426,7 +428,7 @@ static int qxl_framebuffer_surface_dirty(struct 
drm_framebuffer *fb,
}
 
qxl_draw_dirty_fb(qdev, fb, qobj, flags, color,
- clips, num_clips, inc);
+ clips, num_clips, inc, 0);
 
drm_modeset_unlock_all(fb->dev);
 
@@ -535,6 +537,7 @@ static void qxl_primary_atomic_update(struct drm_plane 
*plane,
.x2 = plane->state->fb->width,
.y2 = plane->state->fb->height
};
+   uint32_t dumb_shadow_offset = 0;
 
if (old_state->fb) {
bo_old = gem_to_qxl_bo(old_state->fb->obj[0]);
@@ -551,7 +554,12 @@ static void qxl_primary_atomic_update(struct drm_plane 
*plane,
qxl_primary_apply_cursor(plane);
}
 
-   qxl_draw_dirty_fb(qdev, plane->state->fb, bo, 0, 0, , 1, 1);
+   if (bo->is_dumb)
+   dumb_shadow_offset =
+   qdev->dumb_heads[plane->state->crtc->index].x;
+
+   qxl_draw_dirty_fb(qdev, plane->state->fb, bo, 0, 0, , 1, 1,
+ dumb_shadow_offset);
 }
 
 static void qxl_primary_atomic_disable(struct drm_plane *plane,
@@ -707,12 +715,68 @@ static void qxl_cursor_atomic_disable(struct drm_plane 
*plane,
qxl_release_fence_buffer_objects(release);
 }
 
+static void qxl_update_dumb_head(struct qxl_device *qdev,
+int index, struct qxl_bo *bo)
+{
+   uint32_t width, height;
+
+   if (index >= qdev->monitors_config->max_allowed)
+   return;
+
+   if (bo && bo->is_dumb) {
+   width = bo->surf.width;
+   height = bo->surf.height;
+   } else {
+   width = 0;
+   height = 0;
+   }
+
+   if (qdev->dumb_heads[index].width == width &&
+   qdev->dumb_heads[index].height == height)
+   return;
+
+   DRM_DEBUG("#%d: %dx%d -> %dx%d\n", index,
+ qdev->dumb_heads[index].width,
+ qdev->dumb_heads[index].height,
+ width, height);
+  

[PATCH v2 16/18] drm/qxl: implement prime kmap/kunmap

2018-12-13 Thread Gerd Hoffmann
Generic fbdev emulation needs this.  Also: We must keep track of the
number of mappings now, so we don't unmap early in case two users want a
kmap of the same bo.  Add a sanity check to destroy callback to make
sure kmap/kunmap is balanced.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h|  1 +
 drivers/gpu/drm/qxl/qxl_object.c |  6 ++
 drivers/gpu/drm/qxl/qxl_prime.c  | 17 +
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 43c6df9cf9..8c3af1cdbe 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -84,6 +84,7 @@ struct qxl_bo {
struct ttm_bo_kmap_obj  kmap;
unsigned int pin_count;
void*kptr;
+   unsigned intmap_count;
int type;
 
/* Constant after initialization */
diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index 024c8dd317..4928fa6029 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -36,6 +36,7 @@ static void qxl_ttm_bo_destroy(struct ttm_buffer_object *tbo)
qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
 
qxl_surface_evict(qdev, bo, false);
+   WARN_ON_ONCE(bo->map_count > 0);
mutex_lock(>gem.mutex);
list_del_init(>list);
mutex_unlock(>gem.mutex);
@@ -131,6 +132,7 @@ int qxl_bo_kmap(struct qxl_bo *bo, void **ptr)
if (bo->kptr) {
if (ptr)
*ptr = bo->kptr;
+   bo->map_count++;
return 0;
}
r = ttm_bo_kmap(>tbo, 0, bo->tbo.num_pages, >kmap);
@@ -139,6 +141,7 @@ int qxl_bo_kmap(struct qxl_bo *bo, void **ptr)
bo->kptr = ttm_kmap_obj_virtual(>kmap, _iomem);
if (ptr)
*ptr = bo->kptr;
+   bo->map_count = 1;
return 0;
 }
 
@@ -180,6 +183,9 @@ void qxl_bo_kunmap(struct qxl_bo *bo)
 {
if (bo->kptr == NULL)
return;
+   bo->map_count--;
+   if (bo->map_count > 0)
+   return;
bo->kptr = NULL;
ttm_bo_kunmap(>kmap);
 }
diff --git a/drivers/gpu/drm/qxl/qxl_prime.c b/drivers/gpu/drm/qxl/qxl_prime.c
index a55dece118..708378844c 100644
--- a/drivers/gpu/drm/qxl/qxl_prime.c
+++ b/drivers/gpu/drm/qxl/qxl_prime.c
@@ -22,7 +22,7 @@
  * Authors: Andreas Pokorny
  */
 
-#include "qxl_drv.h"
+#include "qxl_object.h"
 
 /* Empty Implementations as there should not be any other driver for a virtual
  * device that might share buffers with qxl */
@@ -54,13 +54,22 @@ struct drm_gem_object *qxl_gem_prime_import_sg_table(
 
 void *qxl_gem_prime_vmap(struct drm_gem_object *obj)
 {
-   WARN_ONCE(1, "not implemented");
-   return ERR_PTR(-ENOSYS);
+   struct qxl_bo *bo = gem_to_qxl_bo(obj);
+   void *ptr;
+   int ret;
+
+   ret = qxl_bo_kmap(bo, );
+   if (ret < 0)
+   return ERR_PTR(ret);
+
+   return ptr;
 }
 
 void qxl_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
 {
-   WARN_ONCE(1, "not implemented");
+   struct qxl_bo *bo = gem_to_qxl_bo(obj);
+
+   qxl_bo_kunmap(bo);
 }
 
 int qxl_gem_prime_mmap(struct drm_gem_object *obj,
-- 
2.9.3

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


[PATCH v2 12/18] drm/qxl: track primary bo

2018-12-13 Thread Gerd Hoffmann
Track which bo is used as primary surface.  With that in place we don't
need the primary_created flag any more, we can just check the primary bo
pointer instead.

Also verify we don't already have a primary surface in
qxl_io_create_primary().

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h | 2 +-
 drivers/gpu/drm/qxl/qxl_cmd.c | 7 +--
 drivers/gpu/drm/qxl/qxl_display.c | 2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index cb767aaef6..150b1a4f66 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -229,7 +229,7 @@ struct qxl_device {
 
struct qxl_ram_header *ram_header;
 
-   unsigned int primary_created:1;
+   struct qxl_bo *primary_bo;
 
struct qxl_memslot main_slot;
struct qxl_memslot surfaces_slot;
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index 626e803f60..aed0242e11 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -372,13 +372,16 @@ void qxl_io_flush_surfaces(struct qxl_device *qdev)
 void qxl_io_destroy_primary(struct qxl_device *qdev)
 {
wait_for_io_cmd(qdev, 0, QXL_IO_DESTROY_PRIMARY_ASYNC);
-   qdev->primary_created = false;
+   qdev->primary_bo = NULL;
 }
 
 void qxl_io_create_primary(struct qxl_device *qdev, struct qxl_bo *bo)
 {
struct qxl_surface_create *create;
 
+   if (WARN_ON(qdev->primary_bo))
+   return;
+
DRM_DEBUG_DRIVER("qdev %p, ram_header %p\n", qdev, qdev->ram_header);
create = >ram_header->create_surface;
create->format = bo->surf.format;
@@ -397,7 +400,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, struct 
qxl_bo *bo)
create->type = QXL_SURF_TYPE_PRIMARY;
 
wait_for_io_cmd(qdev, 0, QXL_IO_CREATE_PRIMARY_ASYNC);
-   qdev->primary_created = true;
+   qdev->primary_bo = bo;
 }
 
 void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id)
diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 79dc8a1fa3..828e4f773c 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -302,7 +302,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc 
*crtc,
struct qxl_head head;
int oldcount, i = qcrtc->index;
 
-   if (!qdev->primary_created) {
+   if (!qdev->primary_bo) {
DRM_DEBUG_KMS("no primary surface, skip (%s)\n", reason);
return;
}
-- 
2.9.3

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


[PATCH v2 11/18] drm/qxl: drop unused offset parameter from qxl_io_create_primary()

2018-12-13 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h | 1 -
 drivers/gpu/drm/qxl/qxl_cmd.c | 7 +++
 drivers/gpu/drm/qxl/qxl_display.c | 2 +-
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 27e0a3fc08..cb767aaef6 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -385,7 +385,6 @@ void qxl_update_screen(struct qxl_device *qxl);
 /* qxl io operations (qxl_cmd.c) */
 
 void qxl_io_create_primary(struct qxl_device *qdev,
-  unsigned int offset,
   struct qxl_bo *bo);
 void qxl_io_destroy_primary(struct qxl_device *qdev);
 void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id);
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index 73ef41ac5f..626e803f60 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -375,8 +375,7 @@ void qxl_io_destroy_primary(struct qxl_device *qdev)
qdev->primary_created = false;
 }
 
-void qxl_io_create_primary(struct qxl_device *qdev,
-  unsigned int offset, struct qxl_bo *bo)
+void qxl_io_create_primary(struct qxl_device *qdev, struct qxl_bo *bo)
 {
struct qxl_surface_create *create;
 
@@ -387,9 +386,9 @@ void qxl_io_create_primary(struct qxl_device *qdev,
create->height = bo->surf.height;
create->stride = bo->surf.stride;
if (bo->shadow) {
-   create->mem = qxl_bo_physical_address(qdev, bo->shadow, offset);
+   create->mem = qxl_bo_physical_address(qdev, bo->shadow, 0);
} else {
-   create->mem = qxl_bo_physical_address(qdev, bo, offset);
+   create->mem = qxl_bo_physical_address(qdev, bo, 0);
}
 
DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr);
diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index a4bdcca715..79dc8a1fa3 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -557,7 +557,7 @@ static void qxl_primary_atomic_update(struct drm_plane 
*plane,
 
if (!bo->is_primary) {
if (!same_shadow) {
-   qxl_io_create_primary(qdev, 0, bo);
+   qxl_io_create_primary(qdev, bo);
qxl_primary_apply_cursor(plane);
}
bo->is_primary = true;
-- 
2.9.3

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


[PATCH v2 10/18] drm/qxl: move qxl_primary_apply_cursor to correct place

2018-12-13 Thread Gerd Hoffmann
The cursor must be set again after creating the primary surface.
Also drop the error message.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_display.c | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 1dde3b2ecb..a4bdcca715 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -533,7 +533,6 @@ static void qxl_primary_atomic_update(struct drm_plane 
*plane,
.x2 = plane->state->fb->width,
.y2 = plane->state->fb->height
};
-   int ret;
bool same_shadow = false;
 
if (old_state->fb) {
@@ -554,16 +553,13 @@ static void qxl_primary_atomic_update(struct drm_plane 
*plane,
if (!same_shadow)
qxl_io_destroy_primary(qdev);
bo_old->is_primary = false;
-
-   ret = qxl_primary_apply_cursor(plane);
-   if (ret)
-   DRM_ERROR(
-   "could not set cursor after creating primary");
}
 
if (!bo->is_primary) {
-   if (!same_shadow)
+   if (!same_shadow) {
qxl_io_create_primary(qdev, 0, bo);
+   qxl_primary_apply_cursor(plane);
+   }
bo->is_primary = true;
}
 
-- 
2.9.3

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


[PATCH v2 08/18] drm/qxl: use QXL_GEM_DOMAIN_SURFACE for shadow bo.

2018-12-13 Thread Gerd Hoffmann
The shadow bo is used as qxl surface, so allocate it as
QXL_GEM_DOMAIN_SURFACE.  Should usually be allocated in
PRIV ttm domain then, so this reduces VRAM memory pressure.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index ce0b9c40fc..1dde3b2ecb 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -758,7 +758,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane,
user_bo->shadow = old_bo->shadow;
} else {
qxl_bo_create(qdev, user_bo->gem_base.size,
- true, true, QXL_GEM_DOMAIN_VRAM, NULL,
+ true, true, QXL_GEM_DOMAIN_SURFACE, NULL,
  _bo->shadow);
}
}
-- 
2.9.3

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


[PATCH v2 09/18] drm/qxl: use QXL_GEM_DOMAIN_SURFACE for dumb gem objects

2018-12-13 Thread Gerd Hoffmann
dumb buffers are used as qxl surfaces, so allocate them as
QXL_GEM_DOMAIN_SURFACE.  Should usually be allocated in
PRIV ttm domain then, so this reduces VRAM memory pressure.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_dumb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c
index e3765739c3..272d19b677 100644
--- a/drivers/gpu/drm/qxl/qxl_dumb.c
+++ b/drivers/gpu/drm/qxl/qxl_dumb.c
@@ -59,7 +59,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv,
surf.stride = pitch;
surf.format = format;
r = qxl_gem_object_create_with_handle(qdev, file_priv,
- QXL_GEM_DOMAIN_VRAM,
+ QXL_GEM_DOMAIN_SURFACE,
  args->size, , ,
  );
if (r)
-- 
2.9.3

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


[PATCH v2 07/18] drm/qxl: allow both PRIV and VRAM placement for QXL_GEM_DOMAIN_SURFACE

2018-12-13 Thread Gerd Hoffmann
qxl surfaces (used for framebuffers and gem objects) can live in both
VRAM and PRIV ttm domains.  Update placement setup to include both.
Put PRIV first in the list so it is preferred, so VRAM will have more
room for objects which must be allocated there.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_object.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index 34eff8b21e..024c8dd317 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -60,8 +60,10 @@ void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 
domain, bool pinned)
qbo->placement.busy_placement = qbo->placements;
if (domain == QXL_GEM_DOMAIN_VRAM)
qbo->placements[c++].flags = TTM_PL_FLAG_CACHED | 
TTM_PL_FLAG_VRAM | pflag;
-   if (domain == QXL_GEM_DOMAIN_SURFACE)
+   if (domain == QXL_GEM_DOMAIN_SURFACE) {
qbo->placements[c++].flags = TTM_PL_FLAG_CACHED | 
TTM_PL_FLAG_PRIV | pflag;
+   qbo->placements[c++].flags = TTM_PL_FLAG_CACHED | 
TTM_PL_FLAG_VRAM | pflag;
+   }
if (domain == QXL_GEM_DOMAIN_CPU)
qbo->placements[c++].flags = TTM_PL_MASK_CACHING | 
TTM_PL_FLAG_SYSTEM | pflag;
if (!c)
-- 
2.9.3

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


[PATCH v2 06/18] drm/qxl: use separate offset spaces for the two slots / ttm memory types.

2018-12-13 Thread Gerd Hoffmann
Without that ttm offsets are not unique, they can refer to objects
in both VRAM and PRIV memory (aka main and surfaces slot).

One of those "why things didn't blow up without this" moments.
Probably offset conflicts are rare enough by pure luck.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h |  5 -
 drivers/gpu/drm/qxl/qxl_kms.c |  5 +++--
 drivers/gpu/drm/qxl/qxl_ttm.c | 10 +-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 3ebe66abf2..27e0a3fc08 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -136,6 +136,7 @@ struct qxl_memslot {
uint64_tstart_phys_addr;
uint64_tsize;
uint64_thigh_bits;
+   uint64_tgpu_offset;
 };
 
 enum {
@@ -312,8 +313,10 @@ qxl_bo_physical_address(struct qxl_device *qdev, struct 
qxl_bo *bo,
(bo->tbo.mem.mem_type == TTM_PL_VRAM)
? >main_slot : >surfaces_slot;
 
+   WARN_ON_ONCE((bo->tbo.offset & slot->gpu_offset) != slot->gpu_offset);
+
/* TODO - need to hold one of the locks to read tbo.offset */
-   return slot->high_bits | (bo->tbo.offset + offset);
+   return slot->high_bits | (bo->tbo.offset - slot->gpu_offset + offset);
 }
 
 /* qxl_fb.c */
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index 3c1753667d..82c764623f 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -83,10 +83,11 @@ static void setup_slot(struct qxl_device *qdev,
high_bits <<= (64 - (qdev->rom->slot_gen_bits + 
qdev->rom->slot_id_bits));
slot->high_bits = high_bits;
 
-   DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx\n",
+   DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx, gpu_offset 0x%lx\n",
 slot->index, slot->name,
 (unsigned long)slot->start_phys_addr,
-(unsigned long)slot->size);
+(unsigned long)slot->size,
+(unsigned long)slot->gpu_offset);
 }
 
 void qxl_reinit_memslots(struct qxl_device *qdev)
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index 886f61e94f..36ea993aac 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -100,6 +100,11 @@ static int qxl_invalidate_caches(struct ttm_bo_device 
*bdev, uint32_t flags)
 static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 struct ttm_mem_type_manager *man)
 {
+   struct qxl_device *qdev = qxl_get_qdev(bdev);
+   unsigned int gpu_offset_shift =
+   64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits + 8);
+   struct qxl_memslot *slot;
+
switch (type) {
case TTM_PL_SYSTEM:
/* System memory */
@@ -110,8 +115,11 @@ static int qxl_init_mem_type(struct ttm_bo_device *bdev, 
uint32_t type,
case TTM_PL_VRAM:
case TTM_PL_PRIV:
/* "On-card" video ram */
+   slot = (type == TTM_PL_VRAM) ?
+   >main_slot : >surfaces_slot;
+   slot->gpu_offset = (uint64_t)type << gpu_offset_shift;
man->func = _bo_manager_func;
-   man->gpu_offset = 0;
+   man->gpu_offset = slot->gpu_offset;
man->flags = TTM_MEMTYPE_FLAG_FIXED |
 TTM_MEMTYPE_FLAG_MAPPABLE;
man->available_caching = TTM_PL_MASK_CACHING;
-- 
2.9.3

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


[PATCH v2 05/18] drm/qxl: drop unused fields from struct qxl_device

2018-12-13 Thread Gerd Hoffmann
slot_id_bits and slot_gen_bits can be read directly from qxlrom instead.
va_slot_mask is never used anywhere.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h |  3 ---
 drivers/gpu/drm/qxl/qxl_kms.c | 10 ++
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index d015d4fff1..3ebe66abf2 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -232,9 +232,6 @@ struct qxl_device {
 
struct qxl_memslot main_slot;
struct qxl_memslot surfaces_slot;
-   uint8_t slot_id_bits;
-   uint8_t slot_gen_bits;
-   uint64_tva_slot_mask;
 
spinlock_t  release_lock;
struct idr  release_idr;
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index a9288100ae..3c1753667d 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -78,9 +78,9 @@ static void setup_slot(struct qxl_device *qdev,
 
slot->generation = qdev->rom->slot_generation;
high_bits = (qdev->rom->slots_start + slot->index)
-   << qdev->slot_gen_bits;
+   << qdev->rom->slot_gen_bits;
high_bits |= slot->generation;
-   high_bits <<= (64 - (qdev->slot_gen_bits + qdev->slot_id_bits));
+   high_bits <<= (64 - (qdev->rom->slot_gen_bits + 
qdev->rom->slot_id_bits));
slot->high_bits = high_bits;
 
DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx\n",
@@ -235,12 +235,6 @@ int qxl_device_init(struct qxl_device *qdev,
r = -ENOMEM;
goto cursor_ring_free;
}
-   /* TODO - slot initialization should happen on reset. where is our
-* reset handler? */
-   qdev->slot_gen_bits = qdev->rom->slot_gen_bits;
-   qdev->slot_id_bits = qdev->rom->slot_id_bits;
-   qdev->va_slot_mask =
-   (~(uint64_t)0) >> (qdev->slot_id_bits + qdev->slot_gen_bits);
 
idr_init(>release_idr);
spin_lock_init(>release_idr_lock);
-- 
2.9.3

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


[PATCH v2 03/18] drm/qxl: simplify slot management

2018-12-13 Thread Gerd Hoffmann
Drop pointless indirection, remove the mem_slots array and index
variables, drop dynamic allocation.  Store memslots in qxl_device
instead.

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/qxl/qxl_drv.h | 15 +
 drivers/gpu/drm/qxl/qxl_kms.c | 72 +--
 2 files changed, 36 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 7eabf4a9ed..f9dddfe7d9 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -130,9 +130,11 @@ struct qxl_mman {
 };
 
 struct qxl_memslot {
+   int index;
+   const char  *name;
uint8_t generation;
uint64_tstart_phys_addr;
-   uint64_tend_phys_addr;
+   uint64_tsize;
uint64_thigh_bits;
 };
 
@@ -228,11 +230,8 @@ struct qxl_device {
 
unsigned int primary_created:1;
 
-   struct qxl_memslot  *mem_slots;
-   uint8_t n_mem_slots;
-
-   uint8_t main_mem_slot;
-   uint8_t surfaces_mem_slot;
+   struct qxl_memslot main_slot;
+   struct qxl_memslot surfaces_slot;
uint8_t slot_id_bits;
uint8_t slot_gen_bits;
uint64_tva_slot_mask;
@@ -312,8 +311,8 @@ static inline uint64_t
 qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
unsigned long offset)
 {
-   int slot_id = bo->type == QXL_GEM_DOMAIN_VRAM ? qdev->main_mem_slot : 
qdev->surfaces_mem_slot;
-   struct qxl_memslot *slot = &(qdev->mem_slots[slot_id]);
+   struct qxl_memslot *slot = bo->type == QXL_GEM_DOMAIN_VRAM
+   ? >main_slot : >surfaces_slot;
 
/* TODO - need to hold one of the locks to read tbo.offset */
return slot->high_bits | (bo->tbo.offset + offset);
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index 15238a413f..a9288100ae 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -53,40 +53,46 @@ static bool qxl_check_device(struct qxl_device *qdev)
return true;
 }
 
-static void setup_hw_slot(struct qxl_device *qdev, int slot_index,
- struct qxl_memslot *slot)
+static void setup_hw_slot(struct qxl_device *qdev, struct qxl_memslot *slot)
 {
qdev->ram_header->mem_slot.mem_start = slot->start_phys_addr;
-   qdev->ram_header->mem_slot.mem_end = slot->end_phys_addr;
-   qxl_io_memslot_add(qdev, slot_index);
+   qdev->ram_header->mem_slot.mem_end = slot->start_phys_addr + slot->size;
+   qxl_io_memslot_add(qdev, qdev->rom->slots_start + slot->index);
 }
 
-static uint8_t setup_slot(struct qxl_device *qdev, uint8_t slot_index_offset,
-   unsigned long start_phys_addr, unsigned long end_phys_addr)
+static void setup_slot(struct qxl_device *qdev,
+  struct qxl_memslot *slot,
+  unsigned int slot_index,
+  const char *slot_name,
+  unsigned long start_phys_addr,
+  unsigned long size)
 {
uint64_t high_bits;
-   struct qxl_memslot *slot;
-   uint8_t slot_index;
 
-   slot_index = qdev->rom->slots_start + slot_index_offset;
-   slot = >mem_slots[slot_index];
+   slot->index = slot_index;
+   slot->name = slot_name;
slot->start_phys_addr = start_phys_addr;
-   slot->end_phys_addr = end_phys_addr;
+   slot->size = size;
 
-   setup_hw_slot(qdev, slot_index, slot);
+   setup_hw_slot(qdev, slot);
 
slot->generation = qdev->rom->slot_generation;
-   high_bits = slot_index << qdev->slot_gen_bits;
+   high_bits = (qdev->rom->slots_start + slot->index)
+   << qdev->slot_gen_bits;
high_bits |= slot->generation;
high_bits <<= (64 - (qdev->slot_gen_bits + qdev->slot_id_bits));
slot->high_bits = high_bits;
-   return slot_index;
+
+   DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx\n",
+slot->index, slot->name,
+(unsigned long)slot->start_phys_addr,
+(unsigned long)slot->size);
 }
 
 void qxl_reinit_memslots(struct qxl_device *qdev)
 {
-   setup_hw_slot(qdev, qdev->main_mem_slot, 
>mem_slots[qdev->main_mem_slot]);
-   setup_hw_slot(qdev, qdev->surfaces_mem_slot, 
>mem_slots[qdev->surfaces_mem_slot]);
+   setup_hw_slot(qdev, >main_slot);
+   setup_hw_slot(qdev, >surfaces_slot);
 }
 
 static void qxl_gc_work(struct work_struct *work)
@@ -231,22 +237,11 @@ int qxl_device_init(struct qxl_device *qdev,
}
/* TODO - slot initialization should happen on reset. where is our
 * reset handler? */
-   qdev->n_mem_slots = qdev->rom->slots_end;
qdev->slot_gen_bits = qdev->rom->slot_gen_bits;
qdev->slot_id_bits = qdev->rom->slot_id_bits;
qdev->va_slot_mask =
(~(uint64_t)0) >> (qdev->slot_id_bits 

CISTI'2019 - Doctoral Symposium

2018-12-13 Thread Maria Lemos
* Proceedings published in IEEE Xplore and indexed by ISI, Scopus, etc.


---
Doctoral Symposium of CISTI'2019 - 14th Iberian Conference on Information 
Systems and Technologies
   Coimbra, Portugal, 19 - 22 
June 2019
   
http://www.cisti.eu/ 




The purpose of CISTI'2019’s Doctoral Symposium is to provide graduate students 
a setting where they can, informally, expose and discuss their work, collecting 
valuable expert opinions and sharing new ideas, methods and applications. The 
Doctoral Symposium is an excellent opportunity for PhD students to present and 
discuss their work in a Workshop format. Each presentation will be evaluated by 
a panel composed by at least three Information Systems and Technologies experts.



Contributions Submission

The Doctoral Symposium is opened to PhD students whose research area includes 
the themes proposed for this Conference. Submissions must include an extended 
abstract (maximum 4 pages), following the Conference style guide 
. All selected contributions will be 
handed out along with the Conference Proceedings, in CD with an ISBN. These 
contributions will be available in the IEEE Xplore 
 Digital 
Library and will be sent for indexing in ISI, Scopus, EI-Compendex, INSPEC and 
Google Scholar.

Submissions must include the field, the PhD institution and the number of 
months devoted to the development of the work. Additionally, they should 
include in a clear and succinct manner:

•The problem approached and its significance or relevance
•The research objectives and related investigation topics
•A brief display of what is already known
•A proposed solution methodology for the problem
•Expected results



Important Dates

Paper submission: February 10, 2019

Notification of acceptance: March 17, 2019

Submission of accepted papers: March 31, 2019

Payment of registration, to ensure the inclusion of an accepted paper in the 
conference proceedings: April 1, 2019



Organizing Committee

Álvaro Rocha, Universidade de Coimbra

Manuel Pérez Cota, Universidad de Vigo



Scientific Committee

Manuel Pérez Cota, Universidad de Vigo (Chair)

A. Augusto Sousa, FEUP, Universidade do Porto

Adolfo Lozano Tello, Universidad de Extremadura

Alma María Gómez Rodríguez, Universidade de Vigo

Álvaro Rocha, Universidade de Coimbra

Ana Amélia Carvalho, Universidade de Coimbra

Ana Maria Ramalho Correia, NOVA Information Management School

António Coelho, FEUP, Universidade do Porto

Antonio Garcia-Loureiro, Universidad de Santiago de Compostela

Arnaldo Martins, Universidade de Aveiro

Arturo Méndez Penín, Universidade de Vigo

Bráulio Alturas, ISCTE - Insituto Universitário de Lisboa

Carlos Costa, ISEG, Universidade de Lisboa

Carlos Ferrás Sexto, Universidad de Santiago de Compostela

David Fonseca, La Salle, Universitat Ramon Llull

Ernest Redondo, Universidad Politécnica de Catalunya

Fernando Moreira, Universidade Portucalense

Fernando Ramos, Universidade de Aveiro

Francisco Restivo, Universidade Católica Portuguesa

Gonçalo Paiva Dias, Universidade de Aveiro

Gonzalo Cuevas Agustin, Universidad Politécnica de Madrid

Guilhermina Maria Lobato de Miranda, IE, Universidade de Lisboa

João Costa, Universidade de Coimbra

João Manuel R.S. Tavares, FEUP, Universidade do Porto

José Antonio Calvo-Manzano Villalón, Universidad Politécnica de Madrid

José Borbinha, IST, Universidade de Lisboa

José Machado, Universidade do Minho

José Martins, Universidade de Trás-os-Montes e Alto Douro

Juan de Dios Murillo, Universidad Nacional de Costa Rica

Leandro Rodríguez Linares, Universidade de Vigo

Luciano Boquete, Universidad de Alcalá

Luis Camarinha Matos, Universidade Nova de Lisboa

Luis Macedo, Universidade de Coimbra

Luís Paulo Reis, FEUP, Universidade do Porto

Marco Painho, NOVA Information Management School

Mareca López María Pilar, Universidad Politécnica de Madrid

María José Lado Touriño, Universidade de Vigo

Mário Piattini, Universidad de Castilla-La Mancha

Mário Rela, Universidade de Coimbra

Martin Llamas-Nistal, Universidad de Vigo

Miguel Ramón González Castro, Ence, Energía y Celulosa

Nelson Rocha, Universidade de Aveiro

Paulo Pinto, Univesidade Nova de Lisboa

Óscar Mealha, Universidade de Aveiro

Ramiro Gonçalves, Universidade de Trás-os-Montes e Alto Douro

Vitor Santos, NOVA Information Management School

Yolanda García Vázquez, Universidad de Santiago de Compostela




Doctoral Symposium webpage: https://goo.gl/JTrcLB


Kind 

Re: [PATCH 7/7] drm: Split out drm_probe_helper.h

2018-12-13 Thread Daniel Vetter
On Mon, Dec 10, 2018 at 02:40:25PM +0100, Benjamin Gaignard wrote:
> Le lun. 10 déc. 2018 à 12:10, Benjamin Gaignard
>  a écrit :
> >
> > Le lun. 10 déc. 2018 à 11:24, Thierry Reding
> >  a écrit :
> > >
> > > On Mon, Dec 10, 2018 at 11:11:33AM +0100, Daniel Vetter wrote:
> > > > Having the probe helper stuff (which pretty much everyone needs) in
> > > > the drm_crtc_helper.h file (which atomic drivers should never need) is
> > > > confusing. Split them out.
> > > >
> > > > To make sure I actually achieved the goal here I went through all
> > > > drivers. And indeed, all atomic drivers are now free of
> > > > drm_crtc_helper.h includes.
> > > >
> >
> > I have difficulties to apply this with git on top of drm-misc-next.
> > It is because of that I got errors (encoder and connector types not
> > found) while compiling adv7511_audio.c and exynos_dp.c ?
> >
> 
> Nack on this patch because it break compiling at least on sti driver.
> drm_probe_helper.h doesn't bring the same includes than drm_crtc_helper.h:
> #include 
> #include 
> #include 
> so some types, structures and functions proptotypes are missing while 
> compiling.

Hm, I thought I've compile-tested all the arm stuff, I guess I've failed.
Will respin, sorry for the confusion.
-Daniel

> 
> 
> > Benjamin
> > > > Signed-off-by: Daniel Vetter 
> > > > Cc: linux-arm-ker...@lists.infradead.org
> > > > Cc: virtualization@lists.linux-foundation.org
> > > > Cc: etna...@lists.freedesktop.org
> > > > Cc: linux-samsung-...@vger.kernel.org
> > > > Cc: intel-...@lists.freedesktop.org
> > > > Cc: linux-media...@lists.infradead.org
> > > > Cc: linux-amlo...@lists.infradead.org
> > > > Cc: linux-arm-...@vger.kernel.org
> > > > Cc: freedr...@lists.freedesktop.org
> > > > Cc: nouv...@lists.freedesktop.org
> > > > Cc: spice-de...@lists.freedesktop.org
> > > > Cc: amd-...@lists.freedesktop.org
> > > > Cc: linux-renesas-...@vger.kernel.org
> > > > Cc: linux-rockc...@lists.infradead.org
> > > > Cc: linux-st...@st-md-mailman.stormreply.com
> > > > Cc: linux-te...@vger.kernel.org
> > > > Cc: xen-de...@lists.xen.org
> > > > ---
> > > >  .../gpu/drm/amd/amdgpu/amdgpu_connectors.c|  2 +-
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c|  2 +-
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  2 +-
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  1 +
> > > >  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
> > > >  .../amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c  |  2 +-
> > > >  .../display/amdgpu_dm/amdgpu_dm_services.c|  2 +-
> > > >  drivers/gpu/drm/arc/arcpgu_crtc.c |  2 +-
> > > >  drivers/gpu/drm/arc/arcpgu_drv.c  |  2 +-
> > > >  drivers/gpu/drm/arc/arcpgu_sim.c  |  2 +-
> > > >  drivers/gpu/drm/arm/hdlcd_crtc.c  |  2 +-
> > > >  drivers/gpu/drm/arm/hdlcd_drv.c   |  2 +-
> > > >  drivers/gpu/drm/arm/malidp_crtc.c |  2 +-
> > > >  drivers/gpu/drm/arm/malidp_drv.c  |  2 +-
> > > >  drivers/gpu/drm/arm/malidp_mw.c   |  2 +-
> > > >  drivers/gpu/drm/armada/armada_510.c   |  2 +-
> > > >  drivers/gpu/drm/armada/armada_crtc.c  |  2 +-
> > > >  drivers/gpu/drm/armada/armada_drv.c   |  2 +-
> > > >  drivers/gpu/drm/armada/armada_fb.c|  2 +-
> > > >  drivers/gpu/drm/ast/ast_drv.c |  1 +
> > > >  drivers/gpu/drm/ast/ast_mode.c|  1 +
> > > >  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c|  2 +-
> > > >  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  |  2 +-
> > > >  drivers/gpu/drm/bochs/bochs_drv.c |  1 +
> > > >  drivers/gpu/drm/bochs/bochs_kms.c |  1 +
> > > >  drivers/gpu/drm/bridge/adv7511/adv7511.h  |  2 +-
> > > >  drivers/gpu/drm/bridge/analogix-anx78xx.c |  3 +-
> > > >  .../drm/bridge/analogix/analogix_dp_core.c|  2 +-
> > > >  drivers/gpu/drm/bridge/cdns-dsi.c |  2 +-
> > > >  drivers/gpu/drm/bridge/dumb-vga-dac.c |  2 +-
> > > >  .../bridge/megachips-stdp-ge-b850v3-fw.c  |  2 +-
> > > >  drivers/gpu/drm/bridge/nxp-ptn3460.c  |  2 +-
> > > >  drivers/gpu/drm/bridge/panel.c|  2 +-
> > > >  drivers/gpu/drm/bridge/parade-ps8622.c|  2 +-
> > > >  drivers/gpu/drm/bridge/sii902x.c  |  2 +-
> > > >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |  2 +-
> > > >  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |  2 +-
> > > >  drivers/gpu/drm/bridge/tc358764.c |  2 +-
> > > >  drivers/gpu/drm/bridge/tc358767.c |  2 +-
> > > >  drivers/gpu/drm/bridge/ti-sn65dsi86.c |  2 +-
> > > >  drivers/gpu/drm/bridge/ti-tfp410.c|  2 +-
> > > >  drivers/gpu/drm/cirrus/cirrus_drv.c   |  1 +
> > > >  drivers/gpu/drm/cirrus/cirrus_mode.c  |  1 +
> > > >  drivers/gpu/drm/drm_atomic_helper.c   |  1 -
> > > >  drivers/gpu/drm/drm_dp_mst_topology.c |  2 +-
> > > >  drivers/gpu/drm/drm_modeset_helper.c  |  2 +-
> > > >  

Re: [PATCH v6 0/7] Add virtio-iommu driver

2018-12-13 Thread Joerg Roedel
Hi,

to make progress on this, we should first agree on the protocol used
between guest and host. I have a few points to discuss on the protocol
first.

On Tue, Dec 11, 2018 at 06:20:57PM +, Jean-Philippe Brucker wrote:
> [1] Virtio-iommu specification v0.9, sources and pdf
> git://linux-arm.org/virtio-iommu.git virtio-iommu/v0.9
> http://jpbrucker.net/virtio-iommu/spec/v0.9/virtio-iommu-v0.9.pdf

Looking at this I wonder why it doesn't make the IOTLB visible to the
guest. the UNMAP requests seem to require that the TLB is already
flushed to make the unmap visible.

I think that will cost significant performance for both, vfio and
dma-iommu use-cases which both do (vfio at least to some degree),
deferred flushing.

I also wonder whether the protocol should implement a
protocol version handshake and iommu-feature set queries.

> [3] git://linux-arm.org/linux-jpb.git virtio-iommu/v0.9.1
> git://linux-arm.org/kvmtool-jpb.git virtio-iommu/v0.9

Unfortunatly gitweb seems to be broken on linux-arm.org. What is missing
in this patch-set to make this work on x86?

Regards,

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


[PATCH net V2 4/4] vhost: log dirty page correctly

2018-12-13 Thread Jason Wang
Vhost dirty page logging API is designed to sync through GPA. But we
try to log GIOVA when device IOTLB is enabled. This is wrong and may
lead to missing data after migration.

To solve this issue, when logging with device IOTLB enabled, we will:

1) reuse the device IOTLB translation result of GIOVA->HVA mapping to
   get HVA, for writable descriptor, get HVA through iovec. For used
   ring update, translate its GIOVA to HVA
2) traverse the GPA->HVA mapping to get the possible GPA and log
   through GPA. Pay attention this reverse mapping is not guaranteed
   to be unique, so we should log each possible GPA in this case.

This fix the failure of scp to guest during migration. In -next, we
will probably support passing GIOVA->GPA instead of GIOVA->HVA.

Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")
Reported-by: Jintack Lim 
Cc: Jintack Lim 
Signed-off-by: Jason Wang 
---
 drivers/vhost/net.c   |  3 +-
 drivers/vhost/vhost.c | 79 +++
 drivers/vhost/vhost.h |  3 +-
 3 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index ad7a6f475a44..784df2b49628 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1192,7 +1192,8 @@ static void handle_rx(struct vhost_net *net)
if (nvq->done_idx > VHOST_NET_BATCH)
vhost_net_signal_used(nvq);
if (unlikely(vq_log))
-   vhost_log_write(vq, vq_log, log, vhost_len);
+   vhost_log_write(vq, vq_log, log, vhost_len,
+   vq->iov, in);
total_len += vhost_len;
if (unlikely(vhost_exceeds_weight(++recv_pkts, total_len))) {
vhost_poll_queue(>poll);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 55e5aa662ad5..3660310604fd 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1733,11 +1733,67 @@ static int log_write(void __user *log_base,
return r;
 }
 
+static int log_write_hva(struct vhost_virtqueue *vq, u64 hva, u64 len)
+{
+   struct vhost_umem *umem = vq->umem;
+   struct vhost_umem_node *u;
+   u64 gpa;
+   int r;
+   bool hit = false;
+
+   list_for_each_entry(u, >umem_list, link) {
+   if (u->userspace_addr < hva &&
+   u->userspace_addr + u->size >=
+   hva + len) {
+   gpa = u->start + hva - u->userspace_addr;
+   r = log_write(vq->log_base, gpa, len);
+   if (r < 0)
+   return r;
+   hit = true;
+   }
+   }
+
+   /* No reverse mapping, should be a bug */
+   WARN_ON(!hit);
+   return 0;
+}
+
+static void log_used(struct vhost_virtqueue *vq, u64 used_offset, u64 len)
+{
+   struct iovec iov[64];
+   int i, ret;
+
+   if (!vq->iotlb) {
+   log_write(vq->log_base, vq->log_addr + used_offset, len);
+   return;
+   }
+
+   ret = translate_desc(vq, (u64)(uintptr_t)vq->used + used_offset,
+len, iov, 64, VHOST_ACCESS_WO);
+   WARN_ON(ret < 0);
+
+   for (i = 0; i < ret; i++) {
+   ret = log_write_hva(vq, (u64)(uintptr_t)iov[i].iov_base,
+   iov[i].iov_len);
+   WARN_ON(ret);
+   }
+}
+
 int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
-   unsigned int log_num, u64 len)
+   unsigned int log_num, u64 len, struct iovec *iov, int count)
 {
int i, r;
 
+   if (vq->iotlb) {
+   for (i = 0; i < count; i++) {
+   r = log_write_hva(vq, (u64)(uintptr_t)iov[i].iov_base,
+ iov[i].iov_len);
+   if (r < 0)
+   return r;
+   }
+   return 0;
+   }
+
/* Make sure data written is seen before log. */
smp_wmb();
for (i = 0; i < log_num; ++i) {
@@ -1769,9 +1825,8 @@ static int vhost_update_used_flags(struct vhost_virtqueue 
*vq)
smp_wmb();
/* Log used flag write. */
used = >used->flags;
-   log_write(vq->log_base, vq->log_addr +
- (used - (void __user *)vq->used),
- sizeof vq->used->flags);
+   log_used(vq, (used - (void __user *)vq->used),
+sizeof vq->used->flags);
if (vq->log_ctx)
eventfd_signal(vq->log_ctx, 1);
}
@@ -1789,9 +1844,8 @@ static int vhost_update_avail_event(struct 
vhost_virtqueue *vq, u16 avail_event)
smp_wmb();
/* Log avail event write */
used = vhost_avail_event(vq);
-   log_write(vq->log_base, vq->log_addr +
- 

Re: [PATCH] kbuild, x86: revert macros in extended asm workarounds

2018-12-13 Thread Peter Zijlstra
On Thu, Dec 13, 2018 at 06:17:41PM +0900, Masahiro Yamada wrote:
> Revert the following commits:
> 
> - 5bdcd510c2ac9efaf55c4cbd8d46421d8e2320cd
>   ("x86/jump-labels: Macrofy inline assembly code to work around GCC inlining 
> bugs")
> 
> - d5a581d84ae6b8a4a740464b80d8d9cf1e7947b2
>   ("x86/cpufeature: Macrofy inline assembly code to work around GCC inlining 
> bugs")
> 
> - 0474d5d9d2f7f3b11262f7bf87d0e7314ead9200.
>   ("x86/extable: Macrofy inline assembly code to work around GCC inlining 
> bugs")
> 
> - 494b5168f2de009eb80f198f668da374295098dd.
>   ("x86/paravirt: Work around GCC inlining bugs when compiling paravirt ops")
> 
> - f81f8ad56fd1c7b99b2ed1c314527f7d9ac447c6.
>   ("x86/bug: Macrofy the BUG table section handling, to work around GCC 
> inlining bugs")
> 
> - 77f48ec28e4ccff94d2e5f4260a83ac27a7f3099.
>   ("x86/alternatives: Macrofy lock prefixes to work around GCC inlining bugs")
> 
> - 9e1725b410594911cc5981b6c7b4cea4ec054ca8.
>   ("x86/refcount: Work around GCC inlining bug")
>   (Conflicts: arch/x86/include/asm/refcount.h)
> 
> - c06c4d8090513f2974dfdbed2ac98634357ac475.
>   ("x86/objtool: Use asm macros to work around GCC inlining bugs")
> 
> - 77b0bf55bc675233d22cd5df97605d516d64525e.
>   ("kbuild/Makefile: Prepare for using macros in inline assembly code to work 
> around asm() related GCC inlining bugs")
> 

I don't think we want to blindly revert all that. Some of them actually
made sense and did clean up things irrespective of the asm-inline issue.

In particular I like the jump-label one. The cpufeature one OTOh, yeah,
I'd love to get that reverted.

And as a note; the normal commit quoting style is:

  d5a581d84ae6 ("x86/cpufeature: Macrofy inline assembly code to work around 
GCC inlining bugs")
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH net V2 3/4] Revert "net: vhost: lock the vqs one by one"

2018-12-13 Thread Jason Wang
This reverts commit 78139c94dc8c96a478e67dab3bee84dc6eccb5fd. We don't
protect device IOTLB with vq mutex, which will lead e.g use after free
for device IOTLB entries. And since we've switched to use
mutex_trylock() in previous patch, it's safe to revert it without
having deadlock.

Fixes: commit 78139c94dc8c ("net: vhost: lock the vqs one by one")
Cc: Tonghao Zhang 
Signed-off-by: Jason Wang 
---
 drivers/vhost/vhost.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 5915f240275a..55e5aa662ad5 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -295,11 +295,8 @@ static void vhost_vq_meta_reset(struct vhost_dev *d)
 {
int i;
 
-   for (i = 0; i < d->nvqs; ++i) {
-   mutex_lock(>vqs[i]->mutex);
+   for (i = 0; i < d->nvqs; ++i)
__vhost_vq_meta_reset(d->vqs[i]);
-   mutex_unlock(>vqs[i]->mutex);
-   }
 }
 
 static void vhost_vq_reset(struct vhost_dev *dev,
@@ -895,6 +892,20 @@ static inline void __user *__vhost_get_user(struct 
vhost_virtqueue *vq,
 #define vhost_get_used(vq, x, ptr) \
vhost_get_user(vq, x, ptr, VHOST_ADDR_USED)
 
+static void vhost_dev_lock_vqs(struct vhost_dev *d)
+{
+   int i = 0;
+   for (i = 0; i < d->nvqs; ++i)
+   mutex_lock_nested(>vqs[i]->mutex, i);
+}
+
+static void vhost_dev_unlock_vqs(struct vhost_dev *d)
+{
+   int i = 0;
+   for (i = 0; i < d->nvqs; ++i)
+   mutex_unlock(>vqs[i]->mutex);
+}
+
 static int vhost_new_umem_range(struct vhost_umem *umem,
u64 start, u64 size, u64 end,
u64 userspace_addr, int perm)
@@ -976,6 +987,7 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev,
int ret = 0;
 
mutex_lock(>mutex);
+   vhost_dev_lock_vqs(dev);
switch (msg->type) {
case VHOST_IOTLB_UPDATE:
if (!dev->iotlb) {
@@ -1009,6 +1021,7 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev,
break;
}
 
+   vhost_dev_unlock_vqs(dev);
mutex_unlock(>mutex);
 
return ret;
-- 
2.17.1

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


[PATCH net V2 2/4] vhost_net: switch to use mutex_trylock() in vhost_net_busy_poll()

2018-12-13 Thread Jason Wang
We used to hold the mutex of paired virtqueue in
vhost_net_busy_poll(). But this will results an inconsistent lock
order which may cause deadlock if we try to bring back the protection
of device IOTLB with vq mutex that requires to hold mutex of all
virtqueues at the same time.

Fix this simply by switching to use mutex_trylock(), when fail just
skip the busy polling. This can happen when device IOTLB is under
updating which should be rare.

Fixes: commit 78139c94dc8c ("net: vhost: lock the vqs one by one")
Cc: Tonghao Zhang 
Signed-off-by: Jason Wang 
---
 drivers/vhost/net.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index ab11b2bee273..ad7a6f475a44 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -513,7 +513,13 @@ static void vhost_net_busy_poll(struct vhost_net *net,
struct socket *sock;
struct vhost_virtqueue *vq = poll_rx ? tvq : rvq;
 
-   mutex_lock_nested(>mutex, poll_rx ? VHOST_NET_VQ_TX: 
VHOST_NET_VQ_RX);
+   /* Try to hold the vq mutex of the paired virtqueue. We can't
+* use mutex_lock() here since we could not guarantee a
+* consistenet lock ordering.
+*/
+   if (!mutex_trylock(>mutex))
+   return;
+
vhost_disable_notify(>dev, vq);
sock = rvq->private_data;
 
-- 
2.17.1

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


[PATCH net V2 1/4] vhost: make sure used idx is seen before log in vhost_add_used_n()

2018-12-13 Thread Jason Wang
We miss a write barrier that guarantees used idx is updated and seen
before log. This will let userspace sync and copy used ring before
used idx is update. Fix this by adding a barrier before log_write().

Fixes: 8dd014adfea6f ("vhost-net: mergeable buffers support")
Signed-off-by: Jason Wang 
---
 drivers/vhost/vhost.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 6b98d8e3a5bf..5915f240275a 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -2220,6 +2220,8 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct 
vring_used_elem *heads,
return -EFAULT;
}
if (unlikely(vq->log_used)) {
+   /* Make sure used idx is seen before log. */
+   smp_wmb();
/* Log used index update. */
log_write(vq->log_base,
  vq->log_addr + offsetof(struct vring_used, idx),
-- 
2.17.1

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


[PATCH net V2 0/4] Fix various issue of vhost

2018-12-13 Thread Jason Wang
Hi:

This series tries to fix various issues of vhost:

- Patch 1 adds a missing write barrier between used idx updating and
  logging.
- Patch 2-3 brings back the protection of device IOTLB through vq
  mutex, this fixes possible use after free in device IOTLB entries.
- Patch 4-7 fixes the diry page logging when device IOTLB is
  enabled. We should done through GPA instead of GIOVA, this was done
  through intorudce HVA->GPA reverse mapping and convert HVA to GPA
  during logging dirty pages.

Please consider them for -stable.

Thanks

Changes from V1:
- silent compiler warning for 32bit.
- use mutex_trylock() on slowpath instead of mutex_lock() even on fast
  path.

Jason Wang (4):
  vhost: make sure used idx is seen before log in vhost_add_used_n()
  vhost_net: switch to use mutex_trylock() in vhost_net_busy_poll()
  Revert "net: vhost: lock the vqs one by one"
  vhost: log dirty page correctly

 drivers/vhost/net.c   |  11 -
 drivers/vhost/vhost.c | 102 ++
 drivers/vhost/vhost.h |   3 +-
 3 files changed, 95 insertions(+), 21 deletions(-)

-- 
2.17.1

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


[PATCH] VSOCK: Send reset control packet when socket is partially bound

2018-12-13 Thread Jorgen Hansen
If a server side socket is bound to an address, but not in the listening
state yet, incoming connection requests should receive a reset control
packet in response. However, the function used to send the reset
silently drops the reset packet if the sending socket isn't bound
to a remote address (as is the case for a bound socket not yet in
the listening state). This change fixes this by using the src
of the incoming packet as destination for the reset packet in
this case.

Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
Reviewed-by: Adit Ranadive 
Reviewed-by: Vishnu Dasa 
Signed-off-by: Jorgen Hansen 
---
 net/vmw_vsock/vmci_transport.c | 67 +++---
 1 file changed, 50 insertions(+), 17 deletions(-)

diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 0ae3614..402d84e 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -264,6 +264,31 @@ vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src,
 }
 
 static int
+vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src,
+ struct sockaddr_vm *dst,
+ enum vmci_transport_packet_type type,
+ u64 size,
+ u64 mode,
+ struct vmci_transport_waiting_info *wait,
+ u16 proto,
+ struct vmci_handle handle)
+{
+   struct vmci_transport_packet *pkt;
+   int err;
+
+   pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return -ENOMEM;
+
+   err = __vmci_transport_send_control_pkt(pkt, src, dst, type, size,
+   mode, wait, proto, handle,
+   true);
+   kfree(pkt);
+
+   return err;
+}
+
+static int
 vmci_transport_send_control_pkt(struct sock *sk,
enum vmci_transport_packet_type type,
u64 size,
@@ -272,9 +297,7 @@ vmci_transport_send_control_pkt(struct sock *sk,
u16 proto,
struct vmci_handle handle)
 {
-   struct vmci_transport_packet *pkt;
struct vsock_sock *vsk;
-   int err;
 
vsk = vsock_sk(sk);
 
@@ -284,17 +307,10 @@ vmci_transport_send_control_pkt(struct sock *sk,
if (!vsock_addr_bound(>remote_addr))
return -EINVAL;
 
-   pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
-   if (!pkt)
-   return -ENOMEM;
-
-   err = __vmci_transport_send_control_pkt(pkt, >local_addr,
-   >remote_addr, type, size,
-   mode, wait, proto, handle,
-   true);
-   kfree(pkt);
-
-   return err;
+   return vmci_transport_alloc_send_control_pkt(>local_addr,
+>remote_addr,
+type, size, mode,
+wait, proto, handle);
 }
 
 static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
@@ -312,12 +328,29 @@ static int vmci_transport_send_reset_bh(struct 
sockaddr_vm *dst,
 static int vmci_transport_send_reset(struct sock *sk,
 struct vmci_transport_packet *pkt)
 {
+   struct sockaddr_vm dst;
+   struct sockaddr_vm *dst_ptr;
+   struct vsock_sock *vsk;
+
if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST)
return 0;
-   return vmci_transport_send_control_pkt(sk,
-   VMCI_TRANSPORT_PACKET_TYPE_RST,
-   0, 0, NULL, VSOCK_PROTO_INVALID,
-   VMCI_INVALID_HANDLE);
+
+   vsk = vsock_sk(sk);
+
+   if (!vsock_addr_bound(>local_addr))
+   return -EINVAL;
+
+   if (vsock_addr_bound(>remote_addr)) {
+   dst_ptr = >remote_addr;
+   } else {
+   vsock_addr_init(, pkt->dg.src.context,
+   pkt->src_port);
+   dst_ptr = 
+   }
+   return vmci_transport_alloc_send_control_pkt(>local_addr, dst_ptr,
+VMCI_TRANSPORT_PACKET_TYPE_RST,
+0, 0, NULL, VSOCK_PROTO_INVALID,
+VMCI_INVALID_HANDLE);
 }
 
 static int vmci_transport_send_negotiate(struct sock *sk, size_t size)
-- 
2.6.2

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