Updated WP bit & 4MB pages patch

Martin Mares (mj@mj.gts.cz)
Thu, 31 Jul 1997 10:09:53 +0200


Hi,

The previous patch was a little buggy (I must have been sleeping whan I was
writing it), sending a new one... Please test if you have a machine where the
previous WP detection did crash or a PPro.

Have a nice fortnight

-- 
Martin `MJ' Mares   <mj@gts.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
"Diplomacy is an art of saying "nice doggy" until you can find a rock."

--- init.c.mj Wed Jul 30 12:24:13 1997 +++ init.c Thu Jul 31 10:07:02 1997 @@ -230,7 +230,7 @@ set_in_cr4(X86_CR4_PGE); __pe += _PAGE_GLOBAL; } - pgd_val(pg_dir[768]) = _PAGE_TABLE + _PAGE_4M + __pa(address); + pgd_val(pg_dir[768]) = __pe; pg_dir++; address += 4*1024*1024; continue; @@ -261,6 +261,43 @@ return free_area_init(start_mem, end_mem); } +/* + * Test if the WP bit works in supervisor mode. It isn't supported on 386's + * and also on some strange 486's (NexGen etc.). All 586+'s are OK. The jumps + * before and after the test are here to work-around some nasty CPU bugs. + */ + +__initfunc(void test_wp_bit(void)) +{ + unsigned char tmp_reg; + unsigned long old = pg0[0]; + + printk("Checking if this processor honours the WP bit even in supervisor mode... "); + pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_READONLY)); + local_flush_tlb(); + current->mm->mmap->vm_start += PAGE_SIZE; + __asm__ __volatile__( + "jmp 1f; 1:\n" + "movb %0,%1\n" + "movb %1,%0\n" + "jmp 1f; 1:\n" + :"=m" (*(char *) __va(0)), + "=q" (tmp_reg) + :/* no inputs */ + :"memory"); + pg0[0] = old; + local_flush_tlb(); + current->mm->mmap->vm_start -= PAGE_SIZE; + if (wp_works_ok < 0) { + wp_works_ok = 0; + printk("No.\n"); +#ifndef CONFIG_M386 + panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386"); +#endif + } else + printk("Ok.\n"); +} + __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) { unsigned long start_low_mem = PAGE_SIZE; @@ -339,30 +376,9 @@ reservedpages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10)); -/* test if the WP bit is honoured in supervisor mode */ - if (wp_works_ok < 0) { - unsigned char tmp_reg; - unsigned long old = pg0[0]; - printk("Checking if this processor honours the WP bit even in supervisor mode... "); - pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_READONLY)); - local_flush_tlb(); - current->mm->mmap->vm_start += PAGE_SIZE; - __asm__ __volatile__( - "movb %0,%1 ; movb %1,%0" - :"=m" (*(char *) __va(0)), - "=q" (tmp_reg) - :/* no inputs */ - :"memory"); - pg0[0] = old; - local_flush_tlb(); - current->mm->mmap->vm_start -= PAGE_SIZE; - if (wp_works_ok < 0) { - wp_works_ok = 0; - printk("No.\n"); - } else - printk("Ok.\n"); - } - return; + + if (wp_works_ok < 0) + test_wp_bit(); } void free_initmem(void)