lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <aCbhBttvi8mvsyGE@perf>
Date: Fri, 16 May 2025 15:53:58 +0900
From: Youngmin Nam <youngmin.nam@...sung.com>
To: Mark Rutland <mark.rutland@....com>, Marc Zyngier <maz@...nel.org>,
	Daniel Lezcano <daniel.lezcano@...aro.org>, Thomas Gleixner
	<tglx@...utronix.de>
Cc: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
	junhosj.choi@...sung.com, hajun.sung@...sung.com, joonki.min@...sung.com,
	d7271.choe@...sung.com, jkkkkk.choi@...sung.com, jt1217.kim@...sung.com,
	qperret@...gle.com, willdeacon@...gle.com, dhyun.cha@...sung.com,
	kn_hong.choi@...sung.com, mankyum.kim@...sung.com
Subject: [QUESTION] arch_counter_register() restricts CNTPT access when
 booted in EL1, even if EL2 is supported

Hi arm arch timer experts,

While reviewing the arm_arch_timer code in Linux 6.12,
I noticed that the function arch_counter_register() restricts the use of the physical counter (cntpct_el0)
on systems where the kernel is running in EL1, even if EL2 is supported and cntpct_el0 is accessible.

In our case:
- We are not using pKVM.
- The kernel is booted in EL1.
- We disabled VIRT_PPI and explicitly selected PHYS_NONSECURE_PPI for the timer refering to below code.

static enum arch_timer_ppi_nr __init arch_timer_select_ppi(void)
{
	if (is_kernel_in_hyp_mode())
		return ARCH_TIMER_HYP_PPI;

	if (!is_hyp_mode_available() && arch_timer_ppi[ARCH_TIMER_VIRT_PPI])
		return ARCH_TIMER_VIRT_PPI;

	if (IS_ENABLED(CONFIG_ARM64))
		return ARCH_TIMER_PHYS_NONSECURE_PPI;

	return ARCH_TIMER_PHYS_SECURE_PPI;
}

Despite this, the `arch_counter_register()` logic selects `cntvct_el0` unconditionally
due to the `!is_hyp_mode_available()` condition.

static void __init arch_counter_register(unsigned type)
{
	u64 (*scr)(void);
	u64 start_count;
	int width;

	/* Register the CP15 based counter if we have one */
	if (type & ARCH_TIMER_TYPE_CP15) {
		u64 (*rd)(void);

		if ((IS_ENABLED(CONFIG_ARM64) && !is_hyp_mode_available()) ||
		    arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) {
			if (arch_timer_counter_has_wa()) {
				rd = arch_counter_get_cntvct_stable;
				scr = raw_counter_get_cntvct_stable;
			} else {
				rd = arch_counter_get_cntvct;
				scr = arch_counter_get_cntvct;
			}
		} else {
			if (arch_timer_counter_has_wa()) {
				rd = arch_counter_get_cntpct_stable;
				scr = raw_counter_get_cntpct_stable;
			} else {
				rd = arch_counter_get_cntpct;
				scr = arch_counter_get_cntpct;
			}
		}

As I understand it, `is_hyp_mode_available()` checks whether the kernel booted into EL2
— not whether EL2 is *supported* by the hardware.

Therefore, even on systems where EL2 exists and `cntpct_el0` is accessible from EL1,
the kernel still forces the use of `cntvct_el0` if the boot EL is EL1.

Is this restriction to `cntvct_el0` in EL1 an architectural requirement,
or simply a conservative default to avoid possible traps on some systems?

If the hardware clearly supports EL2 and allows CNTPT access from EL1, could this restriction be relaxed?

Any guidance would be appreciated.


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ