From: James Hogan <james.hogan@imgtec.com> To: Ralf Baechle <ralf@linux-mips.org> Cc: James Hogan <james.hogan@imgtec.com>, Matt Redfearn <matt.redfearn@imgtec.com>, Leonid Yegoshin <leonid.yegoshin@imgtec.com>, <linux-mips@linux-mips.org> Subject: [PATCH 3/9] MIPS: traps: Ensure full EBase is written Date: Thu, 1 Sep 2016 17:30:09 +0100 [thread overview] Message-ID: <c4de81b497c4a02a2bec5abc5234b7d84b75c5ec.1472747205.git-series.james.hogan@imgtec.com> (raw) In-Reply-To: <cover.d93e43428f3c573bdd18d7c874830705b39c3a8a.1472747205.git-series.james.hogan@imgtec.com> From: Matt Redfearn <matt.redfearn@imgtec.com> On CPUs which support the EBase WG (write gate) flag, the most significant bits of the exception base can be changed. Firmware running on a VP(E) using MIPS rproc may change EBase to point into the user segment where the firmware is located such that it can service interrupts. When control is transferred back to the kernel the EBase must be switched back into the kernel segment, such that the kernel's exception vectors are used. Similarly when vectored interrupts (vint) or vectored external interrupt controllers (veic) are enabled an exception vector is allocated from bootmem, and written to the EBase register. Due to the WG flag being clear, only bits 29:12 will be written. Asside from the rproc case above this is normally fine (as it will usually be a low allocation within the KSeg0 range, however when Enhanced Virtual Addressing (EVA) is enabled the allocation may be outside of the traditional KSeg0/KSeg1 address range, resulting in the wrong EBase being written. Correct both cases (configure_exception_vector() for the boot CPU, and per_cpu_trap_init() for secondary CPUs) to write EBase with the WG flag first if supported. On the Malta EVA configuration, KSeg0 is mapped to physical address 0, and memory is allocated from the KUSeg segment which is mapped to physical address 0x80000000, which physically aliases the RAM at 0. This only worked due to the exception base address aliasing the same underlying RAM that was written to & cache flushed, and due to flush_icache_range() going beyond the call of duty and flushing from the L2 cache too (due to the differing physical addresses). Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com> Cc: linux-mips@linux-mips.org --- arch/mips/kernel/traps.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cb2419dc4651..4900e590d86e 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2091,6 +2091,14 @@ static void configure_exception_vector(void) { if (cpu_has_veic || cpu_has_vint) { unsigned long sr = set_c0_status(ST0_BEV); + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); write_c0_status(sr); /* Setting vector spacing enables EI/VI mode */ @@ -2127,8 +2135,17 @@ void per_cpu_trap_init(bool is_boot_cpu) * We shouldn't trust a secondary core has a sane EBASE register * so use the one calculated by the boot CPU. */ - if (!is_boot_cpu) + if (!is_boot_cpu) { + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); + } cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; -- git-series 0.8.10
WARNING: multiple messages have this Message-ID (diff)
From: James Hogan <james.hogan@imgtec.com> To: Ralf Baechle <ralf@linux-mips.org> Cc: James Hogan <james.hogan@imgtec.com>, Matt Redfearn <matt.redfearn@imgtec.com>, Leonid Yegoshin <leonid.yegoshin@imgtec.com>, linux-mips@linux-mips.org Subject: [PATCH 3/9] MIPS: traps: Ensure full EBase is written Date: Thu, 1 Sep 2016 17:30:09 +0100 [thread overview] Message-ID: <c4de81b497c4a02a2bec5abc5234b7d84b75c5ec.1472747205.git-series.james.hogan@imgtec.com> (raw) Message-ID: <20160901163009.LwjRHR_-pbe2-tPjUcdmTUPvEsu0LL3XZQCHX9kcc8c@z> (raw) In-Reply-To: <cover.d93e43428f3c573bdd18d7c874830705b39c3a8a.1472747205.git-series.james.hogan@imgtec.com> From: Matt Redfearn <matt.redfearn@imgtec.com> On CPUs which support the EBase WG (write gate) flag, the most significant bits of the exception base can be changed. Firmware running on a VP(E) using MIPS rproc may change EBase to point into the user segment where the firmware is located such that it can service interrupts. When control is transferred back to the kernel the EBase must be switched back into the kernel segment, such that the kernel's exception vectors are used. Similarly when vectored interrupts (vint) or vectored external interrupt controllers (veic) are enabled an exception vector is allocated from bootmem, and written to the EBase register. Due to the WG flag being clear, only bits 29:12 will be written. Asside from the rproc case above this is normally fine (as it will usually be a low allocation within the KSeg0 range, however when Enhanced Virtual Addressing (EVA) is enabled the allocation may be outside of the traditional KSeg0/KSeg1 address range, resulting in the wrong EBase being written. Correct both cases (configure_exception_vector() for the boot CPU, and per_cpu_trap_init() for secondary CPUs) to write EBase with the WG flag first if supported. On the Malta EVA configuration, KSeg0 is mapped to physical address 0, and memory is allocated from the KUSeg segment which is mapped to physical address 0x80000000, which physically aliases the RAM at 0. This only worked due to the exception base address aliasing the same underlying RAM that was written to & cache flushed, and due to flush_icache_range() going beyond the call of duty and flushing from the L2 cache too (due to the differing physical addresses). Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com> Cc: linux-mips@linux-mips.org --- arch/mips/kernel/traps.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cb2419dc4651..4900e590d86e 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2091,6 +2091,14 @@ static void configure_exception_vector(void) { if (cpu_has_veic || cpu_has_vint) { unsigned long sr = set_c0_status(ST0_BEV); + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); write_c0_status(sr); /* Setting vector spacing enables EI/VI mode */ @@ -2127,8 +2135,17 @@ void per_cpu_trap_init(bool is_boot_cpu) * We shouldn't trust a secondary core has a sane EBASE register * so use the one calculated by the boot CPU. */ - if (!is_boot_cpu) + if (!is_boot_cpu) { + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); + } cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; -- git-series 0.8.10
next prev parent reply other threads:[~2016-09-01 16:32 UTC|newest] Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-09-01 16:30 [PATCH 0/9] MIPS: General EVA fixes & cleanups James Hogan 2016-09-01 16:30 ` [PATCH 1/9] MIPS: traps: 64bit kernels should read CP0_EBase 64bit James Hogan 2016-09-01 16:30 ` James Hogan 2016-09-21 13:08 ` Ralf Baechle 2016-09-21 15:01 ` Matt Redfearn 2016-09-21 15:01 ` Matt Redfearn 2016-10-02 10:30 ` Maciej W. Rozycki 2016-10-05 15:56 ` James Hogan 2016-10-05 15:56 ` James Hogan 2016-10-06 16:18 ` Maciej W. Rozycki 2016-10-06 18:05 ` James Hogan 2016-10-06 18:05 ` James Hogan 2016-10-06 19:56 ` Maciej W. Rozycki 2016-10-06 20:19 ` James Hogan 2016-10-06 20:19 ` James Hogan 2016-10-06 22:41 ` Maciej W. Rozycki 2016-10-06 22:50 ` James Hogan 2016-10-06 22:50 ` James Hogan 2016-10-06 23:07 ` Maciej W. Rozycki 2016-10-07 15:35 ` David Daney 2016-10-07 15:41 ` David Daney 2016-10-07 17:39 ` Maciej W. Rozycki 2016-09-01 16:30 ` [PATCH 2/9] MIPS: traps: Convert ebase to KSeg0 James Hogan 2016-09-01 16:30 ` James Hogan 2016-09-01 16:30 ` James Hogan [this message] 2016-09-01 16:30 ` [PATCH 3/9] MIPS: traps: Ensure full EBase is written James Hogan 2016-09-21 13:19 ` Ralf Baechle 2016-09-01 16:30 ` [PATCH 4/9] MIPS: c-r4k: Drop bc_wback_inv() from icache flush James Hogan 2016-09-01 16:30 ` James Hogan 2016-09-01 16:30 ` [PATCH 5/9] MIPS: c-r4k: Split user/kernel flush_icache_range() James Hogan 2016-09-01 16:30 ` James Hogan 2016-09-01 16:30 ` [PATCH 6/9] MIPS: cacheflush: Use __flush_icache_user_range() James Hogan 2016-09-01 16:30 ` James Hogan 2016-09-01 16:30 ` [PATCH 7/9] MIPS: uprobes: Flush icache via kernel address James Hogan 2016-09-01 16:30 ` James Hogan 2016-09-21 13:26 ` Ralf Baechle 2016-09-21 18:15 ` Leonid Yegoshin 2016-09-21 18:15 ` Leonid Yegoshin 2016-09-22 21:15 ` James Hogan 2016-09-22 21:15 ` James Hogan 2016-09-22 21:38 ` Leonid Yegoshin 2016-09-22 21:38 ` Leonid Yegoshin 2016-09-22 21:42 ` Leonid Yegoshin 2016-09-22 21:42 ` Leonid Yegoshin 2016-09-22 22:13 ` James Hogan 2016-09-22 22:27 ` Leonid Yegoshin 2016-09-22 22:27 ` Leonid Yegoshin 2016-09-23 7:10 ` James Hogan 2016-09-01 16:30 ` [PATCH 8/9] MIPS: KVM: Use __local_flush_icache_user_range() James Hogan 2016-09-01 16:30 ` [PATCH 9/9] MIPS: c-r4k: Fix flush_icache_range() for EVA James Hogan 2016-09-01 16:30 ` James Hogan
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=c4de81b497c4a02a2bec5abc5234b7d84b75c5ec.1472747205.git-series.james.hogan@imgtec.com \ --to=james.hogan@imgtec.com \ --cc=leonid.yegoshin@imgtec.com \ --cc=linux-mips@linux-mips.org \ --cc=matt.redfearn@imgtec.com \ --cc=ralf@linux-mips.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.