
From: Zenghui Yu <yuzenghui@huawei.com> euleros inclusion category: feature feature: Hisi non-cacheable snoopy support ------------------------------------------------- Kunpeng 920 offers the HHA ncsnp capability, with which hypervisor doesn't need to perform a lot of cache maintenance like before (in case the guest has some non-cacheable Stage-1 mappings). Currently we apply this hardware capability when - VCPU switching MMU+caches on/off - creating Stage-2 mappings for Daborts Reviewed-by: zhanghailiang <zhang.zhanghailiang@huawei.com> Signed-off-by: Zenghui Yu <yuzenghui@huawei.com> Reviewed-by: Hailiang Zhang <zhang.zhanghailiang@huawei.com> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> --- arch/arm/include/asm/hisi_cpu_model.h | 2 ++ arch/arm64/include/asm/hisi_cpu_model.h | 2 ++ virt/kvm/arm/arm.c | 2 ++ virt/kvm/arm/hisi_cpu_model.c | 34 +++++++++++++++++++++++++++++++++ virt/kvm/arm/mmu.c | 4 ++-- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/hisi_cpu_model.h b/arch/arm/include/asm/hisi_cpu_model.h index 16aea01..54cc3c2 100644 --- a/arch/arm/include/asm/hisi_cpu_model.h +++ b/arch/arm/include/asm/hisi_cpu_model.h @@ -11,6 +11,8 @@ enum hisi_cpu_type { }; extern enum hisi_cpu_type hi_cpu_type; +extern bool kvm_ncsnp_support; void probe_hisi_cpu_type(void); +void probe_hisi_ncsnp_support(void); #endif /* __HISI_CPU_MODEL_H__ */ diff --git a/arch/arm64/include/asm/hisi_cpu_model.h b/arch/arm64/include/asm/hisi_cpu_model.h index f686a75..e0da0ef 100644 --- a/arch/arm64/include/asm/hisi_cpu_model.h +++ b/arch/arm64/include/asm/hisi_cpu_model.h @@ -14,6 +14,8 @@ enum hisi_cpu_type { }; extern enum hisi_cpu_type hi_cpu_type; +extern bool kvm_ncsnp_support; void probe_hisi_cpu_type(void); +void probe_hisi_ncsnp_support(void); #endif /* __HISI_CPU_MODEL_H__ */ diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 264aba2..cc21446 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -72,6 +72,7 @@ /* Hisi cpu type enum */ enum hisi_cpu_type hi_cpu_type = UNKNOWN_HI_TYPE; +bool kvm_ncsnp_support; static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); @@ -1677,6 +1678,7 @@ int kvm_arch_init(void *opaque) /* Probe the Hisi CPU type */ probe_hisi_cpu_type(); + probe_hisi_ncsnp_support(); if (!is_hyp_mode_available()) { kvm_info("HYP mode not available\n"); diff --git a/virt/kvm/arm/hisi_cpu_model.c b/virt/kvm/arm/hisi_cpu_model.c index fb06e0b..b0f7e0d 100644 --- a/virt/kvm/arm/hisi_cpu_model.c +++ b/virt/kvm/arm/hisi_cpu_model.c @@ -80,3 +80,37 @@ void probe_hisi_cpu_type(void) WARN_ON(hi_cpu_type == UNKNOWN_HI_TYPE); } + +#define NCSNP_MMIO_BASE 0x20107E238 + +/* + * We have the fantastic HHA ncsnp capability on Kunpeng 920, + * with which hypervisor doesn't need to perform a lot of cache + * maintenance like before (in case the guest has non-cacheable + * Stage-1 mappings). + */ +void probe_hisi_ncsnp_support(void) +{ + void __iomem *base; + unsigned int high; + + kvm_ncsnp_support = false; + + if (hi_cpu_type != HI_1620) + goto out; + + base = ioremap(NCSNP_MMIO_BASE, 4); + if (!base) { + pr_err("Unable to map MMIO region when probing ncsnp!\n"); + goto out; + } + + high = readl_relaxed(base) >> 28; + iounmap(base); + if (high != 0x1) + kvm_ncsnp_support = true; + +out: + kvm_info("Hisi ncsnp: %s\n", kvm_ncsnp_support ? "enabled" : + "disabled"); +} diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index f74d1a7..3a280b3 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c @@ -1806,7 +1806,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (writable) kvm_set_pfn_dirty(pfn); - if (fault_status != FSC_PERM) + if (fault_status != FSC_PERM && !kvm_ncsnp_support) clean_dcache_guest_page(pfn, vma_pagesize); if (exec_fault) @@ -2465,7 +2465,7 @@ void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled) * If switching it off, need to clean the caches. * Clean + invalidate does the trick always. */ - if (now_enabled != was_enabled) + if (now_enabled != was_enabled && !kvm_ncsnp_support) stage2_flush_vm(vcpu->kvm); /* Caches are now on, stop trapping VM ops (until a S/W op) */ -- 1.8.3