Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 07/10] clk: amlogic: Support POWER_OF_TWO for PLL pre-divider
From: Jerome Brunet @ 2026-05-26 12:27 UTC (permalink / raw)
  To: Jian Hu
  Cc: Jian Hu via B4 Relay, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl, linux-kernel,
	linux-clk, devicetree, linux-amlogic, linux-arm-kernel
In-Reply-To: <3fda1592-f7d0-4e86-8615-602804673414@amlogic.com>

On mar. 26 mai 2026 at 17:58, Jian Hu <jian.hu@amlogic.com> wrote:

> On 5/20/2026 3:35 PM, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>>
>> On mer. 20 mai 2026 at 13:47, Jian Hu <jian.hu@amlogic.com> wrote:
>>
>>> On 5/14/2026 11:11 PM, Jerome Brunet wrote:
>>>> [ EXTERNAL EMAIL ]
>>>>
>>>> On lun. 11 mai 2026 at 20:47, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:
>>>>
>>>>> From: Jian Hu <jian.hu@amlogic.com>
>>>>>
>>>>> The A9 PLL pre-divider uses a division factor of 2^n to ensure a clock
>>>>> duty cycle of 50% after predivision.
>>>>>
>>>>> Add flag 'CLK_MESON_PLL_N_POWER_OF_TWO' to indicate that the PLL
>>>>> pre-divider division factor is 2^n.
>>>> I understand what you are doing here but I have to ask why this can't be
>>>> implemented with independent dividers that already supports power of 2 ?
>>>
>>> If we use independent dividers, the n member would have to be removed from
>>> meson_clk_pll_data.
>>>
>>> However, n is referenced 35 times in clk-pll.c, which means we would need
>>> to modify all
>>> related logic across the file. This would be a relatively large
>>> change.
>> Yes
>>
>>>
>>> Moreover, for all Amlogic chips, the n divider is an indispensable part of
>>> the DCO clock.
>> There is hardly a justification here
>>
>>> The difference between SoC generations is as follows:
>>>      Previous SoCs PLL: n = 1, 2, 3, 4... (linear divider)
>>>      A9 SoC PLL:            n = 2^0, 2^1, 2^2, 2^3, 2^4... (power-of-two
>>> divider)
>> Yes that was fairly obvious
>>
>>> Therefore, splitting out the n divider from the DCO clock might not be a
>>> good design choice.
>> I'm not sure I agree and you've only stated your point of view without
>> providing any technical justification here.
>>
>>  From the datasheets of the different SoC we have, the documented
>> limitation is always the DCO output rate range. Nothing related to n (or
>> m, or the mult-range for that matter). This is a legacy problem, we
>> started with monolithic driver and slowly simplified it.
>>
>> As far as I can see now, reworking the PLL driver to be a simple
>> multiplier driver with range output rate constraint could actually be
>> simpler than the current code. I would also make simpler to accomodate
>> differences such as the one presented here.
>>
>> Unless you can provide technical reasons why going in this direction
>> would be incorrect, that's where I'd prefer to go.
>>
>>> [...]
>>>
>>> Best regards,
>>>
>>> Jian
>> --
>> Jerome
>
>
> I agree that having an independent N divider would simplify the PLL rate
> calculation.
>
> A separate pre-divider for N is technically possible, but there are some
> hardware constraints that need to be considered:
>
> N = 1 is the preferred operating mode except a few fixed-frequency PLLs.
> Larger N values reduce the PLL phase detector frequency, which may
> negatively impact
> jitter performance and overall PLL stability.

Understood. You could really make a difference by going deeper and
explaining what those constraints are, especially since you ask question
internally at Amlogic.

At the moment what is documented is a range regarding the output rate of
the PLLs. A PLL is made of a pre-divider and fractional multiplier.
and you are saying that for the multiplier to work and lock, there is
actually a constraint the input rate too.

If you can discuss with your HW team and clarify what the constraints
really are, that would help to better model the PLL. In then more likely
for us to figure out the best way to drive it.


>
> Because of this, we cannot guarantee stable system operation when arbitrary
> larger
> N values are used.
>
> Some PLLs require non-1 N values to generate specific fixed output
> frequencies because
> the target rate cannot be achieved with N = 1 while keeping the PLL while
> keeping the
> PLL within its valid operating range. So N is designed to have other values
> ​​to
> satisfy this requirement.

Again it seems like the constraints we are using are not the real
limitation, just by-products, which the situation unclear.

>
> For example, the AXG PCIe PLL uses N = 3 to generate the required 100 MHz
> output frequency,
> since the target frequency cannot be achieved with N = 1.
>

PCIe is a topic in itself. It uses different ops for historic reasons though
I suspect, with proper constraints, it would not really need to.

>
> Additionally, is the refactored pre-divider N implemented as a separate
> patchset,
> independent from the A9 PLL changes?

I could be seen as a pre-requisite.

>
>
> Best regards,
>
>
> Jian

-- 
Jerome


^ permalink raw reply

* Re: [PATCH v2] irqchip/gic-v4: Harden against bogus command line
From: Marc Zyngier @ 2026-05-26 12:24 UTC (permalink / raw)
  To: Mostafa Saleh; +Cc: linux-arm-kernel, linux-kernel, tglx
In-Reply-To: <20260526112618.3629321-1-smostafa@google.com>

On Tue, 26 May 2026 12:26:18 +0100,
Mostafa Saleh <smostafa@google.com> wrote:
> 

nit: $SUBJECT isn't quite telling the full story, and the command-line
is only a second order effect. Something like:

"irqchip/gic-v4: Don't advertise VLPIs if no ITS is probed"

actually describes the nature of the issue.

> When accidentally setting “kvm-arm.vgic_v4_enable=1” on the wrong
> setup that has no MSI controller device tree node (it exists but
> not used) and GICv4, it caused a panic as “gic_domain” is NULL and
> the kernel attempted to access its ops.
> 
> Originally, I hit this on an older kernel, but was able to reproduce
> it on upstream with Qemu by hacking this unreasonable setup.
> 
> [   33.145536] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
> [   33.145658] Mem abort info:
> [   33.145751]   ESR = 0x0000000096000006
> ...
> [   33.154057] CPU: 1 UID: 0 PID: 295 Comm: lkvm-static Not tainted 7.1.0-rc4-ge3f15ad3970e #5 PREEMPT
> [   33.156922] Hardware name: linux,dummy-virt (DT)
> [   33.158780] pstate: 81402005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
> [   33.160340] pc : __irq_domain_instantiate+0x1d4/0x578
> [   33.162602] lr : __irq_domain_instantiate+0x1cc/0x578
> 
> Set vLPI support to false at init time if the host has no ITS, so it
> propagates properly to kvm_vgic_global_state.has_gicv4.
>
> Suggested-by: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> 
> ---
> v2: Fix the issue at construction as Marc suggested.
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 291d7668cc8d..d02cb9c17c0b 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -5837,6 +5837,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>  		its_acpi_probe();
>  
>  	if (list_empty(&its_nodes)) {
> +		rdists->has_vlpis = false;
>  		pr_warn("ITS: No ITS available, not enabling LPIs\n");
>  		return -ENXIO;
>  	}

With the above fixed:

Acked-by: Marc Zyngier <maz@kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH] arm64: kernel: Disable CNP on HiSilicon HIP09
From: Zeng Heng @ 2026-05-26 12:19 UTC (permalink / raw)
  To: Vladimir Murzin, Zeng Heng, corbet, kuninori.morimoto.gx, maz,
	oupton, catalin.marinas, lucaswei, yeoreum.yun, skhan,
	james.clark, broonie, mark.rutland, lpieralisi, ryan.roberts,
	will, tongtiangen, kevin.brodsky, yangyicong, miko.lenczewski
  Cc: linux-doc, wangkefeng.wang, linux-kernel, linux-arm-kernel,
	sunnanyong
In-Reply-To: <3e7d5472-9c40-456c-876e-c2e71fa0e8fa@arm.com>

Hi Vladimir,

On 2026/5/26 20:10, Vladimir Murzin wrote:
> Hi,
> 
> On 5/26/26 02:57, Zeng Heng wrote:
>> From: Tong Tiangen <tongtiangen@huawei.com>
>>
>> HiSilicon HIP09 implements TLB entry matching behavior that deviates
>> from the ARM architecture specification when the CNP (Common not Private)
>> bit is set in TTBRx_ELx.
>>
>> When TTBRx.CNP=1, TLB entries may be incorrectly shared between CPU
>> cores, leading to TLB conflicts and stale mappings. This affects
>> coherency and can result in incorrect translations.
>>
>> Add the hardware erratum workaround (Hisilicon erratum 162100125) to
>> disable CNP on affected HIP09 cores.
>>
>> Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
>> Signed-off-by: Zeng Heng <zengheng4@huawei.com>
>> ---
>>   Documentation/arch/arm64/silicon-errata.rst |  2 ++
>>   arch/arm64/Kconfig                          | 15 +++++++++++++++
>>   arch/arm64/kernel/cpu_errata.c              |  7 +++++++
>>   arch/arm64/kernel/cpufeature.c              |  3 ++-
>>   arch/arm64/tools/cpucaps                    |  1 +
>>   5 files changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
>> index 211119ce7adc..cd50059edb85 100644
>> --- a/Documentation/arch/arm64/silicon-errata.rst
>> +++ b/Documentation/arch/arm64/silicon-errata.rst
>> @@ -284,6 +284,8 @@ stable kernels.
>>   +----------------+-----------------+-----------------+-----------------------------+
>>   | Hisilicon      | Hip09           | #162100801      | HISILICON_ERRATUM_162100801 |
>>   +----------------+-----------------+-----------------+-----------------------------+
>> +| Hisilicon      | Hip09           | #162100125      | HISILICON_ERRATUM_162100125 |
>> ++----------------+-----------------+-----------------+-----------------------------+
>>   +----------------+-----------------+-----------------+-----------------------------+
>>   | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
>>   +----------------+-----------------+-----------------+-----------------------------+
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index fe60738e5943..ed6207c75b54 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -1273,6 +1273,21 @@ config HISILICON_ERRATUM_162100801
>>   
>>   	  If unsure, say Y.
>>   
>> +config HISILICON_ERRATUM_162100125
>> +	bool "Hisilicon erratum 162100125"
>> +	default y
>> +	help
>> +	  On HiSilicon HIP09, TLB entry matching behavior when CNP
>> +	  (TTBRx.CNP=1) is enabled differs from the ARM architecture
>> +	  specification.
>> +
>> +	  TLB entries may be incorrectly shared between CPUs, potentially
>> +	  causing TLB conflicts and stale mappings.
>> +
>> +	  Disable CNP support for affected HiSilicon HIP09 cores.
>> +
>> +	  If unsure, say Y.
>> +
>>   config QCOM_FALKOR_ERRATUM_1003
>>   	bool "Falkor E1003: Incorrect translation due to ASID change"
>>   	default y
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index 5377e4c2eba2..26d9677a20fc 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -968,6 +968,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>>   		.matches = has_impdef_pmuv3,
>>   		.cpu_enable = cpu_enable_impdef_pmuv3_traps,
>>   	},
>> +#ifdef CONFIG_HISILICON_ERRATUM_162100125
>> +	{
>> +		.desc = "Hisilicon erratum 162100125",
>> +		.capability = ARM64_WORKAROUND_HISILICON_ERRATUM_162100125,
>> +		ERRATA_MIDR_ALL_VERSIONS(MIDR_HISI_HIP09),
>> +	},
>> +#endif
>>   	{
>>   	}
>>   };
>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>> index 6d53bb15cf7b..c4b0db77a58a 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -1785,7 +1785,8 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
>>   	if (is_kdump_kernel())
>>   		return false;
>>   
>> -	if (cpus_have_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP))
>> +	if (cpus_have_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP) ||
>> +	    cpus_have_cap(ARM64_WORKAROUND_HISILICON_ERRATUM_162100125))
>>   		return false;
> 
> Since we now have a second user for this workaround, would it
> make sense to:
> 1. factor out the existing ARM64_WORKAROUND_NVIDIA_CARMEL_CNP into a common capability,
>     for example ARM64_WORKAROUND_DISABLE_CNP
> 2. wire up erratum 162100125 to use the common ARM64_WORKAROUND_DISABLE_CNP capability?
> 
> Cheers
> Vladimir
> 

This makes sense to me. Thanks for the reminder.

Best regards,
Zeng Heng

>>   
>>   	return has_cpuid_feature(entry, scope);
>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>> index 811c2479e82d..b797d4893adc 100644
>> --- a/arch/arm64/tools/cpucaps
>> +++ b/arch/arm64/tools/cpucaps
>> @@ -128,3 +128,4 @@ WORKAROUND_REPEAT_TLBI
>>   WORKAROUND_SPECULATIVE_AT
>>   WORKAROUND_SPECULATIVE_SSBS
>>   WORKAROUND_SPECULATIVE_UNPRIV_LOAD
>> +WORKAROUND_HISILICON_ERRATUM_162100125
>> -- 2.43.0
>>
> 
> 
> 



^ permalink raw reply

* Re: [PATCH] arm64: kernel: Disable CNP on HiSilicon HIP09
From: Vladimir Murzin @ 2026-05-26 12:10 UTC (permalink / raw)
  To: Zeng Heng, corbet, kuninori.morimoto.gx, maz, oupton,
	catalin.marinas, lucaswei, yeoreum.yun, skhan, james.clark,
	broonie, mark.rutland, lpieralisi, ryan.roberts, will,
	tongtiangen, kevin.brodsky, yangyicong, miko.lenczewski
  Cc: linux-doc, wangkefeng.wang, linux-kernel, linux-arm-kernel
In-Reply-To: <20260526015720.206854-1-zengheng@huaweicloud.com>

Hi,

On 5/26/26 02:57, Zeng Heng wrote:
> From: Tong Tiangen <tongtiangen@huawei.com>
> 
> HiSilicon HIP09 implements TLB entry matching behavior that deviates
> from the ARM architecture specification when the CNP (Common not Private)
> bit is set in TTBRx_ELx.
> 
> When TTBRx.CNP=1, TLB entries may be incorrectly shared between CPU
> cores, leading to TLB conflicts and stale mappings. This affects
> coherency and can result in incorrect translations.
> 
> Add the hardware erratum workaround (Hisilicon erratum 162100125) to
> disable CNP on affected HIP09 cores.
> 
> Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
> Signed-off-by: Zeng Heng <zengheng4@huawei.com>
> ---
>  Documentation/arch/arm64/silicon-errata.rst |  2 ++
>  arch/arm64/Kconfig                          | 15 +++++++++++++++
>  arch/arm64/kernel/cpu_errata.c              |  7 +++++++
>  arch/arm64/kernel/cpufeature.c              |  3 ++-
>  arch/arm64/tools/cpucaps                    |  1 +
>  5 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
> index 211119ce7adc..cd50059edb85 100644
> --- a/Documentation/arch/arm64/silicon-errata.rst
> +++ b/Documentation/arch/arm64/silicon-errata.rst
> @@ -284,6 +284,8 @@ stable kernels.
>  +----------------+-----------------+-----------------+-----------------------------+
>  | Hisilicon      | Hip09           | #162100801      | HISILICON_ERRATUM_162100801 |
>  +----------------+-----------------+-----------------+-----------------------------+
> +| Hisilicon      | Hip09           | #162100125      | HISILICON_ERRATUM_162100125 |
> ++----------------+-----------------+-----------------+-----------------------------+
>  +----------------+-----------------+-----------------+-----------------------------+
>  | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
>  +----------------+-----------------+-----------------+-----------------------------+
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index fe60738e5943..ed6207c75b54 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1273,6 +1273,21 @@ config HISILICON_ERRATUM_162100801
>  
>  	  If unsure, say Y.
>  
> +config HISILICON_ERRATUM_162100125
> +	bool "Hisilicon erratum 162100125"
> +	default y
> +	help
> +	  On HiSilicon HIP09, TLB entry matching behavior when CNP
> +	  (TTBRx.CNP=1) is enabled differs from the ARM architecture
> +	  specification.
> +
> +	  TLB entries may be incorrectly shared between CPUs, potentially
> +	  causing TLB conflicts and stale mappings.
> +
> +	  Disable CNP support for affected HiSilicon HIP09 cores.
> +
> +	  If unsure, say Y.
> +
>  config QCOM_FALKOR_ERRATUM_1003
>  	bool "Falkor E1003: Incorrect translation due to ASID change"
>  	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 5377e4c2eba2..26d9677a20fc 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -968,6 +968,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>  		.matches = has_impdef_pmuv3,
>  		.cpu_enable = cpu_enable_impdef_pmuv3_traps,
>  	},
> +#ifdef CONFIG_HISILICON_ERRATUM_162100125
> +	{
> +		.desc = "Hisilicon erratum 162100125",
> +		.capability = ARM64_WORKAROUND_HISILICON_ERRATUM_162100125,
> +		ERRATA_MIDR_ALL_VERSIONS(MIDR_HISI_HIP09),
> +	},
> +#endif
>  	{
>  	}
>  };
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 6d53bb15cf7b..c4b0db77a58a 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1785,7 +1785,8 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
>  	if (is_kdump_kernel())
>  		return false;
>  
> -	if (cpus_have_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP))
> +	if (cpus_have_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP) ||
> +	    cpus_have_cap(ARM64_WORKAROUND_HISILICON_ERRATUM_162100125))
>  		return false;

Since we now have a second user for this workaround, would it
make sense to:
1. factor out the existing ARM64_WORKAROUND_NVIDIA_CARMEL_CNP into a common capability,
   for example ARM64_WORKAROUND_DISABLE_CNP
2. wire up erratum 162100125 to use the common ARM64_WORKAROUND_DISABLE_CNP capability?

Cheers
Vladimir

>  
>  	return has_cpuid_feature(entry, scope);
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 811c2479e82d..b797d4893adc 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -128,3 +128,4 @@ WORKAROUND_REPEAT_TLBI
>  WORKAROUND_SPECULATIVE_AT
>  WORKAROUND_SPECULATIVE_SSBS
>  WORKAROUND_SPECULATIVE_UNPRIV_LOAD
> +WORKAROUND_HISILICON_ERRATUM_162100125
> -- 2.43.0
> 



^ permalink raw reply

* Re: [PATCH v3 2/2] drm/bridge: analogix_dp: Add support for optional data-lanes mapping
From: Luca Ceresoli @ 2026-05-26 12:07 UTC (permalink / raw)
  To: Damon Ding
  Cc: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
	airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
	neil.armstrong, rfoss, Laurent.pinchart, jonas, jernej.skrabec,
	nicolas.frattaroli, cristian.ciocaltea, sebastian.reichel,
	dmitry.baryshkov, luca.ceresoli, dianders, m.szyprowski,
	dri-devel, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel
In-Reply-To: <20260525094731.121380-3-damon.ding@rock-chips.com>

On Mon, 25 May 2026 17:47:31 +0800, Damon Ding <damon.ding@rock-chips.com> wrote:

Hello Damon,

>
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index 8cf6b73bceac..d53ab25bc57b 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -1234,6 +1234,59 @@ static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
> [ ... skip 11 lines ... ]
> +	int ret, i;
> +
> +	memcpy(video_info->lane_map, map, sizeof(map));
> +
> +	num_lanes = drm_of_get_data_lanes_count_ep(dp->dev->of_node, 1, 0, 1,
> +						   video_info->max_lane_count);

Should num_lanes be > 4, the buffers could overflow. I realize it should
not happen, but analogix_dp_dt_parse_pdata() can set max_lane_count from
the device tree, so a bogus dtb could cause such overflow.

Perhaps you should just (in a separate patch) error out in
analogix_dp_dt_parse_pdata() to prevent this. And maybe even adding an
BUG_ON(lane_count > 4) here.

Otherwise LGTM.

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



^ permalink raw reply

* Re: [PATCH v5 2/4] PCI: Use standard wait times for PCIe link monitoring
From: Lukas Wunner @ 2026-05-26 11:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczy??ski,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Thierry Reding, Jonathan Hunter, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár, Michal Simek,
	Kevin Xie, Aksh Garg, linux-pci, devicetree, linux-tegra,
	linux-kernel, linux-arm-kernel, Thierry Reding
In-Reply-To: <20260526-tegra264-pcie-v5-2-84a813b979d7@nvidia.com>

On Tue, May 26, 2026 at 10:53:11AM +0200, Thierry Reding wrote:
> Instead of defining the wait values for each driver, use common values
> defined in the core pci.h header file. Note that most drivers don't use
> the millisecond waits, but rather usleep_range(), so add these commonly
> used values to the header so that all drivers can use them.

Hm, why not just replace usleep_range() with msleep() and use the existing
macro instead of defining new ones?

> +++ b/drivers/pci/pci.h
> @@ -63,6 +63,8 @@ struct pcie_tlp_log;
>  /* Parameters for the waiting for link up routine */
>  #define PCIE_LINK_WAIT_MAX_RETRIES	10
>  #define PCIE_LINK_WAIT_SLEEP_MS		90
> +#define PCIE_LINK_WAIT_US_MIN		90000
> +#define PCIE_LINK_WAIT_US_MAX		100000

If you absolutely positively want to add a new macro, consider
90 * USEC_PER_MSEC instead of 90000.  Moreover, consider using
fsleep() instead of adding an additional MAX macro.

Thanks,

Lukas


^ permalink raw reply

* Re: [PATCH] KVM: arm64: Preserve all guest ZCR_EL2.LEN values
From: Mark Rutland @ 2026-05-26 12:03 UTC (permalink / raw)
  To: Mark Brown
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
	Suzuki K Poulose, Catalin Marinas, Will Deacon, linux-arm-kernel,
	kvmarm, linux-kernel
In-Reply-To: <b4fdceb6-5fa7-4829-a60e-6f80f47f032a@sirena.org.uk>

On Tue, May 26, 2026 at 11:19:38AM +0100, Mark Brown wrote:
> On Mon, May 25, 2026 at 07:36:50PM +0100, Mark Rutland wrote:
> > On Fri, May 22, 2026 at 07:00:04PM +0100, Mark Brown wrote:
> 
> > > Since b3d29a823099 ("KVM: arm64: nv: Handle ZCR_EL2 traps") when guests
> > > write to ZCR_EL2 we have clamped the value of ZCR_EL2.LEN to be at most
> > > that configuring the maximum guest VL. This is not the behaviour the
> 
> ...
> 
> > Have we sought feedback from architects? While I said "*or* the
> > architcture requires a clarification", I think it should be clarified
> > more explicitly either way given that the pattern is unusual.

The part I asked for clarification on was:

  AFAICT, none of the values for the SMCR_ELx.LEN and ZCR_ELx.LEN fields
  are reserved or unallocated. Thus all the bits of those fields should
  be stateful, and a read should observe the last value written,
  regardless of the effective value of the field.

  [...]

  Either what we're doing is wrong, or the architcture requires a
  clarification to say that values corresponding to unimplmented vector
  lengths are reserved.

> > Given this is particularly subtle, please keep me in the loop when
> > speaking with architects about this.
> 
> TBH it didn't strike me as subtle, I don't see anything in the
> architecture which would lead me to expect the current behaviour. 

The point I was trying to get across is that I don't think this is
specified clearly enough, and I think we need to get this clarified.

There's a general principle regarding reserved values. See K1.2.19
("Reserved values in System and memory-mapped registers and translation
table entries"), and specifically note "reserved values of fields".

There's no explicit statement either way regarding the values for
ZCR_ELx.LEN and SMCR_ELx.LEN. The statement regarding the selection of
the effective vector length implies *some* constraints, but
(explicitly!) doesn't specify the behaviour for direct reads.

It's possible for a reader to come to one of the following conclusions:

(a) Any value written to the LEN field must be preserved exactly. In all
    cases a read must observe the last value written.

(b) Some values written to the LEN field are reserved, and don't need to
    be preserved exactly.

    For example, since the only architecturally-defined VLs are
    powers-of-two, the only "legitimate" values are: 0b0000, 0b0001,
    0b0011, 0b0111, 0b1111. Hence any written value could be collapsed
    to that set.

(c) Some values written to the LEN field are reserved, and can be
    replaced with *any* value.

    See the statement at the end of K1.2.19 regarding subsequent reads
    returning an UNKNOWN value.

While one simple reading is that all values must be preserved exactly, I
don't think this watertight, and I think while some people will take
reading (a), others will take (b) or (c). I should have spelled that out
more clearly in my initial mail, sorry.

> The psudocode all just has direct assignments for the write

The pseudocode doesn't capture the detail I've described above.

> and there's language in the ARM (eg, in the ZCR_EL2 description)
> saying "for all purposes other than returning the result of a direct
> read of ZCR_EL2" which seems specifically intended to cover there
> being a divergence between the written and effective values, though I
> guess it doesn't explicitly mention writes in the text.  

That permits a divergence, but does not define the boundary conditions
for what a direct read can observe.

Mark.


^ permalink raw reply

* Re: [PATCH] arm64: mm: call pagetable dtor when freeing hot-removed page tables
From: Kevin Brodsky @ 2026-05-26 11:54 UTC (permalink / raw)
  To: Vishal Moola, Catalin Marinas
  Cc: Andrew Morton, Alistair Popple, linux-arm-kernel, linux-kernel,
	linux-mm, will, david
In-Reply-To: <ahAjudlB32VbkKbG@fedora>

On 22/05/2026 11:36, Vishal Moola wrote:
>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>> index 4c8959153ac4..9d42cbddce27 100644
>> --- a/arch/arm64/mm/mmu.c
>> +++ b/arch/arm64/mm/mmu.c
>> @@ -1441,6 +1441,9 @@ static void free_hotplug_page_range(struct page *page, size_t size,
>>  
>>  static void free_hotplug_pgtable_page(struct page *page)
>>  {
>> +	if (folio_test_pgtable(page_folio(page)))
> This should work.
>
>> +		pagetable_dtor(page_ptdesc(page));
>> +
>>  	free_hotplug_page_range(page, PAGE_SIZE, NULL);
> In the case we presumably have a page table page (ptdesc) at this
> point, we should really be freeing it with pagetable_free() as well.

Agreed, I think this is the right thing to do, something like:

if (folio_test_pgtable(page_folio(page)))
pagetable_dtor_free(page_ptdesc(page)); else
free_hotplug_page_range(page, PAGE_SIZE, NULL);


Strangely enough x86 calls pagetable_free() in both cases.

My series protecting page tables with pkeys has a patch [1] to get
vmemmap to allocate page tables with pagetable_alloc(). The diff above
will require pagetable_*_ctor() to be called as well, but I think that's
the right thing to do anyway. That could be posted as a separate series,
but I'm hesitant due to the lack of NUMA awareness in pagetable_alloc().

- Kevin

[1] https://lore.kernel.org/all/20260526-kpkeys-v8-14-eaaacdacc67c@arm.com/

> Its not a big deal that we don't right now, but losing track of the
> matching allocation/free sites will become a headache when separately
> allocating from struct page.
>
>>  }


^ permalink raw reply

* Re: [PATCH v9 0/4] firmware: ti_sci: Introduce BOARDCFG_MANAGED mode for Jacinto family
From: Nishanth Menon @ 2026-05-26 11:52 UTC (permalink / raw)
  To: Tero Kristo, Santosh Shilimkar, Michael Turquette, Stephen Boyd,
	Brian Masney, Thomas Richard (TI)
  Cc: Nishanth Menon, Gregory CLEMENT, richard.genoud, Udit Kumar,
	Abhash Kumar, Thomas Petazzoni, linux-arm-kernel, linux-kernel,
	linux-clk, Dhruva Gole, Kendall Willis
In-Reply-To: <20260519-ti-sci-jacinto-s2r-restore-irq-v9-0-c550a8ae0f31@bootlin.com>

Hi Thomas Richard (TI),

On Tue, 19 May 2026 17:06:55 +0200, Thomas Richard (TI) wrote:
> This is the 9th iteration of this series. The only change is that now the
> irq_lock mutex is used unconditionally in set_irq() and free_irq(). It
> makes the code easier, and prevents coccinelle warnings.
> 
> Best Regards,
> Thomas
> 
> [...]

I have applied the following to branch ti-drivers-soc-next on [1].
Thank you!

[1/4] firmware: ti_sci: add BOARDCFG_MANAGED mode support
      commit: e9f06763b9b88cb1338ef8a3f113b0fb94d714dd
[2/4] firmware: ti_sci: add support for restoring IRQs during resume
      commit: 703b341fdd875c2d9c30a835021689e5a430a39a
[3/4] clk: keystone: sci-clk: add restore_context() operation
      commit: 3c5912373340cb79db6585f0fcd8107198d4933d
[4/4] firmware: ti_sci: add support for restoring clock context during resume
      commit: dc51f820bd32415445655aa6e3af9011b9e3e0f3

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D
https://ti.com/opensource



^ permalink raw reply

* Re: [PATCH V2 00/11] soc: ti: keystone/k3 navigator queue/dma/ringacc cleanups
From: Nishanth Menon @ 2026-05-26 11:51 UTC (permalink / raw)
  To: Justin Stitt, Bill Wendling, Nick Desaulniers, Nathan Chancellor,
	Santosh Shilimkar, Nishanth Menon
  Cc: afd, llvm, linux-arm-kernel, linux-kernel
In-Reply-To: <20260512170623.3174416-1-nm@ti.com>

Hi Nishanth Menon,

On Tue, 12 May 2026 12:06:12 -0500, Nishanth Menon wrote:
> Fix W=2 (clang/gcc), sparse, smatch and coccinelle warnings.
> No functional changes.
> 
> Tested: NFS boot (via nav subsystem) on k2l-evm, k2hk-evm and k2g-evm
> based on next-20260507:
> https://gist.github.com/nmenon/cff02a5f2a72fde5fcb49664fcc834d2
> 
> [...]

I have applied the following to branch ti-drivers-soc-next on [1].
Thank you!

[01/11] soc: ti: knav_qmss: Remove remaining redundant ENOMEM printks
        commit: a76c24eb1f10366f128c621f876c20a13ae53489
[02/11] soc: ti: knav_qmss: Rename global kdev to knav_qdev to fix -Wshadow
        commit: 7db27a04fb8a33a7f9904961ee6f3c75f65d1118
[03/11] soc: ti: knav_qmss: Inline lockdep condition in for_each_handle_rcu
        commit: b6542cf0f4d062133f6e05de03382080ad941c67
[04/11] soc: ti: knav_qmss: Fix kernel-doc Return: tags
        commit: 7650590dbf12a3d4a3d302cd33ac31270e39c43c
[05/11] soc: ti: knav_qmss: Use %pe to print PTR_ERR()
        commit: a5f624c4fee6d7b51f7bc4bd6e213c220b610ec3
[06/11] soc: ti: knav_qmss: Fix __iomem annotations and __be32 type
        commit: cb1a271a4f20faae9a10891bfae2b543778d2b4a
[07/11] soc: ti: knav_qmss_acc: Fix kernel-doc Return: tag
        commit: ebc1a345bf1166b22035f0cfbf877b9d0e80ba4e
[08/11] soc: ti: knav_dma: Remove unused DMA_PRIO_MASK macro
        commit: 2b47cc255a952d3bd7ec3c0f38fdd81ccde3cb58
[09/11] soc: ti: knav_dma: Remove dead check on unsigned args.args[0]
        commit: fe5272e13e34025a9bb10cc452805e5085492a92
[10/11] soc: ti: knav_dma: Use IOMEM_ERR_PTR() in pktdma_get_regs()
        commit: 81f2c17bc0596f619616a2e85fab142c8316de85
[11/11] soc: ti: k3-ringacc: Use str_enabled_disabled() helper
        commit: 33050d81b828c7d699ad0ad0c7489a198c527019

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D
https://ti.com/opensource



^ permalink raw reply

* Re: [PATCH v5 0/7] Add support for Video, Camera, Graphics clock controllers on Eliza
From: Taniya Das @ 2026-05-26 11:40 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Maxime Coquelin,
	Alexandre Torgue, Luca Weiss, Ajit Pandey, Imran Shaik,
	Jagadeesh Kona, linux-arm-msm, linux-clk, devicetree,
	linux-kernel, linux-stm32, linux-arm-kernel, Konrad Dybcio
In-Reply-To: <27l6r6gp6zpddgkxne7jasjxamy4dmdkwg3xyp6hrmdbtk7mxj@jxsgeq4yvfhh>



On 5/25/2026 4:43 PM, Dmitry Baryshkov wrote:
>> The patches have been tested on Qualcomm Eliza MTP board.
>>
>> Changes in v5:
>> - Taken care of comments from v3, v4.
> Which comments? Please be more specific in changelogics.

Sorry, my bad, it was the 'sashiko-bot' comments.

-- 
Thanks,
Taniya Das



^ permalink raw reply

* Re: [PATCH v5 1/7] dt-bindings: clock: qcom: Add video clock controller on Qualcomm Eliza SoC
From: Taniya Das @ 2026-05-26 11:38 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Maxime Coquelin,
	Alexandre Torgue, Luca Weiss, Ajit Pandey, Imran Shaik,
	Jagadeesh Kona, linux-arm-msm, linux-clk, devicetree,
	linux-kernel, linux-stm32, linux-arm-kernel
In-Reply-To: <20260526-muscular-skylark-of-wholeness-6ef2a8@quoll>



On 5/26/2026 3:07 PM, Krzysztof Kozlowski wrote:
> On Mon, May 25, 2026 at 04:16:03PM +0530, Taniya Das wrote:
>> Eliza Video clock controller is on CX and MX rails similar to Milos.
>> Add compatible string for Eliza video clock controller to the existing
>> Milos videocc binding and add the dt-bindings header for Eliza.
>>
>> The video clock controller exposes power domains, so '#power-domain-cells'
>> must be present in the device node. Add it to the required properties list
>> to enforce this in binding validation.
> 
> That's ABI change, so you need to explain impact on existing devices -
> Milos.

Currently there is no ABI breakage and no impact to the existing
devices, since the nodes [1], [2] using this bindings are already
specifying the '#power-domain-cells' property.

[1] videocc -
https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/milos.dtsi#L1849
[2] camcc -
https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/milos.dtsi#L1918

-- 
Thanks,
Taniya Das



^ permalink raw reply

* Re: [PATCH v5 6/7] clk: qcom: camcc: Add support for camera clock controller for Eliza
From: Taniya Das @ 2026-05-26 11:38 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Maxime Coquelin,
	Alexandre Torgue, Luca Weiss, Ajit Pandey, Imran Shaik,
	Jagadeesh Kona, linux-arm-msm, linux-clk, devicetree,
	linux-kernel, linux-stm32, linux-arm-kernel, Konrad Dybcio
In-Reply-To: <lbixqj4cgausikhelm3iq5kamgmxf6ibhv67p6aya3fyqpdck5@ygy2yzntbo35>



On 5/25/2026 4:42 PM, Dmitry Baryshkov wrote:
> The camcc and cambistmclkccc drivers looks pretty close to SM8750,
> except for using a different PLLs. Would it make sense to have common
> drivers instead?

Dmitry, on Eliza, CAMCC and CAMBISTMCLKCC are powered by the CX and MX
rails, whereas on SM8750 they use the MMCX and MXC rails. The PLL
types/configurations differ across the two platforms and the frequencies
across rcgs are also updated.

Due to these differences in power domains, PLLs and frequency plans
update reusing the SM8750 drivers for Eliza was not considered.

-- 
Thanks,
Taniya Das



^ permalink raw reply

* Re: [PATCH] irqchip/gic-v4: Harden against bogus command line
From: Mostafa Saleh @ 2026-05-26 11:33 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-arm-kernel, linux-kernel, tglx
In-Reply-To: <86wlwqv711.wl-maz@kernel.org>

On Tue, May 26, 2026 at 10:45 AM Marc Zyngier <maz@kernel.org> wrote:
>
>
> You should still be able to have a virtual ITS, just no direct
> injection of any sort.
>

True, my bad.

> If you're happy with that, please respin a patch with this hack.
>

Done!

Thanks,
Mostafa

> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH v8 01/10] dt-bindings: display: rockchip: analogix-dp: Fix hclk as third clock for RK3588
From: Damon Ding @ 2026-05-26 11:27 UTC (permalink / raw)
  To: Conor Dooley
  Cc: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
	airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
	neil.armstrong, rfoss, Laurent.pinchart, jonas, jernej.skrabec,
	nicolas.frattaroli, cristian.ciocaltea, sebastian.reichel,
	dmitry.baryshkov, luca.ceresoli, dianders, m.szyprowski,
	dri-devel, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel
In-Reply-To: <f6c2f07b-52b8-4181-aa1d-a7d8dcda245c@rock-chips.com>

Hi Conor,

On 5/26/2026 8:54 AM, Damon Ding wrote:
> Hi Conor,
> 
> On 5/26/2026 12:54 AM, Conor Dooley wrote:
>> On Mon, May 25, 2026 at 08:53:22PM +0800, Damon Ding wrote:
>>> RK3588 eDP controller requires HCLK_VO1 to access the VO1 GRF
>>> registers and enable the video datapath.
>>>
>>> Previously, the clock was enabled implicitly via the 'rockchip,vo-grf'
>>> phandle reference, which allowed the eDP to work without explicitly
>>> managing the hclk_vo1 clock. However, this is not safe or explicit.
>>>
>>> To make the clock dependency explicit, enforce per-SoC clock-names
>>> requirements:
>>>   - RK3288: 2 clocks (dp, pclk)
>>>   - RK3399: 3 clocks (dp, pclk, grf)
>>>   - RK3588: 3 clocks (dp, pclk, hclk)
>>>
>>> Do not reuse the 'grf' clock name for RK3588 because it represents
>>> a different clock with distinct control logic:
>>> - The 'grf' clock is only for GRF register access and is toggled
>>>    dynamically during register access.
>>> - The 'hclk' clock controls both GRF access and video datapath
>>>    gating, and must remain enabled during probe.
>>>
>>> Fixes: f855146263b1 ("dt-bindings: display: rockchip: analogix-dp: 
>>> Add support for RK3588")
>>> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>>>
>>> ---
>>>
>>> Changes in v4:
>>> - Modify the commit msg.
>>>
>>> Changes in v5:
>>> - Enforce the correct third clock name on a per-compatible basis.
>>> - Modify the commit msg simultaneously.
>>>
>>> Changes in v6:
>>> - Expand more detail commit msg about using hclk instead of grf clock.
>>>
>>> Changes in v7:
>>> - List all valid clock names at the top level, and constrain the clock
>>>    count for each platform with minItems/maxItems in allOf.
>>>
>>> Changes in v8:
>>> - Fix indentation to 10 for enum in clock-names property.
>>> ---
>>>   .../rockchip/rockchip,analogix-dp.yaml        | 34 ++++++++++++++++++-
>>>   1 file changed, 33 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/display/rockchip/ 
>>> rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/ 
>>> display/rockchip/rockchip,analogix-dp.yaml
>>> index d99b23b88cc5..a1ab7a77bdd3 100644
>>> --- a/Documentation/devicetree/bindings/display/rockchip/ 
>>> rockchip,analogix-dp.yaml
>>> +++ b/Documentation/devicetree/bindings/display/rockchip/ 
>>> rockchip,analogix-dp.yaml
>>> @@ -26,7 +26,9 @@ properties:
>>>       items:
>>>         - const: dp
>>>         - const: pclk
>>> -      - const: grf
>>> +      - enum:
>>> +          - grf
>>> +          - hclk
>>>     power-domains:
>>>       maxItems: 1
>>> @@ -60,6 +62,32 @@ required:
>>>   allOf:
>>>     - $ref: /schemas/display/bridge/analogix,dp.yaml#
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            enum:
>>> +              - rockchip,rk3288-dp
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          maxItems: 2
>>> +        clock-names:
>>> +          maxItems: 2
>>> +
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            enum:
>>> +              - rockchip,rk3399-edp
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          minItems: 3
>>> +        clock-names:
>>> +          minItems: 3
>>
>> If you go back to v6, you'll see that I never asked you to remove the
>> explict clock-names from here or below. Only the one from the 3288
>> section. The minItems was an addition, not a replacement.
>>
>> pw-bot: changes-requested
>>
> 
> Sorry for the misunderstanding. I will restore the explicit clock-names 
> definitions and fix this in next version.
> 

Sorry to bother you. I attempted to place the explicit clock-names under 
minItems:

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
index a1ab7a77bdd3..ef03edf52de8 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
+++ 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
@@ -87,6 +87,10 @@ allOf:
            minItems: 3
          clock-names:
            minItems: 3
+          items:
+            - const: dp
+            - const: pclk
+            - const: grf

    - if:
        properties:
@@ -100,6 +104,10 @@ allOf:
            minItems: 3
          clock-names:
            minItems: 3
+          items:
+            - const: dp
+            - const: pclk
+            - const: hclk
          resets:
            minItems: 2
          reset-names:

make dt_binding_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml

Then the following errors occurred:

   SCHEMA  Documentation/devicetree/bindings/processed-schema.json
   CHKDT   ./Documentation/devicetree/bindings
/home/ding/drm-misc/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml: 
allOf:2:then:properties:clock-names: 'oneOf' conditional failed, one 
must be fixed:
         False schema does not allow 3
         [{'const': 'dp'}, {'const': 'pclk'}, {'const': 'grf'}] is too long
         [{'const': 'dp'}, {'const': 'pclk'}, {'const': 'grf'}] is too short
         1 was expected
         3 is greater than the maximum of 2
         hint: "minItems" is only needed if less than the "items" list 
length
         from schema $id: http://devicetree.org/meta-schemas/items.yaml
/home/ding/drm-misc/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml: 
allOf:3:then:properties:clock-names: 'oneOf' conditional failed, one 
must be fixed:
         False schema does not allow 3
         [{'const': 'dp'}, {'const': 'pclk'}, {'const': 'hclk'}] is too long
         [{'const': 'dp'}, {'const': 'pclk'}, {'const': 'hclk'}] is too 
short
         1 was expected
         3 is greater than the maximum of 2
         hint: "minItems" is only needed if less than the "items" list 
length
         from schema $id: http://devicetree.org/meta-schemas/items.yaml
   LINT    ./Documentation/devicetree/bindings
   DTEX 
Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.example.dts
   DTC [C] 
Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.example.dtb

Neither keeping only minItems nor only the explicit clock-names causes 
any errors. Would it be a better idea to keep just the explicit 
clock-names here?

Best regards,
Damon

> 
>>
>>> +
>>>     - if:
>>>         properties:
>>>           compatible:
>>> @@ -68,6 +96,10 @@ allOf:
>>>                 - rockchip,rk3588-edp
>>>       then:
>>>         properties:
>>> +        clocks:
>>> +          minItems: 3
>>> +        clock-names:
>>> +          minItems: 3
>>>           resets:
>>>             minItems: 2
>>>           reset-names:
>>> -- 
>>> 2.34.1
>>>
>>>
> 
> 
> 



^ permalink raw reply

* [PATCH v2] irqchip/gic-v4: Harden against bogus command line
From: Mostafa Saleh @ 2026-05-26 11:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: maz, tglx, Mostafa Saleh

When accidentally setting “kvm-arm.vgic_v4_enable=1” on the wrong
setup that has no MSI controller device tree node (it exists but
not used) and GICv4, it caused a panic as “gic_domain” is NULL and
the kernel attempted to access its ops.

Originally, I hit this on an older kernel, but was able to reproduce
it on upstream with Qemu by hacking this unreasonable setup.

[   33.145536] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
[   33.145658] Mem abort info:
[   33.145751]   ESR = 0x0000000096000006
...
[   33.154057] CPU: 1 UID: 0 PID: 295 Comm: lkvm-static Not tainted 7.1.0-rc4-ge3f15ad3970e #5 PREEMPT
[   33.156922] Hardware name: linux,dummy-virt (DT)
[   33.158780] pstate: 81402005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
[   33.160340] pc : __irq_domain_instantiate+0x1d4/0x578
[   33.162602] lr : __irq_domain_instantiate+0x1cc/0x578

Set vLPI support to false at init time if the host has no ITS, so it
propagates properly to kvm_vgic_global_state.has_gicv4.

Suggested-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>

---
v2: Fix the issue at construction as Marc suggested.
---
 drivers/irqchip/irq-gic-v3-its.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 291d7668cc8d..d02cb9c17c0b 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -5837,6 +5837,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 		its_acpi_probe();
 
 	if (list_empty(&its_nodes)) {
+		rdists->has_vlpis = false;
 		pr_warn("ITS: No ITS available, not enabling LPIs\n");
 		return -ENXIO;
 	}
-- 
2.54.0.746.g67dd491aae-goog



^ permalink raw reply related

* [PATCH RFC v8 22/24] arm64: kpkeys: Batch KPKEYS_CTX_PGTABLES switches
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

The kpkeys_hardened_pgtables feature currently switches kpkeys
context in every helper that writes to page tables, such as
set_pte(). With kpkeys implemented using POE, this entails a pair of
ISBs whenever such helper is called.

A simple way to reduce this overhead is to make use of the lazy MMU
mode. We amend the kpkeys_hardened_pgtables guard so that no kpkeys
context switch (i.e. POR_EL1 update) is issued while the lazy MMU
mode is active. Instead, we switch to KPKEYS_CTX_PGTABLES when
entering the lazy MMU mode, and restore the previous context when
exiting it.

Restoring the previous kpkeys context requires storing the original
value of POR_EL1 somewhere. This is a full 64-bit value so we cannot
simply use a TIF flag. There is no straightforward way to reuse
current->thread.por_el1 for that purpose - this is where the current
value of POR_EL1 is stored on a context switch, i.e. the value
corresponding to KPKEYS_CTX_PGTABLES inside a lazy_mmu section.
Instead, we add a new member to thread_struct to hold that value
temporarily. This isn't optimal as that member is unused outside of
lazy MMU sections, but it is the simplest option. Nesting of
sections is not a concern as arch_{enter,leave}_lazy_mmu_mode() are
not called in inner sections (nor do we need to do anything there).

A further optimisation this patch makes is to merge the ISBs when
exiting lazy_mmu mode. That is, if an ISB is going to be issued by
emit_pte_barriers() because kernel pgtables were modified in the
lazy MMU section, we skip the ISB after restoring POR_EL1. This is
done by checking TIF_LAZY_MMU_PENDING and ensuring that POR_EL1 is
restored before emit_pte_barriers() is called.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/include/asm/pgtable.h   | 50 +++++++++++++++++++++++++++++++++++---
 arch/arm64/include/asm/processor.h |  1 +
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 20072f32677d..1c0dcfd14678 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -43,10 +43,44 @@
 
 #ifdef CONFIG_KPKEYS_HARDENED_PGTABLES
 KPKEYS_GUARD_COND(kpkeys_hardened_pgtables, KPKEYS_CTX_PGTABLES,
-		  kpkeys_hardened_pgtables_enabled())
-#else
+		  kpkeys_hardened_pgtables_enabled() &&
+		  !is_lazy_mmu_mode_active())
+
+static void kpkeys_lazy_mmu_enter(void)
+{
+	if (!kpkeys_hardened_pgtables_enabled())
+		return;
+
+	current->thread.por_el1_lazy_mmu = kpkeys_set_context(KPKEYS_CTX_PGTABLES);
+}
+
+static void kpkeys_lazy_mmu_exit(void)
+{
+	u64 saved_por_el1;
+
+	if (!kpkeys_hardened_pgtables_enabled())
+		return;
+
+	saved_por_el1 = current->thread.por_el1_lazy_mmu;
+
+	/*
+	 * We skip any barrier if TIF_LAZY_MMU_PENDING is set:
+	 * emit_pte_barriers() will issue an ISB just after this function
+	 * returns.
+	 */
+	if (test_thread_flag(TIF_LAZY_MMU_PENDING))
+		__kpkeys_set_pkey_reg_nosync(saved_por_el1);
+	else
+		arch_kpkeys_restore_pkey_reg(saved_por_el1);
+}
+#else /* CONFIG_KPKEYS_HARDENED_PGTABLES */
 KPKEYS_GUARD_NOOP(kpkeys_hardened_pgtables)
-#endif
+
+static void kpkeys_lazy_mmu_enter(void) {}
+static void kpkeys_lazy_mmu_exit(void) {}
+#endif /* CONFIG_KPKEYS_HARDENED_PGTABLES */
+
+
 
 static inline void emit_pte_barriers(void)
 {
@@ -79,7 +113,10 @@ static inline void queue_pte_barriers(void)
 	}
 }
 
-static inline void arch_enter_lazy_mmu_mode(void) {}
+static inline void arch_enter_lazy_mmu_mode(void)
+{
+	kpkeys_lazy_mmu_enter();
+}
 
 static inline void arch_flush_lazy_mmu_mode(void)
 {
@@ -89,6 +126,11 @@ static inline void arch_flush_lazy_mmu_mode(void)
 
 static inline void arch_leave_lazy_mmu_mode(void)
 {
+	/*
+	 * The ordering should be preserved to allow kpkeys_lazy_mmu_exit()
+	 * to skip any barrier when TIF_LAZY_MMU_PENDING is set.
+	 */
+	kpkeys_lazy_mmu_exit();
 	arch_flush_lazy_mmu_mode();
 }
 
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6095322343fc..c3a86ddce637 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -193,6 +193,7 @@ struct thread_struct {
 	u64			tpidr2_el0;
 	u64			por_el0;
 	u64			por_el1;
+	u64			por_el1_lazy_mmu;
 #ifdef CONFIG_ARM64_GCS
 	unsigned int		gcs_el0_mode;
 	unsigned int		gcs_el0_locked;

-- 
2.51.2



^ permalink raw reply related

* [PATCH RFC v8 24/24] mm: Add basic tests for kpkeys_hardened_pgtables
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

Add basic tests for the kpkeys_hardened_pgtables feature: try to
perform direct writes to kernel and user page table entries and
ensure they fail.

Multiple cases are considered for kernel page tables, as early page
tables are allocated and/or protected in a different way.

The tests are builtin (cannot be built as a module) because they
refer to multiple symbols that are not exported (e.g.
copy_to_kernel_nofault()).

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 mm/Makefile                               |   1 +
 mm/tests/kpkeys_hardened_pgtables_kunit.c | 200 ++++++++++++++++++++++++++++++
 security/Kconfig.hardening                |  12 ++
 3 files changed, 213 insertions(+)

diff --git a/mm/Makefile b/mm/Makefile
index 7603e6051afa..9ebdbaa696b2 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -151,3 +151,4 @@ obj-$(CONFIG_EXECMEM) += execmem.o
 obj-$(CONFIG_TMPFS_QUOTA) += shmem_quota.o
 obj-$(CONFIG_LAZY_MMU_MODE_KUNIT_TEST) += tests/lazy_mmu_mode_kunit.o
 obj-$(CONFIG_KPKEYS_HARDENED_PGTABLES) += kpkeys_hardened_pgtables.o
+obj-$(CONFIG_KPKEYS_HARDENED_PGTABLES_KUNIT_TEST) += tests/kpkeys_hardened_pgtables_kunit.o
diff --git a/mm/tests/kpkeys_hardened_pgtables_kunit.c b/mm/tests/kpkeys_hardened_pgtables_kunit.c
new file mode 100644
index 000000000000..cab0c2e66500
--- /dev/null
+++ b/mm/tests/kpkeys_hardened_pgtables_kunit.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <kunit/test.h>
+#include <linux/mman.h>
+#include <linux/pgtable.h>
+#include <linux/set_memory.h>
+#include <linux/vmalloc.h>
+
+static void free_page_wrapper(void *ctx)
+{
+	__free_page((struct page *)ctx);
+}
+
+KUNIT_DEFINE_ACTION_WRAPPER(vfree_wrapper, vfree, const void *);
+
+static pud_t *pud_off_k(unsigned long va)
+{
+	return pud_offset(p4d_offset(pgd_offset_k(va), va), va);
+}
+
+static pte_t *get_kernel_pte(unsigned long addr)
+{
+	pmd_t *pmdp = pmd_off_k(addr);
+
+	if (!pmdp || pmd_leaf(*pmdp))
+		return NULL;
+
+	return pte_offset_kernel(pmdp, addr);
+}
+
+#define write_pgtable(type, ptr) do {					\
+	type##_t val;							\
+	int ret;							\
+									\
+	pr_debug("%s: writing to "#type" at %px\n", __func__, (ptr));	\
+									\
+	val = type##p_get(ptr);						\
+	ret = copy_to_kernel_nofault(ptr, &val, sizeof(val));		\
+	KUNIT_EXPECT_EQ_MSG(test, ret, -EFAULT,				\
+			    "Direct "#type" write wasn't prevented");	\
+} while (0)
+
+/*
+ * Try to write linear map page tables, at every level. This is worthwhile
+ * because those page table pages are obtained from different allocators:
+ *
+ * - Static memory (part of the kernel image) for PGD
+ * - memblock for PUD and possibly PMD/PTE
+ * - pagetable_alloc() (buddy allocator) for PMD/PTE if large block mappings are
+ *   used and the linear map is split after being created
+ */
+static void write_direct_map_pgtables(struct kunit *test)
+{
+	struct page *page;
+	unsigned long addr;
+	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int ret;
+
+	if (!kpkeys_enabled())
+		kunit_skip(test, "kpkeys are not supported");
+
+	page = alloc_page(GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, page);
+	ret = kunit_add_action_or_reset(test, free_page_wrapper, page);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	/* Ensure page is PTE-mapped (splitting the linear map if necessary) */
+	ret = set_direct_map_invalid_noflush(page);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+	ret = set_direct_map_default_noflush(page);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	addr = (unsigned long)page_address(page);
+
+	pgdp = pgd_offset_k(addr);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, pgdp, "Failed to get PGD");
+	/*
+	 * swapper_pg_dir is still writable at this stage, so don't check it.
+	 * It is not protected by kpkeys_hardened_pgtables because it should be
+	 * made read-only by mark_rodata_ro(). However since these
+	 * KUnit tests are builtin, they are run before mark_rodata_ro() is
+	 * called.
+	 */
+
+	p4dp = p4d_offset(pgdp, addr);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, p4dp, "Failed to get P4D");
+	if (!mm_p4d_folded(&init_mm))
+		write_pgtable(p4d, p4dp);
+
+	pudp = pud_offset(p4dp, addr);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, pudp, "Failed to get PUD");
+	if (!mm_pud_folded(&init_mm))
+		write_pgtable(pud, pudp);
+
+	pmdp = pmd_offset(pudp, addr);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, pmdp, "Failed to get PMD");
+	write_pgtable(pmd, pmdp);
+
+	ptep = pte_offset_kernel(pmdp, addr);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, ptep, "Failed to get PTE");
+	write_pgtable(pte, ptep);
+}
+
+/* Worth checking since the kernel image is mapped with static page tables */
+static void write_kernel_image_pud(struct kunit *test)
+{
+	pud_t *pudp;
+
+	if (!kpkeys_enabled())
+		kunit_skip(test, "kpkeys are not supported");
+
+	/* The kernel is probably block-mapped, check the PUD to be safe */
+	pudp = pud_off_k((unsigned long)&init_mm);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, pudp, "Failed to get PUD");
+
+	write_pgtable(pud, pudp);
+}
+
+static void write_kernel_vmalloc_pte(struct kunit *test)
+{
+	void *mem;
+	pte_t *ptep;
+	int ret;
+
+	if (!kpkeys_enabled())
+		kunit_skip(test, "kpkeys are not supported");
+
+	mem = vmalloc(PAGE_SIZE);
+	KUNIT_ASSERT_NOT_NULL(test, mem);
+	ret = kunit_add_action_or_reset(test, vfree_wrapper, mem);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	/* vmalloc() without VM_ALLOW_HUGE_VMAP is PTE-mapped */
+	ptep = get_kernel_pte((unsigned long)mem);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, ptep, "Failed to get PTE");
+
+	write_pgtable(pte, ptep);
+}
+
+static void write_vmemmap_pmd(struct kunit *test)
+{
+	struct page *page;
+	pmd_t *pmdp;
+
+	if (!kpkeys_enabled())
+		kunit_skip(test, "kpkeys are not supported");
+
+	/*
+	 * We just need the address of some struct page, so we can free the
+	 * page right away.
+	 */
+	page = alloc_page(GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, page);
+	__free_page(page);
+
+	/* vmemmap may use PMD block mappings */
+	pmdp = pmd_off_k((unsigned long)page);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, pmdp, "Failed to get PMD");
+	write_pgtable(pmd, pmdp);
+}
+
+static void write_user_pmd(struct kunit *test)
+{
+	pmd_t *pmdp;
+	unsigned long uaddr;
+
+	if (!kpkeys_enabled())
+		kunit_skip(test, "kpkeys are not supported");
+
+	uaddr = kunit_vm_mmap(test, NULL, 0, PAGE_SIZE, PROT_READ,
+			      MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, 0);
+	KUNIT_ASSERT_NE_MSG(test, uaddr, 0, "Could not create userspace mm");
+
+	/* We passed MAP_POPULATE so a PMD should already be allocated */
+	pmdp = pmd_off(current->mm, uaddr);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, pmdp, "Failed to get PMD");
+
+	write_pgtable(pmd, pmdp);
+}
+
+static struct kunit_case kpkeys_hardened_pgtables_test_cases[] = {
+	KUNIT_CASE(write_direct_map_pgtables),
+	KUNIT_CASE(write_kernel_image_pud),
+	KUNIT_CASE(write_kernel_vmalloc_pte),
+	KUNIT_CASE(write_vmemmap_pmd),
+	KUNIT_CASE(write_user_pmd),
+	{}
+};
+
+static struct kunit_suite kpkeys_hardened_pgtables_test_suite = {
+	.name = "kpkeys_hardened_pgtables",
+	.test_cases = kpkeys_hardened_pgtables_test_cases,
+};
+kunit_test_suite(kpkeys_hardened_pgtables_test_suite);
+
+MODULE_DESCRIPTION("Tests for the kpkeys_hardened_pgtables feature");
+MODULE_LICENSE("GPL");
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
index fdaf977d4626..48789f93e933 100644
--- a/security/Kconfig.hardening
+++ b/security/Kconfig.hardening
@@ -287,6 +287,18 @@ config KPKEYS_HARDENED_PGTABLES
 	  This option has no effect if the system does not support
 	  kernel pkeys.
 
+config KPKEYS_HARDENED_PGTABLES_KUNIT_TEST
+	bool "KUnit tests for kpkeys_hardened_pgtables" if !KUNIT_ALL_TESTS
+	depends on KPKEYS_HARDENED_PGTABLES
+	depends on KUNIT=y
+	default KUNIT_ALL_TESTS
+	help
+	  Enable this option to check that the kpkeys_hardened_pgtables feature
+	  functions as intended, i.e. prevents arbitrary writes to user and
+	  kernel page tables.
+
+	  If unsure, say N.
+
 endmenu
 
 config CC_HAS_RANDSTRUCT

-- 
2.51.2



^ permalink raw reply related

* [PATCH RFC v8 23/24] arm64: kpkeys: Enable kpkeys_hardened_pgtables support
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

The kpkeys_hardened_pgtables feature needs to be initialised as soon
as the buddy allocator becomes available. The canonical place to
handle this is mem_init().

With that done, all the bits are in place and we can advertise
support for kpkeys_hardened_pgtables by selecting
ARCH_HAS_KPKEYS_HARDENED_PGTABLES if ARM64_POE is enabled.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/Kconfig   | 1 +
 arch/arm64/mm/init.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ab06324a50ae..43d3ab744535 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2146,6 +2146,7 @@ config ARM64_POE
 	select ARCH_USES_HIGH_VMA_FLAGS
 	select ARCH_HAS_PKEYS
 	select ARCH_HAS_KPKEYS
+	select ARCH_HAS_KPKEYS_HARDENED_PGTABLES
 	help
 	  The Permission Overlay Extension is used to implement Memory
 	  Protection Keys. Memory Protection Keys provides a mechanism for
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 97987f850a33..7985045875cf 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -386,6 +386,7 @@ bool page_alloc_available __ro_after_init;
 void __init mem_init(void)
 {
 	page_alloc_available = true;
+	kpkeys_hardened_pgtables_init();
 	swiotlb_update_mem_attributes();
 }
 

-- 
2.51.2



^ permalink raw reply related

* [PATCH RFC v8 21/24] arm64: kpkeys: Guard page table writes
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

When CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, page tables (both
user and kernel) are mapped with a privileged pkey in the linear
mapping. As a result, they can only be written in a privileged
kpkeys context.

Introduce a kpkeys guard that sets POR_EL1 appropriately to allow
writing to page tables, and use this guard wherever necessary. The
scope is kept as small as possible, so that POR_EL1 is quickly reset
to its default value. Where atomics are involved, the guard's scope
encompasses the whole loop to avoid switching POR_EL1 unnecessarily.

This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
(default).

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/include/asm/pgtable.h | 22 +++++++++++++++++++++-
 arch/arm64/mm/fault.c            | 17 ++++++++++-------
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 4dfa42b7d053..20072f32677d 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -39,6 +39,14 @@
 #include <linux/mm_types.h>
 #include <linux/sched.h>
 #include <linux/page_table_check.h>
+#include <linux/kpkeys.h>
+
+#ifdef CONFIG_KPKEYS_HARDENED_PGTABLES
+KPKEYS_GUARD_COND(kpkeys_hardened_pgtables, KPKEYS_CTX_PGTABLES,
+		  kpkeys_hardened_pgtables_enabled())
+#else
+KPKEYS_GUARD_NOOP(kpkeys_hardened_pgtables)
+#endif
 
 static inline void emit_pte_barriers(void)
 {
@@ -359,6 +367,7 @@ static inline pte_t pte_clear_uffd_wp(pte_t pte)
 
 static inline void __set_pte_nosync(pte_t *ptep, pte_t pte)
 {
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*ptep, pte);
 }
 
@@ -830,6 +839,7 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 	}
 #endif /* __PAGETABLE_PMD_FOLDED */
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*pmdp, pmd);
 
 	if (pmd_valid(pmd))
@@ -894,6 +904,7 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
 		return;
 	}
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*pudp, pud);
 
 	if (pud_valid(pud))
@@ -975,6 +986,7 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
 		return;
 	}
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*p4dp, p4d);
 	queue_pte_barriers();
 }
@@ -1103,6 +1115,7 @@ static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
 		return;
 	}
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*pgdp, pgd);
 	queue_pte_barriers();
 }
@@ -1307,6 +1320,7 @@ static inline bool __ptep_test_and_clear_young(struct vm_area_struct *vma,
 {
 	pte_t old_pte, pte;
 
+	guard(kpkeys_hardened_pgtables)();
 	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
@@ -1354,7 +1368,10 @@ static inline pte_t __ptep_get_and_clear_anysz(struct mm_struct *mm,
 					       pte_t *ptep,
 					       unsigned long pgsize)
 {
-	pte_t pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
+	pte_t pte;
+
+	scoped_guard(kpkeys_hardened_pgtables)
+		pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
 
 	switch (pgsize) {
 	case PAGE_SIZE:
@@ -1427,6 +1444,7 @@ static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
 {
 	pte_t old_pte;
 
+	guard(kpkeys_hardened_pgtables)();
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
@@ -1460,6 +1478,7 @@ static inline void __clear_young_dirty_pte(struct vm_area_struct *vma,
 {
 	pte_t old_pte;
 
+	guard(kpkeys_hardened_pgtables)();
 	do {
 		old_pte = pte;
 
@@ -1507,6 +1526,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
 		unsigned long address, pmd_t *pmdp, pmd_t pmd)
 {
 	page_table_check_pmd_set(vma->vm_mm, address, pmdp, pmd);
+	guard(kpkeys_hardened_pgtables)();
 	return __pmd(xchg_relaxed(&pmd_val(*pmdp), pmd_val(pmd)));
 }
 #endif
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 739800835920..35f9b702f87d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -227,13 +227,16 @@ int __ptep_set_access_flags_anysz(struct vm_area_struct *vma,
 	 */
 	pte_val(entry) ^= PTE_RDONLY;
 	pteval = pte_val(pte);
-	do {
-		old_pteval = pteval;
-		pteval ^= PTE_RDONLY;
-		pteval |= pte_val(entry);
-		pteval ^= PTE_RDONLY;
-		pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval);
-	} while (pteval != old_pteval);
+	scoped_guard(kpkeys_hardened_pgtables) {
+		do {
+			old_pteval = pteval;
+			pteval ^= PTE_RDONLY;
+			pteval |= pte_val(entry);
+			pteval ^= PTE_RDONLY;
+			pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval,
+						 pteval);
+		} while (pteval != old_pteval);
+	}
 
 	/*
 	 * Invalidate the local stale read-only entry.  Remote stale entries

-- 
2.51.2



^ permalink raw reply related

* [PATCH RFC v8 20/24] arm64: kpkeys: Protect init_pg_dir
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

When kpkeys_hardened_pgtables is enabled, protect the page tables
that map the kernel image by setting the appropriate pkey for the
linear mapping of those pages.

Most other static page tables (e.g. swapper_pg_dir) should be
read-only both in the kernel image mapping and the linear mapping,
so there is no need to change their pkey.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/include/asm/kpkeys.h |  7 +++++++
 arch/arm64/mm/mmu.c             | 13 +++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/arch/arm64/include/asm/kpkeys.h b/arch/arm64/include/asm/kpkeys.h
index c1daab643195..382ae27532e3 100644
--- a/arch/arm64/include/asm/kpkeys.h
+++ b/arch/arm64/include/asm/kpkeys.h
@@ -64,6 +64,13 @@ static __always_inline void arch_kpkeys_restore_pkey_reg(u64 pkey_reg)
 
 #endif /* CONFIG_ARM64_POE */
 
+#ifdef CONFIG_KPKEYS_HARDENED_PGTABLES
+
+#define arch_kpkeys_protect_static_pgtables arch_kpkeys_protect_static_pgtables
+void arch_kpkeys_protect_static_pgtables(void);
+
+#endif /* CONFIG_KPKEYS_HARDENED_PGTABLES */
+
 #endif	/* __ASSEMBLY__ */
 
 #endif	/* __ASM_KPKEYS_H */
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a9cc189affd8..072500579c94 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1055,6 +1055,19 @@ void __init mark_linear_text_alias_ro(void)
 			    PAGE_KERNEL_RO);
 }
 
+#ifdef CONFIG_KPKEYS_HARDENED_PGTABLES
+void __init arch_kpkeys_protect_static_pgtables(void)
+{
+	extern char __pi_init_pg_dir[], __pi_init_pg_end[];
+	unsigned long addr = (unsigned long)lm_alias(__pi_init_pg_dir);
+	unsigned long size = __pi_init_pg_end - __pi_init_pg_dir;
+	int ret;
+
+	ret = set_memory_pkey(addr, size / PAGE_SIZE, KPKEYS_PKEY_PGTABLES);
+	WARN_ON(ret);
+}
+#endif /* CONFIG_KPKEYS_HARDENED_PGTABLES */
+
 #ifdef CONFIG_KFENCE
 
 bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL;

-- 
2.51.2



^ permalink raw reply related

* [PATCH RFC v8 19/24] arm64: kpkeys: Protect early page tables
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

Use the dedicated kpkeys allocator for early page tables (used to create
the linear map) when the kpkeys_hardened_pgtables feature is enabled.

CPU features have not been detected at this stage so we use the
early_enabled() helper. This is not a concern as
kpkeys_physmem_pgtable_alloc() does not itself use POE or
set_memory_pkey().

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/mm/mmu.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index c67b46592af6..a9cc189affd8 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -109,8 +109,11 @@ static phys_addr_t __init early_pgtable_alloc(enum pgtable_level pgtable_level)
 {
 	phys_addr_t phys;
 
-	phys = memblock_phys_alloc_range(PAGE_SIZE, PAGE_SIZE, 0,
-					 MEMBLOCK_ALLOC_NOLEAKTRACE);
+	if (kpkeys_hardened_pgtables_early_enabled())
+		phys = kpkeys_physmem_pgtable_alloc();
+	else
+		phys = memblock_phys_alloc_range(PAGE_SIZE, PAGE_SIZE, 0,
+						 MEMBLOCK_ALLOC_NOLEAKTRACE);
 	if (!phys)
 		panic("Failed to allocate page table page\n");
 

-- 
2.51.2



^ permalink raw reply related

* Re: [PATCH] perf cs-etm: stamp pid/tid/EL on each buffered packet to fix cross-pid attribution
From: James Clark @ 2026-05-26 11:18 UTC (permalink / raw)
  To: Amir Ayupov
  Cc: stable, Suzuki K Poulose, Mike Leach, Leo Yan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	John Garry, Will Deacon, coresight, linux-arm-kernel,
	linux-perf-users, linux-kernel
In-Reply-To: <20260515021135.1729028-1-aaupov@meta.com>



On 15/05/2026 3:11 am, Amir Ayupov wrote:
> In a system-wide `perf record -e cs_etm/.../u` capture on aarch64,
> synthesized samples emitted by `perf script --itrace=il64` are
> sometimes attributed to the WRONG sample.pid/tid (and to the wrong
> EL/cpumode) for the chunk of branches that straddle a context-switch
> boundary on a CPU. A branch actually retired by process A is emitted
> with sample.pid set to the thread that next ran on the same CPU.
> 
> Mechanism:
>    1. ETM emits CONTEXTIDR/EL packets in-stream when the kernel updates
>       CONTEXTIDR_EL1 on context switch / EL change. OpenCSD turns these
>       into OCSD_GEN_TRC_ELEM_PE_CONTEXT elements interleaved with
>       OCSD_GEN_TRC_ELEM_INSTR_RANGE elements for retired branch ranges.
>    2. cs_etm_decoder__buffer_range() queues each INSTR_RANGE into
>       packet_queue->packet_buffer[]; packets carry start/end addrs,
>       instr_count, last-instruction info, etc., but NO owner identity.
>    3. PE_CONTEXT goes through cs_etm_decoder__set_tid() ->
>       cs_etm__set_thread(), which immediately mutates tidq->thread and
>       tidq->el. Queued packets are not drained first; reset_timestamp()
>       is called so the next TIMESTAMP triggers OCSD_RESP_WAIT and a
>       drain.
>    4. By drain time in cs_etm__process_traceid_queue() ->
>       cs_etm__sample(), sample.pid/tid is read from the now-mutated
>       tidq->thread and sample.cpumode from the now-mutated tidq->el.
>       Pre-context INSTR_RANGEs get the post-context owner.
> 
> The same race affects branch samples via tidq->prev_packet_thread /
> tidq->prev_packet_el, captured at packet-swap time from
> tidq->thread / tidq->el (which may already have flipped).
> 
> This is independent of PERF_RECORD_SWITCH_CPU_WIDE, which is
> deliberately not used to assign sample identity in this path. The
> bug applies to any cs_etm capture with in-stream CONTEXTIDR
> (PIDFMT_CTXTID or PIDFMT_CTXTID2).
> 
> Effect on downstream tools: branches that should belong to the
> previous thread on the CPU get attributed to the next thread. When
> the two threads share a binary, leaked branches' VAs land in the
> wrong thread's mappings; samples whose IPs land in r-x mappings
> silently pollute that binary's profile, while samples landing in
> R-only/RW mappings show up as out-of-range / non-text samples.
> Either way, AutoFDO/BOLT profiles built from `perf script --itrace`
> output of system-wide cs_etm captures contain misattributed samples.
> 
> Concrete example from `perf script --itrace=il64` of the same
> captured branch (same timestamp, same IP, same from/to addrs) before
> and after this fix:
> 
>    before: launcher_multia 2638146/2638146 705897.219172: \
>                fffcda6b124c 0xfffcda641958/0xfffcda6b123c
>    after:  ws-tcf-sr-io13  2736581/2741587 705897.219172: \
>                fffcda6b124c 0xfffcda641958/0xfffcda6b123c
> 
> The branch was retired by ws-tcf-sr-io13 (tid 2741587) but, before
> the fix, was attributed to launcher_multia (the next thread to run on
> that CPU after the context switch). After the fix, it is correctly
> attributed to ws-tcf-sr-io13.
> 
> Why not "drain on PE_CONTEXT then switch" (deferred-set_thread):
> tidq->thread has two consumers \u2014 sample emission needs the OUTGOING
> identity for queued packets, but cs_etm__mem_access() needs the
> CURRENT thread's maps to fetch instruction bytes for OpenCSD. The
> two needs are temporally inverted; a single tidq->thread cannot
> serve both. Keeping tidq->thread current and stamping owner identity
> per packet is the only design that decouples them cleanly.
> 
> Fix: capture the owning pid/tid/EL on each buffered packet at
> cs_etm_decoder__buffer_packet() time (before any subsequent
> PE_CONTEXT can mutate tidq->thread / tidq->el), and read them at
> sample emission time.
> 
>    - struct cs_etm_packet gains pid_t pid, pid_t tid, int el (storing
>      an ocsd_ex_level value; typed as int so the struct does not
>      depend on OpenCSD headers, which are only included inside
>      HAVE_CSTRACE_SUPPORT).
>    - cs_etm__etmq_get_pid_tid_el() (formerly cs_etm__etmq_get_pid_tid)
>      returns all three.
>    - cs_etm__synth_instruction_sample() reads sample.pid / sample.tid
>      from tidq->packet->{pid,tid} and derives sample.cpumode from
>      tidq->packet->el.
>    - cs_etm__synth_branch_sample() reads sample.pid / sample.tid /
>      cpumode from tidq->prev_packet->{pid,tid,el}.
>    - The separate prev_packet_thread / prev_packet_el bookkeeping in
>      cs_etm__packet_swap() / cs_etm__init_traceid_queue() /
>      cs_etm__free_traceid_queues() is removed; the per-packet stamp
>      on prev_packet now carries that information.
> 
> Cost: 12 bytes added to struct cs_etm_packet (~12-16 KB per
> packet_queue with CS_ETM_PACKET_MAX_BUFFER=1024), 16 bytes saved per
> cs_etm_traceid_queue (one struct thread * + one ocsd_ex_level).
> 
> A residual gap: cs_etm__copy_insn() reads sample.insn bytes via
> cs_etm__mem_access(), which still uses tidq->thread (the current
> thread), so the inline insn bytes for an outgoing-thread sample may
> be looked up against the wrong address space. Fixing this requires
> threading the packet's owner pid through cs_etm__mem_access and is
> left for a follow-up. sample.ip / sample.pid attribution \u2014 what
> AutoFDO/BOLT consume \u2014 is correct.
> 


Hi Amir,

Can you test the patch here to see if it fixes your issue [1]?

We thought it didn't make sense to store the thread on every packet when 
there is only one active thread for the decoder and one for sample 
generation. We also fixed the other issue mentioned above about 
cs_etm__copy_insn() not working.

Thanks
James

[1]: 
https://lore.kernel.org/linux-perf-users/20260526-james-cs-context-tracking-fix-v1-0-ebd602e18287@linaro.org/T/#t



^ permalink raw reply

* [PATCH RFC v8 18/24] arm64: kpkeys: Ensure the linear map can be modified
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

When the kpkeys_hardened_pgtables feature is enabled, we need to be
able to modify attributes (specifically the pkey/POIndex) in the
linear map at page granularity.

Add the appropriate check to can_set_direct_map() on the same
principle as rodata_full and other features.

kpkeys_hardened_pgtables currently requires the linear map to be
fully PTE-mapped, so we also need to ensure that force_pte_mapping()
returns true, like for DEBUG_PAGEALLOC.

Both functions can be called very early, before POE is actually
detected, so the early_enabled() helper is used.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/mm/mmu.c      | 2 +-
 arch/arm64/mm/pageattr.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index dc69553d6326..c67b46592af6 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -760,7 +760,7 @@ static inline bool force_pte_mapping(void)
 	const bool bbml2 = system_capabilities_finalized() ?
 		system_supports_bbml2_noabort() : cpu_supports_bbml2_noabort();
 
-	if (debug_pagealloc_enabled())
+	if (debug_pagealloc_enabled() || kpkeys_hardened_pgtables_early_enabled())
 		return true;
 	if (bbml2)
 		return false;
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 8f3519400bd1..87543ec660f5 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -101,7 +101,8 @@ bool can_set_direct_map(void)
 	 * Realms need to make pages shared/protected at page granularity.
 	 */
 	return rodata_full || debug_pagealloc_enabled() ||
-		arm64_kfence_can_set_direct_map() || is_realm_world();
+		arm64_kfence_can_set_direct_map() || is_realm_world() ||
+		kpkeys_hardened_pgtables_early_enabled();
 }
 
 static int update_range_prot(unsigned long start, unsigned long size,

-- 
2.51.2



^ permalink raw reply related

* [PATCH RFC v8 17/24] arm64: kpkeys: Support KPKEYS_CTX_PGTABLES
From: Kevin Brodsky @ 2026-05-26 11:16 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kevin Brodsky, Andrew Morton, Andy Lutomirski, Catalin Marinas,
	Dave Hansen, David Hildenbrand (Arm), Ira Weiny, Jann Horn,
	Jeff Xu, Joey Gouly, Kees Cook, Linus Walleij, Marc Zyngier,
	Mark Brown, Matthew Wilcox, Maxwell Bland, Mike Rapoport (IBM),
	Peter Zijlstra, Pierre Langlois, Quentin Perret, Rick Edgecombe,
	Ryan Roberts, Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
	linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <20260526-kpkeys-v8-0-eaaacdacc67c@arm.com>

Enable RW access to KPKEYS_PKEY_PGTABLES (used to map page table
pages) if switching to KPKEYS_CTX_PGTABLES, otherwise only grant RO
access.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/include/asm/kpkeys.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kpkeys.h b/arch/arm64/include/asm/kpkeys.h
index fdf3ebe92810..c1daab643195 100644
--- a/arch/arm64/include/asm/kpkeys.h
+++ b/arch/arm64/include/asm/kpkeys.h
@@ -12,7 +12,8 @@
  * Equivalent to por_set_kpkeys_context(0, KPKEYS_CTX_DEFAULT), but can also be
  * used in assembly.
  */
-#define POR_EL1_INIT	POR_ELx_PERM_PREP(KPKEYS_PKEY_DEFAULT, POE_RWX)
+#define POR_EL1_INIT	(POR_ELx_PERM_PREP(KPKEYS_PKEY_DEFAULT, POE_RWX) | \
+			 POR_ELx_PERM_PREP(KPKEYS_PKEY_PGTABLES, POE_R))
 
 #ifndef __ASSEMBLY__
 
@@ -33,6 +34,8 @@ static inline bool arch_supports_kpkeys_early(void)
 static inline u64 por_set_kpkeys_context(u64 por, int ctx)
 {
 	por = por_elx_set_pkey_perms(por, KPKEYS_PKEY_DEFAULT, POE_RWX);
+	por = por_elx_set_pkey_perms(por, KPKEYS_PKEY_PGTABLES,
+				     ctx == KPKEYS_CTX_PGTABLES ? POE_RW : POE_R);
 
 	return por;
 }

-- 
2.51.2



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox