summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>2018-12-21 04:28:41 +0100
committerPaul Mackerras <paulus@ozlabs.org>2018-12-21 04:37:43 +0100
commit8b23eee4e55a32a2b51a180dfd27a8d214acc7a1 (patch)
tree1813e44c5a9992a65f9fbda6a7aa053ff7e0ea91
parentKVM: PPC: Book3S HV: Align gfn to L1 page size when inserting nest-rmap entry (diff)
downloadlinux-8b23eee4e55a32a2b51a180dfd27a8d214acc7a1.tar.xz
linux-8b23eee4e55a32a2b51a180dfd27a8d214acc7a1.zip
KVM: PPC: Book3S HV: Apply combination of host and l1 pte rc for nested guest
The shadow page table contains ptes for translations from nested guest address to host address. Currently when creating these ptes we take the rc bits from the pte for the L1 guest address to host address translation. This is incorrect as we must also factor in the rc bits from the pte for the nested guest address to L1 guest address translation (as contained in the L1 guest partition table for the nested guest). By not calculating these bits correctly L1 may not have been correctly notified when it needed to update its rc bits in the partition table it maintains for its nested guest. Modify the code so that the rc bits in the resultant pte for the L2->L0 translation are the 'and' of the rc bits in the L2->L1 pte and the L1->L0 pte, also accounting for whether this was a write access when setting the dirty bit. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
-rw-r--r--arch/powerpc/kvm/book3s_hv_nested.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index 6a25a2e19018..0bd676ac38fe 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -1337,6 +1337,9 @@ static long int __kvmhv_nested_page_fault(struct kvm_run *run,
perm |= gpte.may_read ? 0UL : _PAGE_READ;
perm |= gpte.may_write ? 0UL : _PAGE_WRITE;
perm |= gpte.may_execute ? 0UL : _PAGE_EXEC;
+ /* Only set accessed/dirty (rc) bits if set in host and l1 guest ptes */
+ perm |= (gpte.rc & _PAGE_ACCESSED) ? 0UL : _PAGE_ACCESSED;
+ perm |= ((gpte.rc & _PAGE_DIRTY) && writing) ? 0UL : _PAGE_DIRTY;
pte = __pte(pte_val(pte) & ~perm);
/* What size pte can we insert? */