Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94b2ae99 authored by Neeraj Upadhyay's avatar Neeraj Upadhyay Committed by Gerrit - the friendly Code Review server
Browse files

arm: traps: emulate a MRRC instruction reading CNTVCT register



In addition to emulating CNTPCT access, emulate CNTVCT access
too, 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: default avatarNeeraj Upadhyay <neeraju@codeaurora.org>
parent 8b23b7e4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ static inline int in_exception_text(unsigned long ptr)
	return in ? : __in_irqentry_text(ptr);
}

extern void get_pct_hook_init(void);
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 task_struct *tsk, struct pt_regs *regs);
+13 −11
Original line number Diff line number Diff line
@@ -764,12 +764,13 @@ late_initcall(arm_mrc_hook_init);

#endif

static int get_pct_trap(struct pt_regs *regs, unsigned int instr)
static int get_timer_count_trap(struct pt_regs *regs, unsigned int instr)
{
	u64 cntpct;
	u64 cval;
	unsigned int res;
	int rd = (instr >> 12) & 0xF;
	int rn =  (instr >> 16) & 0xF;
	int read_virtual = (instr >> 4) & 1;

	res = arm_check_condition(instr, regs->ARM_cpsr);
	if (res == ARM_OPCODE_CONDTEST_FAIL) {
@@ -779,26 +780,27 @@ static int get_pct_trap(struct pt_regs *regs, unsigned int instr)

	if (rd == 15 || rn == 15)
		return 1;
	cntpct = arch_counter_get_cntpct();
	regs->uregs[rd] = cntpct;
	regs->uregs[rn] = cntpct >> 32;
	cval = read_virtual ?
		arch_counter_get_cntvct() : arch_counter_get_cntpct();
	regs->uregs[rd] = cval;
	regs->uregs[rn] = cval >> 32;
	regs->ARM_pc += 4;
	return 0;
}

static struct undef_hook get_pct_hook = {
	.instr_mask	= 0x0ff00fff,
static struct undef_hook get_timer_count_hook = {
	.instr_mask	= 0x0ff00fef,
	.instr_val	= 0x0c500f0e,
	.cpsr_mask	= MODE_MASK,
	.cpsr_val	= USR_MODE,
	.fn		= get_pct_trap,
	.fn		= get_timer_count_trap,
};

void get_pct_hook_init(void)
void get_timer_count_hook_init(void)
{
	register_undef_hook(&get_pct_hook);
	register_undef_hook(&get_timer_count_hook);
}
EXPORT_SYMBOL(get_pct_hook_init);
EXPORT_SYMBOL(get_timer_count_hook_init);

void __bad_xchg(volatile void *ptr, int size)
{
+1 −1
Original line number Diff line number Diff line
@@ -43,5 +43,5 @@ static inline int in_exception_text(unsigned long ptr)
	       ptr < (unsigned long)&__exception_text_end;
}

static inline void get_pct_hook_init(void) {}
static inline void get_timer_count_hook_init(void) {}
#endif
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ config ARM_ARCH_TIMER_EVTSTREAM

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
+1 −1
Original line number Diff line number Diff line
@@ -832,7 +832,7 @@ static void __init arch_timer_mem_init(struct device_node *np)
	arch_timer_detect_rate(base, np);
	arch_timer_mem_register(base, irq);
	arch_timer_common_init();
	get_pct_hook_init();
	get_timer_count_hook_init();
}
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
		       arch_timer_mem_init);