diff options
author | Avi Kivity <avi@qumranet.com> | 2008-05-15 06:51:35 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-20 05:40:50 -0400 |
commit | 1b7fcd3263e5f12dba43d27b64e1578bec070c28 (patch) | |
tree | 7f8d9679404f0b46803c6b1cf926235d170606ee /arch/x86/kvm/mmu.h | |
parent | 7682f2d0dd3ff5bd2756eac018a5b4e7e30ef16c (diff) |
KVM: MMU: Fix false flooding when a pte points to page table
The KVM MMU tries to detect when a speculative pte update is not actually
used by demand fault, by checking the accessed bit of the shadow pte. If
the shadow pte has not been accessed, we deem that page table flooded and
remove the shadow page table, allowing further pte updates to proceed
without emulation.
However, if the pte itself points at a page table and only used for write
operations, the accessed bit will never be set since all access will happen
through the emulator.
This is exactly what happens with kscand on old (2.4.x) HIGHMEM kernels.
The kernel points a kmap_atomic() pte at a page table, and then
proceeds with read-modify-write operations to look at the dirty and accessed
bits. We get a false flood trigger on the kmap ptes, which results in the
mmu spending all its time setting up and tearing down shadows.
Fix by setting the shadow accessed bit on emulated accesses.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/mmu.h')
-rw-r--r-- | arch/x86/kvm/mmu.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 1730757bbc7a..258e5d56298e 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h | |||
@@ -15,7 +15,8 @@ | |||
15 | #define PT_USER_MASK (1ULL << 2) | 15 | #define PT_USER_MASK (1ULL << 2) |
16 | #define PT_PWT_MASK (1ULL << 3) | 16 | #define PT_PWT_MASK (1ULL << 3) |
17 | #define PT_PCD_MASK (1ULL << 4) | 17 | #define PT_PCD_MASK (1ULL << 4) |
18 | #define PT_ACCESSED_MASK (1ULL << 5) | 18 | #define PT_ACCESSED_SHIFT 5 |
19 | #define PT_ACCESSED_MASK (1ULL << PT_ACCESSED_SHIFT) | ||
19 | #define PT_DIRTY_MASK (1ULL << 6) | 20 | #define PT_DIRTY_MASK (1ULL << 6) |
20 | #define PT_PAGE_SIZE_MASK (1ULL << 7) | 21 | #define PT_PAGE_SIZE_MASK (1ULL << 7) |
21 | #define PT_PAT_MASK (1ULL << 7) | 22 | #define PT_PAT_MASK (1ULL << 7) |