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) */