x86: make executable for video bios area
PATCH 1/1 x86: make executable for video bios area
5bd5a452662bc37c54fb6828db1a3faf87e6511c make area between BIOS_BEGIN and BIOS_END have NX protection when boot machine with acpi enable(acpi will disable pcibios).
This commit make my machine can't boot, system hang with black screen very early when I enable CONFIG_FB_UVESA, CONFIG_X86_PAE, CONFIG_ACPI.
below is the maps when boot normal without acpi:
00000000-00001000 rw-s 00000000 00:01 822 /dev/mem 00009000-0000a000 r-xp 00001000 00:01 912 /sbin/v86d 00010000-00050000 rwxp 00000000 00:01 818 /dev/zero 000a0000-000c0000 rw-s 000a0000 00:01 822 /dev/mem 000c0000-00100000 r-xs 000c0000 00:01 822 /dev/mem <== must executable 08048000-0804c000 r-xp 00001000 00:01 912 /sbin/v86d 0804c000-0804d000 rw-p 00004000 00:01 912 /sbin/v86d b7875000-b7876000 r-xp 00000000 00:00 0 [vdso] bfe9d000-bfebe000 rw-p 00000000 00:00 0 [stack]
So I prepare this patch.It works with me.
Any comment is welcome.
Thanks.
--- arch/x86/include/asm/e820.h | 2 ++ arch/x86/mm/pageattr.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletions(-)
arch/x86/include/asm/e820.h +2 -0
@@ -72,6 +72,8 @@ struct e820map {#define BIOS_BEGIN 0x000a0000#define BIOS_END 0x00100000 +#define BIOS_VIDEO 0x000c0000 +#define BIOS_ROM_BASE 0xffe00000#define BIOS_ROM_END 0xffffffff
arch/x86/mm/pageattr.c +2 -1
@@ -260,7 +260,8 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,* PCI BIOS based config access (CONFIG_PCI_GOBIOS) support. */ #ifdef CONFIG_PCI_BIOS -if (pcibios_enabled &&within (pfn,BIOS_BEGIN >>PAGE_SHIFT ,BIOS_END >>PAGE_SHIFT )) +if ((pcibios_enabled ||within (pfn,BIOS_VIDEO >>PAGE_SHIFT ,BIOS_END >>PAGE_SHIFT )) && +within (pfn,BIOS_BEGIN >>PAGE_SHIFT ,BIOS_END >>PAGE_SHIFT ))pgprot_val (forbidden) |= _PAGE_NX;#endif
Signature · 1 line
1.7.3.4
Quoted 59 lines · wangyanqing
5bd5a452662bc37c54fb6828db1a3faf87e6511cmake area betweenBIOS_BEGINandBIOS_ENDhave NX protection when boot machine with acpi enable(acpi will disable pcibios).This commit make my machine can't boot, system hang with black screen very early when I enable
CONFIG_FB_UVESA,CONFIG_X86_PAE,CONFIG_ACPI.below is the maps when boot normal without acpi:
00000000-00001000 rw-s 00000000 00:01 822 /dev/mem 00009000-0000a000 r-xp 00001000 00:01 912 /sbin/v86d 00010000-00050000 rwxp 00000000 00:01 818 /dev/zero 000a0000-000c0000 rw-s 000a0000 00:01 822 /dev/mem 000c0000-00100000 r-xs 000c0000 00:01 822 /dev/mem <== must executable 08048000-0804c000 r-xp 00001000 00:01 912 /sbin/v86d 0804c000-0804d000 rw-p 00004000 00:01 912 /sbin/v86d b7875000-b7876000 r-xp 00000000 00:00 0 [vdso] bfe9d000-bfebe000 rw-p 00000000 00:00 0 [stack]So I prepare this patch.It works with me.
Any comment is welcome.Thanks.
Signed-off-by Wang YanQing <[email protected]>--- arch/x86/include/asm/e820.h | 2 ++ arch/x86/mm/pageattr.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletions(-)arch/x86/include/asm/e820.h +2
-0@@ -72,6 +72,8 @@ struct e820map {#define BIOS_BEGIN 0x000a0000#define BIOS_END 0x00100000 +#define BIOS_VIDEO 0x000c0000 +#define BIOS_ROM_BASE 0xffe00000#define BIOS_ROM_END 0xffffffffarch/x86/mm/pageattr.c +2
-1@@ -260,7 +260,8 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,* PCI BIOS based config access (CONFIG_PCI_GOBIOS) support. */ #ifdef CONFIG_PCI_BIOS -if (pcibios_enabled &&within (pfn,BIOS_BEGIN >>PAGE_SHIFT ,BIOS_END >>PAGE_SHIFT )) +if ((pcibios_enabled ||within (pfn,BIOS_VIDEO >>PAGE_SHIFT ,BIOS_END >>PAGE_SHIFT )) && +within (pfn,BIOS_BEGIN >>PAGE_SHIFT ,BIOS_END >>PAGE_SHIFT ))pgprot_val (forbidden) |= _PAGE_NX;#endif Signature · 1 line
1.7.3.4
This issue also imply another question.
mmap on /dev/mem haven't check whether the target area can mmap with the request privilege. Any comments? Linus
Hi All!
Here is the result of my research, hope it is useful to resolve this question.
Notice:trace from up to down
1:pci_arch_init()
2:pci_mmcfg_early_init() ;boot without PCI_PROBE_NOEARLY
3:__pci_mmcfg_init(1);
4:pci_mmcfg_arch_init(); mmcfg need acpi
5:pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; <== IMPORTANT: clean PCI_PROBE_BIOS away
6:pci_pcbios_init();
7:pci_probe & PCI_PROBE_BIOS ; it will fail
8:pci_find_bios() will no chance to execute
the result is:
1:pcibios_enabled will always 0
2:set_bios_x will no chance to execute, so from BIOS_BEGIN to BIOS_END is NX
lrmi:linux real mode interface project, http://sourceforge.net/projects/lrmi/
v86d use lrmi
lrmi.c:358
if (!map_file((void *)0xc0000, 0x40000,
PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_SHARED, "/dev/mem", 0xc0000)) {
munmap((void *)0, 0x502);
munmap((void *)0xa0000, 0x20000);
real_mem_deinit();
return 0;
}this function to map 000c0000-00100000 with X privilege
00000000-00001000 rw-s 00000000 00:01 822 /dev/mem 00009000-0000a000 r-xp 00001000 00:01 912 /sbin/v86d 00010000-00050000 rwxp 00000000 00:01 818 /dev/zero 000a0000-000c0000 rw-s 000a0000 00:01 822 /dev/mem 000c0000-00100000 r-xs 000c0000 00:01 822 /dev/mem 08048000-0804c000 r-xp 00001000 00:01 912 /sbin/v86d 0804c000-0804d000 rw-p 00004000 00:01 912 /sbin/v86d b779a000-b779b000 r-xp 00000000 00:00 0 [vdso] bfac2000-bfae3000 rw-p 00000000 00:00 0 [stack]
At last we get the reason that my machine hang with black screen The reason is when I boot with ACPI, BIOS_BEGIN to BIOS_END is NX, then v86d try to map 0xc0000 to 0x100000 with executable privilege, it mmap success(mem.c:300, mmap_mem haven't check whether it is illegal), but the pages between BIOS_BEGIN and BIOS_END is NX at all, so it hang!
Question:
1:boot with ACPI make BIOS area NX on X86, is that what we want? 2:mmap_mem haven't check whether it is illegal the mmap target address, right?
Thanks