mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
arm: traps: emulate a MRRC instruction reading CNTVCT register
Emulate CNTVCT access, so that userspace can get CNTVCT value, if the direct counter read is disabled. Also, keep direct access disabled by default for userspace. Change-Id: I70263c129386314880cb28d1e561146ce62d52b8 Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org> Signed-off-by: Cong Zhang <congzhan@codeaurora.org> Signed-off-by: Shadab Naseem <snaseem@codeaurora.org> Signed-off-by: Lijuan Gao <lijuang@codeaurora.org>
This commit is contained in:
parent
dc9b4c45b2
commit
f01ad8d152
5 changed files with 42 additions and 1 deletions
|
|
@ -28,6 +28,7 @@ static inline int __in_irqentry_text(unsigned long ptr)
|
|||
ptr < (unsigned long)&__irqentry_text_end;
|
||||
}
|
||||
|
||||
extern void get_timer_count_hook_init(void);
|
||||
extern void __init early_trap_init(void *);
|
||||
extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
|
||||
extern void ptrace_break(struct pt_regs *regs);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/irq.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/arch_timer.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/unistd.h>
|
||||
|
|
@ -711,6 +712,42 @@ late_initcall(arm_mrc_hook_init);
|
|||
|
||||
#endif
|
||||
|
||||
static int get_timer_count_trap(struct pt_regs *regs, unsigned int instr)
|
||||
{
|
||||
u64 cval;
|
||||
unsigned int res;
|
||||
int rd = (instr >> 12) & 0xF;
|
||||
int rn = (instr >> 16) & 0xF;
|
||||
|
||||
res = arm_check_condition(instr, regs->ARM_cpsr);
|
||||
if (res == ARM_OPCODE_CONDTEST_FAIL) {
|
||||
regs->ARM_pc += 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rd == 15 || rn == 15)
|
||||
return 1;
|
||||
cval = __arch_counter_get_cntvct();
|
||||
regs->uregs[rd] = cval;
|
||||
regs->uregs[rn] = cval >> 32;
|
||||
regs->ARM_pc += 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct undef_hook get_timer_count_hook = {
|
||||
.instr_mask = 0x0ff00fff,
|
||||
.instr_val = 0x0c500f1e,
|
||||
.cpsr_mask = MODE_MASK,
|
||||
.cpsr_val = USR_MODE,
|
||||
.fn = get_timer_count_trap,
|
||||
};
|
||||
|
||||
void get_timer_count_hook_init(void)
|
||||
{
|
||||
register_undef_hook(&get_timer_count_hook);
|
||||
}
|
||||
EXPORT_SYMBOL(get_timer_count_hook_init);
|
||||
|
||||
/*
|
||||
* A data abort trap was taken, but we did not handle the instruction.
|
||||
* Try to abort the user program, or panic if it was the kernel.
|
||||
|
|
|
|||
|
|
@ -110,4 +110,5 @@ static inline u32 arm64_ras_serror_get_severity(u32 esr)
|
|||
|
||||
bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned int esr);
|
||||
void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
|
||||
static inline void get_timer_count_hook_init(void) {}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -387,7 +387,7 @@ config SUN50I_ERRATUM_UNKNOWN1
|
|||
|
||||
config ARM_ARCH_TIMER_VCT_ACCESS
|
||||
bool "Support for ARM architected timer virtual counter access in userspace"
|
||||
default !ARM64
|
||||
default n
|
||||
depends on ARM_ARCH_TIMER
|
||||
help
|
||||
This option enables support for reading the ARM architected timer's
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/acpi.h>
|
||||
|
||||
#include <asm/arch_timer.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/virt.h>
|
||||
|
||||
#include <clocksource/arm_arch_timer.h>
|
||||
|
|
@ -1519,6 +1520,7 @@ static int __init arch_timer_mem_of_init(struct device_node *np)
|
|||
ret = arch_timer_mem_frame_register(frame);
|
||||
if (!ret && !arch_timer_needs_of_probing())
|
||||
ret = arch_timer_common_init();
|
||||
get_timer_count_hook_init();
|
||||
out:
|
||||
kfree(timer_mem);
|
||||
return ret;
|
||||
|
|
|
|||
Loading…
Reference in a new issue