2009-04-09 23:06:58

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 0/6] x86, setup: "glove box" BIOS interrupts

This is a patchset to "glove box" off BIOS interrupts in the x86 setup
code, thus hopefully dealing once and for all with the problems of
BIOSes touching registers they shouldn't.

The concept is simple: we manipulate a register image in memory, then
swap it in immediately before calling the BIOS, and then switch the
register file back. All BIOS interrupts are channeled through this path.

The increase in size is about 8% or ~1.3K in the maximal case.

arch/x86/boot/Makefile | 5 +-
arch/x86/boot/a20.c | 9 +-
arch/x86/boot/apm.c | 76 +++++--------
arch/x86/boot/bioscall.S | 82 +++++++++++++
arch/x86/boot/boot.h | 48 ++++++++
arch/x86/boot/edd.c | 71 +++++-------
arch/x86/boot/header.S | 2 +-
arch/x86/boot/main.c | 39 ++++---
arch/x86/boot/mca.c | 27 ++---
arch/x86/boot/memory.c | 81 +++++++-------
arch/x86/boot/regs.c | 29 +++++
arch/x86/boot/setup.ld | 6 +
arch/x86/boot/tty.c | 52 +++++----
arch/x86/boot/video-bios.c | 27 ++---
arch/x86/boot/video-vesa.c | 137 ++++++++++------------
arch/x86/boot/video-vga.c | 95 +++++++++------
arch/x86/boot/video.c | 42 +++----
arch/x86/boot/video.h | 14 ---
arch/x86/kernel/acpi/realmode/Makefile | 2 +-
arch/x86/kernel/acpi/realmode/bioscall.S | 1 +
arch/x86/kernel/acpi/realmode/regs.c | 1 +
21 files changed, 490 insertions(+), 356 deletions(-)


2009-04-09 23:13:34

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/setup] x86, setup: "glove box" BIOS interrupts in the core boot code

Commit-ID: df7699c56421c0476704f24a43409ac8c505f3d2
Gitweb: http://git.kernel.org/tip/df7699c56421c0476704f24a43409ac8c505f3d2
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 1 Apr 2009 18:13:46 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 9 Apr 2009 16:08:11 -0700

x86, setup: "glove box" BIOS interrupts in the core boot code

Impact: BIOS proofing

"Glove box" off BIOS interrupts in the core boot code.

LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>


---
arch/x86/boot/a20.c | 9 +++--
arch/x86/boot/main.c | 39 ++++++++++++----------
arch/x86/boot/memory.c | 81 +++++++++++++++++++++++------------------------
arch/x86/boot/tty.c | 52 ++++++++++++++++--------------
4 files changed, 95 insertions(+), 86 deletions(-)

diff --git a/arch/x86/boot/a20.c b/arch/x86/boot/a20.c
index 7c19ce8..64a31a6 100644
--- a/arch/x86/boot/a20.c
+++ b/arch/x86/boot/a20.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007-2008 rPath, Inc. - All Rights Reserved
- * Copyright 2009 Intel Corporation
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -90,8 +90,11 @@ static int a20_test_long(void)

static void enable_a20_bios(void)
{
- asm volatile("pushfl; int $0x15; popfl"
- : : "a" ((u16)0x2401));
+ struct biosregs ireg;
+
+ initregs(&ireg);
+ ireg.ax = 0x2401;
+ intcall(0x15, &ireg, NULL);
}

static void enable_a20_kbc(void)
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
index 58f0415..140172b 100644
--- a/arch/x86/boot/main.c
+++ b/arch/x86/boot/main.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -61,11 +62,10 @@ static void copy_boot_params(void)
*/
static void keyboard_set_repeat(void)
{
- u16 ax = 0x0305;
- u16 bx = 0;
- asm volatile("int $0x16"
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
+ struct biosregs ireg;
+ initregs(&ireg);
+ ireg.ax = 0x0305;
+ intcall(0x16, &ireg, NULL);
}

/*
@@ -73,18 +73,22 @@ static void keyboard_set_repeat(void)
*/
static void query_ist(void)
{
+ struct biosregs ireg, oreg;
+
/* Some older BIOSes apparently crash on this call, so filter
it from machines too old to have SpeedStep at all. */
if (cpu.level < 6)
return;

- asm("int $0x15"
- : "=a" (boot_params.ist_info.signature),
- "=b" (boot_params.ist_info.command),
- "=c" (boot_params.ist_info.event),
- "=d" (boot_params.ist_info.perf_level)
- : "a" (0x0000e980), /* IST Support */
- "d" (0x47534943)); /* Request value */
+ initregs(&ireg);
+ ireg.ax = 0xe980; /* IST Support */
+ ireg.edx = 0x47534943; /* Request value */
+ intcall(0x15, &ireg, &oreg);
+
+ boot_params.ist_info.signature = oreg.eax;
+ boot_params.ist_info.command = oreg.ebx;
+ boot_params.ist_info.event = oreg.ecx;
+ boot_params.ist_info.perf_level = oreg.edx;
}

/*
@@ -93,13 +97,12 @@ static void query_ist(void)
static void set_bios_mode(void)
{
#ifdef CONFIG_X86_64
- u32 eax, ebx;
+ struct biosregs ireg;

- eax = 0xec00;
- ebx = 2;
- asm volatile("int $0x15"
- : "+a" (eax), "+b" (ebx)
- : : "ecx", "edx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ax = 0xec00;
+ ireg.bx = 2;
+ intcall(0x15, &ireg, NULL);
#endif
}

diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index 5054c2d..d989de8 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -25,12 +25,16 @@ struct e820_ext_entry {
static int detect_memory_e820(void)
{
int count = 0;
- u32 next = 0;
- u32 size, id, edi;
- u8 err;
+ struct biosregs ireg, oreg;
struct e820entry *desc = boot_params.e820_map;
static struct e820_ext_entry buf; /* static so it is zeroed */

+ initregs(&ireg);
+ ireg.ax = 0xe820;
+ ireg.cx = sizeof buf;
+ ireg.edx = SMAP;
+ ireg.di = (size_t)&buf;
+
/*
* Set this here so that if the BIOS doesn't change this field
* but still doesn't change %ecx, we're still okay...
@@ -38,22 +42,13 @@ static int detect_memory_e820(void)
buf.ext_flags = 1;

do {
- size = sizeof buf;
-
- /* Important: %edx and %esi are clobbered by some BIOSes,
- so they must be either used for the error output
- or explicitly marked clobbered. Given that, assume there
- is something out there clobbering %ebp and %edi, too. */
- asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
- : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
- "=D" (edi), "+m" (buf)
- : "D" (&buf), "d" (SMAP), "a" (0xe820)
- : "esi");
+ intcall(0x15, &ireg, &oreg);
+ ireg.ebx = oreg.ebx; /* for next iteration... */

/* BIOSes which terminate the chain with CF = 1 as opposed
to %ebx = 0 don't always report the SMAP signature on
the final, failing, probe. */
- if (err)
+ if (oreg.eflags & X86_EFLAGS_CF)
break;

/* Some BIOSes stop returning SMAP in the middle of
@@ -61,7 +56,7 @@ static int detect_memory_e820(void)
screwed up the map at that point, we might have a
partial map, the full map, or complete garbage, so
just return failure. */
- if (id != SMAP) {
+ if (oreg.eax != SMAP) {
count = 0;
break;
}
@@ -69,58 +64,62 @@ static int detect_memory_e820(void)
/* ACPI 3.0 added the extended flags support. If bit 0
in the extended flags is zero, we're supposed to simply
ignore the entry -- a backwards incompatible change! */
- if (size > 20 && !(buf.ext_flags & 1))
+ if (oreg.cx > 20 && !(buf.ext_flags & 1))
continue;

*desc++ = buf.std;
count++;
- } while (next && count < ARRAY_SIZE(boot_params.e820_map));
+ } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map));

return boot_params.e820_entries = count;
}

static int detect_memory_e801(void)
{
- u16 ax, bx, cx, dx;
- u8 err;
+ struct biosregs ireg, oreg;

- bx = cx = dx = 0;
- ax = 0xe801;
- asm("stc; int $0x15; setc %0"
- : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
+ initregs(&ireg);
+ ireg.ax = 0xe801;
+ intcall(0x15, &ireg, &oreg);

- if (err)
+ if (oreg.eflags & X86_EFLAGS_CF)
return -1;

/* Do we really need to do this? */
- if (cx || dx) {
- ax = cx;
- bx = dx;
+ if (oreg.cx || oreg.dx) {
+ oreg.ax = oreg.cx;
+ oreg.bx = oreg.dx;
}

- if (ax > 15*1024)
+ if (oreg.ax > 15*1024) {
return -1; /* Bogus! */
-
- /* This ignores memory above 16MB if we have a memory hole
- there. If someone actually finds a machine with a memory
- hole at 16MB and no support for 0E820h they should probably
- generate a fake e820 map. */
- boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
+ } else if (oreg.ax == 15*1024) {
+ boot_params.alt_mem_k = (oreg.dx << 6) + oreg.ax;
+ } else {
+ /*
+ * This ignores memory above 16MB if we have a memory
+ * hole there. If someone actually finds a machine
+ * with a memory hole at 16MB and no support for
+ * 0E820h they should probably generate a fake e820
+ * map.
+ */
+ boot_params.alt_mem_k = oreg.ax;
+ }

return 0;
}

static int detect_memory_88(void)
{
- u16 ax;
- u8 err;
+ struct biosregs ireg, oreg;

- ax = 0x8800;
- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
+ initregs(&ireg);
+ ireg.ah = 0x88;
+ intcall(0x15, &ireg, &oreg);

- boot_params.screen_info.ext_mem_k = ax;
+ boot_params.screen_info.ext_mem_k = oreg.ax;

- return -err;
+ return -(oreg.eflags & X86_EFLAGS_CF); /* 0 or -1 */
}

int detect_memory(void)
diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c
index 7e8e8b2..01ec69c 100644
--- a/arch/x86/boot/tty.c
+++ b/arch/x86/boot/tty.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -22,24 +23,23 @@

void __attribute__((section(".inittext"))) putchar(int ch)
{
- unsigned char c = ch;
+ struct biosregs ireg;

- if (c == '\n')
+ if (ch == '\n')
putchar('\r'); /* \n -> \r\n */

- /* int $0x10 is known to have bugs involving touching registers
- it shouldn't. Be extra conservative... */
- asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal"
- : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
+ initregs(&ireg);
+ ireg.bx = 0x0007;
+ ireg.cx = 0x0001;
+ ireg.ah = 0x0e;
+ ireg.al = ch;
+ intcall(0x10, &ireg, NULL);
}

void __attribute__((section(".inittext"))) puts(const char *str)
{
- int n = 0;
- while (*str) {
+ while (*str)
putchar(*str++);
- n++;
- }
}

/*
@@ -49,14 +49,13 @@ void __attribute__((section(".inittext"))) puts(const char *str)

static u8 gettime(void)
{
- u16 ax = 0x0200;
- u16 cx, dx;
+ struct biosregs ireg, oreg;

- asm volatile("int $0x1a"
- : "+a" (ax), "=c" (cx), "=d" (dx)
- : : "ebx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x02;
+ intcall(0x1a, &ireg, &oreg);

- return dx >> 8;
+ return oreg.dh;
}

/*
@@ -64,19 +63,24 @@ static u8 gettime(void)
*/
int getchar(void)
{
- u16 ax = 0;
- asm volatile("int $0x16" : "+a" (ax));
+ struct biosregs ireg, oreg;
+
+ initregs(&ireg);
+ /* ireg.ah = 0x00; */
+ intcall(0x16, &ireg, &oreg);

- return ax & 0xff;
+ return oreg.al;
}

static int kbd_pending(void)
{
- u8 pending;
- asm volatile("int $0x16; setnz %0"
- : "=qm" (pending)
- : "a" (0x0100));
- return pending;
+ struct biosregs ireg, oreg;
+
+ initregs(&ireg);
+ ireg.ah = 0x01;
+ intcall(0x16, &ireg, &oreg);
+
+ return !(oreg.eflags & X86_EFLAGS_ZF);
}

void kbd_flush(void)

2009-04-09 23:13:54

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/setup] x86, setup: "glove box" BIOS interrupts in the APM code

Commit-ID: d54ea252e4c92357226992cf65d94616a96e6fce
Gitweb: http://git.kernel.org/tip/d54ea252e4c92357226992cf65d94616a96e6fce
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 1 Apr 2009 18:14:26 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 9 Apr 2009 16:08:11 -0700

x86, setup: "glove box" BIOS interrupts in the APM code

Impact: BIOS proofing

"Glove box" off BIOS interrupts in the APM code.

LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Cc: Stephen Rothwell <[email protected]>


---
arch/x86/boot/apm.c | 76 +++++++++++++++++++-------------------------------
1 files changed, 29 insertions(+), 47 deletions(-)

diff --git a/arch/x86/boot/apm.c b/arch/x86/boot/apm.c
index 7aa6033..ee27483 100644
--- a/arch/x86/boot/apm.c
+++ b/arch/x86/boot/apm.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* Original APM BIOS checking by Stephen Rothwell, May 1994
* ([email protected])
@@ -19,75 +20,56 @@

int query_apm_bios(void)
{
- u16 ax, bx, cx, dx, di;
- u32 ebx, esi;
- u8 err;
+ struct biosregs ireg, oreg;

/* APM BIOS installation check */
- ax = 0x5300;
- bx = cx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
- : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
- : : "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x53;
+ intcall(0x15, &ireg, &oreg);

- if (err)
+ if (oreg.flags & X86_EFLAGS_CF)
return -1; /* No APM BIOS */

- if (bx != 0x504d) /* "PM" signature */
+ if (oreg.bx != 0x504d) /* "PM" signature */
return -1;

- if (!(cx & 0x02)) /* 32 bits supported? */
+ if (!(oreg.cx & 0x02)) /* 32 bits supported? */
return -1;

/* Disconnect first, just in case */
- ax = 0x5304;
- bx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
-
- /* Paranoia */
- ebx = esi = 0;
- cx = dx = di = 0;
+ ireg.al = 0x04;
+ intcall(0x15, &ireg, NULL);

/* 32-bit connect */
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
- : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
- "+S" (esi), "+D" (di), "=m" (err)
- : "a" (0x5303));
-
- boot_params.apm_bios_info.cseg = ax;
- boot_params.apm_bios_info.offset = ebx;
- boot_params.apm_bios_info.cseg_16 = cx;
- boot_params.apm_bios_info.dseg = dx;
- boot_params.apm_bios_info.cseg_len = (u16)esi;
- boot_params.apm_bios_info.cseg_16_len = esi >> 16;
- boot_params.apm_bios_info.dseg_len = di;
-
- if (err)
+ ireg.al = 0x03;
+ intcall(0x15, &ireg, &oreg);
+
+ boot_params.apm_bios_info.cseg = oreg.ax;
+ boot_params.apm_bios_info.offset = oreg.ebx;
+ boot_params.apm_bios_info.cseg_16 = oreg.cx;
+ boot_params.apm_bios_info.dseg = oreg.dx;
+ boot_params.apm_bios_info.cseg_len = oreg.si;
+ boot_params.apm_bios_info.cseg_16_len = oreg.hsi;
+ boot_params.apm_bios_info.dseg_len = oreg.di;
+
+ if (oreg.flags & X86_EFLAGS_CF)
return -1;

/* Redo the installation check as the 32-bit connect;
some BIOSes return different flags this way... */

- ax = 0x5300;
- bx = cx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
- : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
- : : "esi", "edi");
+ ireg.al = 0x00;
+ intcall(0x15, &ireg, &oreg);

- if (err || bx != 0x504d) {
+ if ((oreg.eflags & X86_EFLAGS_CF) || oreg.bx != 0x504d) {
/* Failure with 32-bit connect, try to disconect and ignore */
- ax = 0x5304;
- bx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
+ ireg.al = 0x04;
+ intcall(0x15, &ireg, NULL);
return -1;
}

- boot_params.apm_bios_info.version = ax;
- boot_params.apm_bios_info.flags = cx;
+ boot_params.apm_bios_info.version = oreg.ax;
+ boot_params.apm_bios_info.flags = oreg.cx;
return 0;
}

2009-04-09 23:14:26

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Commit-ID: 7a734e7dd93b9aea08ed51036a9a0e2c9dfd8dac
Gitweb: http://git.kernel.org/tip/7a734e7dd93b9aea08ed51036a9a0e2c9dfd8dac
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 1 Apr 2009 18:08:28 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 9 Apr 2009 16:08:11 -0700

x86, setup: "glove box" BIOS calls -- infrastructure

Impact: new interfaces (not yet used)

For all the platforms out there, there is an infinite number of buggy
BIOSes. This adds infrastructure to treat BIOS interrupts more like
toxic waste and "glove box" them -- we switch out the register set,
perform the BIOS interrupt, and then restore the previous state.

LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>


---
arch/x86/boot/Makefile | 5 +-
arch/x86/boot/bioscall.S | 82 ++++++++++++++++++++++++++++++
arch/x86/boot/boot.h | 48 +++++++++++++++++
arch/x86/boot/header.S | 2 +-
arch/x86/boot/regs.c | 29 +++++++++++
arch/x86/boot/setup.ld | 6 ++
arch/x86/kernel/acpi/realmode/Makefile | 2 +-
arch/x86/kernel/acpi/realmode/bioscall.S | 1 +
arch/x86/kernel/acpi/realmode/regs.c | 1 +
9 files changed, 172 insertions(+), 4 deletions(-)

diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 6633b6e..658bc52 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -26,9 +26,10 @@ targets := vmlinux.bin setup.bin setup.elf bzImage
targets += fdimage fdimage144 fdimage288 image.iso mtools.conf
subdir- := compressed

-setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
+setup-y += a20.o bioscall.o cmdline.o copy.o cpu.o cpucheck.o edd.o
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
-setup-y += printf.o string.o tty.o video.o video-mode.o version.o
+setup-y += printf.o regs.o string.o tty.o video.o video-mode.o
+setup-y += version.o
setup-$(CONFIG_X86_APM_BOOT) += apm.o

# The link order of the video-*.o modules can matter. In particular,
diff --git a/arch/x86/boot/bioscall.S b/arch/x86/boot/bioscall.S
new file mode 100644
index 0000000..22b4b3e
--- /dev/null
+++ b/arch/x86/boot/bioscall.S
@@ -0,0 +1,82 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2 or (at your
+ * option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * "Glove box" for BIOS calls. Avoids the constant problems with BIOSes
+ * touching memory they shouldn't be.
+ */
+
+ .code16
+ .text
+ .globl intcall
+ .type intcall, @function
+intcall:
+ /* Self-modify the INT instruction. Ugly, but works. */
+ cmpb %al, 3f
+ je 1f
+ movb %al, 3f
+ jmp 1f /* Synchronize pipeline */
+1:
+ /* Save state */
+ pushfl
+ pushw %fs
+ pushw %gs
+ pushal
+
+ /* Copy input state to stack frame */
+ subw $44, %sp
+ movw %dx, %si
+ movw %sp, %di
+ movw $11, %cx
+ rep; movsd
+
+ /* Pop full state from the stack */
+ popal
+ popw %gs
+ popw %fs
+ popw %es
+ popw %ds
+ popfl
+
+ /* Actual INT */
+ .byte 0xcd /* INT opcode */
+3: .byte 0
+
+ /* Push full state to the stack */
+ pushfl
+ pushw %ds
+ pushw %es
+ pushw %fs
+ pushw %gs
+ pushal
+
+ /* Re-establish C environment invariants */
+ cld
+ movzwl %sp, %esp
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %es
+
+ /* Copy output state from stack frame */
+ movw 68(%esp), %di /* Original %cx == 3rd argument */
+ andw %di, %di
+ jz 4f
+ movw %sp, %si
+ movw $11, %cx
+ rep; movsd
+4: addw $44, %sp
+
+ /* Restore state and return */
+ popal
+ popw %gs
+ popw %fs
+ popfl
+ retl
+ .size intcall, .-intcall
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
index 7b2692e..98239d2 100644
--- a/arch/x86/boot/boot.h
+++ b/arch/x86/boot/boot.h
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -26,6 +27,7 @@
#include <asm/setup.h>
#include "bitops.h"
#include <asm/cpufeature.h>
+#include <asm/processor-flags.h>

/* Useful macros */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
@@ -241,6 +243,49 @@ int enable_a20(void);
/* apm.c */
int query_apm_bios(void);

+/* bioscall.c */
+struct biosregs {
+ union {
+ struct {
+ u32 edi;
+ u32 esi;
+ u32 ebp;
+ u32 _esp;
+ u32 ebx;
+ u32 edx;
+ u32 ecx;
+ u32 eax;
+ u32 _fsgs;
+ u32 _dses;
+ u32 eflags;
+ };
+ struct {
+ u16 di, hdi;
+ u16 si, hsi;
+ u16 bp, hbp;
+ u16 _sp, _hsp;
+ u16 bx, hbx;
+ u16 dx, hdx;
+ u16 cx, hcx;
+ u16 ax, hax;
+ u16 gs, fs;
+ u16 es, ds;
+ u16 flags, hflags;
+ };
+ struct {
+ u8 dil, dih, edi2, edi3;
+ u8 sil, sih, esi2, esi3;
+ u8 bpl, bph, ebp2, ebp3;
+ u8 _spl, _sph, _esp2, _esp3;
+ u8 bl, bh, ebx2, ebx3;
+ u8 dl, dh, edx2, edx3;
+ u8 cl, ch, ecx2, ecx3;
+ u8 al, ah, eax2, eax3;
+ };
+ };
+};
+void intcall(u8 int_no, const struct biosregs *ireg, struct biosregs *oreg);
+
/* cmdline.c */
int cmdline_find_option(const char *option, char *buffer, int bufsize);
int cmdline_find_option_bool(const char *option);
@@ -279,6 +324,9 @@ int sprintf(char *buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
int printf(const char *fmt, ...);

+/* regs.c */
+void initregs(struct biosregs *regs);
+
/* string.c */
int strcmp(const char *str1, const char *str2);
size_t strnlen(const char *s, size_t maxlen);
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 5d84d1c..486d97f 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -221,7 +221,7 @@ setup_data: .quad 0 # 64-bit physical pointer to

# End of setup header #####################################################

- .section ".inittext", "ax"
+ .section ".entrytext", "ax"
start_of_setup:
#ifdef SAFE_RESET_DISK_CONTROLLER
# Reset the disk controller.
diff --git a/arch/x86/boot/regs.c b/arch/x86/boot/regs.c
new file mode 100644
index 0000000..958019b
--- /dev/null
+++ b/arch/x86/boot/regs.c
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2 or (at your
+ * option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Simple helper function for initializing a register set.
+ *
+ * Note that this sets EFLAGS_CF in the input register set; this
+ * makes it easier to catch functions which do nothing but don't
+ * explicitly set CF.
+ */
+
+#include "boot.h"
+
+void initregs(struct biosregs *reg)
+{
+ memset(reg, 0, sizeof *reg);
+ reg->eflags |= X86_EFLAGS_CF;
+ reg->ds = ds();
+ reg->es = ds();
+ reg->fs = fs();
+ reg->gs = gs();
+}
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index bb8dc2d..0f6ec45 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -15,8 +15,11 @@ SECTIONS

. = 497;
.header : { *(.header) }
+ .entrytext : { *(.entrytext) }
.inittext : { *(.inittext) }
.initdata : { *(.initdata) }
+ __end_init = .;
+
.text : { *(.text) }
.text32 : { *(.text32) }

@@ -52,4 +55,7 @@ SECTIONS

. = ASSERT(_end <= 0x8000, "Setup too big!");
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
+ /* Necessary for the very-old-loader check to work... */
+ . = ASSERT(__end_init <= 5*512, "init sections too big!");
+
}
diff --git a/arch/x86/kernel/acpi/realmode/Makefile b/arch/x86/kernel/acpi/realmode/Makefile
index 1c31cc0..167bc16 100644
--- a/arch/x86/kernel/acpi/realmode/Makefile
+++ b/arch/x86/kernel/acpi/realmode/Makefile
@@ -9,7 +9,7 @@
always := wakeup.bin
targets := wakeup.elf wakeup.lds

-wakeup-y += wakeup.o wakemain.o video-mode.o copy.o
+wakeup-y += wakeup.o wakemain.o video-mode.o copy.o bioscall.o regs.o

# The link order of the video-*.o modules can matter. In particular,
# video-vga.o *must* be listed first, followed by video-vesa.o.
diff --git a/arch/x86/kernel/acpi/realmode/bioscall.S b/arch/x86/kernel/acpi/realmode/bioscall.S
new file mode 100644
index 0000000..f51eb0b
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/bioscall.S
@@ -0,0 +1 @@
+#include "../../../boot/bioscall.S"
diff --git a/arch/x86/kernel/acpi/realmode/regs.c b/arch/x86/kernel/acpi/realmode/regs.c
new file mode 100644
index 0000000..6206033
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/regs.c
@@ -0,0 +1 @@
+#include "../../../boot/regs.c"

2009-04-09 23:14:44

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/setup] x86, setup: "glove box" BIOS interrupts in the EDD code

Commit-ID: 3435d3476c5ed955d56a6216ed2d156847b3a575
Gitweb: http://git.kernel.org/tip/3435d3476c5ed955d56a6216ed2d156847b3a575
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 1 Apr 2009 18:17:17 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 9 Apr 2009 16:08:11 -0700

x86, setup: "glove box" BIOS interrupts in the EDD code

Impact: BIOS proofing

"Glove box" off BIOS interrupts in the EDD code.

LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>


---
arch/x86/boot/edd.c | 71 ++++++++++++++++++++++----------------------------
1 files changed, 31 insertions(+), 40 deletions(-)

diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c
index 1aae8f3..c501a5b 100644
--- a/arch/x86/boot/edd.c
+++ b/arch/x86/boot/edd.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -22,17 +23,17 @@
*/
static int read_mbr(u8 devno, void *buf)
{
- u16 ax, bx, cx, dx;
+ struct biosregs ireg, oreg;

- ax = 0x0201; /* Legacy Read, one sector */
- cx = 0x0001; /* Sector 0-0-1 */
- dx = devno;
- bx = (size_t)buf;
- asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
- : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
- : : "esi", "edi", "memory");
+ initregs(&ireg);
+ ireg.ax = 0x0201; /* Legacy Read, one sector */
+ ireg.cx = 0x0001; /* Sector 0-0-1 */
+ ireg.dl = devno;
+ ireg.bx = (size_t)buf;

- return -(u8)ax; /* 0 or -1 */
+ intcall(0x13, &ireg, &oreg);
+
+ return -(oreg.eflags & X86_EFLAGS_CF); /* 0 or -1 */
}

static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
@@ -72,56 +73,46 @@ static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)

static int get_edd_info(u8 devno, struct edd_info *ei)
{
- u16 ax, bx, cx, dx, di;
+ struct biosregs ireg, oreg;

memset(ei, 0, sizeof *ei);

/* Check Extensions Present */

- ax = 0x4100;
- bx = EDDMAGIC1;
- dx = devno;
- asm("pushfl; stc; int $0x13; setc %%al; popfl"
- : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
- : : "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x41;
+ ireg.bx = EDDMAGIC1;
+ ireg.dl = devno;
+ intcall(0x13, &ireg, &oreg);

- if ((u8)ax)
+ if (oreg.eflags & X86_EFLAGS_CF)
return -1; /* No extended information */

- if (bx != EDDMAGIC2)
+ if (oreg.bx != EDDMAGIC2)
return -1;

ei->device = devno;
- ei->version = ax >> 8; /* EDD version number */
- ei->interface_support = cx; /* EDD functionality subsets */
+ ei->version = oreg.ah; /* EDD version number */
+ ei->interface_support = oreg.cx; /* EDD functionality subsets */

/* Extended Get Device Parameters */

ei->params.length = sizeof(ei->params);
- ax = 0x4800;
- dx = devno;
- asm("pushfl; int $0x13; popfl"
- : "+a" (ax), "+d" (dx), "=m" (ei->params)
- : "S" (&ei->params)
- : "ebx", "ecx", "edi");
+ ireg.ah = 0x48;
+ ireg.si = (size_t)&ei->params;
+ intcall(0x13, &ireg, &oreg);

/* Get legacy CHS parameters */

/* Ralf Brown recommends setting ES:DI to 0:0 */
- ax = 0x0800;
- dx = devno;
- di = 0;
- asm("pushw %%es; "
- "movw %%di,%%es; "
- "pushfl; stc; int $0x13; setc %%al; popfl; "
- "popw %%es"
- : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
- : : "esi");
-
- if ((u8)ax == 0) {
- ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
- ei->legacy_max_head = dx >> 8;
- ei->legacy_sectors_per_track = cx & 0x3f;
+ ireg.ah = 0x08;
+ ireg.es = 0;
+ intcall(0x13, &ireg, &oreg);
+
+ if (!(oreg.eflags & X86_EFLAGS_CF)) {
+ ei->legacy_max_cylinder = oreg.ch + ((oreg.cl & 0xc0) << 2);
+ ei->legacy_max_head = oreg.dh;
+ ei->legacy_sectors_per_track = oreg.cl & 0x3f;
}

return 0;

2009-04-09 23:15:14

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/setup] x86, setup: "glove box" BIOS interrupts in the MCA code

Commit-ID: 0a706db320768f8f6e43bbf73b58d2aabdc93354
Gitweb: http://git.kernel.org/tip/0a706db320768f8f6e43bbf73b58d2aabdc93354
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 1 Apr 2009 18:19:00 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 9 Apr 2009 16:08:11 -0700

x86, setup: "glove box" BIOS interrupts in the MCA code

Impact: BIOS proofing

"Glove box" off BIOS interrupts in the MCA code.

LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Cc: James Bottomley <[email protected]>


---
arch/x86/boot/mca.c | 27 ++++++++++++---------------
1 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/arch/x86/boot/mca.c b/arch/x86/boot/mca.c
index 911eaae..a95a531 100644
--- a/arch/x86/boot/mca.c
+++ b/arch/x86/boot/mca.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -16,26 +17,22 @@

int query_mca(void)
{
- u8 err;
- u16 es, bx, len;
-
- asm("pushw %%es ; "
- "int $0x15 ; "
- "setc %0 ; "
- "movw %%es, %1 ; "
- "popw %%es"
- : "=acd" (err), "=acdSD" (es), "=b" (bx)
- : "a" (0xc000));
-
- if (err)
+ struct biosregs ireg, oreg;
+ u16 len;
+
+ initregs(&ireg);
+ ireg.ah = 0xc0;
+ intcall(0x15, &ireg, &oreg);
+
+ if (oreg.eflags & X86_EFLAGS_CF)
return -1; /* No MCA present */

- set_fs(es);
- len = rdfs16(bx);
+ set_fs(oreg.es);
+ len = rdfs16(oreg.bx);

if (len > sizeof(boot_params.sys_desc_table))
len = sizeof(boot_params.sys_desc_table);

- copy_from_fs(&boot_params.sys_desc_table, bx, len);
+ copy_from_fs(&boot_params.sys_desc_table, oreg.bx, len);
return 0;
}

2009-04-09 23:15:47

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/setup] x86, setup: "glove box" BIOS interrupts in the video code

Commit-ID: cf06de7b9cdd3efee7a59dced1977b3c21d43732
Gitweb: http://git.kernel.org/tip/cf06de7b9cdd3efee7a59dced1977b3c21d43732
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 1 Apr 2009 18:20:11 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 9 Apr 2009 16:08:12 -0700

x86, setup: "glove box" BIOS interrupts in the video code

Impact: BIOS proofing

"Glove box" off BIOS interrupts in the video code.

LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>


---
arch/x86/boot/video-bios.c | 27 ++++-----
arch/x86/boot/video-vesa.c | 137 +++++++++++++++++++-------------------------
arch/x86/boot/video-vga.c | 95 +++++++++++++++++++------------
arch/x86/boot/video.c | 42 ++++++-------
arch/x86/boot/video.h | 14 -----
5 files changed, 151 insertions(+), 164 deletions(-)

diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c
index 3fa979c..d660be4 100644
--- a/arch/x86/boot/video-bios.c
+++ b/arch/x86/boot/video-bios.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -29,21 +30,21 @@ static int bios_set_mode(struct mode_info *mi)

static int set_bios_mode(u8 mode)
{
- u16 ax;
+ struct biosregs ireg, oreg;
u8 new_mode;

- ax = mode; /* AH=0x00 Set Video Mode */
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+ initregs(&ireg);
+ ireg.al = mode; /* AH=0x00 Set Video Mode */
+ intcall(0x10, &ireg, NULL);

- ax = 0x0f00; /* Get Current Video Mode */
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+
+ ireg.ah = 0x0f; /* Get Current Video Mode */
+ intcall(0x10, &ireg, &oreg);

do_restore = 1; /* Assume video contents were lost */
- new_mode = ax & 0x7f; /* Not all BIOSes are clean with the top bit */
+
+ /* Not all BIOSes are clean with the top bit */
+ new_mode = ireg.al & 0x7f;

if (new_mode == mode)
return 0; /* Mode change OK */
@@ -53,10 +54,8 @@ static int set_bios_mode(u8 mode)
/* Mode setting failed, but we didn't end up where we
started. That's bad. Try to revert to the original
video mode. */
- ax = boot_params.screen_info.orig_video_mode;
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+ ireg.ax = boot_params.screen_info.orig_video_mode;
+ intcall(0x10, &ireg, NULL);
}
#endif
return -1;
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 4a58c8c..c700147 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -31,7 +32,7 @@ static inline void vesa_store_mode_params_graphics(void) {}
static int vesa_probe(void)
{
#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
- u16 ax, cx, di;
+ struct biosregs ireg, oreg;
u16 mode;
addr_t mode_ptr;
struct mode_info *mi;
@@ -39,13 +40,12 @@ static int vesa_probe(void)

video_vesa.modes = GET_HEAP(struct mode_info, 0);

- ax = 0x4f00;
- di = (size_t)&vginfo;
- asm(INT10
- : "+a" (ax), "+D" (di), "=m" (vginfo)
- : : "ebx", "ecx", "edx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f00;
+ ireg.di = (size_t)&vginfo;
+ intcall(0x10, &ireg, &oreg);

- if (ax != 0x004f ||
+ if (ireg.ax != 0x004f ||
vginfo.signature != VESA_MAGIC ||
vginfo.version < 0x0102)
return 0; /* Not present */
@@ -65,14 +65,12 @@ static int vesa_probe(void)

memset(&vminfo, 0, sizeof vminfo); /* Just in case... */

- ax = 0x4f01;
- cx = mode;
- di = (size_t)&vminfo;
- asm(INT10
- : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
- : : "ebx", "edx", "esi");
+ ireg.ax = 0x4f01;
+ ireg.cx = mode;
+ ireg.di = (size_t)&vminfo;
+ intcall(0x10, &ireg, &oreg);

- if (ax != 0x004f)
+ if (ireg.ax != 0x004f)
continue;

if ((vminfo.mode_attr & 0x15) == 0x05) {
@@ -111,20 +109,19 @@ static int vesa_probe(void)

static int vesa_set_mode(struct mode_info *mode)
{
- u16 ax, bx, cx, di;
+ struct biosregs ireg, oreg;
int is_graphic;
u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;

memset(&vminfo, 0, sizeof vminfo); /* Just in case... */

- ax = 0x4f01;
- cx = vesa_mode;
- di = (size_t)&vminfo;
- asm(INT10
- : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
- : : "ebx", "edx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f01;
+ ireg.cx = vesa_mode;
+ ireg.di = (size_t)&vminfo;
+ intcall(0x10, &ireg, &oreg);

- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return -1;

if ((vminfo.mode_attr & 0x15) == 0x05) {
@@ -141,14 +138,12 @@ static int vesa_set_mode(struct mode_info *mode)
}


- ax = 0x4f02;
- bx = vesa_mode;
- di = 0;
- asm volatile(INT10
- : "+a" (ax), "+b" (bx), "+D" (di)
- : : "ecx", "edx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f02;
+ ireg.bx = vesa_mode;
+ intcall(0x10, &ireg, &oreg);

- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return -1;

graphic_mode = is_graphic;
@@ -171,50 +166,45 @@ static int vesa_set_mode(struct mode_info *mode)
/* Switch DAC to 8-bit mode */
static void vesa_dac_set_8bits(void)
{
+ struct biosregs ireg, oreg;
u8 dac_size = 6;

/* If possible, switch the DAC to 8-bit mode */
if (vginfo.capabilities & 1) {
- u16 ax, bx;
-
- ax = 0x4f08;
- bx = 0x0800;
- asm volatile(INT10
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
-
- if (ax == 0x004f)
- dac_size = bx >> 8;
+ initregs(&ireg);
+ ireg.ax = 0x4f08;
+ ireg.bh = 0x08;
+ intcall(0x10, &ireg, &oreg);
+ if (oreg.ax == 0x004f)
+ dac_size = oreg.bh;
}

/* Set the color sizes to the DAC size, and offsets to 0 */
- boot_params.screen_info.red_size = dac_size;
+ boot_params.screen_info.red_size = dac_size;
boot_params.screen_info.green_size = dac_size;
- boot_params.screen_info.blue_size = dac_size;
- boot_params.screen_info.rsvd_size = dac_size;
+ boot_params.screen_info.blue_size = dac_size;
+ boot_params.screen_info.rsvd_size = dac_size;

- boot_params.screen_info.red_pos = 0;
- boot_params.screen_info.green_pos = 0;
- boot_params.screen_info.blue_pos = 0;
- boot_params.screen_info.rsvd_pos = 0;
+ boot_params.screen_info.red_pos = 0;
+ boot_params.screen_info.green_pos = 0;
+ boot_params.screen_info.blue_pos = 0;
+ boot_params.screen_info.rsvd_pos = 0;
}

/* Save the VESA protected mode info */
static void vesa_store_pm_info(void)
{
- u16 ax, bx, di, es;
+ struct biosregs ireg, oreg;

- ax = 0x4f0a;
- bx = di = 0;
- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
- : : "ecx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f0a;
+ intcall(0x10, &ireg, &oreg);

- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return;

- boot_params.screen_info.vesapm_seg = es;
- boot_params.screen_info.vesapm_off = di;
+ boot_params.screen_info.vesapm_seg = oreg.es;
+ boot_params.screen_info.vesapm_off = oreg.di;
}

/*
@@ -252,7 +242,7 @@ static void vesa_store_mode_params_graphics(void)
void vesa_store_edid(void)
{
#ifdef CONFIG_FIRMWARE_EDID
- u16 ax, bx, cx, dx, di;
+ struct biosregs ireg, oreg;

/* Apparently used as a nonsense token... */
memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
@@ -260,33 +250,26 @@ void vesa_store_edid(void)
if (vginfo.version < 0x0200)
return; /* EDID requires VBE 2.0+ */

- ax = 0x4f15; /* VBE DDC */
- bx = 0x0000; /* Report DDC capabilities */
- cx = 0; /* Controller 0 */
- di = 0; /* ES:DI must be 0 by spec */
-
- /* Note: The VBE DDC spec is different from the main VESA spec;
- we genuinely have to assume all registers are destroyed here. */
-
- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
- : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
- : : "esi", "edx");
+ initregs(&ireg);
+ ireg.ax = 0x4f15; /* VBE DDC */
+ /* ireg.bx = 0x0000; */ /* Report DDC capabilities */
+ /* ireg.cx = 0; */ /* Controller 0 */
+ ireg.es = 0; /* ES:DI must be 0 by spec */
+ intcall(0x10, &ireg, &oreg);

- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return; /* No EDID */

/* BH = time in seconds to transfer EDD information */
/* BL = DDC level supported */

- ax = 0x4f15; /* VBE DDC */
- bx = 0x0001; /* Read EDID */
- cx = 0; /* Controller 0 */
- dx = 0; /* EDID block number */
- di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
- asm(INT10
- : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info),
- "+c" (cx), "+D" (di)
- : : "esi");
+ ireg.ax = 0x4f15; /* VBE DDC */
+ ireg.bx = 0x0001; /* Read EDID */
+ /* ireg.cx = 0; */ /* Controller 0 */
+ /* ireg.dx = 0; */ /* EDID block number */
+ ireg.es = ds();
+ ireg.di =(size_t)&boot_params.edid_info; /* (ES:)Pointer to block */
+ intcall(0x10, &ireg, &oreg);
#endif /* CONFIG_FIRMWARE_EDID */
}

diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index 9e0587a..8f8d827 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -39,30 +40,30 @@ static __videocard video_vga;
/* Set basic 80x25 mode */
static u8 vga_set_basic_mode(void)
{
+ struct biosregs ireg, oreg;
u16 ax;
u8 rows;
u8 mode;

+ initregs(&ireg);
+
#ifdef CONFIG_VIDEO_400_HACK
if (adapter >= ADAPTER_VGA) {
- asm volatile(INT10
- : : "a" (0x1202), "b" (0x0030)
- : "ecx", "edx", "esi", "edi");
+ ireg.ax = 0x1202;
+ ireg.bx = 0x0030;
+ intcall(0x10, &ireg, NULL);
}
#endif

ax = 0x0f00;
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
-
- mode = (u8)ax;
+ intcall(0x10, &ireg, &oreg);
+ mode = oreg.al;

set_fs(0);
rows = rdfs8(0x484); /* rows minus one */

#ifndef CONFIG_VIDEO_400_HACK
- if ((ax == 0x5003 || ax == 0x5007) &&
+ if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) &&
(rows == 0 || rows == 24))
return mode;
#endif
@@ -71,10 +72,8 @@ static u8 vga_set_basic_mode(void)
mode = 3;

/* Set the mode */
- ax = mode;
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+ ireg.ax = mode; /* AH=0: set mode */
+ intcall(0x10, &ireg, NULL);
do_restore = 1;
return mode;
}
@@ -82,43 +81,69 @@ static u8 vga_set_basic_mode(void)
static void vga_set_8font(void)
{
/* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
+ struct biosregs ireg;
+
+ initregs(&ireg);

/* Set 8x8 font */
- asm volatile(INT10 : : "a" (0x1112), "b" (0));
+ ireg.ax = 0x1112;
+ /* ireg.bl = 0; */
+ intcall(0x10, &ireg, NULL);

/* Use alternate print screen */
- asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
+ ireg.ax = 0x1200;
+ ireg.bl = 0x20;
+ intcall(0x10, &ireg, NULL);

/* Turn off cursor emulation */
- asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+ ireg.ax = 0x1201;
+ ireg.bl = 0x34;
+ intcall(0x10, &ireg, NULL);

/* Cursor is scan lines 6-7 */
- asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
+ ireg.ax = 0x0100;
+ ireg.cx = 0x0607;
+ intcall(0x10, &ireg, NULL);
}

static void vga_set_14font(void)
{
/* Set 9x14 font - 80x28 on VGA */
+ struct biosregs ireg;
+
+ initregs(&ireg);

/* Set 9x14 font */
- asm volatile(INT10 : : "a" (0x1111), "b" (0));
+ ireg.ax = 0x1111;
+ /* ireg.bl = 0; */
+ intcall(0x10, &ireg, NULL);

/* Turn off cursor emulation */
- asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+ ireg.ax = 0x1201;
+ ireg.bl = 0x34;
+ intcall(0x10, &ireg, NULL);

/* Cursor is scan lines 11-12 */
- asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
+ ireg.ax = 0x0100;
+ ireg.cx = 0x0b0c;
+ intcall(0x10, &ireg, NULL);
}

static void vga_set_80x43(void)
{
/* Set 80x43 mode on VGA (not EGA) */
+ struct biosregs ireg;
+
+ initregs(&ireg);

/* Set 350 scans */
- asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
+ ireg.ax = 0x1201;
+ ireg.bl = 0x30;
+ intcall(0x10, &ireg, NULL);

/* Reset video mode */
- asm volatile(INT10 : : "a" (0x0003));
+ ireg.ax = 0x0003;
+ intcall(0x10, &ireg, NULL);

vga_set_8font();
}
@@ -225,8 +250,6 @@ static int vga_set_mode(struct mode_info *mode)
*/
static int vga_probe(void)
{
- u16 ega_bx;
-
static const char *card_name[] = {
"CGA/MDA/HGC", "EGA", "VGA"
};
@@ -240,26 +263,26 @@ static int vga_probe(void)
sizeof(ega_modes)/sizeof(struct mode_info),
sizeof(vga_modes)/sizeof(struct mode_info),
};
- u8 vga_flag;

- asm(INT10
- : "=b" (ega_bx)
- : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
- : "ecx", "edx", "esi", "edi");
+ struct biosregs ireg, oreg;
+
+ initregs(&ireg);
+
+ ireg.ax = 0x1200;
+ ireg.bl = 0x10; /* Check EGA/VGA */
+ intcall(0x10, &ireg, &oreg);

#ifndef _WAKEUP
- boot_params.screen_info.orig_video_ega_bx = ega_bx;
+ boot_params.screen_info.orig_video_ega_bx = oreg.bx;
#endif

/* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
- if ((u8)ega_bx != 0x10) {
+ if (oreg.bl != 0x10) {
/* EGA/VGA */
- asm(INT10
- : "=a" (vga_flag)
- : "a" (0x1a00)
- : "ebx", "ecx", "edx", "esi", "edi");
+ ireg.ax = 0x1a00;
+ intcall(0x10, &ireg, &oreg);

- if (vga_flag == 0x1a) {
+ if (oreg.al == 0x1a) {
adapter = ADAPTER_VGA;
#ifndef _WAKEUP
boot_params.screen_info.orig_video_isVGA = 1;
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
index 3bef2c1..bad728b 100644
--- a/arch/x86/boot/video.c
+++ b/arch/x86/boot/video.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -18,33 +19,29 @@

static void store_cursor_position(void)
{
- u16 curpos;
- u16 ax, bx;
+ struct biosregs ireg, oreg;

- ax = 0x0300;
- bx = 0;
- asm(INT10
- : "=d" (curpos), "+a" (ax), "+b" (bx)
- : : "ecx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x03;
+ intcall(0x10, &ireg, &oreg);

- boot_params.screen_info.orig_x = curpos;
- boot_params.screen_info.orig_y = curpos >> 8;
+ boot_params.screen_info.orig_x = oreg.dl;
+ boot_params.screen_info.orig_y = oreg.dh;
}

static void store_video_mode(void)
{
- u16 ax, page;
+ struct biosregs ireg, oreg;

/* N.B.: the saving of the video page here is a bit silly,
since we pretty much assume page 0 everywhere. */
- ax = 0x0f00;
- asm(INT10
- : "+a" (ax), "=b" (page)
- : : "ecx", "edx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x0f;
+ intcall(0x10, &ireg, &oreg);

/* Not all BIOSes are clean with respect to the top bit */
- boot_params.screen_info.orig_video_mode = ax & 0x7f;
- boot_params.screen_info.orig_video_page = page >> 8;
+ boot_params.screen_info.orig_video_mode = oreg.al & 0x7f;
+ boot_params.screen_info.orig_video_page = oreg.bh;
}

/*
@@ -257,7 +254,7 @@ static void restore_screen(void)
int y;
addr_t dst = 0;
u16 *src = saved.data;
- u16 ax, bx, dx;
+ struct biosregs ireg;

if (graphic_mode)
return; /* Can't restore onto a graphic mode */
@@ -296,12 +293,11 @@ static void restore_screen(void)
}

/* Restore cursor position */
- ax = 0x0200; /* Set cursor position */
- bx = 0; /* Page number (<< 8) */
- dx = (saved.cury << 8)+saved.curx;
- asm volatile(INT10
- : "+a" (ax), "+b" (bx), "+d" (dx)
- : : "ecx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x02; /* Set cursor position */
+ ireg.dh = saved.cury;
+ ireg.dl = saved.curx;
+ intcall(0x10, &ireg, NULL);
}
#else
#define save_screen() ((void)0)
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h
index ee63f5d..5bb174a 100644
--- a/arch/x86/boot/video.h
+++ b/arch/x86/boot/video.h
@@ -112,20 +112,6 @@ extern int force_x, force_y; /* Don't query the BIOS for cols/rows */
extern int do_restore; /* Restore screen contents */
extern int graphic_mode; /* Graphics mode with linear frame buffer */

-/*
- * int $0x10 is notorious for touching registers it shouldn't.
- * gcc doesn't like %ebp being clobbered, so define it as a push/pop
- * sequence here.
- *
- * A number of systems, including the original PC can clobber %bp in
- * certain circumstances, like when scrolling. There exists at least
- * one Trident video card which could clobber DS under a set of
- * circumstances that we are unlikely to encounter (scrolling when
- * using an extended graphics mode of more than 800x600 pixels), but
- * it's cheap insurance to deal with that here.
- */
-#define INT10 "pushl %%ebp; pushw %%ds; int $0x10; popw %%ds; popl %%ebp"
-
/* Accessing VGA indexed registers */
static inline u8 in_idx(u16 port, u8 index)
{

2009-04-10 08:02:01

by Pavel Machek

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Hi!

> x86, setup: "glove box" BIOS calls -- infrastructure
>
> Impact: new interfaces (not yet used)
>
> For all the platforms out there, there is an infinite number of buggy
> BIOSes. This adds infrastructure to treat BIOS interrupts more like
> toxic waste and "glove box" them -- we switch out the register set,
> perform the BIOS interrupt, and then restore the previous state.
>
> LKML-Reference: <[email protected]>
> Signed-off-by: H. Peter Anvin <[email protected]>
> Cc: Pavel Machek <[email protected]>

Sounds quite sane. Disadvantage is that we will no longer detect those
buggy BIOSen.

> +/*
> + * "Glove box" for BIOS calls. Avoids the constant problems with BIOSes
> + * touching memory they shouldn't be.
> + */

Touching memory? AFAICT it only prevents touching registers.

> + .code16
> + .text
> + .globl intcall
> + .type intcall, @function
> +intcall:
> + /* Self-modify the INT instruction. Ugly, but works. */
> + cmpb %al, 3f
> + je 1f
> + movb %al, 3f
> + jmp 1f /* Synchronize pipeline */
> +1:

There are various CPU bugs with self-modifying code, but I guess we
are not using it heavily enough. Also we are single-threaded so that
should be ok.
Pavel

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-04-10 08:04:32

by Pavel Machek

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS interrupts in the video code

On Thu 2009-04-09 23:13:47, H. Peter Anvin wrote:
> Commit-ID: cf06de7b9cdd3efee7a59dced1977b3c21d43732
> Gitweb: http://git.kernel.org/tip/cf06de7b9cdd3efee7a59dced1977b3c21d43732
> Author: H. Peter Anvin <[email protected]>
> AuthorDate: Wed, 1 Apr 2009 18:20:11 -0700
> Committer: H. Peter Anvin <[email protected]>
> CommitDate: Thu, 9 Apr 2009 16:08:12 -0700
>
> x86, setup: "glove box" BIOS interrupts in the video code
>
> Impact: BIOS proofing
>
> "Glove box" off BIOS interrupts in the video code.
>
> LKML-Reference: <[email protected]>
> Signed-off-by: H. Peter Anvin <[email protected]>
> Cc: Pavel Machek <[email protected]>

Acked-by: Pavel Machek <[email protected]>

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-04-10 10:40:39

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* Pavel Machek <[email protected]> wrote:

> Hi!
>
> > x86, setup: "glove box" BIOS calls -- infrastructure
> >
> > Impact: new interfaces (not yet used)
> >
> > For all the platforms out there, there is an infinite number of buggy
> > BIOSes. This adds infrastructure to treat BIOS interrupts more like
> > toxic waste and "glove box" them -- we switch out the register set,
> > perform the BIOS interrupt, and then restore the previous state.
> >
> > LKML-Reference: <[email protected]>
> > Signed-off-by: H. Peter Anvin <[email protected]>
> > Cc: Pavel Machek <[email protected]>
>
> Sounds quite sane. Disadvantage is that we will no longer detect
> those buggy BIOSen.

I'd call that an advantage: sandboxing BIOS calls as much as we can
and trusting all data from it as if it were a random packet from the
Internet is the only sane way forward IMHO.

If we really care we could put in checks for unexpected register
state changes ... but is it worth the trouble?

Ingo

2009-04-10 10:44:08

by Pavel Machek

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

On Fri 2009-04-10 12:39:34, Ingo Molnar wrote:
>
> * Pavel Machek <[email protected]> wrote:
>
> > Hi!
> >
> > > x86, setup: "glove box" BIOS calls -- infrastructure
> > >
> > > Impact: new interfaces (not yet used)
> > >
> > > For all the platforms out there, there is an infinite number of buggy
> > > BIOSes. This adds infrastructure to treat BIOS interrupts more like
> > > toxic waste and "glove box" them -- we switch out the register set,
> > > perform the BIOS interrupt, and then restore the previous state.
> > >
> > > LKML-Reference: <[email protected]>
> > > Signed-off-by: H. Peter Anvin <[email protected]>
> > > Cc: Pavel Machek <[email protected]>
> >
> > Sounds quite sane. Disadvantage is that we will no longer detect
> > those buggy BIOSen.
>
> I'd call that an advantage: sandboxing BIOS calls as much as we can
> and trusting all data from it as if it were a random packet from the
> Internet is the only sane way forward IMHO.

Well, difference is that you can defend against arbitrary network
packet, but you can't defend against arbitrarily broken BIOS. If it
loops forever, or overwrites random memory place, we lost...

> If we really care we could put in checks for unexpected register
> state changes ... but is it worth the trouble?

So maybe we do need to cooperate with BIOS people, making them fix
their code. Checking for unexpected changes would certainly be good
idea for firmware testing kit... and it would probably make sense to
complain during regular boot, too.
Pavel

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-04-10 11:27:21

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* Pavel Machek <[email protected]> wrote:

> On Fri 2009-04-10 12:39:34, Ingo Molnar wrote:
> >
> > * Pavel Machek <[email protected]> wrote:
> >
> > > Hi!
> > >
> > > > x86, setup: "glove box" BIOS calls -- infrastructure
> > > >
> > > > Impact: new interfaces (not yet used)
> > > >
> > > > For all the platforms out there, there is an infinite number of buggy
> > > > BIOSes. This adds infrastructure to treat BIOS interrupts more like
> > > > toxic waste and "glove box" them -- we switch out the register set,
> > > > perform the BIOS interrupt, and then restore the previous state.
> > > >
> > > > LKML-Reference: <[email protected]>
> > > > Signed-off-by: H. Peter Anvin <[email protected]>
> > > > Cc: Pavel Machek <[email protected]>
> > >
> > > Sounds quite sane. Disadvantage is that we will no longer detect
> > > those buggy BIOSen.
> >
> > I'd call that an advantage: sandboxing BIOS calls as much as we can
> > and trusting all data from it as if it were a random packet from the
> > Internet is the only sane way forward IMHO.
>
> Well, difference is that you can defend against arbitrary network
> packet, but you can't defend against arbitrarily broken BIOS. If
> it loops forever, or overwrites random memory place, we lost...

We could protect against random memory corruption too, if it ever
became a widespread problem: by executing the BIOS call in a virtual
machine. (We can probably use the KVM code to properly emulate big
real mode, etc.)

That way we can monitor and warn about any undue access patterns.

The solution Peter did here sandboxes the CPU context: which was
observed to be randomly corrupted by BIOSen and depending on
register layout details of other OSs (Windows mostly) it might not
have caused trouble there.

Memory corruption would be noticed under Windows too, so while it
does show up every now and then, it rarely remains unfixed. Register
corruptions will stay unfixed forever if they dont affect Windows
(which they often dont) - so these are far more of a priority to
sandbox.

> > If we really care we could put in checks for unexpected register
> > state changes ... but is it worth the trouble?
>
> So maybe we do need to cooperate with BIOS people, making them fix
> their code. Checking for unexpected changes would certainly be
> good idea for firmware testing kit... and it would probably make
> sense to complain during regular boot, too.

"BIOS people" are operating in a completely different culture. Time
to market, hardware workarounds, short-term differentiators, secret
bootstrap sequences and code compactness are king in that space.
Code quality is dead last in the list. I strongly doubt that given
the radically conflicting priorities a reasonable dialogue can be
established.

Reasonable dialogue could be established with efforts that turn
Linux into a replacement of the firmware: CoreBoot a'ka LinuxBIOS.
Having an end-to-end Linux solution for all things bootstrap is a
very strong concept IMHO. For various reasons that relationship is
not unstrained either, unfortunately.

Ingo

2009-04-10 11:35:46

by Pavel Machek

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Hi!

> > Well, difference is that you can defend against arbitrary network
> > packet, but you can't defend against arbitrarily broken BIOS. If
> > it loops forever, or overwrites random memory place, we lost...
>
> We could protect against random memory corruption too, if it ever
> became a widespread problem: by executing the BIOS call in a virtual
> machine. (We can probably use the KVM code to properly emulate big
> real mode, etc.)

We already have problems where bios corrupts low memory area during
suspend/resume. Not sure how KVM helps.

Anyway I do agree with the patches.

> "BIOS people" are operating in a completely different culture. Time
> to market, hardware workarounds, short-term differentiators, secret
> bootstrap sequences and code compactness are king in that space.
> Code quality is dead last in the list. I strongly doubt that given
> the radically conflicting priorities a reasonable dialogue can be
> established.

"BIOS people" control stuff like SMM mode. We can workaround some BIOS
problems, but definitely not all of them.

For servers, I guess Linux has enough of market share that we could
certify known-good servers (and maybe warn against known-bad).
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-04-10 11:49:56

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* Pavel Machek <[email protected]> wrote:

> > "BIOS people" are operating in a completely different culture.
> > Time to market, hardware workarounds, short-term
> > differentiators, secret bootstrap sequences and code compactness
> > are king in that space. Code quality is dead last in the list. I
> > strongly doubt that given the radically conflicting priorities a
> > reasonable dialogue can be established.
>
> "BIOS people" control stuff like SMM mode. We can workaround some
> BIOS problems, but definitely not all of them.
>
> For servers, I guess Linux has enough of market share that we
> could certify known-good servers (and maybe warn against
> known-bad).

Server space is somewhat less of a problem BIOS quality wise: the
design cycles are longer, the features are more complex and the
profit margins are higher - which all results in saner practices and
more care. They even do server BIOS fixes for Linux.

The problem are the "Does it boot Windows? Ship it, forget it,
buldoze the factory" kind of desktop operations.

Ingo

2009-04-10 17:19:07

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Pavel Machek wrote:
>
>> +/*
>> + * "Glove box" for BIOS calls. Avoids the constant problems with BIOSes
>> + * touching memory they shouldn't be.
>> + */
>
> Touching memory? AFAICT it only prevents touching registers.
>

Ah yes. -EBUGGYCOMMENT. ;)

-hpa

2009-04-10 17:20:49

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Pavel Machek wrote:
>
>> + .code16
>> + .text
>> + .globl intcall
>> + .type intcall, @function
>> +intcall:
>> + /* Self-modify the INT instruction. Ugly, but works. */
>> + cmpb %al, 3f
>> + je 1f
>> + movb %al, 3f
>> + jmp 1f /* Synchronize pipeline */
>> +1:
>
> There are various CPU bugs with self-modifying code, but I guess we
> are not using it heavily enough. Also we are single-threaded so that
> should be ok.
> Pavel
>

This case is extremely straightforward, so I'm not worried about it.
The final JMP is actually not required (there is a LOOP instruction
between the modify and the invocation point) but is there for extra safety.

FWIW, we already do SMC during the transfer to protected mode
(pmjump.S), and hopefully got the issues worked out there.

-hpa

2009-04-10 18:05:49

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 0/6] x86, setup: "glove box" BIOS interrupts

On Friday 10 April 2009, H. Peter Anvin wrote:
> This is a patchset to "glove box" off BIOS interrupts in the x86 setup
> code, thus hopefully dealing once and for all with the problems of
> BIOSes touching registers they shouldn't.
>
> The concept is simple: we manipulate a register image in memory, then
> swap it in immediately before calling the BIOS, and then switch the
> register file back. All BIOS interrupts are channeled through this path.
>
> The increase in size is about 8% or ~1.3K in the maximal case.

FWIW, I like the approach.

Thanks,
Rafael

2009-04-11 16:15:13

by Avi Kivity

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Pavel Machek wrote:
> Hi!
>
>
>>> Well, difference is that you can defend against arbitrary network
>>> packet, but you can't defend against arbitrarily broken BIOS. If
>>> it loops forever, or overwrites random memory place, we lost...
>>>
>> We could protect against random memory corruption too, if it ever
>> became a widespread problem: by executing the BIOS call in a virtual
>> machine. (We can probably use the KVM code to properly emulate big
>> real mode, etc.)
>>
>
> We already have problems where bios corrupts low memory area during
> suspend/resume. Not sure how KVM helps.
>
>

kvm might help detecting these issues, but not in fixing them. If you
isolate the BIOS, then you've prevented corruption, but you've also
prevented it from doing whatever it is it was supposed to do. If you
give it access to memory and the rest of the system, then whatever evil
it has wrought affects the system.

You could try to allow the BIOS access to selected pieces of memory and
hardware, virtualizing the rest, but it seems to me it would be more
like a recipe for a giant headache that a solution.


--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

2009-04-12 05:23:45

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Avi Kivity wrote:
>
> kvm might help detecting these issues, but not in fixing them. If you
> isolate the BIOS, then you've prevented corruption, but you've also
> prevented it from doing whatever it is it was supposed to do. If you
> give it access to memory and the rest of the system, then whatever evil
> it has wrought affects the system.
>
> You could try to allow the BIOS access to selected pieces of memory and
> hardware, virtualizing the rest, but it seems to me it would be more
> like a recipe for a giant headache that a solution.
>

The main thing you could do is drop or virtualize memory accesses to RAM
it should never access in the first place, like some BIOSes which
scribble over random locations in low memory.

-hpa

2009-04-12 14:02:50

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* H. Peter Anvin <[email protected]> wrote:

> Avi Kivity wrote:
>>
>> kvm might help detecting these issues, but not in fixing them.
>> If you isolate the BIOS, then you've prevented corruption, but
>> you've also prevented it from doing whatever it is it was
>> supposed to do. If you give it access to memory and the rest of
>> the system, then whatever evil it has wrought affects the system.
>>
>> You could try to allow the BIOS access to selected pieces of
>> memory and hardware, virtualizing the rest, but it seems to me it
>> would be more like a recipe for a giant headache that a solution.
>>
>
> The main thing you could do is drop or virtualize memory accesses
> to RAM it should never access in the first place, like some BIOSes
> which scribble over random locations in low memory.

it would be enough to get the information out. That way we could see
(from the access patterns) what the heck it is trying to do (did
someone rootkit the bios?), and what we can do about it. Trying to
contain it will likely break the BIOS and causes silent hangs with
no usable bug report left.

Ingo

2009-04-12 14:40:56

by Avi Kivity

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Ingo Molnar wrote:
> * H. Peter Anvin <[email protected]> wrote:
>
>
>> Avi Kivity wrote:
>>
>>> kvm might help detecting these issues, but not in fixing them.
>>> If you isolate the BIOS, then you've prevented corruption, but
>>> you've also prevented it from doing whatever it is it was
>>> supposed to do. If you give it access to memory and the rest of
>>> the system, then whatever evil it has wrought affects the system.
>>>
>>> You could try to allow the BIOS access to selected pieces of
>>> memory and hardware, virtualizing the rest, but it seems to me it
>>> would be more like a recipe for a giant headache that a solution.
>>>
>>>
>> The main thing you could do is drop or virtualize memory accesses
>> to RAM it should never access in the first place, like some BIOSes
>> which scribble over random locations in low memory.
>>
>
> it would be enough to get the information out. That way we could see
> (from the access patterns) what the heck it is trying to do (did
> someone rootkit the bios?), and what we can do about it. Trying to
> contain it will likely break the BIOS and causes silent hangs with
> no usable bug report left.
>

Hmm, it's doable with the 1:1 mode; Andrea did some work on this.

However if the bios tries to do anything clever (like using SMM) things
will fail pretty badly.

--
error compiling committee.c: too many arguments to function

2009-04-12 15:07:31

by Linus Torvalds

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure



On Sat, 11 Apr 2009, H. Peter Anvin wrote:
>
> The main thing you could do is drop or virtualize memory accesses to RAM it
> should never access in the first place, like some BIOSes which scribble over
> random locations in low memory.

Please don't.

This discussion is just taking us down a rat-hole of more complexity, and
_way_ more fragility.

I'm absolutely willing to bet that trying to do the BIOS calls will break
way more than it will fix. Sure, it will probably work for 99.9% of all
BIOSes, but then it will break horribly for some BIOS that tries to do
something "clever". SMM has already been mentioned as an example of
something that simply isn't virtualizable.

Timing is another, very traditional, one. There used to be video BIOSes
that simply didn't work in a dosbox-like environment because they had
tight timing loops that were coupled to hardware. I can pretty much
guarantee that that has gone away as far as the video BIOS is concerned,
but the main BIOS? Who the hell knows.

Sure, none of the calls we do to the BIOS from the kernel should need
anything fancy at all, and maybe I'm pessimistic. But at the same time, I
really don't think the BIOS calls are worth that kind of infrastructure.

Sure, go ahead and wrap them in some kind of "save and restore all
registers" wrapping, but nothing fancier than that. It would just be
overkill, and likely to break more than it fixes.

Linus

2009-04-12 16:35:09

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* Linus Torvalds <[email protected]> wrote:

> Sure, go ahead and wrap them in some kind of "save and restore all
> registers" wrapping, but nothing fancier than that. It would just
> be overkill, and likely to break more than it fixes.

Yeah. I only brought up the virtualization thing as a hypothetical:
"if" corrupting the main OS ever became a widespread problem. Then i
made the argument that this is unlikely to happen, because Windows
will be affected by it just as much. (while register state
corruptions might go unnoticed much more easily, just via the random
call-environment clobbering of registers by Windows itself.)

The only case where i could see virtualization to be useful is the
low memory RAM corruption pattern that some people have observed.

The problem with it, it happens on s2ram transitions, and that is
driven by SMM mainly - which is a hypervisor sitting on top of all
the other would-be-hypervisors and thus not virtualizable.

Which leaves us without a single practical case. So it's not going
to happen.

Ingo

2009-04-12 17:54:44

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Linus Torvalds wrote:
>
> This discussion is just taking us down a rat-hole of more complexity, and
> _way_ more fragility.
>
> I'm absolutely willing to bet that trying to do the BIOS calls will break
> way more than it will fix. Sure, it will probably work for 99.9% of all
> BIOSes, but then it will break horribly for some BIOS that tries to do
> something "clever". SMM has already been mentioned as an example of
> something that simply isn't virtualizable.
>
> Timing is another, very traditional, one. There used to be video BIOSes
> that simply didn't work in a dosbox-like environment because they had
> tight timing loops that were coupled to hardware. I can pretty much
> guarantee that that has gone away as far as the video BIOS is concerned,
> but the main BIOS? Who the hell knows.
>
> Sure, none of the calls we do to the BIOS from the kernel should need
> anything fancy at all, and maybe I'm pessimistic. But at the same time, I
> really don't think the BIOS calls are worth that kind of infrastructure.
>
> Sure, go ahead and wrap them in some kind of "save and restore all
> registers" wrapping, but nothing fancier than that. It would just be
> overkill, and likely to break more than it fixes.
>

Agreed completely.

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.

2009-04-12 18:58:56

by Avi Kivity

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Ingo Molnar wrote:
>> Sure, go ahead and wrap them in some kind of "save and restore all
>> registers" wrapping, but nothing fancier than that. It would just
>> be overkill, and likely to break more than it fixes.
>>
>
> Yeah. I only brought up the virtualization thing as a hypothetical:
> "if" corrupting the main OS ever became a widespread problem. Then i
> made the argument that this is unlikely to happen, because Windows
> will be affected by it just as much. (while register state
> corruptions might go unnoticed much more easily, just via the random
> call-environment clobbering of registers by Windows itself.)
>
> The only case where i could see virtualization to be useful is the
> low memory RAM corruption pattern that some people have observed.
>

You could easily check that by checksumming pages (or actually copying
them to high memory) before the call, and verifying after the call.

> The problem with it, it happens on s2ram transitions, and that is
> driven by SMM mainly - which is a hypervisor sitting on top of all
> the other would-be-hypervisors and thus not virtualizable.
>

AMD in fact has a chapter called "Containerizing Platform SMM" or words
to the effect, which describes how to take a running system and drop its
SMM mode into a virtualization container. I made a point of skipping
over those pages with my eyes closed so I can't tell you how incredibly
complex it is.

It's probably even doable on Intel, though much more difficult, due to
Intel not supporting big real mode in a guest, and most SMM code using
it to access memory. You'd end up running most of the code in the
emulator, and performing the transitions by hand.

Of course, the VMM has to be careful not to trigger SMM itself, or much
merriment ensues.

> Which leaves us without a single practical case. So it's not going
> to happen.
>

I don't think the effort is worth the benefit in this case, but there
actually is an interesting use case for this. SMM is known to be
harmful to deterministic replay games and to real time response. If we
can virtualize SMM, we can increase the range of hardware on which the
real time kernel is able to deliver real time guarantees.

--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

2009-04-13 04:17:32

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* Avi Kivity <[email protected]> wrote:

> Ingo Molnar wrote:
>>> Sure, go ahead and wrap them in some kind of "save and restore all
>>> registers" wrapping, but nothing fancier than that. It would just be
>>> overkill, and likely to break more than it fixes.
>>>
>>
>> Yeah. I only brought up the virtualization thing as a
>> hypothetical: "if" corrupting the main OS ever became a
>> widespread problem. Then i made the argument that this is
>> unlikely to happen, because Windows will be affected by it just
>> as much. (while register state corruptions might go unnoticed
>> much more easily, just via the random call-environment clobbering
>> of registers by Windows itself.)
>>
>> The only case where i could see virtualization to be useful is
>> the low memory RAM corruption pattern that some people have
>> observed.
>
> You could easily check that by checksumming pages (or actually
> copying them to high memory) before the call, and verifying after
> the call.

Yes, we could do memory checks, and ... hey, we already do that:

bb577f9: x86: add periodic corruption check
5394f80: x86: check for and defend against BIOS memory corruption

... and i seem to be the one who implemented it! ;-)

That check resulted in logs showing the BIOS corrupting Linux memory
across s2ram cycles or HDMI plug/unplug events on certain boxes (are
Hollywood rootkits in the BIOS now?), and resulted in some
head-scratching but not much more.

See:

"corrupt PMD after resume"

http://bugzilla.kernel.org/show_bug.cgi?id=11237

>> The problem with it, it happens on s2ram transitions, and that is
>> driven by SMM mainly - which is a hypervisor sitting on top of
>> all the other would-be-hypervisors and thus not virtualizable.
>
> AMD in fact has a chapter called "Containerizing Platform SMM" or
> words to the effect, which describes how to take a running system
> and drop its SMM mode into a virtualization container. I made a
> point of skipping over those pages with my eyes closed so I can't
> tell you how incredibly complex it is.
>
> It's probably even doable on Intel, though much more difficult,
> due to Intel not supporting big real mode in a guest, and most SMM
> code using it to access memory. You'd end up running most of the
> code in the emulator, and performing the transitions by hand.
>
> Of course, the VMM has to be careful not to trigger SMM itself, or
> much merriment ensues.
>
>> Which leaves us without a single practical case. So it's not
>> going to happen.
>
> I don't think the effort is worth the benefit in this case, but
> there actually is an interesting use case for this. SMM is known
> to be harmful to deterministic replay games and to real time
> response. If we can virtualize SMM, we can increase the range of
> hardware on which the real time kernel is able to deliver real
> time guarantees.

Hey, i do have a real sweet spot for deterministic execution - but
SMM, while not problem-free (like most of firmware), also has a very
real role in not letting various hardware melt. So SMM should be
thought of as a flexible extended arm of hardware - not some sw bit.

So i think that the memory of that SMM virtualization chapter you've
almost read should be quickly erased from your mind. (Via forceful
means if prompt corrective self-action is not forthcoming.)

The determinism issue can IMHO be solved via a simpler measure: by
making sure the owner of the box always knows when SMMs happened.
Real-time folks are very picky about their hardware and there's many
suppliers, so it would have a real market effect. I know about one
case where a BIOS was modified to lessen its SMM latency impact.

Ingo

2009-04-13 04:25:56

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* Ingo Molnar <[email protected]> wrote:

>
> * Avi Kivity <[email protected]> wrote:
>
> > Ingo Molnar wrote:
> >>> Sure, go ahead and wrap them in some kind of "save and restore all
> >>> registers" wrapping, but nothing fancier than that. It would just be
> >>> overkill, and likely to break more than it fixes.
> >>>
> >>
> >> Yeah. I only brought up the virtualization thing as a
> >> hypothetical: "if" corrupting the main OS ever became a
> >> widespread problem. Then i made the argument that this is
> >> unlikely to happen, because Windows will be affected by it just
> >> as much. (while register state corruptions might go unnoticed
> >> much more easily, just via the random call-environment clobbering
> >> of registers by Windows itself.)
> >>
> >> The only case where i could see virtualization to be useful is
> >> the low memory RAM corruption pattern that some people have
> >> observed.
> >
> > You could easily check that by checksumming pages (or actually
> > copying them to high memory) before the call, and verifying after
> > the call.
>
> Yes, we could do memory checks, and ... hey, we already do that:
>
> bb577f9: x86: add periodic corruption check
> 5394f80: x86: check for and defend against BIOS memory corruption
>
> ... and i seem to be the one who implemented it! ;-)

s/implemented/merged+fixed :-)

Ingo

2009-04-13 06:45:44

by Avi Kivity

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Ingo Molnar wrote:
> * Avi Kivity <[email protected]> wrote:
>
>
>> Ingo Molnar wrote:
>>
>>>> Sure, go ahead and wrap them in some kind of "save and restore all
>>>> registers" wrapping, but nothing fancier than that. It would just be
>>>> overkill, and likely to break more than it fixes.
>>>>
>>>>
>>> Yeah. I only brought up the virtualization thing as a
>>> hypothetical: "if" corrupting the main OS ever became a
>>> widespread problem. Then i made the argument that this is
>>> unlikely to happen, because Windows will be affected by it just
>>> as much. (while register state corruptions might go unnoticed
>>> much more easily, just via the random call-environment clobbering
>>> of registers by Windows itself.)
>>>
>>> The only case where i could see virtualization to be useful is
>>> the low memory RAM corruption pattern that some people have
>>> observed.
>>>
>> You could easily check that by checksumming pages (or actually
>> copying them to high memory) before the call, and verifying after
>> the call.
>>
>
> Yes, we could do memory checks, and ... hey, we already do that:
>
> bb577f9: x86: add periodic corruption check
> 5394f80: x86: check for and defend against BIOS memory corruption
>
> ... and i seem to be the one who implemented it! ;-)
>
> That check resulted in logs showing the BIOS corrupting Linux memory
> across s2ram cycles or HDMI plug/unplug events on certain boxes (are
> Hollywood rootkits in the BIOS now?), and resulted in some
> head-scratching but not much more.
>

Then there's definitely no point in putting it into a container, is
there? I mean, we could track down the exact instruction which caused
the corruption, but how would it help us?

>> I don't think the effort is worth the benefit in this case, but
>> there actually is an interesting use case for this. SMM is known
>> to be harmful to deterministic replay games and to real time
>> response. If we can virtualize SMM, we can increase the range of
>> hardware on which the real time kernel is able to deliver real
>> time guarantees.
>>
>
> Hey, i do have a real sweet spot for deterministic execution - but
> SMM, while not problem-free (like most of firmware), also has a very
> real role in not letting various hardware melt. So SMM should be
> thought of as a flexible extended arm of hardware - not some sw bit.
>
> So i think that the memory of that SMM virtualization chapter you've
> almost read should be quickly erased from your mind. (Via forceful
> means if prompt corrective self-action is not forthcoming.)
>

I'll keep my remaining neurons, thanks.


--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

2009-04-13 16:29:22

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Ingo Molnar wrote:
>> Yes, we could do memory checks, and ... hey, we already do that:
>>
>> bb577f9: x86: add periodic corruption check
>> 5394f80: x86: check for and defend against BIOS memory corruption
>>
>> ... and i seem to be the one who implemented it! ;-)
>
> s/implemented/merged+fixed :-)

Actually, what would probably be more productive than trying to track
corruption would be to drop the low 1 MB of memory before suspend to RAM
- make sure that it is as close to completely unused as possible.

All *known* cases of low memory corruption are either boot time or due
to s2ram.

I don't know how realistic it is to make the low 1 MB completely unused
over the s2ram cycle. The trivial way of doing it is to simply not use
it -- it's only some 600K after all; a more sophisticated way would be
to explicitly constrain it to transient uses that would be dead at s2ram.

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.

2009-04-13 16:56:44

by Pavel Machek

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

On Mon 2009-04-13 09:27:20, H. Peter Anvin wrote:
> Ingo Molnar wrote:
> >> Yes, we could do memory checks, and ... hey, we already do that:
> >>
> >> bb577f9: x86: add periodic corruption check
> >> 5394f80: x86: check for and defend against BIOS memory corruption
> >>
> >> ... and i seem to be the one who implemented it! ;-)
> >
> > s/implemented/merged+fixed :-)
>
> Actually, what would probably be more productive than trying to track
> corruption would be to drop the low 1 MB of memory before suspend to RAM
> - make sure that it is as close to completely unused as possible.
>
> All *known* cases of low memory corruption are either boot time or due
> to s2ram.
>
> I don't know how realistic it is to make the low 1 MB completely unused
> over the s2ram cycle. The trivial way of doing it is to simply not use
> it -- it's only some 600K after all; a more sophisticated way would be
> to explicitly constrain it to transient uses that would be dead at s2ram.

That should be doable... with memory hotplug support etc, eventually.

OTOH all known corruption is within 64K IIRC, and reserving that is
rather easy.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-04-13 17:02:11

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Pavel Machek wrote:
>
> OTOH all known corruption is within 64K IIRC, and reserving that is
> rather easy.
> Pavel

Sadly, not so.

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.

2009-04-13 18:34:51

by Alan Jenkins

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

On 4/13/09, H. Peter Anvin <[email protected]> wrote:
> Ingo Molnar wrote:
>>> Yes, we could do memory checks, and ... hey, we already do that:
>>>
>>> bb577f9: x86: add periodic corruption check
>>> 5394f80: x86: check for and defend against BIOS memory corruption
>>>
>>> ... and i seem to be the one who implemented it! ;-)
>>
>> s/implemented/merged+fixed :-)
>
> Actually, what would probably be more productive than trying to track
> corruption would be to drop the low 1 MB of memory before suspend to RAM
> - make sure that it is as close to completely unused as possible.
>
> All *known* cases of low memory corruption are either boot time or due
> to s2ram.

IIRC, the first person to report the issue found that it triggered
when hotplugging a HDMI cable.

2009-04-13 19:08:56

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Alan Jenkins wrote:
> IIRC, the first person to report the issue found that it triggered
> when hotplugging a HDMI cable.

Oh, that's right. Either we were invoking the video BIOS from the
kernel (which we do actually do sometimes) -- in which case we have
control over when it happens -- or there is commingling of the video
BIOS and mainboard BIOS combined with SMM crap. Joy.

-hpa

2009-04-14 00:07:47

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure


* H. Peter Anvin <[email protected]> wrote:

> Alan Jenkins wrote:
>> IIRC, the first person to report the issue found that it triggered
>> when hotplugging a HDMI cable.
>
> Oh, that's right. Either we were invoking the video BIOS from the
> kernel (which we do actually do sometimes) -- in which case we
> have control over when it happens -- or there is commingling of
> the video BIOS and mainboard BIOS combined with SMM crap. Joy.

The corruption pattern in the bugzilla:

http://bugzilla.kernel.org/show_bug.cgi?id=11237

... looks like an x86 descriptor table. Does the pattern below make
any sense to anyone? I've attached the relevant bits of one of the
reports below.

Ingo

[ 28.414367] Corrupted low memory at c000c000 (c000 phys) = 02062004
[ 28.414367] Corrupted low memory at c000c004 (c004 phys) = 0000003a
[ 28.414367] Corrupted low memory at c000c008 (c008 phys) = 00208000
[ 28.414367] Corrupted low memory at c000c00c (c00c phys) = 3e88c6fd
[ 28.414367] Corrupted low memory at c000c018 (c018 phys) = 0000004a
[ 28.414367] Corrupted low memory at c000c01c (c01c phys) = aaaaaa00
[ 28.414367] Corrupted low memory at c000c020 (c020 phys) = 00000644
[ 28.414367] Corrupted low memory at c000c024 (c024 phys) = 00000140
[ 28.414367] Corrupted low memory at c000c028 (c028 phys) = ffffffff
[ 28.414367] Corrupted low memory at c000c02c (c02c phys) = ffffffff
[ 28.414367] Corrupted low memory at c000c030 (c030 phys) = ffffffff
[ 28.414367] Corrupted low memory at c000c034 (c034 phys) = ffffffff
[ 28.414367] Corrupted low memory at c000c038 (c038 phys) = ffffffff
[ 28.414367] Corrupted low memory at c000c03c (c03c phys) = ffffffff
[ 28.414367] Corrupted low memory at c000c040 (c040 phys) = 00fffbff
[ 28.414367] Corrupted low memory at c000c044 (c044 phys) = fd9035c3
[ 28.414367] Corrupted low memory at c000c048 (c048 phys) = a9fe7bf8
[ 28.414367] Corrupted low memory at c000c04c (c04c phys) = 3f00ff0f
[ 28.414367] Corrupted low memory at c000c050 (c050 phys) = c7ffdffe
[ 28.414367] Corrupted low memory at c000c054 (c054 phys) = 3c03bc1e
[ 28.414367] Corrupted low memory at c000c058 (c058 phys) = 00d62480
[ 28.414367] Corrupted low memory at c000c05c (c05c phys) = fffffe14
[ 28.414367] Corrupted low memory at c000c060 (c060 phys) = eb1fe1fe
[ 28.414367] Corrupted low memory at c000c064 (c064 phys) = ff3cf64c
[ 28.414367] Corrupted low memory at c000c068 (c068 phys) = 807f879f
[ 28.414367] Corrupted low memory at c000c06c (c06c phys) = f0266027
[ 28.414367] Corrupted low memory at c000c070 (c070 phys) = 18fe1d74
[ 28.414367] Corrupted low memory at c000c074 (c074 phys) = 6b122000
[ 28.414367] Corrupted low memory at c000c078 (c078 phys) = e7fffbcf
[ 28.414367] Corrupted low memory at c000c07c (c07c phys) = 0ff0f3f0
[ 28.414367] Corrupted low memory at c000c080 (c080 phys) = 9fffee3f
[ 28.414367] Corrupted low memory at c000c084 (c084 phys) = 1bc3e440
[ 28.414367] Corrupted low memory at c000c088 (c088 phys) = 07fc01fe
[ 28.414367] Corrupted low memory at c000c08c (c08c phys) = ff0dfe00
[ 28.414367] Corrupted low memory at c000c090 (c090 phys) = ebe00035
[ 28.414367] Corrupted low memory at c000c094 (c094 phys) = 3fe00ff0
[ 28.414367] Corrupted low memory at c000c098 (c098 phys) = f86ff007
[ 28.414367] Corrupted low memory at c000c09c (c09c phys) = ff803fc0
[ 28.414367] Corrupted low memory at c000c0a0 (c0a0 phys) = e1bfc01f
[ 28.414367] Corrupted low memory at c000c0a4 (c0a4 phys) = fe00ff03
[ 28.414367] Corrupted low memory at c000c0a8 (c0a8 phys) = 86ff007f
[ 28.414367] Corrupted low memory at c000c0ac (c0ac phys) = 78001a30
[ 28.414367] Corrupted low memory at c000c0b0 (c0b0 phys) = f007f81f
[ 28.414367] Corrupted low memory at c000c0b4 (c0b4 phys) = 37f803fc
[ 28.414367] Corrupted low memory at c000c0b8 (c0b8 phys) = c01fe07f
[ 28.414367] Corrupted low memory at c000c0bc (c0bc phys) = dfe00ff0
[ 28.414367] Corrupted low memory at c000c0c0 (c0c0 phys) = 007f81ff
[ 28.414367] Corrupted low memory at c000c0c4 (c0c4 phys) = 7f803fc3
[ 28.414367] Corrupted low memory at c000c0c8 (c0c8 phys) = 000f7ffc
[ 28.414367] Corrupted low memory at c000c0cc (c0cc phys) = 03fc0ff8
[ 28.414367] Corrupted low memory at c000c0d0 (c0d0 phys) = fc01fe1b
[ 28.414367] Corrupted low memory at c000c0d4 (c0d4 phys) = 0ff03fe0
[ 28.414367] Corrupted low memory at c000c0d8 (c0d8 phys) = f007f86f
[ 28.414367] Corrupted low memory at c000c0dc (c0dc phys) = 3fc0ff80
[ 28.414367] Corrupted low memory at c000c0e0 (c0e0 phys) = c01fe1bf
[ 28.414367] Corrupted low memory at c000c0e4 (c0e4 phys) = 07bffe00
[ 28.414367] Corrupted low memory at c000c0e8 (c0e8 phys) = fe07fc01
[ 28.414367] Corrupted low memory at c000c0ec (c0ec phys) = 00ff0dfe
[ 28.414367] Corrupted low memory at c000c0f0 (c0f0 phys) = f81ff007
[ 28.414367] Corrupted low memory at c000c0f4 (c0f4 phys) = 03fc37f8
[ 28.414367] Corrupted low memory at c000c0f8 (c0f8 phys) = e07fc01f
[ 28.414367] Corrupted low memory at c000c0fc (c0fc phys) = 0ff0dfe0
[ 28.414367] Corrupted low memory at c000c100 (c100 phys) = dfff0003
[ 28.414367] Corrupted low memory at c000c104 (c104 phys) = 03fe00ff
[ 28.414367] Corrupted low memory at c000c108 (c108 phys) = 7f86ff00
[ 28.414367] Corrupted low memory at c000c10c (c10c phys) = 0ff803fc
[ 28.414367] Corrupted low memory at c000c110 (c110 phys) = fe1bfc01
[ 28.414367] Corrupted low memory at c000c114 (c114 phys) = 3fe00ff0
[ 28.414367] Corrupted low memory at c000c118 (c118 phys) = f86ff007
[ 28.414367] Corrupted low memory at c000c11c (c11c phys) = ff8001ef
[ 28.414367] Corrupted low memory at c000c120 (c120 phys) = ff007f81
[ 28.414367] Corrupted low memory at c000c124 (c124 phys) = c37f803f
[ 28.414367] Corrupted low memory at c000c128 (c128 phys) = fc01fe07
[ 28.414367] Corrupted low memory at c000c12c (c12c phys) = 0dfe00ff
[ 28.414367] Corrupted low memory at c000c130 (c130 phys) = f007f81f
[ 28.414367] Corrupted low memory at c000c134 (c134 phys) = 37f803fc
[ 28.414367] Corrupted low memory at c000c138 (c138 phys) = c000f7ff
[ 28.414367] Corrupted low memory at c000c13c (c13c phys) = 803fc0ff
[ 28.414367] Corrupted low memory at c000c140 (c140 phys) = bfc01fe1
[ 28.414367] Corrupted low memory at c000c144 (c144 phys) = 00ff03fe
[ 28.414367] Corrupted low memory at c000c148 (c148 phys) = ff007f86
[ 28.414367] Corrupted low memory at c000c14c (c14c phys) = 03fc0ff8
[ 28.414367] Corrupted low memory at c000c150 (c150 phys) = fc01fe1b
[ 28.414367] Corrupted low memory at c000c154 (c154 phys) = 007bffe0
[ 28.414367] Corrupted low memory at c000c158 (c158 phys) = 1fe07fc0
[ 28.414367] Corrupted low memory at c000c15c (c15c phys) = e00ff0df
[ 28.414367] Corrupted low memory at c000c160 (c160 phys) = 7f81ff00
[ 28.414367] Corrupted low memory at c000c164 (c164 phys) = 803fc37f
[ 28.414367] Corrupted low memory at c000c168 (c168 phys) = fe07fc01
[ 28.414367] Corrupted low memory at c000c16c (c16c phys) = 00ff0dfe
[ 28.414367] Corrupted low memory at c000c170 (c170 phys) = 3dfff000
[ 28.414367] Corrupted low memory at c000c174 (c174 phys) = f03fe00f
[ 28.414367] Corrupted low memory at c000c178 (c178 phys) = 07f86ff0
[ 28.414367] Corrupted low memory at c000c17c (c17c phys) = c0ff803f
[ 28.414367] Corrupted low memory at c000c180 (c180 phys) = 1fe1bfc0
[ 28.414367] Corrupted low memory at c000c184 (c184 phys) = 03fe00ff
[ 28.414367] Corrupted low memory at c000c188 (c188 phys) = 7f86ff00
[ 28.414367] Corrupted low memory at c000c18c (c18c phys) = fff8001e
[ 28.414367] Corrupted low memory at c000c190 (c190 phys) = 1ff007f8
[ 28.414367] Corrupted low memory at c000c194 (c194 phys) = fc37f803
[ 28.414367] Corrupted low memory at c000c198 (c198 phys) = 7fc01fe0
[ 28.414367] Corrupted low memory at c000c19c (c19c phys) = f0dfe00f
[ 28.414367] Corrupted low memory at c000c1a0 (c1a0 phys) = ff007f81
[ 28.414367] Corrupted low memory at c000c1a4 (c1a4 phys) = c37f803f
[ 28.414367] Corrupted low memory at c000c1a8 (c1a8 phys) = fc000f7f
[ 28.414367] Corrupted low memory at c000c1ac (c1ac phys) = f803fc0f
[ 28.414367] Corrupted low memory at c000c1b0 (c1b0 phys) = 1bfc01fe
[ 28.414367] Corrupted low memory at c000c1b4 (c1b4 phys) = e00ff03f
[ 28.414367] Corrupted low memory at c000c1b8 (c1b8 phys) = 6ff007f8
[ 28.414367] Corrupted low memory at c000c1bc (c1bc phys) = 803fc0ff
[ 28.414367] Corrupted low memory at c000c1c0 (c1c0 phys) = bfc01fe1
[ 28.414367] Corrupted low memory at c000c1c4 (c1c4 phys) = 0007bffe
[ 28.414367] Corrupted low memory at c000c1c8 (c1c8 phys) = 01fe07fc
[ 28.414367] Corrupted low memory at c000c1cc (c1cc phys) = fe00ff0d
[ 28.414367] Corrupted low memory at c000c1d0 (c1d0 phys) = 07f81ff0
[ 28.414367] Corrupted low memory at c000c1d4 (c1d4 phys) = f803fc37
[ 28.414367] Corrupted low memory at c000c1d8 (c1d8 phys) = 1fe07fc0
[ 28.414367] Corrupted low memory at c000c1dc (c1dc phys) = e00ff0df
[ 28.414367] Corrupted low memory at c000c1e0 (c1e0 phys) = 03dfff00
[ 28.414367] Corrupted low memory at c000c1e4 (c1e4 phys) = ff03fe00
[ 28.414367] Corrupted low memory at c000c1e8 (c1e8 phys) = 007f86ff
[ 28.414367] Corrupted low memory at c000c1ec (c1ec phys) = fc0ff803
[ 28.414367] Corrupted low memory at c000c1f0 (c1f0 phys) = 01fe1bfc
[ 28.414367] Corrupted low memory at c000c1f4 (c1f4 phys) = f03fe00f
[ 28.414367] Corrupted low memory at c000c1f8 (c1f8 phys) = 07f86ff0
[ 28.414367] Corrupted low memory at c000c1fc (c1fc phys) = efff8001
[ 28.414367] Corrupted low memory at c000c200 (c200 phys) = 81ff007f
[ 28.414367] Corrupted low memory at c000c204 (c204 phys) = 3fc37f80
[ 28.414367] Corrupted low memory at c000c208 (c208 phys) = 07fc01fe
[ 28.414367] Corrupted low memory at c000c20c (c20c phys) = ff0dfe00
[ 28.414367] Corrupted low memory at c000c210 (c210 phys) = 1ff007f8
[ 28.414367] Corrupted low memory at c000c214 (c214 phys) = fc37f803
[ 28.414367] Corrupted low memory at c000c218 (c218 phys) = ffc000f7
[ 28.414367] Corrupted low memory at c000c21c (c21c phys) = ff803fc0
[ 28.414367] Corrupted low memory at c000c220 (c220 phys) = e1bfc01f
[ 28.414367] Corrupted low memory at c000c224 (c224 phys) = fe00ff03
[ 28.414367] Corrupted low memory at c000c228 (c228 phys) = 86ff007f
[ 28.414367] Corrupted low memory at c000c22c (c22c phys) = f803fc0f
[ 28.414367] Corrupted low memory at c000c230 (c230 phys) = 1bfc01fe
[ 28.414367] Corrupted low memory at c000c234 (c234 phys) = e0007bff
[ 28.414367] Corrupted low memory at c000c238 (c238 phys) = c01fe07f
[ 28.414367] Corrupted low memory at c000c23c (c23c phys) = dfe00ff0
[ 28.414367] Corrupted low memory at c000c240 (c240 phys) = 007f81ff
[ 28.414367] Corrupted low memory at c000c244 (c244 phys) = 7f803fc3
[ 28.414367] Corrupted low memory at c000c248 (c248 phys) = 01fe07fc
[ 28.414367] Corrupted low memory at c000c24c (c24c phys) = fe00ff0d
[ 28.414367] Corrupted low memory at c000c250 (c250 phys) = 003dfff0
[ 28.414367] Corrupted low memory at c000c254 (c254 phys) = 0ff03fe0
[ 28.414367] Corrupted low memory at c000c258 (c258 phys) = f007f86f
[ 28.414367] Corrupted low memory at c000c25c (c25c phys) = 3fc0ff80
[ 28.414367] Corrupted low memory at c000c260 (c260 phys) = c01fe1bf
[ 28.414367] Corrupted low memory at c000c264 (c264 phys) = ff03fe00
[ 28.414367] Corrupted low memory at c000c268 (c268 phys) = 007f86ff
[ 28.414367] Corrupted low memory at c000c26c (c26c phys) = 1efff800
[ 28.414367] Corrupted low memory at c000c270 (c270 phys) = f81ff007
[ 28.414367] Corrupted low memory at c000c274 (c274 phys) = 03fc37f8
[ 28.414367] Corrupted low memory at c000c278 (c278 phys) = e07fc01f
[ 28.414367] Corrupted low memory at c000c27c (c27c phys) = 0ff0dfe0
[ 28.414367] Corrupted low memory at c000c280 (c280 phys) = 81ff007f
[ 28.414367] Corrupted low memory at c000c284 (c284 phys) = 3fc37f80
[ 28.414367] Corrupted low memory at c000c288 (c288 phys) = 7ffc000f
[ 28.414367] Corrupted low memory at c000c28c (c28c phys) = 0ff803fc
[ 28.414367] Corrupted low memory at c000c290 (c290 phys) = fe1bfc01
[ 28.414367] Corrupted low memory at c000c294 (c294 phys) = 3fe00ff0
[ 28.414367] Corrupted low memory at c000c298 (c298 phys) = f86ff007
[ 28.414367] Corrupted low memory at c000c29c (c29c phys) = ff803fc0
[ 28.414367] Corrupted low memory at c000c2a0 (c2a0 phys) = e1bfc01f
[ 28.414367] Corrupted low memory at c000c2a4 (c2a4 phys) = fe0007bf
[ 28.414367] Corrupted low memory at c000c2a8 (c2a8 phys) = fc01fe07
[ 28.414367] Corrupted low memory at c000c2ac (c2ac phys) = 0dfe00ff
[ 28.414367] Corrupted low memory at c000c2b0 (c2b0 phys) = f007f81f
[ 28.414367] Corrupted low memory at c000c2b4 (c2b4 phys) = 37f803fc
[ 28.414367] Corrupted low memory at c000c2b8 (c2b8 phys) = c01fe07f
[ 28.414367] Corrupted low memory at c000c2bc (c2bc phys) = dfe00ff0
[ 28.414367] Corrupted low memory at c000c2c0 (c2c0 phys) = 0003dfff
[ 28.414367] Corrupted low memory at c000c2c4 (c2c4 phys) = 00ff03fe
[ 28.414367] Corrupted low memory at c000c2c8 (c2c8 phys) = ff007f86
[ 28.414367] Corrupted low memory at c000c2cc (c2cc phys) = 03fc0ff8
[ 28.414367] Corrupted low memory at c000c2d0 (c2d0 phys) = fc01fe1b
[ 28.414367] Corrupted low memory at c000c2d4 (c2d4 phys) = 0ff03fe0
[ 28.414367] Corrupted low memory at c000c2d8 (c2d8 phys) = f007f86f
[ 28.414367] Corrupted low memory at c000c2dc (c2dc phys) = 01efff80
[ 28.414367] Corrupted low memory at c000c2e0 (c2e0 phys) = 7f81ff00
[ 28.414367] Corrupted low memory at c000c2e4 (c2e4 phys) = 803fc37f
[ 28.414367] Corrupted low memory at c000c2e8 (c2e8 phys) = fe07fc01
[ 28.414367] Corrupted low memory at c000c2ec (c2ec phys) = 00ff0dfe
[ 28.414367] Corrupted low memory at c000c2f0 (c2f0 phys) = f81ff007
[ 28.414367] Corrupted low memory at c000c2f4 (c2f4 phys) = 03fc37f8
[ 28.414367] Corrupted low memory at c000c2f8 (c2f8 phys) = f7ffc000
[ 28.414367] Corrupted low memory at c000c2fc (c2fc phys) = c0ff803f
[ 28.414367] Corrupted low memory at c000c300 (c300 phys) = 1fe1bfc0
[ 28.414367] Corrupted low memory at c000c304 (c304 phys) = 03fe00ff
[ 28.414367] Corrupted low memory at c000c308 (c308 phys) = 7f86ff00
[ 28.414367] Corrupted low memory at c000c30c (c30c phys) = 0ff803fc
[ 28.414367] Corrupted low memory at c000c310 (c310 phys) = fe1bfc01
[ 28.414367] Corrupted low memory at c000c314 (c314 phys) = ffe0007b
[ 28.414367] Corrupted low memory at c000c318 (c318 phys) = 7fc01fe0
[ 28.414367] Corrupted low memory at c000c31c (c31c phys) = f0dfe00f
[ 28.414367] Corrupted low memory at c000c320 (c320 phys) = ff007f81
[ 28.414367] Corrupted low memory at c000c324 (c324 phys) = c37f803f
[ 28.414367] Corrupted low memory at c000c328 (c328 phys) = fc01fe07
[ 28.414367] Corrupted low memory at c000c32c (c32c phys) = 0dfe00ff
[ 28.414367] Corrupted low memory at c000c330 (c330 phys) = f0003dff
[ 28.414367] Corrupted low memory at c000c334 (c334 phys) = e00ff03f
[ 28.414367] Corrupted low memory at c000c338 (c338 phys) = 6ff007f8
[ 28.414367] Corrupted low memory at c000c33c (c33c phys) = 803fc0ff
[ 28.414367] Corrupted low memory at c000c340 (c340 phys) = bfc01fe1
[ 28.414367] Corrupted low memory at c000c344 (c344 phys) = 00ff03fe
[ 28.414367] Corrupted low memory at c000c348 (c348 phys) = ff007f86
[ 28.414367] Corrupted low memory at c000c34c (c34c phys) = 001efff8
[ 28.414367] Corrupted low memory at c000c350 (c350 phys) = 07f81ff0
[ 28.414367] Corrupted low memory at c000c354 (c354 phys) = f803fc37
[ 28.414367] Corrupted low memory at c000c358 (c358 phys) = 1fe07fc0
[ 28.414367] Corrupted low memory at c000c35c (c35c phys) = e00ff0df
[ 28.414367] Corrupted low memory at c000c360 (c360 phys) = 7f81ff00
[ 28.414367] Corrupted low memory at c000c364 (c364 phys) = 803fc37f
[ 28.414367] Corrupted low memory at c000c368 (c368 phys) = 0f7ffc00
[ 28.414367] Corrupted low memory at c000c36c (c36c phys) = fc0ff803
[ 28.414367] Corrupted low memory at c000c370 (c370 phys) = 01fe1bfc
[ 28.414367] Corrupted low memory at c000c374 (c374 phys) = f03fe00f
[ 28.414367] Corrupted low memory at c000c378 (c378 phys) = 07f86ff0
[ 28.414367] Corrupted low memory at c000c37c (c37c phys) = c0ff803f
[ 28.414367] Corrupted low memory at c000c380 (c380 phys) = 1fe1bfc0
[ 28.414367] Corrupted low memory at c000c384 (c384 phys) = bffe0007
[ 28.414367] Corrupted low memory at c000c388 (c388 phys) = 07fc01fe
[ 28.414367] Corrupted low memory at c000c38c (c38c phys) = ff0dfe00
[ 28.414367] Corrupted low memory at c000c390 (c390 phys) = 1ff007f8
[ 28.414367] Corrupted low memory at c000c394 (c394 phys) = fc37f803
[ 28.414367] Corrupted low memory at c000c398 (c398 phys) = 7fc01fe0
[ 28.414367] Corrupted low memory at c000c39c (c39c phys) = f0dfe00f
[ 28.414367] Corrupted low memory at c000c3a0 (c3a0 phys) = ff0003df
[ 28.414367] Corrupted low memory at c000c3a4 (c3a4 phys) = fe00ff03
[ 28.414367] Corrupted low memory at c000c3a8 (c3a8 phys) = 86ff007f
[ 28.414367] Corrupted low memory at c000c3ac (c3ac phys) = f803fc0f
[ 28.414367] Corrupted low memory at c000c3b0 (c3b0 phys) = 1bfc01fe
[ 28.414367] Corrupted low memory at c000c3b4 (c3b4 phys) = e00ff03f
[ 28.414367] Corrupted low memory at c000c3b8 (c3b8 phys) = 6ff007f8
[ 28.414367] Corrupted low memory at c000c3bc (c3bc phys) = 8001efff
[ 28.414367] Pid: 2217, comm: suspend-steph Not tainted 2.6.27-rc6 #2
[ 28.414367] [<c02485eb>] dpm_power_up+0x33/0x96
[ 28.414367] [<c01431e1>] suspend_devices_and_enter+0xc3/0x11c
[ 28.414367] [<c014333c>] enter_state+0xc3/0x113
[ 28.414367] [<c0143413>] state_store+0x87/0x9a
[ 28.414367] [<c014338c>] state_store+0x0/0x9a
[ 28.414367] [<c01e6687>] kobj_attr_store+0x18/0x1c
[ 28.414367] [<c01b3fc6>] sysfs_write_file+0xb0/0xdd
[ 28.414367] [<c01b3f16>] sysfs_write_file+0x0/0xdd
[ 28.414367] [<c017a87f>] vfs_write+0x84/0x121
[ 28.414367] [<c017a9b4>] sys_write+0x3c/0x63
[ 28.414367] [<c01038a3>] sysenter_do_call+0x12/0x2f
[ 28.414367] =======================
[ 28.416720] ACPI: Waking up from system sleep state S3

2009-04-14 04:44:49

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Ingo Molnar wrote:
>
> ... looks like an x86 descriptor table. Does the pattern below make
> any sense to anyone? I've attached the relevant bits of one of the
> reports below.
>

It's weird... it's clearly not random, but the pattern is shifting all
over the place. Almost makes me want to guess some kind of bitmask (the
0xaaaaaa00 bit and the stretches of 00 and ff kind of hint that way) but
even then it doesn't really seem to make a whole lot of sense. Perhaps
it's a data segment of some code which is barfing on memory.

960 bytes at 0xc000 (48K)... almost makes one wonder if someone confused
address 0xc000 with segment 0xc000 (the VGA BIOS)...

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.

2009-04-14 09:04:16

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

H. Peter Anvin wrote:
> Ingo Molnar wrote:
>
>> ... looks like an x86 descriptor table. Does the pattern below make
>> any sense to anyone? I've attached the relevant bits of one of the
>> reports below.
>>
>>
>
> It's weird... it's clearly not random, but the pattern is shifting all
> over the place. Almost makes me want to guess some kind of bitmask (the
> 0xaaaaaa00 bit and the stretches of 00 and ff kind of hint that way) but
> even then it doesn't really seem to make a whole lot of sense. Perhaps
> it's a data segment of some code which is barfing on memory.
>
> 960 bytes at 0xc000 (48K)... almost makes one wonder if someone confused
> address 0xc000 with segment 0xc000 (the VGA BIOS)...
>

(I wonder if its a bunch of super-secret HDMI crypto keys ;)

J

2009-04-14 16:04:47

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [tip:x86/setup] x86, setup: "glove box" BIOS calls -- infrastructure

Jeremy Fitzhardinge wrote:
>
> (I wonder if its a bunch of super-secret HDMI crypto keys ;)
>

It's too long to be an EDID block (128 bytes), but it could be part of it.

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.