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

Avi Kivity
2009-04-05T08:41:08Z

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.

--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.