i386 Segment protect properly
PATCH 8/21 i386 Segment protect properly
It is impossible to have a zero length segment in descriptor tables using "normal" segments. One of many ways to properly protect segments to zero length is to map the base to an umapped page. Create a nicer way to do this, and stop subtracting 1 from the length passed to set_limit (note calling set limit with a zero limit does something very bad! - not anymore).
Signed-off-by Zachary Amsden <[email protected]>
include/asm-i386/desc.h +9 -0
@@ -158,6 +158,15 @@ static inline unsigned long get_desc_basreturn base; } +static inline void prepare_protected_segment (int cpu,int gdt_entry,void *base,u32 size) +{ +struct desc_struct *gdt =get_cpu_gdt_table (cpu); + +/* Forced zero-length segments to 1-byte access at unmapped page zero */ +set_base (gdt[gdt_entry], size >0 ? (u32 )base :0 ); +set_limit (gdt[gdt_entry], size >0 ? size -1 :0 ); +} +struct bios_segment_save {struct desc_struct save_desc_40;struct desc_struct *gdt;
include/asm-i386/system.h +1 -1
@@ -54,7 +54,7 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" ); } while(0)#define set_base (ldt,base) _set_base( ((char *)&(ldt)) , (base) ) -#define set_limit (ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1) ) +#define set_limit (ldt,limit) _set_limit( ((char *)&(ldt)) , (limit) )static inline unsigned long _get_base (char * addr) {
drivers/pnp/pnpbios/bioscalls.c +2 -4
@@ -103,10 +103,8 @@ static inline u16 call_pnp_bios(u16 funcspin_lock_irqsave (&pnp_bios_lock, flags);/* The lock prevents us bouncing CPU here */ -if (ts1_size) -Q2_SET_SEL (smp_processor_id (),PNP_TS1 , ts1_base, ts1_size); -if (ts2_size) -Q2_SET_SEL (smp_processor_id (),PNP_TS2 , ts2_base, ts2_size); +prepare_protected_segment (smp_processor_id (),GDT_ENTRY_PNPBIOS_TS1 , ts1_base, ts1_size); +prepare_protected_segment (smp_processor_id (),GDT_ENTRY_PNPBIOS_TS2 , ts2_base, ts2_size); __asm__ __volatile__( "pushl %%ebp\n\t"