[Xquartz-changes] xserver: Branch 'master' - 15 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Tue Nov 12 14:03:52 PST 2013


 Xext/shm.c                         |   51 +++++++++++-
 Xext/shmint.h                      |   22 +++++
 configure.ac                       |   59 ++++++++++++++
 hw/xfree86/common/xf86Bus.c        |    5 -
 hw/xfree86/x86emu/decode.c         |   10 ++
 hw/xfree86/x86emu/x86emu/regs.h    |    9 ++
 hw/xfree86/x86emu/x86emu/x86emui.h |   12 ++
 include/Makefile.am                |    1 
 include/busfault.h                 |   48 +++++++++++
 include/dix-config.h.in            |   14 +++
 include/dixstruct.h                |    4 
 include/os.h                       |    2 
 include/protocol-versions.h        |    4 
 include/xorg-config.h.in           |    3 
 include/xorg-server.h.in           |    3 
 mi/miinitext.c                     |    2 
 os/Makefile.am                     |    5 +
 os/WaitFor.c                       |    5 +
 os/busfault.c                      |  150 +++++++++++++++++++++++++++++++++++++
 os/io.c                            |    4 
 os/osinit.c                        |    5 +
 present/present.c                  |   16 ++-
 record/record.c                    |    4 
 23 files changed, 422 insertions(+), 16 deletions(-)

New commits:
commit 4a251f5883b042cd902c192060a0be2b11148f2b
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Fri Nov 8 14:55:33 2013 -0800

    xfree86: Fix build without libpciaccess
    
    Regression fix from commit 04ab07ca19236d6c9a947e065fb69b0dd0d16639
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Reviewed-by: Connor Behan <connor.behan at gmail.com>

diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 329d0b3..d463e91 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -266,9 +266,12 @@ xf86IsEntityPrimary(int entityIndex)
 {
     EntityPtr pEnt = xf86Entities[entityIndex];
 
+#ifdef XSERVER_LIBPCIACCESS
     if (primaryBus.type == BUS_PLATFORM && pEnt->bus.type == BUS_PCI)
 	return MATCH_PCI_DEVICES(pEnt->bus.id.pci, primaryBus.id.plat->pdev);
-    else if (primaryBus.type != pEnt->bus.type)
+#endif
+
+    if (primaryBus.type != pEnt->bus.type)
         return FALSE;
 
     switch (pEnt->bus.type) {
commit 5b02d5b7aaabf1ba8dcbdfe4525b7995b4e79f92
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Thu Nov 7 21:08:56 2013 -0800

    Enable XTRANS_SEND_FDS on Solaris too.
    
    Requires passing through the __EXTENSIONS__ and _XOPEN_SOURCE defines
    in order to expose the msg_control members in struct msghdr.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/configure.ac b/configure.ac
index ff3f4a9..eb90b1a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,6 +31,7 @@ RELEASE_DATE="2013-10-31"
 RELEASE_NAME="Bom Retiro"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AC_USE_SYSTEM_EXTENSIONS
 
 # Require xorg-macros minimum of 1.14 for XORG_COMPILER_BRAND in XORG_DEFAULT_OPTIONS
 m4_ifndef([XORG_MACROS_VERSION],
@@ -1096,7 +1097,7 @@ AC_ARG_ENABLE(xtrans-send-fds,	AS_HELP_STRING([--disable-xtrans-send-fds], [Use
 case "x$XTRANS_SEND_FDS" in
 xauto)
 	case "$host_os" in
-	linux*)
+	linux*|solaris*)
 		XTRANS_SEND_FDS=yes
 		;;
 	*)
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 9bdbe53..d4fbe99 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -449,6 +449,14 @@
 #include "dix-config-apple-verbatim.h"
 #endif
 
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+/* Defined if needed to expose struct msghdr.msg_control */
+#undef _XOPEN_SOURCE
+
 /* Have support for X shared memory fence library (xshmfence) */
 #undef HAVE_XSHMFENCE
 
commit c4c154d18ef42dc550f2675a9ee88e07b1ca6bed
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Thu Nov 7 21:05:33 2013 -0800

    Avoid conflicts with Solaris <sys/regset.h> defines that clash with our names
    
    When building on Solaris with _XOPEN_SOURCE set to a recent XPG release,
    <stdlib.h> and other core headers start including <sys/regset.h>, which
    has a bunch of unfortunately named macros such as "CS", "ES", etc. for
    x86 & x64 registers which clash with existing variable & struct member
    names in Xorg - so #undef these so they don't interfere with our use.
    
    (Yes, have filed a bug against the system headers for exposing these,
     but this solves the problem for building on existing releases.)
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/x86emu/decode.c b/hw/xfree86/x86emu/decode.c
index 12f8fb8..08a07b1 100644
--- a/hw/xfree86/x86emu/decode.c
+++ b/hw/xfree86/x86emu/decode.c
@@ -38,6 +38,16 @@
 ****************************************************************************/
 
 #include <stdlib.h>
+
+#if defined(__sun) && defined(CS) /* avoid conflicts with Solaris sys/regset.h */
+# undef CS
+# undef DS
+# undef SS
+# undef ES
+# undef FS
+# undef GS
+#endif
+
 #include "x86emu/x86emui.h"
 
 /*----------------------------- Implementation ----------------------------*/
diff --git a/hw/xfree86/x86emu/x86emu/regs.h b/hw/xfree86/x86emu/x86emu/regs.h
index 6bd0611..2ecafa0 100644
--- a/hw/xfree86/x86emu/x86emu/regs.h
+++ b/hw/xfree86/x86emu/x86emu/regs.h
@@ -112,6 +112,15 @@ struct i386_special_regs {
  * CS, DS, ES, SS.
  */
 
+#if defined(__sun) && defined(CS) /* avoid conflicts with Solaris sys/regset.h */
+# undef CS
+# undef DS
+# undef SS
+# undef ES
+# undef FS
+# undef GS
+#endif
+
 struct i386_segment_regs {
     u16 CS, DS, SS, ES, FS, GS;
 };
diff --git a/hw/xfree86/x86emu/x86emu/x86emui.h b/hw/xfree86/x86emu/x86emu/x86emui.h
index f11dc10..5e20d97 100644
--- a/hw/xfree86/x86emu/x86emu/x86emui.h
+++ b/hw/xfree86/x86emu/x86emu/x86emui.h
@@ -73,7 +73,17 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#endif
+/* avoid conflicts with Solaris sys/regset.h */
+# if defined(__sun) && defined(CS)
+#  undef CS
+#  undef DS
+#  undef SS
+#  undef ES
+#  undef FS
+#  undef GS
+# endif
+#endif /* NO_SYS_HEADERS */
+
 /*--------------------------- Inline Functions ----------------------------*/
 
 #ifdef  __cplusplus
diff --git a/record/record.c b/record/record.c
index f3a26a7..2c70460 100644
--- a/record/record.c
+++ b/record/record.c
@@ -1393,6 +1393,10 @@ typedef struct {
     short first, last;          /* if for extension, major opcode interval */
 } SetInfoRec, *SetInfoPtr;
 
+#if defined(ERR) && defined(__sun)
+#undef ERR /* Avoid conflict with Solaris <sys/regset.h> */
+#endif
+
 /* These constant are used to index into an array of SetInfoRec. */
 enum { REQ,                     /* set info for requests */
     REP,                        /* set info for replies */
commit d7f9be0f8541368bf1a095ad1fbe7f38be6d3d15
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 11 15:48:41 2013 -0800

    Proper spelling of MAP_ANONYMOUS is MAP_ANON.
    
    The former doesn't exist on BSD and the latter is available everywhere
    AFAIK (checked Solaris and Linux).
    
    You also might want to wrap that line ;).
    
    Reported-by: Mark Kettenis <mark.kettenis at xs4all.nl>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/busfault.c b/os/busfault.c
index 78e7693..43bb6ea 100644
--- a/os/busfault.c
+++ b/os/busfault.c
@@ -121,7 +121,8 @@ busfault_sigaction(int sig, siginfo_t *info, void *param)
      * /dev/zero over that area and keep going
      */
 
-    new_addr = mmap(busfault->addr, busfault->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
+    new_addr = mmap(busfault->addr, busfault->size, PROT_READ|PROT_WRITE,
+                    MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
 
     if (new_addr == MAP_FAILED)
         goto panic;
commit fc84166e65c35ad75f566b135dcfc305ad5a2fde
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 7 15:18:28 2013 -0800

    Get rid of the rest of the FD passing code when XTRANS_SEND_FDS isn't set
    
    req_fds and SetReqFds in include/dixstruct.h
    
    ReadFdFromClient, WriteFdToClient and the FD flushing in os/io.c
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/dixstruct.h b/include/dixstruct.h
index 456e633..6f5667f 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -110,15 +110,19 @@ typedef struct _Client {
 
     DeviceIntPtr clientPtr;
     ClientIdPtr clientIds;
+#if XTRANS_SEND_FDS
     int req_fds;
+#endif
 } ClientRec;
 
+#if XTRANS_SEND_FDS
 static inline void
 SetReqFds(ClientPtr client, int req_fds) {
     if (client->req_fds != 0 && req_fds != client->req_fds)
         LogMessage(X_ERROR, "Mismatching number of request fds %d != %d\n", req_fds, client->req_fds);
     client->req_fds = req_fds;
 }
+#endif
 
 /*
  * Scheduling interface
diff --git a/include/os.h b/include/os.h
index 11b2198..450e1a8 100644
--- a/include/os.h
+++ b/include/os.h
@@ -98,9 +98,11 @@ extern _X_EXPORT int WaitForSomething(int *     /*pClientsReady */
 
 extern _X_EXPORT int ReadRequestFromClient(ClientPtr /*client */ );
 
+#if XTRANS_SEND_FDS
 extern _X_EXPORT int ReadFdFromClient(ClientPtr client);
 
 extern _X_EXPORT int WriteFdToClient(ClientPtr client, int fd, Bool do_close);
+#endif
 
 extern _X_EXPORT Bool InsertFakeRequest(ClientPtr /*client */ ,
                                         char * /*data */ ,
diff --git a/os/io.c b/os/io.c
index a20faa5..922a8eb 100644
--- a/os/io.c
+++ b/os/io.c
@@ -259,12 +259,14 @@ ReadRequestFromClient(ClientPtr client)
         oc->input = oci;
     }
 
+#if XTRANS_SEND_FDS
     /* Discard any unused file descriptors */
     while (client->req_fds > 0) {
         int req_fd = ReadFdFromClient(client);
         if (req_fd >= 0)
             close(req_fd);
     }
+#endif
     /* advance to start of next request */
 
     oci->bufptr += oci->lenLastReq;
@@ -491,6 +493,7 @@ ReadRequestFromClient(ClientPtr client)
     return needed;
 }
 
+#if XTRANS_SEND_FDS
 int
 ReadFdFromClient(ClientPtr client)
 {
@@ -513,6 +516,7 @@ WriteFdToClient(ClientPtr client, int fd, Bool do_close)
 
     return _XSERVTransSendFd(oc->trans_conn, fd, do_close);
 }
+#endif
 
 /*****************************************************************
  * InsertFakeRequest
commit a239e6faf3fce848ac0d10c48f8e817db68a493c
Merge: 43e5a43 f70a8bf
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 11 15:26:12 2013 -0800

    Merge remote-tracking branch 'jeremyhu/master'

commit 43e5a43fa8994e50cf01dd954118f4ef2c4e7933
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Nov 7 12:01:41 2013 -0500

    present: Don't try to initialize when building without present support
    
    There's a --disable-present, so it'd be nice if it worked.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Mark Kettenis <kettenis at openbsd.org>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/mi/miinitext.c b/mi/miinitext.c
index 6366182..67511b8 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -287,7 +287,9 @@ static ExtensionModule staticExtensions[] = {
 #ifdef DPMSExtension
     {DPMSExtensionInit, DPMSExtensionName, &noDPMSExtension},
 #endif
+#ifdef PRESENT
     {present_extension_init, PRESENT_NAME, NULL},
+#endif
 #ifdef DRI3
     {dri3_extension_init, DRI3_NAME, NULL},
 #endif
commit 0822a23e048b12c98c654e8b6af711c5f2c97141
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 7 03:19:42 2013 -0800

    present: Change debug output a bit to help diagnose missing vblank signals
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index fab105d..228d43a 100644
--- a/present/present.c
+++ b/present/present.c
@@ -374,6 +374,7 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
     present_vblank_ptr  vblank, tmp;
     int                 s;
 
+    DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
     xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
         if (vblank->event_id == event_id) {
             xorg_list_del(&vblank->event_queue);
@@ -658,8 +659,10 @@ present_pixmap(WindowPtr window,
     }
 
     if (pixmap)
-        DebugPresent(("q %p %8lld: %08lx -> %08lx (crtc %d)\n",
-                      vblank, target_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id, target_crtc ? 1 : 0));
+        DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p)\n",
+                      vblank->event_id, vblank, target_msc,
+                      vblank->pixmap->drawable.id, vblank->window->drawable.id,
+                      target_crtc));
 
     xorg_list_add(&vblank->event_queue, &present_exec_queue);
     if (target_msc >= crtc_msc) {
commit 20bb49ae9ba11d3dccfba191483cd682d9c9d96c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 6 23:56:26 2013 -0800

    Present: Check for window/fence destroyed when idling pixmaps
    
    A client destroying objects in the middle of an unflip can end up
    having the screen flip window or fence set to NULL in the unflip
    notify path. Check for these and don't try to use those objects.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index 4c97ce4..fab105d 100644
--- a/present/present.c
+++ b/present/present.c
@@ -184,8 +184,10 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
 static void
 present_pixmap_idle(PixmapPtr pixmap, WindowPtr window, CARD32 serial, struct present_fence *present_fence)
 {
-    present_fence_set_triggered(present_fence);
-    present_send_idle_notify(window, serial, pixmap, present_fence);
+    if (present_fence)
+        present_fence_set_triggered(present_fence);
+    if (window)
+        present_send_idle_notify(window, serial, pixmap, present_fence);
 }
 
 RRCrtcPtr
@@ -297,7 +299,8 @@ present_flip_idle(ScreenPtr screen)
     if (screen_priv->flip_pixmap) {
         present_pixmap_idle(screen_priv->flip_pixmap, screen_priv->flip_window,
                             screen_priv->flip_serial, screen_priv->flip_idle_fence);
-        present_fence_destroy(screen_priv->flip_idle_fence);
+        if (screen_priv->flip_idle_fence)
+            present_fence_destroy(screen_priv->flip_idle_fence);
         dixDestroyPixmap(screen_priv->flip_pixmap, screen_priv->flip_pixmap->drawable.id);
         screen_priv->flip_crtc = NULL;
         screen_priv->flip_window = NULL;
commit 41da295eb50fa08eaacd0ecde99f43a716fcb41a
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Nov 3 13:12:40 2013 -0800

    Trap SIGBUS to handle truncated shared memory segments
    
    If a client passes a section of memory via file descriptor and then
    subsequently truncates that file, the underlying pages will be freed
    and the addresses invalidated. Subsequent accesses to the page will
    fail with a SIGBUS error.
    
    Trap that SIGBUS, figure out which segment was causing the error and
    then allocate new pages to fill in for that region. Mark the offending
    shared segment as invalid and free the resource ID so that the client
    will be able to tell when subsequently attempting to use the segment.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    
    v2: Use MAP_FIXED to simplify the recovery logic (Mark Kettenis)
    v3: Also catch errors in ShmCreateSegment
    
    Conflicts:
    	include/dix-config.h.in
    	include/xorg-config.h.in

diff --git a/Xext/shm.c b/Xext/shm.c
index 109a381..46ce521 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -438,9 +438,11 @@ ShmDetachSegment(pointer value, /* must conform to DeleteType */
     if (--shmdesc->refcnt)
         return TRUE;
 #if SHM_FD_PASSING
-    if (shmdesc->is_fd)
+    if (shmdesc->is_fd) {
+        if (shmdesc->busfault)
+            busfault_unregister(shmdesc->busfault);
         munmap(shmdesc->addr, shmdesc->size);
-    else
+    } else
 #endif
         shmdt(shmdesc->addr);
     for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next);
@@ -1099,6 +1101,19 @@ ProcShmCreatePixmap(ClientPtr client)
 }
 
 #ifdef SHM_FD_PASSING
+
+static void
+ShmBusfaultNotify(void *context)
+{
+    ShmDescPtr shmdesc = context;
+
+    ErrorF("shared memory 0x%x truncated by client\n",
+           (unsigned int) shmdesc->resource);
+    busfault_unregister(shmdesc->busfault);
+    shmdesc->busfault = NULL;
+    FreeResource (shmdesc->resource, RT_NONE);
+}
+
 static int
 ProcShmAttachFd(ClientPtr client)
 {
@@ -1143,6 +1158,15 @@ ProcShmAttachFd(ClientPtr client)
     shmdesc->refcnt = 1;
     shmdesc->writable = !stuff->readOnly;
     shmdesc->size = statb.st_size;
+    shmdesc->resource = stuff->shmseg;
+
+    shmdesc->busfault = busfault_register_mmap(shmdesc->addr, shmdesc->size, ShmBusfaultNotify, shmdesc);
+    if (!shmdesc->busfault) {
+        munmap(shmdesc->addr, shmdesc->size);
+        free(shmdesc);
+        return BadAlloc;
+    }
+
     shmdesc->next = Shmsegs;
     Shmsegs = shmdesc;
 
@@ -1198,6 +1222,15 @@ ProcShmCreateSegment(ClientPtr client)
     shmdesc->refcnt = 1;
     shmdesc->writable = !stuff->readOnly;
     shmdesc->size = stuff->size;
+
+    shmdesc->busfault = busfault_register_mmap(shmdesc->addr, shmdesc->size, ShmBusfaultNotify, shmdesc);
+    if (!shmdesc->busfault) {
+        close(fd);
+        munmap(shmdesc->addr, shmdesc->size);
+        free(shmdesc);
+        return BadAlloc;
+    }
+
     shmdesc->next = Shmsegs;
     Shmsegs = shmdesc;
 
diff --git a/Xext/shmint.h b/Xext/shmint.h
index 7b3ea9b..21d6cc4 100644
--- a/Xext/shmint.h
+++ b/Xext/shmint.h
@@ -62,6 +62,10 @@ typedef struct _ShmFuncs {
 #define SHM_FD_PASSING  1
 #endif
 
+#ifdef SHM_FD_PASSING
+#include "busfault.h"
+#endif
+
 typedef struct _ShmDesc {
     struct _ShmDesc *next;
     int shmid;
@@ -71,6 +75,7 @@ typedef struct _ShmDesc {
     unsigned long size;
 #ifdef SHM_FD_PASSING
     Bool is_fd;
+    struct busfault *busfault;
     XID resource;
 #endif
 } ShmDescRec, *ShmDescPtr;
diff --git a/configure.ac b/configure.ac
index 04de2cd..01f2a2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1171,6 +1171,25 @@ case "$DRI3,$HAVE_DRI3PROTO" in
 		;;
 esac
 
+AC_CHECK_FUNCS([sigaction])
+
+BUSFAULT=no
+
+case x"$ac_cv_func_sigaction" in
+	xyes)
+		AC_DEFINE(HAVE_SIGACTION, 1, [Have sigaction function])
+		BUSFAULT=yes
+		;;
+esac
+
+case x"$BUSFAULT" in
+	xyes)
+		AC_DEFINE(BUSFAULT, 1, [Include busfault OS API])
+		;;
+esac
+
+AM_CONDITIONAL(BUSFAULT, test x"$BUSFAULT" = xyes)
+
 PKG_CHECK_MODULES([XSHMFENCE], $XSHMFENCE,
 		  [HAVE_XSHMFENCE=yes], [HAVE_XSHMFENCE=no])
 
diff --git a/include/Makefile.am b/include/Makefile.am
index 5cdea1d..13d91e2 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,6 +2,7 @@ if XORG
 sdk_HEADERS =		\
 	XIstubs.h	\
 	Xprintf.h	\
+	busfault.h	\
 	callback.h	\
 	client.h	\
 	closestr.h	\
diff --git a/include/busfault.h b/include/busfault.h
new file mode 100644
index 0000000..3b66881
--- /dev/null
+++ b/include/busfault.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _BUSFAULT_H_
+#define _BUSFAULT_H_
+
+#include <dix-config.h>
+
+#ifdef BUSFAULT
+
+#include <sys/types.h>
+
+typedef void (*busfault_notify_ptr) (void *context);
+
+struct busfault *
+busfault_register_mmap(void *addr, size_t size, busfault_notify_ptr notify, void *context);
+
+void
+busfault_unregister(struct busfault *busfault);
+
+void
+busfault_check(void);
+
+Bool
+busfault_init(void);
+
+#endif
+
+#endif /* _BUSFAULT_H_ */
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index e4eea8d..9bdbe53 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -455,4 +455,7 @@
 /* Use XTrans FD passing support */
 #undef XTRANS_SEND_FDS
 
+/* Wrap SIGBUS to catch MIT-SHM faults */
+#undef BUSFAULT
+
 #endif /* _DIX_CONFIG_H_ */
diff --git a/os/Makefile.am b/os/Makefile.am
index 364b6da..a1bbb4d 100644
--- a/os/Makefile.am
+++ b/os/Makefile.am
@@ -5,6 +5,7 @@ AM_CFLAGS = $(DIX_CFLAGS) $(SHA1_CFLAGS)
 SECURERPC_SRCS = rpcauth.c
 XDMCP_SRCS = xdmcp.c
 XORG_SRCS = log.c
+BUSFAULT_SRCS = busfault.c
 
 libos_la_SOURCES = 	\
 	WaitFor.c	\
@@ -39,6 +40,10 @@ AM_CFLAGS += $(LIBUNWIND_CFLAGS)
 libos_la_LIBADD += $(LIBUNWIND_LIBS)
 endif
 
+if BUSFAULT
+libos_la_SOURCES += $(BUSFAULT_SRCS)
+endif
+
 EXTRA_DIST = $(SECURERPC_SRCS) $(XDMCP_SRCS)
 
 if SPECIAL_DTRACE_OBJECTS
diff --git a/os/WaitFor.c b/os/WaitFor.c
index c5f4cd7..39fedd9 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -72,6 +72,7 @@ SOFTWARE.
 #ifdef DPMSExtension
 #include "dpmsproc.h"
 #endif
+#include "busfault.h"
 
 #ifdef WIN32
 /* Error codes from windows sockets differ from fileio error codes  */
@@ -162,6 +163,10 @@ WaitForSomething(int *pClientsReady)
         SmartScheduleStopTimer();
     nready = 0;
 
+#ifdef BUSFAULT
+    busfault_check();
+#endif
+
     /* We need a while loop here to handle 
        crashed connections and the screen saver timeout */
     while (1) {
diff --git a/os/busfault.c b/os/busfault.c
new file mode 100644
index 0000000..78e7693
--- /dev/null
+++ b/os/busfault.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/Xos.h>
+#include <X11/Xdefs.h>
+#include "misc.h"
+#include <busfault.h>
+#include <list.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+struct busfault {
+    struct xorg_list    list;
+
+    void                *addr;
+    size_t              size;
+
+    Bool                valid;
+
+    busfault_notify_ptr notify;
+    void                *context;
+};
+
+static Bool             busfaulted;        
+static struct xorg_list busfaults;
+
+struct busfault *
+busfault_register_mmap(void *addr, size_t size, busfault_notify_ptr notify, void *context)
+{
+    struct busfault     *busfault;
+
+    busfault = calloc(1, sizeof (struct busfault));
+    if (!busfault)
+        return NULL;
+
+    busfault->addr = addr;
+    busfault->size = size;
+    busfault->notify = notify;
+    busfault->context = context;
+    busfault->valid = TRUE;
+
+    xorg_list_add(&busfault->list, &busfaults);
+    return busfault;
+}
+
+void
+busfault_unregister(struct busfault *busfault)
+{
+    xorg_list_del(&busfault->list);
+    free(busfault);
+}
+
+void
+busfault_check(void)
+{
+    struct busfault     *busfault, *tmp;
+
+    if (!busfaulted)
+        return;
+
+    busfaulted = FALSE;
+
+    xorg_list_for_each_entry_safe(busfault, tmp, &busfaults, list) {
+        if (!busfault->valid)
+            (*busfault->notify)(busfault->context);
+    }
+}
+
+static void (*previous_busfault_sigaction)(int sig, siginfo_t *info, void *param);
+
+static void
+busfault_sigaction(int sig, siginfo_t *info, void *param)
+{
+    void                *fault = info->si_addr;
+    struct busfault     *busfault = NULL;
+    void                *new_addr;
+
+    /* Locate the faulting address in our list of shared segments
+     */
+    xorg_list_for_each_entry(busfault, &busfaults, list) {
+        if ((char *) busfault->addr <= (char *) fault && (char *) fault < (char *) busfault->addr + busfault->size) {
+            break;
+        }
+    }
+    if (!busfault)
+        goto panic;
+
+    if (!busfault->valid)
+        goto panic;
+
+    busfault->valid = FALSE;
+    busfaulted = TRUE;
+
+    /* The client truncated the file; unmap the shared file, map
+     * /dev/zero over that area and keep going
+     */
+
+    new_addr = mmap(busfault->addr, busfault->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
+
+    if (new_addr == MAP_FAILED)
+        goto panic;
+
+    return;
+panic:
+    if (previous_busfault_sigaction)
+        (*previous_busfault_sigaction)(sig, info, param);
+    else
+        FatalError("bus error");
+}
+
+Bool
+busfault_init(void)
+{
+    struct sigaction    act, old_act;
+
+    act.sa_sigaction = busfault_sigaction;
+    act.sa_flags = SA_SIGINFO;
+    if (sigaction(SIGBUS, &act, &old_act) < 0)
+        return FALSE;
+    previous_busfault_sigaction = old_act.sa_sigaction;
+    xorg_list_init(&busfaults);
+    return TRUE;
+}
diff --git a/os/osinit.c b/os/osinit.c
index 6c66f9c..60d1069 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -149,6 +149,8 @@ OsSigHandler(int signo)
 }
 #endif /* !WIN32 || __CYGWIN__ */
 
+#include "busfault.h"
+
 void
 OsInit(void)
 {
@@ -185,6 +187,9 @@ OsInit(void)
             }
         }
 #endif /* !WIN32 || __CYGWIN__ */
+#ifdef BUSFAULT
+        busfault_init();
+#endif
 
 #ifdef HAVE_BACKTRACE
         /*
commit 719e880d7698d92f9b854b217ef9680aaa446f2e
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 6 23:22:51 2013 -0800

    Require libXtrans version 1.3.2
    
    This has the FD passing support included
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/configure.ac b/configure.ac
index 96ceb4c..04de2cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -806,7 +806,7 @@ FIXESPROTO="fixesproto >= 5.0"
 DAMAGEPROTO="damageproto >= 1.1"
 XCMISCPROTO="xcmiscproto >= 1.2.0"
 BIGREQSPROTO="bigreqsproto >= 1.1.0"
-XTRANS="xtrans >= 1.2.2"
+XTRANS="xtrans >= 1.3.2"
 PRESENTPROTO="presentproto >= 1.0"
 
 dnl List of libraries that require a specific version
commit bee2ec54049377e0033d49abff20d7bd069c62aa
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Nov 3 10:08:15 2013 -0800

    Xext: Enable MIT-SHM FD-passing request definitions only when possible
    
    Check to see if xtrans FD passing is available and use that to
    advertise the appropriate version of the SHM extension
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/Xext/shm.c b/Xext/shm.c
index 1a70260..109a381 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -384,7 +384,7 @@ ProcShmAttach(ClientPtr client)
         return BadValue;
     }
     for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next) {
-        if (!shmdesc->is_fd && shmdesc->shmid == stuff->shmid)
+        if (!SHMDESC_IS_FD(shmdesc) && shmdesc->shmid == stuff->shmid)
             break;
     }
     if (shmdesc) {
@@ -396,7 +396,9 @@ ProcShmAttach(ClientPtr client)
         shmdesc = malloc(sizeof(ShmDescRec));
         if (!shmdesc)
             return BadAlloc;
+#ifdef SHM_FD_PASSING
         shmdesc->is_fd = FALSE;
+#endif
         shmdesc->addr = shmat(stuff->shmid, 0,
                               stuff->readOnly ? SHM_RDONLY : 0);
         if ((shmdesc->addr == ((char *) -1)) || SHMSTAT(stuff->shmid, &buf)) {
@@ -435,9 +437,11 @@ ShmDetachSegment(pointer value, /* must conform to DeleteType */
 
     if (--shmdesc->refcnt)
         return TRUE;
+#if SHM_FD_PASSING
     if (shmdesc->is_fd)
         munmap(shmdesc->addr, shmdesc->size);
     else
+#endif
         shmdt(shmdesc->addr);
     for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next);
     *prev = shmdesc->next;
@@ -1094,6 +1098,7 @@ ProcShmCreatePixmap(ClientPtr client)
     return BadAlloc;
 }
 
+#ifdef SHM_FD_PASSING
 static int
 ProcShmAttachFd(ClientPtr client)
 {
@@ -1209,6 +1214,7 @@ ProcShmCreateSegment(ClientPtr client)
     WriteToClient(client, sizeof (xShmCreateSegmentReply), &rep);
     return Success;
 }
+#endif /* SHM_FD_PASSING */
 
 static int
 ProcShmDispatch(ClientPtr client)
@@ -1239,10 +1245,12 @@ ProcShmDispatch(ClientPtr client)
             return ProcPanoramiXShmCreatePixmap(client);
 #endif
         return ProcShmCreatePixmap(client);
+#ifdef SHM_FD_PASSING
     case X_ShmAttachFd:
         return ProcShmAttachFd(client);
     case X_ShmCreateSegment:
         return ProcShmCreateSegment(client);
+#endif
     default:
         return BadRequest;
     }
@@ -1343,6 +1351,7 @@ SProcShmCreatePixmap(ClientPtr client)
     return ProcShmCreatePixmap(client);
 }
 
+#ifdef SHM_FD_PASSING
 static int
 SProcShmAttachFd(ClientPtr client)
 {
@@ -1364,6 +1373,7 @@ SProcShmCreateSegment(ClientPtr client)
     swapl(&stuff->size);
     return ProcShmCreateSegment(client);
 }
+#endif  /* SHM_FD_PASSING */
 
 static int
 SProcShmDispatch(ClientPtr client)
@@ -1382,10 +1392,12 @@ SProcShmDispatch(ClientPtr client)
         return SProcShmGetImage(client);
     case X_ShmCreatePixmap:
         return SProcShmCreatePixmap(client);
+#ifdef SHM_FD_PASSING
     case X_ShmAttachFd:
         return SProcShmAttachFd(client);
     case X_ShmCreateSegment:
         return SProcShmCreateSegment(client);
+#endif
     default:
         return BadRequest;
     }
diff --git a/Xext/shmint.h b/Xext/shmint.h
index db35fbb..7b3ea9b 100644
--- a/Xext/shmint.h
+++ b/Xext/shmint.h
@@ -56,16 +56,31 @@ typedef struct _ShmFuncs {
     void (*PutImage) (XSHM_PUT_IMAGE_ARGS);
 } ShmFuncs, *ShmFuncsPtr;
 
+#include <protocol-versions.h>
+
+#if SERVER_SHM_MAJOR_VERSION == 1 && SERVER_SHM_MINOR_VERSION >= 2
+#define SHM_FD_PASSING  1
+#endif
+
 typedef struct _ShmDesc {
     struct _ShmDesc *next;
     int shmid;
     int refcnt;
     char *addr;
-    Bool is_fd;
     Bool writable;
     unsigned long size;
+#ifdef SHM_FD_PASSING
+    Bool is_fd;
+    XID resource;
+#endif
 } ShmDescRec, *ShmDescPtr;
 
+#ifdef SHM_FD_PASSING
+#define SHMDESC_IS_FD(shmdesc)  ((shmdesc)->is_fd)
+#else
+#define SHMDESC_IS_FD(shmdesc)  (0)
+#endif
+
 extern _X_EXPORT void
  ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs);
 
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index 5ceaeb0..95df8ce 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -93,7 +93,11 @@
 
 /* SHM */
 #define SERVER_SHM_MAJOR_VERSION		1
+#if XTRANS_SEND_FDS
+#define SERVER_SHM_MINOR_VERSION		2
+#else
 #define SERVER_SHM_MINOR_VERSION		1
+#endif
 
 /* Sync */
 #define SERVER_SYNC_MAJOR_VERSION		3
commit ea8acfe3e2f74a46c3f1e91809b4b99af18502b7
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 6 23:06:28 2013 -0800

    Require xextproto version 7.2.99.901
    
    This includes the MIT-SHM FD passing requests
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/configure.ac b/configure.ac
index e223202..96ceb4c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -798,7 +798,7 @@ dnl Required modules
 XPROTO="xproto >= 7.0.22"
 RANDRPROTO="randrproto >= 1.4.0"
 RENDERPROTO="renderproto >= 0.11"
-XEXTPROTO="xextproto >= 7.1.99"
+XEXTPROTO="xextproto >= 7.2.99.901"
 INPUTPROTO="inputproto >= 2.3"
 KBPROTO="kbproto >= 1.0.3"
 FONTSPROTO="fontsproto"
commit 914672fefacc15386041e7c2bc3beed4faf45e9d
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 7 14:20:26 2013 -0800

    Remove dix-config.h config variables from xorg-config.h
    
    xorg-config.h includes dix-config, so there's no need to duplicate.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index e3444da..487d7ad 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -145,7 +145,4 @@
 /* Support APM/ACPI power management in the server */
 #undef XF86PM
 
-/* Have support for X shared memory fence library (xshmfence) */
-#undef HAVE_XSHMFENCE
-
 #endif /* _XORG_CONFIG_H_ */
commit 7aad79c5a582ece301d950bd65f0bcb4b9956e86
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 6 23:05:46 2013 -0800

    Make XTrans FD passing support optional. Define only on Linux
    
    Until other operating systems have a libXtrans port for FD passing,
    disable this on non-Linux systems.
    
    Note that this define affects how libXtrans gets built into the X
    server, which is why it need only define the symbol
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 6925df8..e223202 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1118,6 +1118,41 @@ case "$DRI2,$HAVE_DRI2PROTO" in
 esac
 AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
 
+AC_ARG_ENABLE(xtrans-send-fds,	AS_HELP_STRING([--disable-xtrans-send-fds], [Use Xtrans support for fd passing (default: auto)]), [XTRANS_SEND_FDS=$enableval], [XTRANS_SEND_FDS=auto])
+
+case "x$XTRANS_SEND_FDS" in
+xauto)
+	case "$host_os" in
+	linux*)
+		XTRANS_SEND_FDS=yes
+		;;
+	*)
+		XTRANS_SEND_FDS=no
+		;;
+	esac
+esac
+
+case "x$XTRANS_SEND_FDS" in
+xyes)
+	AC_DEFINE(XTRANS_SEND_FDS, 1, [Enable xtrans fd passing support])
+	;;
+esac
+
+case "$DRI3,$XTRANS_SEND_FDS" in
+	yes,yes | auto,yes)
+		;;
+	yes,no)
+		AC_MSG_ERROR([DRI3 requested, but xtrans fd passing support not found.])
+		DRI3=no
+		;;
+	no,*)
+		;;
+	*)
+		AC_MSG_NOTICE([DRI3 disabled because xtrans fd passing support not found.])
+		DRI3=no
+		;;
+esac
+
 PKG_CHECK_MODULES([DRI3PROTO], $DRI3PROTO,
                   [HAVE_DRI3PROTO=yes], [HAVE_DRI3PROTO=no])
 
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 156383b..e4eea8d 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -452,4 +452,7 @@
 /* Have support for X shared memory fence library (xshmfence) */
 #undef HAVE_XSHMFENCE
 
+/* Use XTrans FD passing support */
+#undef XTRANS_SEND_FDS
+
 #endif /* _DIX_CONFIG_H_ */
diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in
index 960817e..0c651bf 100644
--- a/include/xorg-server.h.in
+++ b/include/xorg-server.h.in
@@ -221,4 +221,7 @@
 /* Have support for X shared memory fence library (xshmfence) */
 #undef HAVE_XSHMFENCE
 
+/* Use XTrans FD passing support */
+#undef XTRANS_SEND_FDS
+
 #endif /* _XORG_SERVER_H_ */


More information about the Xquartz-changes mailing list