x86: Reducing footprint of BIOS32 service mappings
diff mbox series

Message ID 817ecb6f0907191742i13df19afmc4e258a857c3b465@mail.gmail.com
State New, archived
Headers show
Series
  • x86: Reducing footprint of BIOS32 service mappings
Related show

Commit Message

tip-bot for Siarhei Liakh July 20, 2009, 12:42 a.m. UTC
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>.

---

Signed-off-by: Siarhei Liakh <sliakh.lkml@gmail.com>
Signed-off-by: Xuxian Jiang <jiang@cs.ncsu.edu>

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/

Comments

H. Peter Anvin July 20, 2009, 12:53 a.m. UTC | #1
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
tip-bot for Siarhei Liakh July 20, 2009, 1:02 a.m. UTC | #2
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 mbox series

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