diff options
Diffstat (limited to 'hw/kdrive/vesa')
-rw-r--r-- | hw/kdrive/vesa/Makefile.am | 2 | ||||
-rw-r--r-- | hw/kdrive/vesa/Xvesa.man | 21 | ||||
-rw-r--r-- | hw/kdrive/vesa/vesa.c | 13 | ||||
-rw-r--r-- | hw/kdrive/vesa/vm86.c | 57 | ||||
-rw-r--r-- | hw/kdrive/vesa/vm86.h | 9 |
5 files changed, 83 insertions, 19 deletions
diff --git a/hw/kdrive/vesa/Makefile.am b/hw/kdrive/vesa/Makefile.am index 2338672a8..8bfb8a919 100644 --- a/hw/kdrive/vesa/Makefile.am +++ b/hw/kdrive/vesa/Makefile.am @@ -31,10 +31,12 @@ Xvesa_LDADD = \ $(top_builddir)/miext/shadow/libshadow.a \ $(top_builddir)/randr/librandr.a \ $(top_builddir)/render/librender.a \ + $(top_builddir)/xfixes/libxfixes.a \ $(top_builddir)/fb/libfb.a \ $(top_builddir)/mi/libmi.a \ $(top_builddir)/Xext/libXext.a \ $(top_builddir)/randr/librandr.a \ $(top_builddir)/render/librender.a \ + $(top_builddir)/xfixes/libxfixes.a \ $(top_builddir)/dix/libxpstubs.a \ $(XSERVER_LIBS) diff --git a/hw/kdrive/vesa/Xvesa.man b/hw/kdrive/vesa/Xvesa.man index c09defdb6..fdac902ca 100644 --- a/hw/kdrive/vesa/Xvesa.man +++ b/hw/kdrive/vesa/Xvesa.man @@ -15,6 +15,7 @@ running the video BIOS in VM86 mode. .B Xvesa can use both standard VGA BIOS modes and any modes advertised by a VESA BIOS if available. + .B Xvesa runs untrusted code with full privileges, and is therefore a fairly insecure X server. @@ -29,8 +30,8 @@ specifies the VESA video mode to use. If mode .I n is not supported by your BIOS and hardware, .B Xvesa -will fail, hang your system, or cause your monitor to explode; you are -on your own. This option overrides any +will fail, hang your system, damage your hardware, or cause a global +thermonuclear war; you are on your own. This option overrides any .B -screen options. .TP 8 @@ -60,10 +61,24 @@ want to use this option. pass RGB values in the order that works on broken BIOSes. Use this if the colours are wrong in PseudoColor and 16 colour modes. .TP 8 +.B -map-holes +use a contiguous (hole-less) memory map. This fixes a segmentation +violation with some rare BIOSes that violate the VESA specification, +but may cause slightly higher memory usage on systems that overcommit +memory. +.TP 8 .B -verbose emit diagnostic messages during BIOS initialization and teardown. .SH KEYBOARD -To be written. +Multiple key presses recognized directly by +.B Xvesa +are: +.TP 8 +.B Ctrl+Alt+Backspace +Immediately kill the server. +.TP 8 +.B Ctrl+Alt+F1...F12 +Switch to virtual console 1 through 12. .SH BUGS .B Xvesa opens all IO ports and runs your VESA BIOS, which may be assumed to be diff --git a/hw/kdrive/vesa/vesa.c b/hw/kdrive/vesa/vesa.c index 4913dbd79..52cc3bcfa 100644 --- a/hw/kdrive/vesa/vesa.c +++ b/hw/kdrive/vesa/vesa.c @@ -38,6 +38,7 @@ Bool vesa_restore = FALSE; Bool vesa_verbose = FALSE; Bool vesa_force_text = FALSE; Bool vesa_restore_font = TRUE; +Bool vesa_map_holes = TRUE; #define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver) @@ -202,7 +203,7 @@ vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv) { int code; - priv->vi = Vm86Setup(); + priv->vi = Vm86Setup(vesa_map_holes); if(!priv->vi) goto fail; @@ -231,7 +232,7 @@ vesaListModes (void) int nmode; int n; - vi = Vm86Setup (); + vi = Vm86Setup (vesa_map_holes); if (!vi) { ErrorF ("Can't setup vm86\n"); @@ -267,7 +268,7 @@ vesaTestMode (void) int nmode; int n; - vi = Vm86Setup (); + vi = Vm86Setup (vesa_map_holes); if (!vi) { ErrorF ("Can't setup vm86\n"); @@ -1854,6 +1855,12 @@ vesaProcessArgument (int argc, char **argv, int i) } else if(!strcmp(argv[i], "-force-text")) { vesa_force_text = TRUE; return 1; + } else if(!strcmp(argv[i], "-map-holes")) { + vesa_map_holes = TRUE; + return 1; + } else if(!strcmp(argv[i], "-no-map-holes")) { + vesa_map_holes = FALSE; + return 1; } else if(!strcmp(argv[i], "-trash-font")) { vesa_restore_font = FALSE; return 1; diff --git a/hw/kdrive/vesa/vm86.c b/hw/kdrive/vesa/vm86.c index b5a3983ea..da85b83a9 100644 --- a/hw/kdrive/vesa/vm86.c +++ b/hw/kdrive/vesa/vm86.c @@ -66,10 +66,11 @@ static const U8 retcode_data[2] = { 0xCD, 0xFF }; Vm86InfoPtr -Vm86Setup(void) +Vm86Setup(int mapHoles) { int devmem = -1, devzero = -1; void *magicMem, *loMem, *hiMem; + void *hole1, *hole2; U32 stack_base, ret_code; Vm86InfoPtr vi = NULL; @@ -85,6 +86,12 @@ Vm86Setup(void) goto fail; } + magicMem = MAP_FAILED; + loMem = MAP_FAILED; + hiMem = MAP_FAILED; + hole1 = MAP_FAILED; + hole2 = MAP_FAILED; + magicMem = mmap((void*)MAGICMEM_BASE, MAGICMEM_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, @@ -92,7 +99,18 @@ Vm86Setup(void) if(magicMem == MAP_FAILED) { ErrorF("Couldn't map magic memory\n"); - goto fail; + goto unmapfail; + } + + if(mapHoles) { + hole1 = mmap((void*)HOLE1_BASE, HOLE1_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devzero, HOLE1_BASE); + + if(hole1 == MAP_FAILED) { + ErrorF("Couldn't map first hole\n"); + goto unmapfail; + } } loMem = mmap((void*)LOMEM_BASE, LOMEM_SIZE, @@ -101,7 +119,18 @@ Vm86Setup(void) if(loMem == MAP_FAILED) { ErrorF("Couldn't map low memory\n"); munmap(magicMem, MAGICMEM_SIZE); - goto fail; + goto unmapfail; + } + + if(mapHoles) { + hole2 = mmap((void*)HOLE2_BASE, HOLE2_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devzero, HOLE2_BASE); + + if(hole2 == MAP_FAILED) { + ErrorF("Couldn't map first hole\n"); + goto unmapfail; + } } hiMem = mmap((void*)HIMEM_BASE, HIMEM_SIZE, @@ -110,9 +139,7 @@ Vm86Setup(void) devmem, HIMEM_BASE); if(hiMem == MAP_FAILED) { ErrorF("Couldn't map high memory\n"); - munmap(magicMem, MAGICMEM_SIZE); - munmap(loMem, LOMEM_SIZE); - goto fail; + goto unmapfail; } vi = xalloc(sizeof(Vm86InfoRec)); @@ -120,7 +147,9 @@ Vm86Setup(void) goto unmapfail; vi->magicMem = magicMem; + vi->hole1 = hole1; vi->loMem = loMem; + vi->hole2 = hole2; vi->hiMem = hiMem; vi->brk = LOMEM_BASE; @@ -150,9 +179,11 @@ Vm86Setup(void) return vi; unmapfail: - munmap(magicMem, MAGICMEM_SIZE); - munmap(loMem, LOMEM_SIZE); - munmap(hiMem, HIMEM_SIZE); + if(magicMem != MAP_FAILED) munmap(magicMem, MAGICMEM_SIZE); + if(hole1 != MAP_FAILED) munmap(magicMem, HOLE1_SIZE); + if(loMem != MAP_FAILED) munmap(loMem, LOMEM_SIZE); + if(hole2 != MAP_FAILED) munmap(magicMem, HOLE2_SIZE); + if(hiMem != MAP_FAILED) munmap(hiMem, HIMEM_SIZE); fail: if(devmem >= 0) close(devmem); @@ -166,9 +197,11 @@ fail: void Vm86Cleanup(Vm86InfoPtr vi) { - munmap(vi->magicMem, MAGICMEM_SIZE); - munmap(vi->loMem, LOMEM_SIZE); - munmap(vi->hiMem, HIMEM_SIZE); + if(vi->magicMem != MAP_FAILED) munmap(vi->magicMem, MAGICMEM_SIZE); + if(vi->hole1 != MAP_FAILED) munmap(vi->magicMem, HOLE1_SIZE); + if(vi->loMem != MAP_FAILED) munmap(vi->loMem, LOMEM_SIZE); + if(vi->hole2 != MAP_FAILED) munmap(vi->magicMem, HOLE2_SIZE); + if(vi->hiMem != MAP_FAILED) munmap(vi->hiMem, HIMEM_SIZE); xfree(vi); } diff --git a/hw/kdrive/vesa/vm86.h b/hw/kdrive/vesa/vm86.h index e37cd7f28..dce777b39 100644 --- a/hw/kdrive/vesa/vm86.h +++ b/hw/kdrive/vesa/vm86.h @@ -91,6 +91,12 @@ typedef unsigned int U32; #define HIMEM_BASE 0xA0000 #define HIMEM_SIZE (SYSMEM_BASE + SYSMEM_SIZE - HIMEM_BASE) +#define HOLE1_BASE (MAGICMEM_BASE + MAGICMEM_SIZE) +#define HOLE1_SIZE (LOMEM_BASE - HOLE1_BASE) + +#define HOLE2_BASE (LOMEM_BASE + LOMEM_SIZE) +#define HOLE2_SIZE (HIMEM_BASE - HOLE2_BASE) + /* The BIOS ROM */ #define ROM_BASE 0xC0000 #define ROM_SIZE 0x30000 @@ -105,6 +111,7 @@ typedef unsigned int U32; typedef struct _Vm86InfoRec { void *magicMem, *loMem, *hiMem; + void *hole1, *hole2; U32 brk; struct vm86_struct vms; U32 ret_code, stack_base; @@ -121,7 +128,7 @@ typedef struct _Vm86InfoRec { #define HML(vi,i) (*(U32*)(&MM(vi,i))) Vm86InfoPtr -Vm86Setup(void); +Vm86Setup(int); void Vm86Cleanup(Vm86InfoPtr vi); |