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-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8f6d2408-cada-4f03-aa95-31bd234aa47d@linaro.org>
Date: Mon, 27 May 2024 14:20:14 +0200
From: Philippe Mathieu-Daudé <philmd@...aro.org>
To: Jiaxun Yang <jiaxun.yang@...goat.com>, Huacai Chen
 <chenhuacai@...nel.org>, Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
 Daniel Lezcano <daniel.lezcano@...aro.org>,
 Thomas Gleixner <tglx@...utronix.de>
Cc: linux-kernel@...r.kernel.org, linux-mips@...r.kernel.org
Subject: Re: [PATCH v2] clocksource: Add node counter timer driver for
 MIPS/Loongson64

Hi Jiaxun,

On 17/5/24 19:13, Jiaxun Yang wrote:
> Node counter is a timer presents on many Loongson-3 series CPUs.
> It is maintained on every node in system. To avoid synchronisation
> complexity we only access the copy from first node in system.
> 
> It also has many ways to be accessed, on latest Loongson-3 CPU with
> IOCSR instruction support it should be accessed with a IOCSR request,
> while on earlier Loongson-3 CPUs it is attached to a 32 bits MMIO bus.
> For QEMU's Loongson-3 virt system it is mapped to a 64 bit MMIO location.
> 
> On some rare case the counter is disabled by firmware or not present
> on chip, so we need to perform a lightweight test to ensure it is
> running before actually use it.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@...goat.com>
> ---
> Changes in v2:
> - Fix build failure when it's not enabled.
> - Link to v1: https://lore.kernel.org/r/20240512-loongson_nodecnt-v1-1-2157b92ef8f8@flygoat.com
> ---
>   MAINTAINERS                                      |   1 +
>   arch/mips/include/asm/mach-loongson64/loongson.h |   3 +
>   arch/mips/loongson64/time.c                      |   3 +
>   drivers/clocksource/Kconfig                      |   8 ++
>   drivers/clocksource/loongson-nodecnt.c           | 112 +++++++++++++++++++++++
>   5 files changed, 127 insertions(+)


> diff --git a/drivers/clocksource/loongson-nodecnt.c b/drivers/clocksource/loongson-nodecnt.c
> new file mode 100644
> index 000000000000..3cea4045ce75
> --- /dev/null
> +++ b/drivers/clocksource/loongson-nodecnt.c


> +#define NODECNT_REGBASE		0x3ff00408
> +
> +static void __iomem *nodecnt_reg;
> +static u64 (*nodecnt_read_fn)(void);
> +
> +static u64 notrace nodecnt_read_2x32(void)
> +{
> +	unsigned int hi, hi2, lo;
> +
> +	do {
> +		hi = readl_relaxed(nodecnt_reg + 4);
> +		lo = readl_relaxed(nodecnt_reg);
> +		hi2 = readl_relaxed(nodecnt_reg + 4);
> +	} while (hi2 != hi);
> +
> +	return (((u64) hi) << 32) + lo;
> +}
> +
> +static u64 notrace nodecnt_read_64(void)
> +{
> +	return readq_relaxed(nodecnt_reg);
> +}


> +int __init nodecnt_clocksource_init(void)
> +{
> +	int err;
> +	uint64_t delta;
> +
> +	if (!cpu_clock_freq)
> +		return -ENODEV;
> +
> +	if (cpu_has_csr() && csr_readl(LOONGSON_CSR_FEATURES) & LOONGSON_CSRF_NODECNT) {
> +		nodecnt_read_fn = nodecnt_read_csr;
> +	} else if (loongson_sysconf.bridgetype == VIRTUAL) {
> +		nodecnt_reg = ioremap(NODECNT_REGBASE, 8);
> +		if (!nodecnt_reg)
> +			return -ENOMEM;
> +		nodecnt_read_fn = nodecnt_read_64;
> +	} else {
> +		switch (boot_cpu_data.processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) {
> +		case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0:
> +		case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_1:
> +		case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_0:
> +		case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_1:
> +			break;
> +		default:
> +			return -ENODEV;
> +		}
> +		nodecnt_reg = ioremap(NODECNT_REGBASE, 8);
> +		if (!nodecnt_reg)
> +			return -ENOMEM;
> +		nodecnt_read_fn = nodecnt_read_2x32;
> +	}
> +
> +	/* Test if nodecnt is usable */
> +	delta = nodecnt_read_fn();
> +	udelay(10);
> +	delta = nodecnt_read_fn() - delta;
> +
> +	if (!delta) {
> +		pr_info("nodecnt: clocksource unusable\n");
> +		err = -ENODEV;
> +		goto out;
> +	}
> +
> +	err = clocksource_register_hz(&nodecnt_clocksource, cpu_clock_freq);
> +	if (err) {
> +		pr_err("nodecnt: clocksource register failed\n");
> +		goto out;
> +	}
> +
> +	/* It fits for sched_clock if we don't suffer from cross node access */
> +	if (loongson_sysconf.bridgetype == VIRTUAL || loongson_sysconf.nr_nodes <= 1)
> +		sched_clock_register(nodecnt_read_fn, 64, cpu_clock_freq);

return 0; ? ...

> +
> +out:

.. or:

   if (err) ?

> +	if (nodecnt_reg)
> +		iounmap(nodecnt_reg);
> +	return err;
> +}
> 
> ---
> base-commit: 75fa778d74b786a1608d55d655d42b480a6fa8bd
> change-id: 20240512-loongson_nodecnt-0704f76bc959
> 
> Best regards,


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ