From 4edf00a46bee692f62578b5280c5774f9b65a08f Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 6 May 2016 14:36:23 +0100 Subject: MIPS: Retrieve ASID masks using function accepting struct cpuinfo_mips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for supporting variable ASID masks, retrieve ASID masks using functions in asm/cpu-info.h which accept struct cpuinfo_mips. This will allow those functions to determine the ASID mask based upon the CPU in a later patch. This also allows for the r3k & r8k cases to be handled in Kconfig, which is arguably cleaner than the previous #ifdefs. Signed-off-by: Paul Burton Signed-off-by: James Hogan Cc: Paolo Bonzini Cc: Radim Krčmář Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13210/ Signed-off-by: Ralf Baechle --- arch/mips/lib/dump_tlb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/mips/lib/dump_tlb.c') diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 92a37319efbe..3283aa7423e4 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -73,6 +73,8 @@ static void dump_tlb(int first, int last) unsigned long s_entryhi, entryhi, asid; unsigned long long entrylo0, entrylo1, pa; unsigned int s_index, s_pagemask, pagemask, c0, c1, i; + unsigned long asidmask = cpu_asid_mask(¤t_cpu_data); + int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4); #ifdef CONFIG_32BIT bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA); int pwidth = xpa ? 11 : 8; @@ -86,7 +88,7 @@ static void dump_tlb(int first, int last) s_pagemask = read_c0_pagemask(); s_entryhi = read_c0_entryhi(); s_index = read_c0_index(); - asid = s_entryhi & 0xff; + asid = s_entryhi & asidmask; for (i = first; i <= last; i++) { write_c0_index(i); @@ -115,7 +117,7 @@ static void dump_tlb(int first, int last) * due to duplicate TLB entry. */ if (!((entrylo0 | entrylo1) & ENTRYLO_G) && - (entryhi & 0xff) != asid) + (entryhi & asidmask) != asid) continue; /* @@ -126,9 +128,9 @@ static void dump_tlb(int first, int last) c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; - printk("va=%0*lx asid=%02lx\n", + printk("va=%0*lx asid=%0*lx\n", vwidth, (entryhi & ~0x1fffUL), - entryhi & 0xff); + asidwidth, entryhi & asidmask); /* RI/XI are in awkward places, so mask them off separately */ pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI); if (xpa) -- cgit From 382208dc8c856b4d8ba602031412842b121decb2 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 11 May 2016 15:50:31 +0100 Subject: MIPS: dump_tlb: Preserve and dump GuestID The GuestID for root TLB operations (GuestCtl1.RID) is modified by TLB reads, so needs preserving by dump_tlb() like the ASID field of EntryHi. Also dump the GuestID of each entry if it exists alongside the ASID, as it forms an important part of the TLB entry when VZ guests are used. Signed-off-by: James Hogan Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13230/ Signed-off-by: Ralf Baechle --- arch/mips/lib/dump_tlb.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'arch/mips/lib/dump_tlb.c') diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 3283aa7423e4..2cb10dba8838 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -72,7 +72,8 @@ static void dump_tlb(int first, int last) { unsigned long s_entryhi, entryhi, asid; unsigned long long entrylo0, entrylo1, pa; - unsigned int s_index, s_pagemask, pagemask, c0, c1, i; + unsigned int s_index, s_pagemask, s_guestctl1 = 0; + unsigned int pagemask, guestctl1 = 0, c0, c1, i; unsigned long asidmask = cpu_asid_mask(¤t_cpu_data); int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4); #ifdef CONFIG_32BIT @@ -89,6 +90,8 @@ static void dump_tlb(int first, int last) s_entryhi = read_c0_entryhi(); s_index = read_c0_index(); asid = s_entryhi & asidmask; + if (cpu_has_guestid) + s_guestctl1 = read_c0_guestctl1(); for (i = first; i <= last; i++) { write_c0_index(i); @@ -99,6 +102,8 @@ static void dump_tlb(int first, int last) entryhi = read_c0_entryhi(); entrylo0 = read_c0_entrylo0(); entrylo1 = read_c0_entrylo1(); + if (cpu_has_guestid) + guestctl1 = read_c0_guestctl1(); /* EHINV bit marks entire entry as invalid */ if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV) @@ -128,15 +133,19 @@ static void dump_tlb(int first, int last) c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; - printk("va=%0*lx asid=%0*lx\n", + printk("va=%0*lx asid=%0*lx", vwidth, (entryhi & ~0x1fffUL), asidwidth, entryhi & asidmask); + if (cpu_has_guestid) + printk(" gid=%02lx", + (guestctl1 & MIPS_GCTL1_RID) + >> MIPS_GCTL1_RID_SHIFT); /* RI/XI are in awkward places, so mask them off separately */ pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI); if (xpa) pa |= (unsigned long long)readx_c0_entrylo0() << 30; pa = (pa << 6) & PAGE_MASK; - printk("\t["); + printk("\n\t["); if (cpu_has_rixi) printk("ri=%d xi=%d ", (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0, @@ -166,6 +175,8 @@ static void dump_tlb(int first, int last) write_c0_entryhi(s_entryhi); write_c0_index(s_index); write_c0_pagemask(s_pagemask); + if (cpu_has_guestid) + write_c0_guestctl1(s_guestctl1); } void dump_tlb_all(void) -- cgit From 4b62fad50efd1cff9017d3e4dcfcf5c4b6c13193 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 11 May 2016 15:50:32 +0100 Subject: MIPS: Print GuestCtl1 on machine check exception The GuestCtl1 CP0 register can contain the GuestID used for root TLB operations, which affects TLB matching. The other TLB registers are already dumped out to the log on a machine check exception due to multiple matching TLB entries, so also dump the value of the GuestCtl1 register if GuestIDs are supported. Signed-off-by: James Hogan Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13232/ Signed-off-by: Ralf Baechle --- arch/mips/lib/dump_tlb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/lib/dump_tlb.c') diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 2cb10dba8838..0f80b936e75e 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -19,6 +19,8 @@ void dump_tlb_regs(void) pr_info("Index : %0x\n", read_c0_index()); pr_info("PageMask : %0x\n", read_c0_pagemask()); + if (cpu_has_guestid) + pr_info("GuestCtl1: %0x\n", read_c0_guestctl1()); pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi()); pr_info("EntryLo0 : %0*lx\n", field, read_c0_entrylo0()); pr_info("EntryLo1 : %0*lx\n", field, read_c0_entrylo1()); -- cgit