| Submitter | Siarhei Liakh |
|---|---|
| Date | 2009-07-20 00:42:21 |
| Message ID | <817ecb6f0907191742i13df19afmc4e258a857c3b465@mail.gmail.com> |
| Download | mbox | patch |
| Permalink | /patch/36265/ |
| State | New |
| Headers | show |
Comments
Siarhei Liakh wrote: > According to BIOS32 specification > (http://members.datafast.net.au/dft0802/specs/bios32.pdf), at most two > pages per BIOS32 service should be set executable and no pages need to > be writeable. This patch modifies bios32_service() to set proper page > access permissions at time of service discovery, as described in the > specification. > Further, hardcoded protection of memory area between 640k to 1Mb have > been removed from static_protections(), since only pages mentioned > above need to be executable, not whole BIOS region. > > The patch have been developed for Linux 2.6.30 x86 by Siarhei Liakh > <sliakh.lkml@gmail.com> and Xuxian Jiang <jiang@cs.ncsu.edu>. > Specifications mean little in the BIOS space, unfortunately. Do we have any notion about how many machines this has been tested on? -hpa
For now I have only tested it on my home system and qemu. Actuallym in both cases, I had to compile kernel with only CONFIG_PCI_GOBIOS=y, since Kernel prefers other ways to access PCI when possible (with CONFIG_PCI_GOANY=y). On Sun, Jul 19, 2009 at 8:53 PM, H. Peter Anvin<hpa@zytor.com> wrote: > Siarhei Liakh wrote: >> According to BIOS32 specification >> (http://members.datafast.net.au/dft0802/specs/bios32.pdf), at most two >> pages per BIOS32 service should be set executable and no pages need to >> be writeable. This patch modifies bios32_service() to set proper page >> access permissions at time of service discovery, as described in the >> specification. >> Further, hardcoded protection of memory area between 640k to 1Mb have >> been removed from static_protections(), since only pages mentioned >> above need to be executable, not whole BIOS region. >> >> The patch have been developed for Linux 2.6.30 x86 by Siarhei Liakh >> <sliakh.lkml@gmail.com> and Xuxian Jiang <jiang@cs.ncsu.edu>. >> > > Specifications mean little in the BIOS space, unfortunately. Do we have > any notion about how many machines this has been tested on? > > -hpa > > -- > H. Peter Anvin, Intel Open Source Technology Center > I work for Intel. I don't speak on their behalf. > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Patch
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index e17efed..9ce45d2 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -254,13 +254,6 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, pgprot_t forbidden = __pgprot(0); /* - * The BIOS area between 640k and 1Mb needs to be executable for - * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support. - */ - if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT)) - pgprot_val(forbidden) |= _PAGE_NX; - - /* * The kernel text needs to be executable for obvious reasons * Does not cover __inittext since that is gone later on. On * 64bit we do not enforce !NX on the low mapping diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 1c975cc..31a2653 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c @@ -8,6 +8,7 @@ #include <linux/uaccess.h> #include <asm/pci_x86.h> #include <asm/pci-functions.h> +#include <asm/cacheflush.h> /* BIOS32 signature: "_32_" */ #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24)) @@ -69,6 +70,7 @@ static unsigned long bios32_service(unsigned long service) unsigned long length; /* %ecx */ unsigned long entry; /* %edx */ unsigned long flags; + unsigned long pg_address; local_irq_save(flags); __asm__("lcall *(%%edi); cld" @@ -82,15 +84,21 @@ static unsigned long bios32_service(unsigned long service) local_irq_restore(flags); switch (return_code) { - case 0: - return address + entry; - case 0x80: /* Not present */ - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); - return 0; - default: /* Shouldn't happen */ - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", - service, return_code); - return 0; + case 0: /* Service present, set proper page access */ + address += entry; + pg_address = PFN_DOWN(address + PAGE_OFFSET) << PAGE_SHIFT; + set_memory_ro(pg_address, 2); + set_memory_x(pg_address, 2); + return address; + case 0x80: /* Not present */ + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", + service); + return 0; + default: /* Shouldn't happen */ + printk(KERN_WARNING "bios32_service(0x%lx): " + "returned 0x%x -- BIOS bug!\n", + service, return_code); + return 0; } } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in