modesetting: Allow a DRM fd to be passed on command line with -masterfd [v2]
This lets an application open a suitable DRM device and pass the file
descriptor to the mode setting driver through an X server command line
option, '-masterfd'.
There's a companion application, xlease, which creates a DRM master by
leasing an output from another X server. That is available at
git clone git://people.freedesktop.org/~keithp/xlease
v2:
Always print usage, but note that it can't be used if
setuid/gid
Suggested-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
(cherry picked from commit 38ff29ec8e
)
This commit is contained in:
parent
d60ce5b01f
commit
bc1882aa23
|
@ -53,6 +53,8 @@ DevPrivateKeyRec xf86ScreenKeyRec;
|
|||
ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */
|
||||
ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */
|
||||
|
||||
int xf86DRMMasterFd = -1; /* Command line argument for DRM master file descriptor */
|
||||
|
||||
const unsigned char byte_reversed[256] = {
|
||||
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
|
||||
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
|
||||
|
|
|
@ -93,6 +93,7 @@ extern _X_EXPORT int xf86LogVerbose; /* log file verbosity level */
|
|||
|
||||
extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */
|
||||
extern int xf86NumGPUScreens;
|
||||
extern _X_EXPORT int xf86DRMMasterFd; /* Command line argument for DRM master file descriptor */
|
||||
#ifndef DEFAULT_VERBOSE
|
||||
#define DEFAULT_VERBOSE 0
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "xf86.h"
|
||||
#include "xf86Priv.h"
|
||||
#include "xf86_OSproc.h"
|
||||
#include "compiler.h"
|
||||
#include "xf86Pci.h"
|
||||
|
@ -194,11 +195,24 @@ modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn)
|
|||
return pPriv->ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
get_passed_fd(void)
|
||||
{
|
||||
if (xf86DRMMasterFd >= 0) {
|
||||
xf86DrvMsg(-1, X_INFO, "Using passed DRM master file descriptor %d\n", xf86DRMMasterFd);
|
||||
return dup(xf86DRMMasterFd);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
open_hw(const char *dev)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = get_passed_fd()) != -1)
|
||||
return fd;
|
||||
|
||||
if (dev)
|
||||
fd = open(dev, O_RDWR | O_CLOEXEC, 0);
|
||||
else {
|
||||
|
@ -818,6 +832,12 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
ms->fd_passed = FALSE;
|
||||
if ((ms->fd = get_passed_fd()) >= 0) {
|
||||
ms->fd_passed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef XSERVER_PLATFORM_BUS
|
||||
if (pEnt->location.type == BUS_PLATFORM) {
|
||||
#ifdef XF86_PDEV_SERVER_FD
|
||||
|
@ -1502,6 +1522,9 @@ SetMaster(ScrnInfoPtr pScrn)
|
|||
return TRUE;
|
||||
#endif
|
||||
|
||||
if (ms->fd_passed)
|
||||
return TRUE;
|
||||
|
||||
ret = drmSetMaster(ms->fd);
|
||||
if (ret)
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n",
|
||||
|
@ -1754,7 +1777,8 @@ LeaveVT(ScrnInfoPtr pScrn)
|
|||
return;
|
||||
#endif
|
||||
|
||||
drmDropMaster(ms->fd);
|
||||
if (!ms->fd_passed)
|
||||
drmDropMaster(ms->fd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -84,6 +84,7 @@ struct ms_drm_queue {
|
|||
|
||||
typedef struct _modesettingRec {
|
||||
int fd;
|
||||
Bool fd_passed;
|
||||
|
||||
int Chipset;
|
||||
EntityInfoPtr pEnt;
|
||||
|
|
|
@ -346,6 +346,13 @@ xf86CloseConsole(void)
|
|||
close(xf86Info.consoleFd); /* make the vt-manager happy */
|
||||
}
|
||||
|
||||
#define CHECK_FOR_REQUIRED_ARGUMENT() \
|
||||
if (((i + 1) >= argc) || (!argv[i + 1])) { \
|
||||
ErrorF("Required argument to %s not specified\n", argv[i]); \
|
||||
UseMsg(); \
|
||||
FatalError("Required argument to %s not specified\n", argv[i]); \
|
||||
}
|
||||
|
||||
int
|
||||
xf86ProcessArgument(int argc, char *argv[], int i)
|
||||
{
|
||||
|
@ -366,6 +373,19 @@ xf86ProcessArgument(int argc, char *argv[], int i)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[i], "-masterfd")) {
|
||||
CHECK_FOR_REQUIRED_ARGUMENT();
|
||||
if (xf86PrivsElevated())
|
||||
FatalError("\nCannot specify -masterfd when server is setuid/setgid\n");
|
||||
if (sscanf(argv[++i], "%d", &xf86DRMMasterFd) != 1) {
|
||||
UseMsg();
|
||||
xf86DRMMasterFd = -1;
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -375,4 +395,5 @@ xf86UseMsg(void)
|
|||
ErrorF("vtXX use the specified VT number\n");
|
||||
ErrorF("-keeptty ");
|
||||
ErrorF("don't detach controlling tty (for debugging only)\n");
|
||||
ErrorF("-masterfd <fd> use the specified fd as the DRM master fd (not if setuid/gid)\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue