GL/glx/glxdri.c | 17 debian/changelog | 25 + debian/patches/15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch | 190 ++++++++ debian/patches/16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch | 96 ++++ debian/patches/17_x86emu_handle_cpuid.patch | 230 ++++++++++ debian/patches/series | 3 exa/exa.c | 2 exa/exa_accel.c | 2 exa/exa_render.c | 1 include/xkbsrv.h | 16 xkb/xkbActions.c | 9 xkb/xkbUtils.c | 23 - 12 files changed, 588 insertions(+), 26 deletions(-)
New commits: commit fa82a1ac6d1544be1654abc182b9fbd347c68156 Author: Julien Cristau <[EMAIL PROTECTED]> Date: Tue Apr 1 17:48:30 2008 +0200 Update changelog with cherry-picked patches diff --git a/debian/changelog b/debian/changelog index ecdcc51..689b0d3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,13 @@ xorg-server (2:1.4.1~git20080131-3) UNRELEASED; urgency=low stuck (closes: #473165). * xkb: when copying the keymap, make sure the structs default to 0/NULL (cherry-picked from upstream). Fixes a crash and closes: #461783. + * __glXDRIbindTexImage: Fail if no texture bound to pixmap's texture target + (cherry-picked from upstream). + * EXA: Fix off-by-one in polyline drawing (cherry-picked from upstream). + * EXA: Skip empty glyphs (cherry-picked from upstream). + * Fix overly-restrictive integer overflow check in EXA pixmap creation + (cherry-picked from upstream). Fixes BadAlloc errors returned by + XCreatePixmap for pixmaps of width 8192 or greater (closes: #471782). Following patches by Bart Trojanowski, stolen from the ubuntu package: * 15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch commit c62a00cffab4b588b4574418610e7344c575fc12 Author: Eric Anholt <[EMAIL PROTECTED]> Date: Fri Aug 17 12:14:16 2007 -0700 Fix overly-restrictive integer overflow check in EXA pixmap creation. The result was that at 32bpp, pixmaps of width 8192 or greater couldn't be created, due to treating a pitch value as a width. diff --git a/exa/exa.c b/exa/exa.c index aa42b92..b2faf2f 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -253,7 +253,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) pExaScr->info->pixmapPitchAlign); pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; - if (pExaPixmap->fb_pitch > 32767) { + if (pExaPixmap->fb_pitch > 131071) { fbDestroyPixmap(pPixmap); return NULL; } commit 6763ecba754eb0e88c3c78a2833e30806709c21c Author: Michel Dänzer <[EMAIL PROTECTED]> Date: Thu Oct 18 17:44:48 2007 +0200 EXA: Skip empty glyphs. diff --git a/exa/exa_render.c b/exa/exa_render.c index 2dd3fc1..ad1c02b 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -1184,6 +1184,7 @@ exaGlyphs (CARD8 op, y1 = y - glyph->info.y; if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height || + glyph->info.width == 0 || glyph->info.height == 0 || (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) goto nextglyph; commit 4aea0c011c6888b1d826f9678e79aa5d73cebf9c Author: Pierre Willenbrock <[EMAIL PROTECTED]> Date: Tue Oct 23 16:45:13 2007 +0200 EXA: Fix off-by-one in polyline drawing. diff --git a/exa/exa_accel.c b/exa/exa_accel.c index aed4e42..e8444c6 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -535,7 +535,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, x1 = ppt[0].x; y1 = ppt[0].y; /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < npt; i++) { + for (i = 0; i < npt - 1; i++) { if (mode == CoordModePrevious) { x2 = x1 + ppt[i + 1].x; y2 = y1 + ppt[i + 1].y; commit a9173e10b530abcd302b59a09fb2c61e8914aebe Author: Michel Dänzer <[EMAIL PROTECTED]> Date: Fri Aug 24 13:04:48 2007 +0200 __glXDRIbindTexImage: Fail if no texture bound to pixmap's texture target. We would most likely crash somewhere in Mesa if we tried to continue in this case. diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index 09abca3..4f80155 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -374,17 +374,25 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, { RegionPtr pRegion = NULL; PixmapPtr pixmap; - int bpp, override = 0; + int bpp, override = 0, texname; GLenum format, type; ScreenPtr pScreen = glxPixmap->pScreen; __GLXDRIscreen * const screen = (__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum); + CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ? + GL_TEXTURE_BINDING_2D : + GL_TEXTURE_BINDING_RECTANGLE_NV, + &texname)); + + if (!texname) + return __glXError(GLXBadContextState); + pixmap = (PixmapPtr) glxPixmap->pDraw; if (screen->texOffsetStart && screen->driScreen.setTexOffset) { __GLXpixmap **texOffsetOverride = screen->texOffsetOverride; - int i, firstEmpty = 16, texname; + int i, firstEmpty = 16; for (i = 0; i < 16; i++) { if (texOffsetOverride[i] == glxPixmap) @@ -409,11 +417,6 @@ alreadyin: glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext; - CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ? - GL_TEXTURE_BINDING_2D : - GL_TEXTURE_BINDING_RECTANGLE_NV, - &texname)); - if (texname == glxPixmap->texname) return Success; commit b7cede6e5b1c14bb4a1fc445125994b3e06f0e47 Author: Julien Cristau <[EMAIL PROTECTED]> Date: Tue Apr 1 16:38:50 2008 +0200 Update changelog, add closers. diff --git a/debian/changelog b/debian/changelog index 608528c..ecdcc51 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,10 @@ xorg-server (2:1.4.1~git20080131-3) UNRELEASED; urgency=low * XKB: Fix processInputProc wrapping (cherry-picked from upstream). - Thanks to Thomas Jaeger. + Thanks to Thomas Jaeger. This should fix the bug with some keys getting + stuck (closes: #473165). + * xkb: when copying the keymap, make sure the structs default to 0/NULL + (cherry-picked from upstream). Fixes a crash and closes: #461783. Following patches by Bart Trojanowski, stolen from the ubuntu package: * 15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch commit 98037d1922f7a637d1a68503280d5bcfab3e050d Author: Peter Hutterer <[EMAIL PROTECTED]> Date: Thu Feb 7 15:48:04 2008 +1030 xkb: when copying the keymap, make sure the structs default to 0/NULL. It actually does help if a pointer is NULL rather than pointing to nirvana when you're trying to free it lateron. Who would have thought? diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c index e90df0d..ce4df4c 100644 --- a/xkb/xkbUtils.c +++ b/xkb/xkbUtils.c @@ -1707,9 +1707,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) else { if (dst->geom->sz_shapes) { xfree(dst->geom->shapes); - dst->geom->shapes = NULL; } - + dst->geom->shapes = NULL; dst->geom->num_shapes = 0; dst->geom->sz_shapes = 0; } @@ -1758,6 +1757,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) } dst->geom->num_sections = 0; + dst->geom->sections = NULL; } if (src->geom->num_sections) { @@ -1769,6 +1769,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) tmp = xalloc(src->geom->num_sections * sizeof(XkbSectionRec)); if (!tmp) return FALSE; + memset(tmp, 0, src->geom->num_sections * sizeof(XkbSectionRec)); dst->geom->sections = tmp; dst->geom->num_sections = src->geom->num_sections; @@ -1804,6 +1805,10 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) return FALSE; dsection->doodads = tmp; } + else { + dsection->doodads = NULL; + } + for (k = 0, sdoodad = ssection->doodads, ddoodad = dsection->doodads; @@ -1831,9 +1836,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) else { if (dst->geom->sz_sections) { xfree(dst->geom->sections); - dst->geom->sections = NULL; } + dst->geom->sections = NULL; dst->geom->num_sections = 0; dst->geom->sz_sections = 0; } @@ -1862,6 +1867,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) } } } + dst->geom->num_doodads = 0; + dst->geom->doodads = NULL; } if (src->geom->num_doodads) { @@ -1874,7 +1881,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) sizeof(XkbDoodadRec)); if (!tmp) return FALSE; - bzero(tmp, src->geom->num_doodads * sizeof(XkbDoodadRec)); + memset(tmp, 0, src->geom->num_doodads * sizeof(XkbDoodadRec)); dst->geom->doodads = tmp; dst->geom->sz_doodads = src->geom->num_doodads; @@ -1903,9 +1910,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) else { if (dst->geom->sz_doodads) { xfree(dst->geom->doodads); - dst->geom->doodads = NULL; } + dst->geom->doodads = NULL; dst->geom->num_doodads = 0; dst->geom->sz_doodads = 0; } @@ -1933,10 +1940,10 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) dst->geom->num_key_aliases = dst->geom->sz_key_aliases; } else { - if (dst->geom->sz_key_aliases && dst->geom->key_aliases) { + if (dst->geom->key_aliases) { xfree(dst->geom->key_aliases); - dst->geom->key_aliases = NULL; } + dst->geom->key_aliases = NULL; dst->geom->num_key_aliases = 0; dst->geom->sz_key_aliases = 0; } @@ -1967,8 +1974,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) else { if (dst->geom->label_font) { xfree(dst->geom->label_font); - dst->geom->label_font = NULL; } + dst->geom->label_font = NULL; dst->geom->label_color = NULL; dst->geom->base_color = NULL; } commit 7d9fc60aec35b694918b2baac1bdb56933bfb298 Author: Julien Cristau <[EMAIL PROTECTED]> Date: Tue Apr 1 16:25:07 2008 +0200 Add 17_x86emu_handle_cpuid.patch to fix X86EMU CPUID handling. Closes: #451089 diff --git a/debian/changelog b/debian/changelog index 34ca6bf..608528c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,8 @@ xorg-server (2:1.4.1~git20080131-3) UNRELEASED; urgency=low - Restrict access to I/O ports in range 0-0xFF from x86emu. * 16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch - Fix improper emulation of PCI access General Software BIOS. + * Add 151_x86emu_handle_cpuid.patch to fix X86EMU CPUID handling. + (closes: #451089). -- Julien Cristau <[EMAIL PROTECTED]> Tue, 01 Apr 2008 15:56:23 +0200 diff --git a/debian/patches/17_x86emu_handle_cpuid.patch b/debian/patches/17_x86emu_handle_cpuid.patch new file mode 100644 index 0000000..1a69fb6 --- /dev/null +++ b/debian/patches/17_x86emu_handle_cpuid.patch @@ -0,0 +1,230 @@ +From e76dd7d7991b32cfc0f64bddcdcee201f34a85c5 Mon Sep 17 00:00:00 2001 +From: Bart Trojanowski <[EMAIL PROTECTED]> +Date: Sat, 2 Feb 2008 12:21:57 -0500 +Subject: [PATCH] X86EMU: handle CPUID instruction + +This bug is tracked here: +https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-amd/+bug/180742 + +After trying to switch from X to VT (or just quit) the video-amd driver +attempts to issue INT 10/0 to go to mode 3 (VGA). The emulator, running +the BIOS code, would then spit out: + + c000:0282: A2 ILLEGAL EXTENDED X86 OPCODE! + +The opcode was 0F A2, or CPUID; it was not implemented in the emulator. +This simple patch, against 1.3.0.0, handles the CPUID instruction in one of +two ways: + 1) if ran on __i386__ or __x86_64__ then it calls the CPUID instruction + directly. + 2) if ran elsewhere it returns a canned 486dx4 set of values for + function 1. + +This fix allows the video-amd driver to switch back to console mode, +with the GSW BIOS. + +Thanks to Symbio Technologies for funding my work, and ThinCan for +providing hardware :) + +Signed-off-by: Bart Trojanowski <[EMAIL PROTECTED]> +--- + hw/xfree86/x86emu/ops2.c | 16 ++++++- + hw/xfree86/x86emu/prim_ops.c | 44 +++++++++++++++++ + hw/xfree86/x86emu/x86emu/prim_ops.h | 1 + + hw/xfree86/x86emu/x86emu/prim_x86_gcc.h | 79 +++++++++++++++++++++++++++++++ + 4 files changed, 139 insertions(+), 1 deletions(-) + create mode 100644 hw/xfree86/x86emu/x86emu/prim_x86_gcc.h + +diff --git a/hw/xfree86/x86emu/ops2.c b/hw/xfree86/x86emu/ops2.c +index 8c6c535..324de8a 100644 +--- a/hw/xfree86/x86emu/ops2.c ++++ b/hw/xfree86/x86emu/ops2.c +@@ -328,6 +328,20 @@ static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)) + } + + /**************************************************************************** ++REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output ++Handles opcode 0x0f,0xa2 ++****************************************************************************/ ++static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2)) ++{ ++ START_OF_INSTR(); ++ DECODE_PRINTF("CPUID\n"); ++ TRACE_AND_STEP(); ++ cpuid(); ++ DECODE_CLEAR_SEGOVR(); ++ END_OF_INSTR(); ++} ++ ++/**************************************************************************** + REMARKS: + Handles opcode 0x0f,0xa3 + ****************************************************************************/ +@@ -2734,7 +2748,7 @@ void (*x86emu_optab2[256])(u8) = + + /* 0xa0 */ x86emuOp2_push_FS, + /* 0xa1 */ x86emuOp2_pop_FS, +-/* 0xa2 */ x86emuOp2_illegal_op, ++/* 0xa2 */ x86emuOp2_cpuid, + /* 0xa3 */ x86emuOp2_bt_R, + /* 0xa4 */ x86emuOp2_shld_IMM, + /* 0xa5 */ x86emuOp2_shld_CL, +diff --git a/hw/xfree86/x86emu/prim_ops.c b/hw/xfree86/x86emu/prim_ops.c +index 461e09e..07ccfe5 100644 +--- a/hw/xfree86/x86emu/prim_ops.c ++++ b/hw/xfree86/x86emu/prim_ops.c +@@ -102,6 +102,12 @@ + #define PRIM_OPS_NO_REDEFINE_ASM + #include "x86emu/x86emui.h" + ++#if defined(__GNUC__) ++# if defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__) ++# include "x86emu/prim_x86_gcc.h" ++# endif ++#endif ++ + /*------------------------- Global Variables ------------------------------*/ + + static u32 x86emu_parity_tab[8] = +@@ -2654,3 +2660,41 @@ DB( if (CHECK_SP_ACCESS()) + return res; + } + ++/**************************************************************************** ++REMARKS: ++CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output ++****************************************************************************/ ++void cpuid (void) ++{ ++ u32 feature = M.x86.R_EAX; ++#ifdef X86EMU_HAS_HW_CPUID ++ hw_cpuid(&M.x86.R_EAX, &M.x86.R_EBX, &M.x86.R_ECX, &M.x86.R_EDX); ++#endif ++ switch (feature) { ++ case 0: ++ M.x86.R_EAX = 1; // maximum function number we support ++#ifndef X86EMU_HAS_PRIM_CPUID ++ M.x86.R_EBX = 0x756e6547; ++ M.x86.R_ECX = 0x6c65746e; ++ M.x86.R_EDX = 0x49656e69; ++#endif ++ break; ++ case 1: ++#ifndef X86EMU_HAS_PRIM_CPUID ++ M.x86.R_EAX = 0x00000480; // 486dx4 ++ M.x86.R_EBX = 0x00000000; ++ M.x86.R_ECX = 0x00000000; ++ M.x86.R_EDX = 0x00000002; // VME ++#else ++ M.x86.R_EDX &= 0x00000012; // TSC and VME ++#endif ++ break; ++ default: ++ M.x86.R_EAX = 0; // don't support extended features ++ M.x86.R_EBX = 0; ++ M.x86.R_ECX = 0; ++ M.x86.R_EDX = 0; ++ break; ++ } ++} ++ +diff --git a/hw/xfree86/x86emu/x86emu/prim_ops.h b/hw/xfree86/x86emu/x86emu/prim_ops.h +index bea8357..6ac2a29 100644 +--- a/hw/xfree86/x86emu/x86emu/prim_ops.h ++++ b/hw/xfree86/x86emu/x86emu/prim_ops.h +@@ -133,6 +133,7 @@ void push_word (u16 w); + void push_long (u32 w); + u16 pop_word (void); + u32 pop_long (void); ++void cpuid (void); + + #ifdef __cplusplus + } /* End of "C" linkage for C++ */ +diff --git a/hw/xfree86/x86emu/x86emu/prim_x86_gcc.h b/hw/xfree86/x86emu/x86emu/prim_x86_gcc.h +new file mode 100644 +index 0000000..c085ddc +--- /dev/null ++++ b/hw/xfree86/x86emu/x86emu/prim_x86_gcc.h +@@ -0,0 +1,79 @@ ++/**************************************************************************** ++* ++* Inline helpers for x86emu ++* ++* Copyright (C) 2008 Bart Trojanowski, Symbio Technologies, LLC ++* ++* ======================================================================== ++* ++* 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 authors not be used ++* in advertising or publicity pertaining to distribution of the software ++* without specific, written prior permission. The authors makes no ++* representations about the suitability of this software for any purpose. ++* It is provided "as is" without express or implied warranty. ++* ++* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++* EVENT SHALL THE AUTHORS 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. ++* ++* ======================================================================== ++* ++* Language: GNU C ++* Environment: GCC on i386 or x86-64 ++* Developer: Bart Trojanowski ++* ++* Description: This file defines a few x86 macros that can be used by the ++* emulator to execute native instructions. ++* ++* For PIC vs non-PIC code refer to: ++* http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well ++* ++****************************************************************************/ ++#ifndef __X86EMU_PRIM_X86_GCC_H ++#define __X86EMU_PRIM_X86_GCC_H ++ ++#include "x86emu/types.h" ++ ++#if !defined(__GNUC__) || !(defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__)) ++#error This file is intended to be used by gcc on i386 or x86-64 system ++#endif ++ ++#if defined(__PIC__) && defined(__i386__) ++ ++#define X86EMU_HAS_HW_CPUID 1 ++static inline void hw_cpuid (u32 *a, u32 *b, u32 *c, u32 *d) ++{ ++ __asm__ __volatile__ ("pushl %%ebx \n\t" ++ "cpuid \n\t" ++ "movl %%ebx, %1 \n\t" ++ "popl %%ebx \n\t" ++ : "=a" (*a), "=r" (*b), ++ "=c" (*c), "=d" (*d) ++ : "a" (*a), "c" (*c) ++ : "cc"); ++} ++ ++#else // ! (__PIC__ && __i386__) ++ ++#define X86EMU_HAS_HW_CPUID 1 ++static inline void hw_cpuid (u32 *a, u32 *b, u32 *c, u32 *d) ++{ ++ __asm__ __volatile__ ("cpuid" ++ : "=a" (*a), "=b" (*b), ++ "=c" (*c), "=d" (*d) ++ : "a" (*a), "c" (*c) ++ : "cc"); ++} ++ ++#endif // __PIC__ && __i386__ ++ ++ ++#endif // __X86EMU_PRIM_X86_GCC_H +-- +1.5.3.7.1150.g149d432 + diff --git a/debian/patches/series b/debian/patches/series index 83cc18a..845fa9f 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -12,6 +12,7 @@ 14_default_screen_section.diff 15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch 16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch +17_x86emu_handle_cpuid.patch 21_glx_align_fixes.patch 40_default_dpi_96.patch 41_vbe_filter_less.diff commit d469b5a9c437ff0937d5079ca1f7bd8fcf9b42aa Author: Julien Cristau <[EMAIL PROTECTED]> Date: Tue Apr 1 16:01:18 2008 +0200 Add patches to fix broken -amd support. * 15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch - Restrict access to I/O ports in range 0-0xFF from x86emu. * 16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch - Fix improper emulation of PCI access General Software BIOS. https://launchpad.net/bugs/140051 diff --git a/debian/changelog b/debian/changelog index 14f1370..34ca6bf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,12 @@ xorg-server (2:1.4.1~git20080131-3) UNRELEASED; urgency=low * XKB: Fix processInputProc wrapping (cherry-picked from upstream). Thanks to Thomas Jaeger. + Following patches by Bart Trojanowski, stolen from the ubuntu package: + * 15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch + - Restrict access to I/O ports in range 0-0xFF from x86emu. + * 16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch + - Fix improper emulation of PCI access General Software BIOS. + -- Julien Cristau <[EMAIL PROTECTED]> Tue, 01 Apr 2008 15:56:23 +0200 xorg-server (2:1.4.1~git20080131-2) unstable; urgency=low diff --git a/debian/patches/15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch b/debian/patches/15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch new file mode 100644 index 0000000..e883d92 --- /dev/null +++ b/debian/patches/15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch @@ -0,0 +1,190 @@ +From 6061612987ebba7ca65835e658b8d969be13a22d Mon Sep 17 00:00:00 2001 +From: Bart Trojanowski <[EMAIL PROTECTED]> +Date: Fri, 11 Jan 2008 11:52:59 -0500 +Subject: [PATCH] X86EMU: added blacklist for I/O port in 0-0xFF range + +Signed-off-by: Bart Trojanowski <[EMAIL PROTECTED]> + +Work funded by: Symbio Technologies + +There seems to be an inconsistency between what the x86emu gets from the +PCI handling code and by accessing hardware directly. x86emu relies on +a set of functions to emulate PCI access. When things goes wrong, the +emulator is asked to execute an OUT instruction on port 0x20. + +I've put together a patch against xserver-xorg package that prevents +accesses to BAD registers. This turns a freeze into a segfault in X. + +http://www.jukie.net/~bart/patches/xorg-server/20080111/0001-X86EMU- +added-blacklist-for-I-O-port-in-0-0xFF-range.patch + +It does not address the DDC not working, I hope that after fixing the +bugs in x86emu, things may improve. + +Anyway, I am continuing to investigate the real cause of the PCI access +issue. To find out more read this thread: + +http://lists.freedesktop.org/archives/xorg/2008-January/031811.html + +-Bart + + +diff -Nurp xorg-server-1.4.1~git20080118/hw/xfree86/int10/helper_exec.c xorg-server-1.4.1~git20080118-working/hw/xfree86/int10/helper_exec.c +--- xorg-server-1.4.1~git20080118/hw/xfree86/int10/helper_exec.c 2008-01-18 13:23:40.000000000 -0800 ++++ xorg-server-1.4.1~git20080118-working/hw/xfree86/int10/helper_exec.c 2008-01-22 09:53:27.000000000 -0800 +@@ -21,6 +21,8 @@ + #define PRINT_PORT 0 + + #include <unistd.h> ++#include <sys/types.h> ++#include <signal.h> + + #include <X11/Xos.h> + #include "xf86.h" +@@ -210,6 +212,72 @@ stack_trace(xf86Int10InfoPtr pInt) + xf86ErrorFVerb(3, "\n"); + } + ++enum port_action_e { ++ PORT_ACTION_PERMIT, ++ PORT_ACTION_WARN, ++ PORT_ACTION_BAIL, ++ PORT_ACTION_MAX ++}; ++ ++static const struct port_range { ++ CARD16 start, end; ++ enum port_action_e access; ++} port_range_table[] = { ++ // NOTE: port ranges are non overlapping and sorted ++ { 0x00, 0x1f, PORT_ACTION_BAIL }, // DMA ++ { 0x20, 0x21, PORT_ACTION_BAIL }, // PIC ++ { 0x40, 0x47, PORT_ACTION_BAIL }, // PIT 1&2 ++ { 0x50, 0x53, PORT_ACTION_BAIL }, ++ { 0x70, 0x77, PORT_ACTION_BAIL }, // CMOS/RTC ++ { 0x81, 0x8f, PORT_ACTION_BAIL }, // DIAG REGS ++ { 0xa0, 0xa1, PORT_ACTION_BAIL }, // PIC2 ++ { 0xc0, 0xdf, PORT_ACTION_BAIL }, // DMA ++}; ++#define ARRAY_SIZE(X) (sizeof((X)) / (sizeof(*(X)))) ++#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)])) ++ ++static void assert_port_access_allowed (CARD16 port, CARD16 width) ++{ ++ CARD16 access_start, access_end; ++ const struct port_range *pr, *pr_start, *pr_end; ++ ++ access_start = port; ++ access_end = port + width - 1; ++ ++ // TODO: if the list gets too long we should do a binary search ++ // or convert the port list to a bitmap representation ++ pr_start = port_range_table; ++ pr_end = ARRAY_END(port_range_table); ++ ++ for (pr = pr_start; pr < pr_end; pr++) { ++ if (access_end < pr->start) ++ continue; ++ if (access_start > pr->end) ++ break; ++ ++ // we are in the pr range now ++ switch (pr->access) { ++ default: ++ continue; ++ case PORT_ACTION_BAIL: ++ case PORT_ACTION_WARN: ++ break; ++ } ++ ++ ErrorF("Emulator asked to make a suspect %saccess to " ++ "port %u (0x%04x)%s\n", ++ (width == 1) ? "byte " : ++ (width == 2) ? "word " : ++ (width == 4) ? "long " : "", ++ port, port, ++ (pr->access == PORT_ACTION_BAIL) ++ ? "; terminating." : "ignoring."); ++ ++ if (pr->access == PORT_ACTION_BAIL) ++ kill(getpid(), SIGSEGV); ++ } ++} ++ + int + port_rep_inb(xf86Int10InfoPtr pInt, + CARD16 port, CARD32 base, int d_f, CARD32 count) +@@ -319,7 +387,7 @@ x_inb(CARD16 port) + ErrorF(" inb(%#x) = %2.2x\n", port, val); + #ifdef __NOT_YET__ + } else if (port < 0x0100) { /* Don't interfere with mainboard */ +- val = 0; ++ val = 0; + xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2, + "inb 0x%4.4x\n", port); + if (xf86GetVerbosity() > 3) { +@@ -327,10 +395,14 @@ x_inb(CARD16 port) + stack_trace(Int10Current); + } + #endif /* __NOT_YET__ */ +- } else if (!pciCfg1inb(port, &val)) { +- val = inb(Int10Current->ioBase + port); +- if (PRINT_PORT && DEBUG_IO_TRACE()) +- ErrorF(" inb(%#x) = %2.2x\n", port, val); ++ } else { ++ assert_port_access_allowed (port, sizeof(val)); ++ ++ if (!pciCfg1inb(port, &val)) { ++ val = inb(Int10Current->ioBase + port); ++ if (PRINT_PORT && DEBUG_IO_TRACE()) ++ ErrorF(" inb(%#x) = %2.2x\n", port, val); ++ } + } + return val; + } +@@ -349,10 +421,14 @@ x_inw(CARD16 port) + */ + X_GETTIMEOFDAY(&tv); + val = (CARD16)(tv.tv_usec / 3); +- } else if (!pciCfg1inw(port, &val)) { +- val = inw(Int10Current->ioBase + port); +- if (PRINT_PORT && DEBUG_IO_TRACE()) +- ErrorF(" inw(%#x) = %4.4x\n", port, val); ++ } else { ++ assert_port_access_allowed (port, sizeof(val)); ++ ++ if (!pciCfg1inw(port, &val)) { ++ val = inw(Int10Current->ioBase + port); ++ if (PRINT_PORT && DEBUG_IO_TRACE()) ++ ErrorF(" inw(%#x) = %4.4x\n", port, val); ++ } + } + return val; + } +@@ -384,6 +460,8 @@ x_outb(CARD16 port, CARD8 val) + } else if (!pciCfg1outb(port, val)) { + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" outb(%#x, %2.2x)\n", port, val); ++ ++ assert_port_access_allowed (port, sizeof(val)); + outb(Int10Current->ioBase + port, val); + } + } +@@ -404,6 +482,8 @@ x_inl(CARD16 port) + { + CARD32 val; + ++ assert_port_access_allowed (port, sizeof(val)); ++ + if (!pciCfg1in(port, &val)) { + val = inl(Int10Current->ioBase + port); + if (PRINT_PORT && DEBUG_IO_TRACE()) +@@ -418,6 +498,8 @@ x_outl(CARD16 port, CARD32 val) + if (!pciCfg1out(port, val)) { + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" outl(%#x, %8.8x)\n", port, val); ++ ++ assert_port_access_allowed (port, sizeof(val)); + outl(Int10Current->ioBase + port, val); + } + } diff --git a/debian/patches/16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch b/debian/patches/16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch new file mode 100644 index 0000000..cfc7116 --- /dev/null +++ b/debian/patches/16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch @@ -0,0 +1,96 @@ +From 9c17439807c80876bf7027b17859714b31401ab9 Mon Sep 17 00:00:00 2001 +From: Bart Trojanowski <[EMAIL PROTECTED]> +Date: Fri, 11 Jan 2008 19:59:54 -0500 +Subject: [PATCH] X86EMU: pass the correct bus:dev:fn tag to pci emulation + +Signed-off-by: Bart Trojanowski <[EMAIL PROTECTED]> + +Work funded by: Symbio Technologies + +There seems to be an inconsistency between what the x86emu gets from the +PCI handling code and by accessing hardware directly. x86emu relies on +a set of functions to emulate PCI access. When things goes wrong, the +emulator is asked to execute an OUT instruction on port 0x20. + +I've put together a patch against xserver-xorg package that prevents +accesses to BAD registers. This turns a freeze into a segfault in X. + +http://www.jukie.net/~bart/patches/xorg-server/20080111/0001-X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch + +It does not address the DDC not working, I hope that after fixing the +bugs in x86emu, things may improve. + +Anyway, I am continuing to investigate the real cause of the PCI access +issue. To find out more read this thread: + +http://lists.freedesktop.org/archives/xorg/2008-January/031811.html + +-Bart + +diff -Nurp xorg-server-1.4.1~git20080118-patched/hw/xfree86/int10/helper_exec.c xorg-server-1.4.1~git20080118-working/hw/xfree86/int10/helper_exec.c +--- xorg-server-1.4.1~git20080118-patched/hw/xfree86/int10/helper_exec.c 2008-01-22 10:22:26.000000000 -0800 ++++ xorg-server-1.4.1~git20080118-working/hw/xfree86/int10/helper_exec.c 2008-01-22 11:00:52.000000000 -0800 +@@ -542,7 +542,8 @@ Mem_wl(CARD32 addr, CARD32 val) + + static CARD32 PciCfg1Addr = 0; + +-#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff) ++#define PCI_OFFSET(x) ((x) & 0x000000ff) ++#define PCI_TAG(x) ((x) & 0x00ffff00) + + static int + pciCfg1in(CARD16 addr, CARD32 *val) +@@ -552,7 +553,7 @@ pciCfg1in(CARD16 addr, CARD32 *val) + return 1; + } + if (addr == 0xCFC) { +- *val = pciReadLong(Int10Current->Tag, OFFSET(PciCfg1Addr)); ++ *val = pciReadLong(PCI_TAG(PciCfg1Addr), PCI_OFFSET(PciCfg1Addr)); + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" cfg_inl(%#x) = %8.8x\n", PciCfg1Addr, *val); + return 1; +@@ -570,7 +571,7 @@ pciCfg1out(CARD16 addr, CARD32 val) + if (addr == 0xCFC) { + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" cfg_outl(%#x, %8.8x)\n", PciCfg1Addr, val); +- pciWriteLong(Int10Current->Tag, OFFSET(PciCfg1Addr), val); ++ pciWriteLong(PCI_TAG(PciCfg1Addr), PCI_OFFSET(PciCfg1Addr), val); + return 1; + } + return 0; +@@ -588,7 +589,7 @@ pciCfg1inw(CARD16 addr, CARD16 *val) + } + if ((addr >= 0xCFC) && (addr <= 0xCFF)) { + offset = addr - 0xCFC; +- *val = pciReadWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset); ++ *val = pciReadWord(PCI_TAG(PciCfg1Addr), PCI_OFFSET(PciCfg1Addr) + offset); + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" cfg_inw(%#x) = %4.4x\n", PciCfg1Addr + offset, *val); + return 1; +@@ -611,7 +612,7 @@ pciCfg1outw(CARD16 addr, CARD16 val) + offset = addr - 0xCFC; + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" cfg_outw(%#x, %4.4x)\n", PciCfg1Addr + offset, val); +- pciWriteWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val); ++ pciWriteWord(PCI_TAG(PciCfg1Addr), PCI_OFFSET(PciCfg1Addr) + offset, val); + return 1; + } + return 0; +@@ -629,7 +630,7 @@ pciCfg1inb(CARD16 addr, CARD8 *val) + } + if ((addr >= 0xCFC) && (addr <= 0xCFF)) { + offset = addr - 0xCFC; +- *val = pciReadByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset); ++ *val = pciReadByte(PCI_TAG(PciCfg1Addr), PCI_OFFSET(PciCfg1Addr) + offset); + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" cfg_inb(%#x) = %2.2x\n", PciCfg1Addr + offset, *val); + return 1; +@@ -652,7 +653,7 @@ pciCfg1outb(CARD16 addr, CARD8 val) + offset = addr - 0xCFC; + if (PRINT_PORT && DEBUG_IO_TRACE()) + ErrorF(" cfg_outb(%#x, %2.2x)\n", PciCfg1Addr + offset, val); +- pciWriteByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val); ++ pciWriteByte(PCI_TAG(PciCfg1Addr), PCI_OFFSET(PciCfg1Addr) + offset, val); + return 1; + } + return 0; diff --git a/debian/patches/series b/debian/patches/series index d1576ad..83cc18a 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -10,6 +10,8 @@ 11_dont_crash_on_bad_dri_mode.diff 13_debian_add_xkbpath_env_variable.diff 14_default_screen_section.diff +15_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch +16_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch 21_glx_align_fixes.patch 40_default_dpi_96.patch 41_vbe_filter_less.diff commit 21c433da5711b32876092541342ee5174de95fdd Author: Julien Cristau <[EMAIL PROTECTED]> Date: Tue Apr 1 15:57:45 2008 +0200 Update changelog diff --git a/debian/changelog b/debian/changelog index e3824db..14f1370 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +xorg-server (2:1.4.1~git20080131-3) UNRELEASED; urgency=low + + * XKB: Fix processInputProc wrapping (cherry-picked from upstream). + Thanks to Thomas Jaeger. + + -- Julien Cristau <[EMAIL PROTECTED]> Tue, 01 Apr 2008 15:56:23 +0200 + xorg-server (2:1.4.1~git20080131-2) unstable; urgency=low [ Brice Goglin ] commit eb05b43152d481ba8c3b113243162769e5c20bd0 Author: Thomas Jaeger <[EMAIL PROTECTED]> Date: Tue Apr 1 15:27:06 2008 +0300 XKB: Fix processInputProc wrapping If input processing is frozen, only wrap realInputProc: don't smash processInputProc as well. When input processing is thawed, pIP will be rewrapped correctly. This supersedes the previous workaround in 50e80c9. Signed-off-by: Daniel Stone <[EMAIL PROTECTED]> (cherry picked from commit 37b1258f0a288a79ce6a3eef3559e17a67c4dd96) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index 9174eb6..acf3bb0 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -241,6 +241,14 @@ typedef struct _XkbSrvLedInfo { typedef struct { ProcessInputProc processInputProc; + /* If processInputProc is set to something different than realInputProc, + * UNWRAP and COND_WRAP will not touch processInputProc and update only + * realInputProc. This ensures that + * processInputProc == (frozen ? EnqueueEvent : realInputProc) + * + * WRAP_PROCESS_INPUT_PROC should only be called during initialization, + * since it may destroy this invariant. + */ ProcessInputProc realInputProc; DeviceUnwrapProc unwrapProc; } xkbDeviceInfoRec, *xkbDeviceInfoPtr; @@ -258,14 +266,14 @@ typedef struct device->public.processInputProc = proc; \ oldprocs->processInputProc = \ oldprocs->realInputProc = device->public.realInputProc; \ - if (proc != device->public.enqueueInputProc) \ - device->public.realInputProc = proc; \ + device->public.realInputProc = proc; \ oldprocs->unwrapProc = device->unwrapProc; \ device->unwrapProc = unwrapproc; #define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \ - backupproc = device->public.processInputProc; \ - device->public.processInputProc = oldprocs->processInputProc; \ + backupproc = device->public.realInputProc; \ + if (device->public.processInputProc == device->public.realInputProc)\ + device->public.processInputProc = oldprocs->realInputProc; \ device->public.realInputProc = oldprocs->realInputProc; \ device->unwrapProc = oldprocs->unwrapProc; diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 6edac29..59d34c5 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -50,15 +50,14 @@ xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, pointer data) { xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); - ProcessInputProc tmp = device->public.processInputProc; - ProcessInputProc dummy; /* unused, but neede for macro */ + ProcessInputProc backupproc; if(xkbPrivPtr->unwrapProc) xkbPrivPtr->unwrapProc = NULL; - UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, dummy); + UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); proc(device,data); - WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, - tmp,xkbUnwrapProc); -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]