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.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html