Re: cr3 OOS optimisation breaks 32-bit GNU/kFreeBSD guest

Marcelo Tosatti
2009-04-05T11:30:02Z

On Sun, Apr 05, 2009 at 11:41:39AM +0300, Avi Kivity wrote:
> Marcelo Tosatti wrote:
>> The problem is when the page is unreachable due to a higher level path
>> being unlinked. Say:
>>
>> level 4 -> level 3 . level 2 -> level 1 (global unsync)
>>
>> The dot there means level 3 is not linked to level 2, so invlpg can't
>> reach the global unsync at level 1.
>>
>> kvm_mmu_get_page does sync pages when it finds them, so the code is
>> already safe for the "linking a page which contains global ptes" case
>> you mention above.
>>
>
> The recursive resync ignores global pages (or it would hit them on cr3
> switch too).
>
> But we have a bigger problem, invlpg can miss even if nothing is unlinked:
>
> access address x through global pte
> -> pte instantiated into spte
> switch to cr3 where x is not mapped, or mapped differently
> write to pte
> -> no fault since pte is unsync
> invlpg x
> -> no way this can hit the spte
> switch cr3 back
> access address x
> -> use old spte
>
> Here's one way to make this work:
>
> - add a hash of global pagetables, indexed by virtual address instead
> of the pagetable's gfn
> - invlpg checks this hash in addition to the recursive walk
>
> We'd need to make the virtual address part of sp->role to avoid needing
> to link the same page multiple times in the virtual address hash.

Humpf, yes. It seems its too expensive/complex to handle this, for such
small gain (~= 2% on AIM7 with RHEL3 guest).

Are you okay with just disabling the global pages optimization?