[Lguest] [PATCH] lguest: PAE support

Matias Zabaljauregui zabaljauregui at gmail.com
Fri Jun 12 09:20:56 EST 2009


On Thu, 2009-06-11 at 17:10 +0930, Rusty Russell wrote:
> Debugged why guest was crashing immediately with unhandled page fault, also
> fixed a potential future problem.  Please review.
> 
> lguest: PAE fixes
> 
> 1) j wasn't initialized in setup_pagetables, so they weren't set up for me
>    causing immediate guest crashes.
Oops,  don't understand how it worked on my test boxes all these days.

> 
> 2) gpte_addr should not re-read the pmd from the Guest.  Especially
>    not BUG_ON() based on the value.  If we ever supported SMP guests,
>    they could trigger that.  And the Launcher could also trigger it
>    (tho currently root-only).
> 
thanks for fixing this as well.


Matias


> Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
> 
> diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
> --- a/drivers/lguest/page_tables.c
> +++ b/drivers/lguest/page_tables.c
> @@ -154,26 +154,25 @@ static unsigned long gpmd_addr(pgd_t gpg
>  	BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
>  	return gpage + pmd_index(vaddr) * sizeof(pmd_t);
>  }
> -#endif
>  
>  static unsigned long gpte_addr(struct lg_cpu *cpu,
> +			       pmd_t gpmd, unsigned long vaddr)
> +{
> +	unsigned long gpage = pmd_pfn(gpmd) << PAGE_SHIFT;
> +
> +	BUG_ON(!(pmd_flags(gpmd) & _PAGE_PRESENT));
> +	return gpage + pte_index(vaddr) * sizeof(pte_t);
> +}
> +#else
> +static unsigned long gpte_addr(struct lg_cpu *cpu,
>  				pgd_t gpgd, unsigned long vaddr)
>  {
> -#ifdef CONFIG_X86_PAE
> -	pmd_t gpmd;
> -#endif
> -	unsigned long gpage;
> +	unsigned long gpage = pgd_pfn(gpgd) << PAGE_SHIFT;
>  
>  	BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
> -#ifdef CONFIG_X86_PAE
> -	gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t);
> -	gpage = pmd_pfn(gpmd) << PAGE_SHIFT;
> -	BUG_ON(!(pmd_flags(gpmd) & _PAGE_PRESENT));
> -#else
> -	gpage = pgd_pfn(gpgd) << PAGE_SHIFT;
> -#endif
>  	return gpage + pte_index(vaddr) * sizeof(pte_t);
>  }
> +#endif
>  /*:*/
>  
>  /*M:014 get_pfn is slow: we could probably try to grab batches of pages here as
> @@ -339,10 +338,15 @@ bool demand_page(struct lg_cpu *cpu, uns
>  		 * number in the shadow PMD is the page we just allocated. */
>  		native_set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd)));
>  	}
> -#endif
> +
> +	/* OK, now we look at the lower level in the Guest page table: keep its
> +	 * address, because we might update it later. */
> +	gpte_ptr = gpte_addr(cpu, gpmd, vaddr);
> +#else
>  	/* OK, now we look at the lower level in the Guest page table: keep its
>  	 * address, because we might update it later. */
>  	gpte_ptr = gpte_addr(cpu, gpgd, vaddr);
> +#endif
>  	gpte = lgread(cpu, gpte_ptr, pte_t);
>  
>  	/* If this page isn't in the Guest page tables, we can't page it in. */
> @@ -522,7 +526,6 @@ unsigned long guest_pa(struct lg_cpu *cp
>  {
>  	pgd_t gpgd;
>  	pte_t gpte;
> -
>  #ifdef CONFIG_X86_PAE
>  	pmd_t gpmd;
>  #endif
> @@ -534,13 +537,14 @@ unsigned long guest_pa(struct lg_cpu *cp
>  		return -1UL;
>  	}
>  
> -	gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t);
>  #ifdef CONFIG_X86_PAE
>  	gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t);
>  	if (!(pmd_flags(gpmd) & _PAGE_PRESENT))
>  		kill_guest(cpu, "Bad address %#lx", vaddr);
> +	gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t);
> +#else
> +	gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t);
>  #endif
> -	gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t);
>  	if (!(pte_flags(gpte) & _PAGE_PRESENT))
>  		kill_guest(cpu, "Bad address %#lx", vaddr);
>  
> @@ -847,7 +851,7 @@ static unsigned long setup_pagetables(st
>  	/* The top level points to the linear page table pages above.
>  	 * We setup the identity and linear mappings here. */
>  #ifdef CONFIG_X86_PAE
> -	for (i = 0, j; i < mapped_pages && j < PTRS_PER_PMD;
> +	for (i = j = 0; i < mapped_pages && j < PTRS_PER_PMD;
>  	     i += PTRS_PER_PTE, j++) {
>  		native_set_pmd(&pmd, __pmd(((unsigned long)(linear + i)
>  		- mem_base) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER));
> 




More information about the Lguest mailing list