Re: Handle kernel page faults using task gate

From: Chuck Ebbert
Date: Thu Jun 30 2005 - 12:04:01 EST


On Wed, 29 Jun 2005 at 18:43:47 +0300, eliad lubovsky wrote:

> my page fault handler:
> static void pagefault_fn(void)
> {
> unsigned int address, aligned_page_fault_address;
> struct vm_struct *area;
>
> /* retrieve the page fault address */
> __asm__("movl %%cr2,%0":"=r" (address));
>
> aligned_page_fault_address = ((address+PAGE_SIZE)&(~(4096-1)));
>
> area = find_vm_area((void*)(aligned_page_fault_address));
>
> /* allocate a new physical page, expand the stack size */
> expend_stack_size(area);
>
> // asm ("pushf; orl $0x00004000, (%esp); popf; iret"); /* sets NT */
> // asm ("pushf; andl $0xffffbfff, (%esp); popf; iret"); /* clears NT */
> asm ("iret");
> }


That will work exactly once. :(

On the next fault, control wil be transferred to the instruction after
the iret. It needs to be like this:

======================

static void pagefault_fn(void) {
unsigned int address, aligned_page_fault_address;
struct vm_struct *area;

/* put one-time initialization code here */

goto handle_fault;

return_from_fault:
asm("iret");

handle_fault:
aligned_page_fault_address = ((address+PAGE_SIZE)&(~(4096-1)));
area = find_vm_area((void*)(aligned_page_fault_address));

/* allocate a new physical page, expand the stack size */
expend_stack_size(area);

goto return_from_fault;
}

======================

(You also need a private stack to hold the local vars for each TSS.)

--
Chuck
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/