[PATCH] paravirt: Be careful about touching BIOS address space
authorRusty Russell <rusty@rustcorp.com.au>
Thu, 7 Dec 2006 01:14:08 +0000 (02:14 +0100)
committerAndi Kleen <andi@basil.nowhere.org>
Thu, 7 Dec 2006 01:14:08 +0000 (02:14 +0100)
BIOS ROM areas may not be mapped into the guest address space, so be careful
when touching those addresses to make sure they appear to be mapped.

[akpm@osdl.org: fix unused var warning]
AK: Changed __get_user to probe_kernel_address

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
arch/i386/kernel/e820.c
arch/i386/pci/pcbios.c

index b755255f2721537c16bbf90f9bd827f871c5f693..b704790f79690be9f3f0f0d1e18e1a509f6a335e 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/efi.h>
 #include <linux/pfn.h>
+#include <linux/uaccess.h>
 
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -155,7 +156,14 @@ static struct resource standard_io_resources[] = { {
        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 } };
 
-#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
+static int romsignature(const unsigned char *x)
+{
+       unsigned short sig;
+       int ret = 0;
+       if (probe_kernel_address((const unsigned short *)x, sig) == 0)
+               ret = (sig == 0xaa55);
+       return ret;
+}
 
 static int __init romchecksum(unsigned char *rom, unsigned long length)
 {
index ed1512a175ab08e200751ed5078f2373a9b5760f..5f5193401beadea0302538b348dacd1a76b261c7 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 #include "pci.h"
 #include "pci-functions.h"
 
@@ -314,6 +315,10 @@ static struct pci_raw_ops * __devinit pci_find_bios(void)
        for (check = (union bios32 *) __va(0xe0000);
             check <= (union bios32 *) __va(0xffff0);
             ++check) {
+               long sig;
+               if (probe_kernel_address(&check->fields.signature, sig))
+                       continue;
+
                if (check->fields.signature != BIOS32_SIGNATURE)
                        continue;
                length = check->fields.length * 16;
@@ -331,11 +336,13 @@ static struct pci_raw_ops * __devinit pci_find_bios(void)
                }
                DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check);
                if (check->fields.entry >= 0x100000) {
-                       printk("PCI: BIOS32 entry (0x%p) in high memory, cannot use.\n", check);
+                       printk("PCI: BIOS32 entry (0x%p) in high memory, "
+                                       "cannot use.\n", check);
                        return NULL;
                } else {
                        unsigned long bios32_entry = check->fields.entry;
-                       DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
+                       DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n",
+                                       bios32_entry);
                        bios32_indirect.address = bios32_entry + PAGE_OFFSET;
                        if (check_pcibios())
                                return &pci_bios_access;