BACKPORT: arm64: Add CNTFRQ_EL0 trap handler
We now trap accesses to CNTVCT_EL0 when the counter is broken enough to require the kernel to mediate the access. But it turns out that some existing userspace (such as OpenMPI) do probe for the counter frequency, leading to an UNDEF exception as CNTVCT_EL0 and CNTFRQ_EL0 share the same control bit. The fix is to handle the exception the same way we do for CNTVCT_EL0. Fixes:a86bd139f2("arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled") Reported-by: Hanjun Guo <guohanjun@huawei.com> Tested-by: Hanjun Guo <guohanjun@huawei.com> Reviewed-by: Hanjun Guo <guohanjun@huawei.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> (cherry picked from commit9842119a23) CVE-2017-13218 Change-Id: I2f163e2511bab6225f319c0a9e732735cbd108a0
This commit is contained in:
parent
6c970498b3
commit
e35b7d2759
2 changed files with 15 additions and 0 deletions
|
|
@ -146,6 +146,9 @@
|
|||
#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CNTFRQ (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/types.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -418,11 +418,23 @@ static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
|
|||
regs->pc += 4;
|
||||
}
|
||||
|
||||
static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
|
||||
{
|
||||
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
|
||||
|
||||
if (rt != 31)
|
||||
regs->regs[rt] = read_sysreg(cntfrq_el0);
|
||||
regs->pc += 4;
|
||||
}
|
||||
|
||||
asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
|
||||
{
|
||||
if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTVCT) {
|
||||
cntvct_read_handler(esr, regs);
|
||||
return;
|
||||
} else if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTFRQ) {
|
||||
cntfrq_read_handler(esr, regs);
|
||||
return;
|
||||
}
|
||||
|
||||
do_undefinstr(regs);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue