diff options
author | Julien Cristau <jcristau@debian.org> | 2008-04-01 16:01:18 +0200 |
---|---|---|
committer | Julien Cristau <jcristau@debian.org> | 2008-04-01 17:08:26 +0200 |
commit | d469b5a9c437ff0937d5079ca1f7bd8fcf9b42aa (patch) | |
tree | c1c8df284e2e49cac7d6a0715dff02d166e7f984 /debian/patches | |
parent | 21c433da5711b32876092541342ee5174de95fdd (diff) |
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
Diffstat (limited to 'debian/patches')
3 files changed, 288 insertions, 0 deletions
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 000000000..e883d9246 --- /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 <bart@symbio-technologies.com> +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 <bart@jukie.net> + +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 000000000..cfc711678 --- /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 <bart@jukie.net> +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 <bart@jukie.net> + +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 d1576adb5..83cc18ace 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 |