]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
arm64: KVM: Enable Common Not Private translations
authorVladimir Murzin <vladimir.murzin@arm.com>
Tue, 31 Jul 2018 13:08:57 +0000 (14:08 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Tue, 18 Sep 2018 11:03:34 +0000 (12:03 +0100)
We rely on cpufeature framework to detect and enable CNP so for KVM we
need to patch hyp to set CNP bit just before TTBR0_EL2 gets written.

For the guest we encode CNP bit while building vttbr, so we don't need
to bother with that in a world switch.

Reviewed-by: James Morse <james.morse@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm/include/asm/kvm_arm.h
arch/arm/include/asm/kvm_mmu.h
arch/arm64/include/asm/kvm_arm.h
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/kvm/hyp-init.S
virt/kvm/arm/arm.c

index 3ab8b3781bfeca7264989b813209a99d115d35f2..2d43dca29c722c716c8375e7bf5bff58ba523376 100644 (file)
 #else
 #define VTTBR_X                (5 - KVM_T0SZ)
 #endif
+#define VTTBR_CNP_BIT     _AC(1, UL)
 #define VTTBR_BADDR_MASK  (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_X)
 #define VTTBR_VMID_SHIFT  _AC(48, ULL)
 #define VTTBR_VMID_MASK(size)  (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
index 265ea9cf7df773bf7d49926d3eed34be25032463..847f01fa429dd4a90cf77249bff97266a8c5dd52 100644 (file)
@@ -355,6 +355,11 @@ static inline int hyp_map_aux_data(void)
 
 #define kvm_phys_to_vttbr(addr)                (addr)
 
+static inline bool kvm_cpu_has_cnp(void)
+{
+       return false;
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ARM_KVM_MMU_H__ */
index aa45df752a166a56a3ace4808db6b985ac8d2898..b476bc46f0abe2f2bf61002fcd4aa07e5ce697b4 100644 (file)
 #define VTCR_EL2_FLAGS                 (VTCR_EL2_COMMON_BITS | VTCR_EL2_TGRAN_FLAGS)
 #define VTTBR_X                                (VTTBR_X_TGRAN_MAGIC - VTCR_EL2_T0SZ_IPA)
 
+#define VTTBR_CNP_BIT     (UL(1))
 #define VTTBR_BADDR_MASK  (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_X)
 #define VTTBR_VMID_SHIFT  (UL(48))
 #define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
index d6fff7de5539f22ffa91202c587e13ee48d7d4de..64337afbf124b44b39c429f34af1aabeeeb37720 100644 (file)
@@ -517,5 +517,10 @@ static inline int hyp_map_aux_data(void)
 
 #define kvm_phys_to_vttbr(addr)                phys_to_ttbr(addr)
 
+static inline bool kvm_cpu_has_cnp(void)
+{
+       return system_supports_cnp();
+}
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ARM64_KVM_MMU_H__ */
index ea92251607862db0b33f9ef416ae86e8463b2d03..4576b86a5579ccb227d8533c4b0c4fa5ad22de93 100644 (file)
@@ -65,6 +65,9 @@ __do_hyp_init:
        b.lo    __kvm_handle_stub_hvc
 
        phys_to_ttbr x4, x0
+alternative_if ARM64_HAS_CNP
+       orr     x4, x4, #TTBR_CNP_BIT
+alternative_else_nop_endif
        msr     ttbr0_el2, x4
 
        mrs     x4, tcr_el1
index c92053bc3f96f875db4d2443ce79ab065fa2a00b..150c8a69cdaf8233db1f94df624cca6e2812beaf 100644 (file)
@@ -496,7 +496,7 @@ static bool need_new_vmid_gen(struct kvm *kvm)
 static void update_vttbr(struct kvm *kvm)
 {
        phys_addr_t pgd_phys;
-       u64 vmid;
+       u64 vmid, cnp = kvm_cpu_has_cnp() ? VTTBR_CNP_BIT : 0;
        bool new_gen;
 
        read_lock(&kvm_vmid_lock);
@@ -546,7 +546,7 @@ static void update_vttbr(struct kvm *kvm)
        pgd_phys = virt_to_phys(kvm->arch.pgd);
        BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK);
        vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits);
-       kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid;
+       kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid | cnp;
 
        write_unlock(&kvm_vmid_lock);
 }