xserver: Branch 'master' - 4 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 6 08:04:49 UTC 2023


 hw/xwayland/xwayland-present.c |   49 ++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 17 deletions(-)

New commits:
commit 13e513d2f04019424761b728340ec716de0c0d29
Author: Jessica Clarke <jrtc27 at jrtc27.com>
Date:   Mon Dec 5 19:58:21 2022 +0000

    xwayland: Stop using event address as event_id
    
    Nothing should be relying on this anymore, so use a counter like other
    places in the tree instead. This ensures that the event_id doesn't get
    cast back into a pointer again in future, and also may be slightly less
    confusing in cases where calloc reuses an address as debug logs would
    show the same event_id for those but now they will be distinct.
    
    Signed-off-by: Jessica Clarke <jrtc27 at jrtc27.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 1c040b85f..66d8b4200 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -930,6 +930,7 @@ xwl_present_pixmap(WindowPtr window,
                    present_notify_ptr notifies,
                    int num_notifies)
 {
+    static uint64_t xwl_present_event_id;
     uint64_t                    ust = 0;
     uint64_t                    target_msc;
     uint64_t                    crtc_msc = 0;
@@ -995,7 +996,7 @@ xwl_present_pixmap(WindowPtr window,
         return BadAlloc;
     }
 
-    vblank->event_id = (uintptr_t)event;
+    vblank->event_id = ++xwl_present_event_id;
 
     /* Xwayland presentations always complete (at least) one frame after they
      * are executed
commit bfe8f54924766366bee90309a13b827c7c99c028
Author: Jessica Clarke <jrtc27 at jrtc27.com>
Date:   Mon Dec 5 19:50:41 2022 +0000

    xwayland: Stop relying on event_id being a valid pointer
    
    On traditional 32-bit and 64-bit architectures, uint64_t can be abused
    to hold a uintptr_t and be cast back to a valid pointer. However, on
    CHERI, and thus Arm's Morello prototype, pointers are capabilities,
    which contain a traditional address alongside additional metadata,
    including a tag bit that ensures it cannot be forged (the only way to
    get a capability with the tag bit set is by using instructions that take
    in another valid capability with sufficient bounds/permissions/etc for
    the request, and any other operation, like overwriting individual bytes
    in memory, will give a capability whose tag is clear). Casting a pointer
    to a uintptr_t is fine as uintptr_t is represented as a capability, but
    casting to a uint64_t yields just the address, losing the metadata and
    tag. Thus, when cast back to a uintptr_t, the capability remains invalid
    and faults on any attempt to dereference.
    
    As with various other places in the tree, address this by searching for
    the pointer in a list so that we no longer rely on this undefined
    behaviour.
    
    Signed-off-by: Jessica Clarke <jrtc27 at jrtc27.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 78b7af2af..1c040b85f 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -84,9 +84,16 @@ xwl_present_window_get_priv(WindowPtr window)
 }
 
 static struct xwl_present_event *
-xwl_present_event_from_id(uint64_t event_id)
+xwl_present_event_from_id(WindowPtr present_window, uint64_t event_id)
 {
-    return (struct xwl_present_event*)(uintptr_t)event_id;
+    present_window_priv_ptr window_priv = present_get_window_priv(present_window, TRUE);
+    struct xwl_present_event *event;
+
+    xorg_list_for_each_entry(event, &window_priv->vblank, vblank.window_list) {
+        if (event->vblank.event_id == event_id)
+            return event;
+    }
+    return NULL;
 }
 
 static struct xwl_present_event *
@@ -546,7 +553,12 @@ xwl_present_queue_vblank(ScreenPtr screen,
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
     struct xwl_window *xwl_window = xwl_window_from_window(present_window);
-    struct xwl_present_event *event = xwl_present_event_from_id(event_id);
+    struct xwl_present_event *event = xwl_present_event_from_id(present_window, event_id);
+
+    if (!event) {
+        ErrorF("present: Error getting event\n");
+        return BadImplementation;
+    }
 
     event->vblank.exec_msc = msc;
 
commit 42d2d9c1d4b1c8ac36d07d8383f2c8f864bb57fa
Author: Jessica Clarke <jrtc27 at jrtc27.com>
Date:   Mon Dec 5 18:47:17 2022 +0000

    xwayland: Pass vblank pointer itself to xwl_present_flip
    
    All these arguments other than damage come from the vblank itself so
    passing the vblank simplifies the caller. Moreover, we pass the event_id
    solely so we can get back to the event, which is just the (extended)
    vblank, so passing the vblank avoids that round trip.
    
    Signed-off-by: Jessica Clarke <jrtc27 at jrtc27.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 67af35b6d..78b7af2af 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -738,18 +738,15 @@ xwl_present_clear_window_flip(WindowPtr window)
 }
 
 static Bool
-xwl_present_flip(WindowPtr present_window,
-                 RRCrtcPtr crtc,
-                 uint64_t event_id,
-                 PixmapPtr pixmap,
-                 Bool sync_flip,
-                 RegionPtr damage)
+xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
 {
+    WindowPtr present_window = vblank->window;
+    PixmapPtr pixmap = vblank->pixmap;
     struct xwl_window           *xwl_window = xwl_window_from_window(present_window);
     struct xwl_present_window   *xwl_present_window = xwl_present_window_priv(present_window);
     BoxPtr                      damage_box;
     struct wl_buffer            *buffer;
-    struct xwl_present_event    *event = xwl_present_event_from_id(event_id);
+    struct xwl_present_event    *event = xwl_present_event_from_vblank(vblank);
 
     if (!xwl_window)
         return FALSE;
@@ -787,7 +784,7 @@ xwl_present_flip(WindowPtr present_window,
 
     wl_surface_commit(xwl_window->surface);
 
-    if (!sync_flip) {
+    if (!vblank->sync_flip) {
         xwl_present_window->sync_callback =
             wl_display_sync(xwl_window->xwl_screen->display);
         wl_callback_add_listener(xwl_present_window->sync_callback,
@@ -851,8 +848,7 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             } else
                 damage = RegionDuplicate(&window->clipList);
 
-            if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
-                                 vblank->pixmap, vblank->sync_flip, damage)) {
+            if (xwl_present_flip(vblank, damage)) {
                 WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
                 PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
 
commit 85a36146681a0229d8547ee250644dc285e225da
Author: Jessica Clarke <jrtc27 at jrtc27.com>
Date:   Mon Dec 5 18:35:43 2022 +0000

    xwayland: Avoid gratuitous round trip through event_id
    
    By adding a new xwl_present_event_from_vblank function we can avoid
    turning the vblank into an event_id, and also abstract away the exact
    encoding for event_id from most places.
    
    Signed-off-by: Jessica Clarke <jrtc27 at jrtc27.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 189e7cfd6..67af35b6d 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -89,6 +89,12 @@ xwl_present_event_from_id(uint64_t event_id)
     return (struct xwl_present_event*)(uintptr_t)event_id;
 }
 
+static struct xwl_present_event *
+xwl_present_event_from_vblank(present_vblank_ptr vblank)
+{
+    return container_of(vblank, struct xwl_present_event, vblank);
+}
+
 static Bool entered_for_each_frame_callback;
 
 Bool
@@ -268,7 +274,7 @@ static void
 xwl_present_free_idle_vblank(present_vblank_ptr vblank)
 {
     present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-    xwl_present_free_event(xwl_present_event_from_id((uintptr_t)vblank));
+    xwl_present_free_event(xwl_present_event_from_vblank(vblank));
 }
 
 static WindowPtr
@@ -306,7 +312,7 @@ xwl_present_flips_stop(WindowPtr window)
         struct xwl_present_event *event;
 
         vblank = xwl_present_window->flip_active;
-        event = xwl_present_event_from_id((uintptr_t)vblank);
+        event = xwl_present_event_from_vblank(vblank);
         if (event->pixmap)
             xwl_present_free_idle_vblank(vblank);
         else
@@ -336,7 +342,7 @@ xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t
 
     if (xwl_present_window->flip_active) {
         struct xwl_present_event *event =
-            xwl_present_event_from_id((uintptr_t)xwl_present_window->flip_active);
+            xwl_present_event_from_vblank(xwl_present_window->flip_active);
 
         if (!event->pixmap)
             xwl_present_free_event(event);


More information about the xorg-commit mailing list