Balbir Singh <bsinghar...@gmail.com> writes: > On 09/04/16 16:13, Aneesh Kumar K.V wrote: >> PowerISA 3.0 adds a parition table indexed by LPID. Parition table allow >> us to specify the MMU model that will be used for guest and host >> translation. >> >> This patch add support with SLB based hash model (UPRT = 0). What is >> required with this model is to support the new hash page table entry >> format and also setup Partition table such we use hash table for >> address translation. >> >> We don't have segment table support yet. >> >> Inorder to make sure we don't load KVM module on Power9 (since we >> don't have kvm support yet) this patch also disable kvm on Power9 >> >> Signed-off-by: Aneesh Kumar K.V <aneesh.ku...@linux.vnet.ibm.com> >> --- >> arch/powerpc/include/asm/book3s/64/mmu-hash.h | 13 +++++++-- >> arch/powerpc/kvm/book3s_hv.c | 6 ++++ >> arch/powerpc/kvm/book3s_pr.c | 6 +++- >> arch/powerpc/mm/hash_native_64.c | 11 ++++++- >> arch/powerpc/mm/hash_utils_64.c | 42 >> +++++++++++++++++++++++++-- >> arch/powerpc/mm/pgtable_64.c | 7 +++++ >> arch/powerpc/platforms/ps3/htab.c | 2 +- >> arch/powerpc/platforms/pseries/lpar.c | 2 +- >> 8 files changed, 81 insertions(+), 8 deletions(-) >> >> diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h >> b/arch/powerpc/include/asm/book3s/64/mmu-hash.h >> index ce73736b42db..843b5d839904 100644 >> --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h >> +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h >> @@ -78,6 +78,10 @@ >> #define HPTE_V_SECONDARY ASM_CONST(0x0000000000000002) >> #define HPTE_V_VALID ASM_CONST(0x0000000000000001) >> >> +/* >> + * ISA 3.0 have a different HPTE format. >> + */ >> +#define HPTE_R_3_0_SSIZE_SHIFT 58 >> #define HPTE_R_PP0 ASM_CONST(0x8000000000000000) >> #define HPTE_R_TS ASM_CONST(0x4000000000000000) >> #define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000) >> @@ -224,7 +228,8 @@ static inline unsigned long hpte_encode_avpn(unsigned >> long vpn, int psize, >> */ >> v = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm); >> v <<= HPTE_V_AVPN_SHIFT; >> - v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT; >> + if (!cpu_has_feature(CPU_FTR_ARCH_300)) >> + v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT; >> return v; >> } >> >> @@ -248,8 +253,12 @@ static inline unsigned long hpte_encode_v(unsigned long >> vpn, int base_psize, >> * aligned for the requested page size >> */ >> static inline unsigned long hpte_encode_r(unsigned long pa, int base_psize, >> - int actual_psize) >> + int actual_psize, int ssize) >> { >> + >> + if (cpu_has_feature(CPU_FTR_ARCH_300)) >> + pa |= ((unsigned long) ssize) << HPTE_R_3_0_SSIZE_SHIFT; >> + > > Looks good, I was wondering if we can compute > cpu_has_feature(CPU_FTR_ARCH_300) once for the instance > and use it, but I am just nit-picking. I've never tried using > ASM_MMU_FTR_IF(), I don't know > if you've explored it. Not very important for this patchset though
There were multiple efforts w.r.t. to this. I tried to fix only radix_enabled() using code patching. But we also had Kevin doing http://mid.gmane.org/1440072876-8321-1-git-send-email-haoke...@gmail.com > >> /* A 4K page needs no special encoding */ >> if (actual_psize == MMU_PAGE_4K) >> return pa & HPTE_R_RPN; >> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c >> index baeddb06811d..c07600efcef6 100644 >> --- a/arch/powerpc/kvm/book3s_hv.c >> +++ b/arch/powerpc/kvm/book3s_hv.c >> @@ -3083,6 +3083,12 @@ static int kvmppc_core_check_processor_compat_hv(void) >> if (!cpu_has_feature(CPU_FTR_HVMODE) || >> !cpu_has_feature(CPU_FTR_ARCH_206)) >> return -EIO; >> + /* >> + * Disable KVM for Power9, untill the required bits merged. >> + */ >> + if (cpu_has_feature(CPU_FTR_ARCH_300)) >> + return -EIO; >> + >> return 0; >> } >> >> diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c >> index 95bceca8f40e..ffbaf40b7f31 100644 >> --- a/arch/powerpc/kvm/book3s_pr.c >> +++ b/arch/powerpc/kvm/book3s_pr.c >> @@ -1683,7 +1683,11 @@ static void kvmppc_core_destroy_vm_pr(struct kvm *kvm) >> >> static int kvmppc_core_check_processor_compat_pr(void) >> { >> - /* we are always compatible */ >> + /* >> + * Disable KVM for Power9 untill the required bits merged. >> + */ >> + if (cpu_has_feature(CPU_FTR_ARCH_300)) >> + return -EIO; >> return 0; >> } >> >> diff --git a/arch/powerpc/mm/hash_native_64.c >> b/arch/powerpc/mm/hash_native_64.c >> index 8eaac81347fd..d873f6507f72 100644 >> --- a/arch/powerpc/mm/hash_native_64.c >> +++ b/arch/powerpc/mm/hash_native_64.c >> @@ -221,7 +221,7 @@ static long native_hpte_insert(unsigned long hpte_group, >> unsigned long vpn, >> return -1; >> >> hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | >> HPTE_V_VALID; >> - hpte_r = hpte_encode_r(pa, psize, apsize) | rflags; >> + hpte_r = hpte_encode_r(pa, psize, apsize, ssize) | rflags; >> >> if (!(vflags & HPTE_V_BOLTED)) { >> DBG_LOW(" i=%x hpte_v=%016lx, hpte_r=%016lx\n", >> @@ -719,6 +719,12 @@ static void native_flush_hash_range(unsigned long >> number, int local) >> local_irq_restore(flags); >> } >> >> +static int native_update_partition_table(u64 patb1) >> +{ >> + partition_tb->patb1 = cpu_to_be64(patb1); > > Do we need to tell the hardware that patb1 was updated? > you mean do we need sync instructions around ? I checked ISA and don't find anthing specific. >> + return 0; >> +} >> + >> void __init hpte_init_native(void) >> { >> ppc_md.hpte_invalidate = native_hpte_invalidate; >> @@ -729,4 +735,7 @@ void __init hpte_init_native(void) >> ppc_md.hpte_clear_all = native_hpte_clear; >> ppc_md.flush_hash_range = native_flush_hash_range; >> ppc_md.hugepage_invalidate = native_hugepage_invalidate; >> + >> + if (cpu_has_feature(CPU_FTR_ARCH_300)) >> + ppc_md.update_partition_table = native_update_partition_table; >> } >> diff --git a/arch/powerpc/mm/hash_utils_64.c >> b/arch/powerpc/mm/hash_utils_64.c >> index e924690a5a0e..43e0d86b7ca1 100644 >> --- a/arch/powerpc/mm/hash_utils_64.c >> +++ b/arch/powerpc/mm/hash_utils_64.c >> @@ -674,6 +674,41 @@ int remove_section_mapping(unsigned long start, >> unsigned long end) >> } >> #endif /* CONFIG_MEMORY_HOTPLUG */ >> >> +static void __init hash_init_partition_table(phys_addr_t hash_table, >> + unsigned long pteg_count) >> +{ >> + unsigned long ps_field; >> + unsigned long htab_size; >> + unsigned long patb_size = 1UL << PATB_SIZE_SHIFT; >> + >> + /* >> + * slb llp encoding for the page size used in VPM real mode. >> + * We can ignore that for lpid 0 >> + */ >> + ps_field = 0; >> + htab_size = __ilog2(pteg_count) - 11; >> + >> + BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 24), "Partition table size too >> large."); >> + partition_tb = __va(memblock_alloc_base(patb_size, patb_size, >> + MEMBLOCK_ALLOC_ANYWHERE)); >> + >> + /* Initialize the Partition Table with no entries */ >> + memset((void *)partition_tb, 0, patb_size); >> + partition_tb->patb0 = cpu_to_be64(ps_field | hash_table | htab_size); >> + /* >> + * FIXME!! This should be done via update_partition table >> + * For now UPRT is 0 for us. >> + */ >> + partition_tb->patb1 = 0; > > So the design is that we allocate upto 2^24/16 entries for the partition table > and set the first entry LPID0 to use HPT with ps_field set to 0 and patb1 > to be updated by the callback we provide via native_update_partition_table? For hash with SLB we will always find patb1 to be 0. Once we get segment table, we will have a if(MMU_FTR_SEG_TABLE) here to do this correctly. > >> + DBG("Partition table %p\n", partition_tb); >> + /* >> + * update partition table control register, >> + * 64 K size. >> + */ >> + mtspr(SPRN_PTCR, __pa(partition_tb) | (PATB_SIZE_SHIFT - 12)); >> + >> +} >> + >> static void __init htab_initialize(void) >> { >> unsigned long table; >> @@ -742,8 +777,11 @@ static void __init htab_initialize(void) >> /* Initialize the HPT with no entries */ >> memset((void *)table, 0, htab_size_bytes); >> >> - /* Set SDR1 */ >> - mtspr(SPRN_SDR1, _SDR1); >> + if (!cpu_has_feature(CPU_FTR_ARCH_300)) >> + /* Set SDR1 */ >> + mtspr(SPRN_SDR1, _SDR1); >> + else >> + hash_init_partition_table(table, pteg_count); >> } >> >> prot = pgprot_val(PAGE_KERNEL); >> diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c >> index 98c91ad18ba7..5fff787da17a 100644 >> --- a/arch/powerpc/mm/pgtable_64.c >> +++ b/arch/powerpc/mm/pgtable_64.c >> @@ -69,6 +69,13 @@ >> #endif >> #endif > > <snip> > > Otherwise looks good! > > Balbir Singh Thanks -aneesh _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev