summaryrefslogtreecommitdiffstats
path: root/arch/mips/kvm/entry.c
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-10-07 23:58:53 +0100
committerJames Hogan <james.hogan@imgtec.com>2017-02-03 15:20:51 +0000
commit7faa6eec6991715d6c1d85c192738dcac405ab89 (patch)
treeff60812dff7d786f1d74d03bdfdc681a3aeb3a09 /arch/mips/kvm/entry.c
parentf7f1427dc0c67e21ba9ec2200b7c8853535b3842 (diff)
downloadlinux-7faa6eec6991715d6c1d85c192738dcac405ab89.tar.bz2
KVM: MIPS/T&E: Activate GVA page tables in guest context
Activate the GVA page tables when in guest context. This will allow the normal Linux TLB refill handler to fill from it when guest memory is read, as well as preventing accidental reading from user memory. Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Radim Krčmář" <rkrcmar@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org
Diffstat (limited to 'arch/mips/kvm/entry.c')
-rw-r--r--arch/mips/kvm/entry.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/arch/mips/kvm/entry.c b/arch/mips/kvm/entry.c
index f81888704caa..f683d123172c 100644
--- a/arch/mips/kvm/entry.c
+++ b/arch/mips/kvm/entry.c
@@ -13,6 +13,7 @@
#include <linux/kvm_host.h>
#include <linux/log2.h>
+#include <asm/mmu_context.h>
#include <asm/msa.h>
#include <asm/setup.h>
#include <asm/uasm.h>
@@ -316,7 +317,20 @@ static void *kvm_mips_build_enter_guest(void *addr)
#else
uasm_i_andi(&p, K0, K0, MIPS_ENTRYHI_ASID);
#endif
- uasm_i_mtc0(&p, K0, C0_ENTRYHI);
+
+ /*
+ * Set up KVM T&E GVA pgd.
+ * This does roughly the same as TLBMISS_HANDLER_SETUP_PGD():
+ * - call tlbmiss_handler_setup_pgd(mm->pgd)
+ * - but skips write into CP0_PWBase for now
+ */
+ UASM_i_LW(&p, A0, (int)offsetof(struct mm_struct, pgd) -
+ (int)offsetof(struct mm_struct, context.asid), T1);
+
+ UASM_i_LA(&p, T9, (unsigned long)tlbmiss_handler_setup_pgd);
+ uasm_i_jalr(&p, RA, T9);
+ uasm_i_mtc0(&p, K0, C0_ENTRYHI);
+
uasm_i_ehb(&p);
/* Disable RDHWR access */