Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 33/33] rust: kbuild: allow `clippy::precedence` for Rust < 1.86.0
From: Gary Guo @ 2026-04-01 15:28 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc
In-Reply-To: <20260401114540.30108-34-ojeda@kernel.org>

On Wed Apr 1, 2026 at 12:45 PM BST, Miguel Ojeda wrote:
> The Clippy `precedence` lint was extended in Rust 1.85.0 to include
> bitmasking and shift operations [1]. However, because it generated
> many hits, in Rust 1.86.0 it was split into a new `precedence_bits`
> lint which is not enabled by default [2].
> 
> In other words, only Rust 1.85 has a different behavior. For instance,
> it reports:
> 
>     warning: operator precedence can trip the unwary
>       --> drivers/gpu/nova-core/fb/hal/ga100.rs:16:5
>        |
>     16 | /     u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::read(bar).adr_39_08()) << FLUSH_SYSMEM_ADDR_SHIFT
>     17 | |         | u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::read(bar).adr_63_40())
>     18 | |             << FLUSH_SYSMEM_ADDR_SHIFT_HI
>        | |_________________________________________^
>        |
>        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#precedence
>        = note: `-W clippy::precedence` implied by `-W clippy::all`
>        = help: to override `-W clippy::all` add `#[allow(clippy::precedence)]`
>     help: consider parenthesizing your expression
>        |
>     16 ~     (u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::read(bar).adr_39_08()) << FLUSH_SYSMEM_ADDR_SHIFT) | (u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::read(bar).adr_63_40())
>     17 +             << FLUSH_SYSMEM_ADDR_SHIFT_HI)
>        |
> 
>     warning: operator precedence can trip the unwary
>        --> drivers/gpu/nova-core/vbios.rs:511:17
>         |
>     511 | /                 u32::from(data[29]) << 24
>     512 | |                     | u32::from(data[28]) << 16
>     513 | |                     | u32::from(data[27]) << 8
>         | |______________________________________________^
>         |
>         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#precedence
>     help: consider parenthesizing your expression
>         |
>     511 ~                 u32::from(data[29]) << 24
>     512 +                     | u32::from(data[28]) << 16 | (u32::from(data[27]) << 8)
>         |
> 
>     warning: operator precedence can trip the unwary
>        --> drivers/gpu/nova-core/vbios.rs:511:17
>         |
>     511 | /                 u32::from(data[29]) << 24
>     512 | |                     | u32::from(data[28]) << 16
>         | |_______________________________________________^ help: consider parenthesizing your expression: `(u32::from(data[29]) << 24) | (u32::from(data[28]) << 16)`
>         |
>         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#precedence
> 
> While so far we try our best to keep all versions Clippy-clean, the
> minimum (which is now Rust 1.85.0 after the bump) and the latest stable
> are the most important ones; and this may be considered "false positives"
> with respect to the behavior in other versions.
> 
> Thus allow this lint for this version using the per-version flags
> mechanism introduced in the previous commit.
> 
> Link: https://github.com/rust-lang/rust-clippy/issues/14097 [1]
> Link: https://github.com/rust-lang/rust-clippy/pull/14115 [2]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

Link: https://lore.kernel.org/rust-for-linux/DFVDKMMA7KPC.2DN0951H3H55Y@kernel.org/
Reviewed-by: Gary Guo <gary@garyguo.net>

> ---
>  Makefile | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)



^ permalink raw reply

* RE: Re: Re: Re: [PATCH 1/2] dt-bindings: gpu: mali-valhall-csf: Document i.MX952 support
From: Guangliu Ding @ 2026-04-01 15:59 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Daniel Baluta (OSS), Daniel Almeida, Alice Ryhl, Boris Brezillon,
	Steven Price, David Airlie, Simona Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam,
	dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, Jiyu Yang
In-Reply-To: <ac05OpEMjKMd8CXy@e142607>

Hi Liviu

> On Wed, Apr 01, 2026 at 10:31:01AM +0000, Guangliu Ding wrote:
> > Hi Liviu
> >
> > > On Wed, Apr 01, 2026 at 09:43:12AM +0000, Guangliu Ding wrote:
> > > > Hi Daniel
> > > >
> > > > > On 4/1/26 11:48, Guangliu Ding wrote:
> > > > > > [You don't often get email from guangliu.ding@nxp.com. Learn
> > > > > > why this is important at
> > > > > > https://aka.ms/LearnAboutSenderIdentification
> > > > > > ]
> > > > > >
> > > > > > Hi Liviu
> > > > > >
> > > > > > Thanks for your review. Please refer to my comments below:
> > > > > >
> > > > > >> On Tue, Mar 31, 2026 at 06:12:38PM +0800, Guangliu Ding wrote:
> > > > > >>> Add compatible string of Mali G310 GPU on i.MX952 board.
> > > > > >>>
> > > > > >>> Signed-off-by: Guangliu Ding <guangliu.ding@nxp.com>
> > > > > >>> Reviewed-by: Jiyu Yang <jiyu.yang@nxp.com>
> > > > > >>> ---
> > > > > >>>
> > > > > >>> Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.y
> > > > > >>> aml
> > > > > >>> | 1
> > > > > >>> +
> > > > > >>>  1 file changed, 1 insertion(+)
> > > > > >>>
> > > > > >>> diff --git
> > > > > >>> a/Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf
> > > > > >>> .yam
> > > > > >>> l
> > > > > >> b/Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.
> > > > > >> yaml
> > > > > >>> index 8eccd4338a2b..6a10843a26e2 100644
> > > > > >>> ---
> > > > > >>> a/Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf
> > > > > >>> .yam
> > > > > >>> l
> > > > > >>> +++ b/Documentation/devicetree/bindings/gpu/arm,mali-valhall
> > > > > >>> +++ -csf
> > > > > >>> +++ .yam
> > > > > >>> +++ l
> > > > > >>> @@ -20,6 +20,7 @@ properties:
> > > > > >>>            - enum:
> > > > > >>>                - mediatek,mt8196-mali
> > > > > >>>                - nxp,imx95-mali            # G310
> > > > > >>> +              - nxp,imx952-mali           # G310
> > > > > >> Can you explain why this is needed? Can it not be covered by
> > > > > >> the existing compatible?
> > > > > > There are functional differences in GPU module (GPUMIX)
> > > > > > between
> > > > > > i.MX95 and i.MX952. So they cannot be fully covered by a
> > > > > > single existing
> > > compatible.
> > > > > > On i.MX952, The GPU clock is controlled by hardware GPU auto
> > > > > > clock-gating mechanism, while the GPU clock is managed
> > > > > > explicitly by the
> > > > > driver on i.MX95.
> > > > > > Because of these behavioral differences, separate compatible
> > > > > > strings "nxp,imx95-mali" and "nxp,imx952-mali" are needed to
> > > > > > allow the driver to handle the two variants independently and
> > > > > > to keep room for future
> > > > > divergence.
> > > > >
> > > > >
> > > > > This information should be added in the commit message
> > > > > explaining why
> > > > >
> > > > > the change is needed.
> > > > >
> > > > >
> > > > > But then where is the driver code taking care of these diferences?
> > > > >
> > > >
> > > > Yes. Currently the driver does not require "nxp,imx952-mali" string.
> > > > However, when GPU ipa_counters are enabled to calculate the GPU
> > > > busy_time/idle_time for GPU DVFS feature, they will conflict with
> > > > the hardware GPU auto clock‑gating mechanism, causing GPU clock to
> > > > remain
> > > always on.
> > > > In such cases, ipa_counters need to be disabled so that the GPU
> > > > auto clock‑gating mechanism can operate normally, using
> "nxp,imx952-mali"
> > > string.
> > >
> > > OK, I understand that you're following guidance from some other
> > > senior people on how to upstream patches so you've tried to create
> > > the smallest patchset to ensure that it gets reviewed and accepted,
> > > but in this case we need to see the other patches as well to decide
> > > if your approach is the right one and we do need a separate compatible
> string.
> > >
> > > If enabling GPU ipa_counters causes the clocks to get stuck active,
> > > that feels like a hardware bug, so figuring out how to handle that
> > > is more important than adding a compatible string.
> > >
> > > Either add the patch(es) that use the compatible to this series in
> > > v2, or put a comment in the commit message on where we can see the
> driver changes.
> > >
> >
> > According to discussions with the GPU vendor, this is a hardware
> > limitation of Mali-G310 rather than a hardware bug, and it has been
> > addressed in newer Mali GPU families.
> 
> I represent the said GPU vendor and I think I know what you're talking about,
> but you're taking the wrong approach. All G310s have a problem where in
> order to enable access to the ipa_counters the automatic clock gating gets
> disabled. So the solution that needs to be implemented when we add support
> for IPA_COUNTERs will apply to all GPUs, not just MX952.

Yes. We have bring-up G310 (V2) GPU on both i.MX95 and i.MX952. And auto clock 
gating mechanism is firstly introduced in i.MX952 (not supported on i.MX95).
According to your update, solution needs to be implemented to all GPUs which support 
auto clock gating mechanism after IPA_COUNTERs are supported in the driver, right?
What's your suggestions for 952 gpu dtb node?
> 
> >
> > In addition, ipa_counters are not enabled in the current Panthor
> > driver. We observed this issue with the private Mali DDK where ipa_counters
> were enabled.
> > Therefore, keeping the compatible string is necessary to allow for future
> divergence.
> 
> This is not an MX952 issue only. You might be aware of it on your SoC, but it's
> not just for it.
> 
> Best regards,
> Liviu
> 
> --
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ¯\_(ツ)_/¯

^ permalink raw reply

* Re: [PATCH v12 2/3] of: Factor arguments passed to of_map_id() into a struct
From: Krzysztof Kozlowski @ 2026-04-01 16:01 UTC (permalink / raw)
  To: Frank Li, Vijayanand Jitta
  Cc: Nipun Gupta, Nikhil Agarwal, Joerg Roedel, Will Deacon,
	Robin Murphy, Marc Zyngier, Lorenzo Pieralisi, Thomas Gleixner,
	Saravana Kannan, Richard Zhu, Lucas Stach,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Dmitry Baryshkov, Konrad Dybcio, Bjorn Andersson, Rob Herring,
	Conor Dooley, Krzysztof Kozlowski, Prakash Gupta, Vikash Garodia,
	linux-kernel, iommu, linux-arm-kernel, devicetree, linux-pci, imx,
	xen-devel, linux-arm-msm, Charan Teja Kalla
In-Reply-To: <acvdqQvcitLTCZbm@lizhi-Precision-Tower-5810>

On 31/03/2026 16:43, Frank Li wrote:
> On Tue, Mar 31, 2026 at 07:34:47PM +0530, Vijayanand Jitta wrote:
>> From: Charan Teja Kalla <charan.kalla@oss.qualcomm.com>
>>
>> Change of_map_id() to take a pointer to struct of_phandle_args
>> instead of passing target device node and translated IDs separately.
>> Update all callers accordingly.
>>
>> Add an explicit filter_np parameter to of_map_id() and of_map_msi_id()
>> to separate the filter input from the output. Previously, the target
>> parameter served dual purpose: as an input filter (if non-NULL, only
>> match entries targeting that node) and as an output (receiving the
>> matched node with a reference held). Now filter_np is the explicit
>> input filter and arg->np is the pure output.
>>
>> Previously, of_map_id() would call of_node_put() on the matched node
>> when a filter was provided, making reference ownership inconsistent.
>> Remove this internal of_node_put() call so that of_map_id() now always
>> transfers ownership of the matched node reference to the caller via
>> arg->np. Callers are now consistently responsible for releasing this
>> reference with of_node_put(arg->np) when done.
>>
>> Suggested-by: Rob Herring (Arm) <robh@kernel.org>
>> Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
>> Signed-off-by: Charan Teja Kalla <charan.kalla@oss.qualcomm.com>
>> Signed-off-by: Vijayanand Jitta <vijayanand.jitta@oss.qualcomm.com>
>> ---
>>  drivers/cdx/cdx_msi.c                    |  7 ++--
>>  drivers/iommu/of_iommu.c                 |  4 +-
>>  drivers/irqchip/irq-gic-its-msi-parent.c | 11 ++++--
>>  drivers/of/base.c                        | 68 +++++++++++++++++---------------
>>  drivers/of/irq.c                         | 10 ++++-
>>  drivers/pci/controller/dwc/pci-imx6.c    | 32 +++++++--------
>>
>> for imx part.
>>
>> Reviewed-by: Frank Li <Frank.Li@nxp.com>

So that's an Ack. Leaving a Rb tag for a tiny tiny piece of big patch
will give impression that everything is reviewed on v13. And the patch
was not reviewed by you.

If you cannot certify the reviewers statement of oversight then use acked

"For instance, maintainers may use it to signify that they are OK with a
patch landing, but they may not have reviewed it as thoroughly as if a
Reviewed-by: was provided."

"For example, if a patch affects multiple subsystems and has an
Acked-by: from one subsystem maintainer then this usually indicates
acknowledgement of *just the part which affects that maintainer's code.*"


Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: gpu: mali-valhall-csf: Document i.MX952 support
From: Krzysztof Kozlowski @ 2026-04-01 16:07 UTC (permalink / raw)
  To: Guangliu Ding, Liviu Dudau
  Cc: Daniel Baluta (OSS), Daniel Almeida, Alice Ryhl, Boris Brezillon,
	Steven Price, David Airlie, Simona Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam,
	dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, Jiyu Yang
In-Reply-To: <AM0PR04MB47075AF2C5863FC665285CA9F350A@AM0PR04MB4707.eurprd04.prod.outlook.com>

On 01/04/2026 13:27, Guangliu Ding wrote:
>>>>
>>>> We discuss only the lack of compatibility in terms of DT, how DT sees
>>>> compatible devices.
>>>>
>>>> And lack of driver code is clear indication that devices are
>>>> compatible in terms how DT understands it. Feel encouraged to bring
>>>> actual arguments in commit msgs in the future.
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>
>>> So the best approach is only reserve "arm,mali-valhall-csf" for now,
>>> since currently there is no need for an additional compatible entry from a DT
>> compatibility perspective.
>>> We can introduce "nxp,imx952-mali" in future commits if hardware or
>>> driver differences actually require it, and include more detailed justification
>> in the commit message. Right?
>>
>> So does that mean you decided not to read writing bindings document?
> 
> Actually, I followed the compatible string of gpu node in imx952.dtsi during
> code work since they share the same GPU IP.
>          gpu: gpu@4d900000 {
>              compatible = "nxp,imx95-mali", "arm,mali-valhall-csf"; > 
> 
> Is this line in writing bindings document that you want to mention about?
> Could you please share more suggestions about the patch optimization?
> 		DO add new compatibles in case there are new features or bugs.

Please read entire file. I feel like you avoid doing this and just ask
me to give you shortcut.

There is more than one point from that trivial writing bindings file
which applies here.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration
From: Suzuki K Poulose @ 2026-04-01 16:14 UTC (permalink / raw)
  To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel
  Cc: mike.leach, james.clark, alexander.shishkin, leo.yan
In-Reply-To: <20260317181705.2456271-2-yeoreum.yun@arm.com>

Hi Levi

On 17/03/2026 18:17, Yeoreum Yun wrote:
> The current ETM4x configuration via sysfs can lead to the following
> inconsistencies:
> 
>    - If a configuration is modified via sysfs while a perf session is
>      active, the running configuration may differ between before
>      a sched-out and after a subsequent sched-in.
> 
>    - Once a perf session is enabled, some read-only register fields
>      (e.g., TRCSSCSR<n>) may not be reported correctly,
>      because drvdata->config is cleared while enabling with perf mode,
>      even though the information was previously read via etm4_init_arch_data().

Thank you for the patch. The patch looks good to me. Some minor comments
below.

> 
> To resolve these inconsistencies, the configuration should be separated into:
> 
>    - active_config, which represents the currently applied configuration

To be more precise, it is the "Applied configuration for the current 
session"

>    - config, which stores the settings configured via sysfs.

While we are at it, should we stop using the drvdata->config for the
"capabilities" for the ETM (e.g., TRCSSCSRn in ss_status ?) Instead
we could save it in "drvdata->ss_status". This keeps everything
separated:

1. Boot time probed capabilities of ETM
2. Sysfs configuration for the next Run
3. Current active configuration for the ETM (sysfs or perf)

Suzuki


> 
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
>   .../hwtracing/coresight/coresight-etm4x-cfg.c |  2 +-
>   .../coresight/coresight-etm4x-core.c          | 45 +++++++++++--------
>   drivers/hwtracing/coresight/coresight-etm4x.h |  2 +
>   3 files changed, 30 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> index c302072b293a..84213d40d1ae 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> @@ -47,7 +47,7 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
>   				   struct cscfg_regval_csdev *reg_csdev, u32 offset)
>   {
>   	int err = -EINVAL, idx;
> -	struct etmv4_config *drvcfg = &drvdata->config;
> +	struct etmv4_config *drvcfg = &drvdata->active_config;
>   	u32 off_mask;
>   
>   	if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) ||
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index d565a73f0042..c552129c4a0c 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -88,9 +88,11 @@ static int etm4_probe_cpu(unsigned int cpu);
>    */
>   static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n)
>   {
> +	struct etmv4_config *config = &drvdata->active_config;
> +
>   	return (n < drvdata->nr_ss_cmp) &&
>   	       drvdata->nr_pe &&
> -	       (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
> +	       (config->ss_status[n] & TRCSSCSRn_PC);
>   }
>   
>   u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit)
> @@ -266,10 +268,11 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
>   static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
>   {
>   	u64 trfcr = drvdata->trfcr;
> +	struct etmv4_config *config = &drvdata->active_config;
>   
> -	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
> +	if (config->mode & ETM_MODE_EXCL_KERN)
>   		trfcr &= ~TRFCR_EL1_ExTRE;
> -	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
> +	if (config->mode & ETM_MODE_EXCL_USER)
>   		trfcr &= ~TRFCR_EL1_E0TRE;
>   
>   	return trfcr;
> @@ -277,7 +280,7 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
>   
>   /*
>    * etm4x_allow_trace - Allow CPU tracing in the respective ELs,
> - * as configured by the drvdata->config.mode for the current
> + * as configured by the drvdata->active_config.mode for the current
>    * session. Even though we have TRCVICTLR bits to filter the
>    * trace in the ELs, it doesn't prevent the ETM from generating
>    * a packet (e.g, TraceInfo) that might contain the addresses from
> @@ -288,12 +291,13 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
>   static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
>   {
>   	u64 trfcr, guest_trfcr;
> +	struct etmv4_config *config = &drvdata->active_config;
>   
>   	/* If the CPU doesn't support FEAT_TRF, nothing to do */
>   	if (!drvdata->trfcr)
>   		return;
>   
> -	if (drvdata->config.mode & ETM_MODE_EXCL_HOST)
> +	if (config->mode & ETM_MODE_EXCL_HOST)
>   		trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE);
>   	else
>   		trfcr = etm4x_get_kern_user_filter(drvdata);
> @@ -301,7 +305,7 @@ static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
>   	write_trfcr(trfcr);
>   
>   	/* Set filters for guests and pass to KVM */
> -	if (drvdata->config.mode & ETM_MODE_EXCL_GUEST)
> +	if (config->mode & ETM_MODE_EXCL_GUEST)
>   		guest_trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE);
>   	else
>   		guest_trfcr = etm4x_get_kern_user_filter(drvdata);
> @@ -494,7 +498,7 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata)
>   static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
>   {
>   	int i, rc;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   	struct coresight_device *csdev = drvdata->csdev;
>   	struct device *etm_dev = &csdev->dev;
>   	struct csdev_access *csa = &csdev->access;
> @@ -666,7 +670,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
>   {
>   	int ctridx;
>   	int rselector;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   
>   	/* No point in trying if we don't have at least one counter */
>   	if (!drvdata->nr_cntr)
> @@ -749,7 +753,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>   {
>   	int ret = 0;
>   	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   	struct perf_event_attr max_timestamp = {
>   		.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
>   	};
> @@ -911,14 +915,17 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa
>   
>   	/* enable any config activated by configfs */
>   	cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
> +
> +	raw_spin_lock(&drvdata->spinlock);
> +
> +	drvdata->active_config = drvdata->config;
> +
>   	if (cfg_hash) {
>   		ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
>   		if (ret)
>   			return ret;
>   	}
>   
> -	raw_spin_lock(&drvdata->spinlock);
> -
>   	drvdata->trcid = path->trace_id;
>   
>   	/* Tracer will never be paused in sysfs mode */
> @@ -1028,7 +1035,7 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata)
>   static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
>   {
>   	u32 control;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   	struct coresight_device *csdev = drvdata->csdev;
>   	struct csdev_access *csa = &csdev->access;
>   	int i;
> @@ -1374,12 +1381,14 @@ static void etm4_init_arch_data(void *info)
>   	u32 etmidr5;
>   	struct etm4_init_arg *init_arg = info;
>   	struct etmv4_drvdata *drvdata;
> +	struct etmv4_config *config;
>   	struct csdev_access *csa;
>   	struct device *dev = init_arg->dev;
>   	int i;
>   
>   	drvdata = dev_get_drvdata(init_arg->dev);
>   	csa = init_arg->csa;
> +	config = &drvdata->active_config;
>   
>   	/*
>   	 * If we are unable to detect the access mechanism,
> @@ -1440,7 +1449,7 @@ static void etm4_init_arch_data(void *info)
>   
>   	/* EXLEVEL_S, bits[19:16] Secure state instruction tracing */
>   	drvdata->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3);
> -	drvdata->config.s_ex_level = drvdata->s_ex_level;
> +	config->s_ex_level = drvdata->s_ex_level;
>   	/* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */
>   	drvdata->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3);
>   	/*
> @@ -1491,8 +1500,7 @@ static void etm4_init_arch_data(void *info)
>   	 */
>   	drvdata->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4);
>   	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> -		drvdata->config.ss_status[i] =
> -			etm4x_relaxed_read32(csa, TRCSSCSRn(i));
> +		config->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));
>   	}
>   	/* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */
>   	drvdata->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);
> @@ -1685,7 +1693,7 @@ static void etm4_set_default(struct etmv4_config *config)
>   static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type)
>   {
>   	int nr_comparator, index = 0;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   
>   	/*
>   	 * nr_addr_cmp holds the number of comparator _pair_, so time 2
> @@ -1726,7 +1734,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
>   {
>   	int i, comparator, ret = 0;
>   	u64 address;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   	struct etm_filters *filters = event->hw.addr_filters;
>   
>   	if (!filters)
> @@ -2246,7 +2254,8 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
>   	if (!desc.name)
>   		return -ENOMEM;
>   
> -	etm4_set_default(&drvdata->config);
> +	etm4_set_default(&drvdata->active_config);
> +	drvdata->config = drvdata->active_config;
>   
>   	pdata = coresight_get_platform_data(dev);
>   	if (IS_ERR(pdata))
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 89d81ce4e04e..76beb896f188 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -1022,6 +1022,7 @@ struct etmv4_save_state {
>    *		allows tracing at all ELs. We don't want to compute this
>    *		at runtime, due to the additional setting of TRFCR_CX when
>    *		in EL2. Otherwise, 0.
> + * @active_config:	structure holding current applied configuration parameters.
>    * @config:	structure holding configuration parameters.
>    * @save_state:	State to be preserved across power loss
>    * @skip_power_up: Indicates if an implementation can skip powering up
> @@ -1079,6 +1080,7 @@ struct etmv4_drvdata {
>   	bool				skip_power_up : 1;
>   	bool				paused : 1;
>   	u64				trfcr;
> +	struct etmv4_config		active_config;
>   	struct etmv4_config		config;
>   	struct etmv4_save_state		*save_state;
>   	DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX);



^ permalink raw reply

* Re: [PATCH v2 6/7] MAINTAINERS: add exynos850-pmu.c to Exynos850 entry
From: Sam Protsenko @ 2026-04-01 16:16 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alexey Klimov, linux-samsung-soc, Peter Griffin,
	André Draszik, Conor Dooley, Alim Akhtar, Tudor Ambarus,
	Rob Herring, Krzysztof Kozlowski, linux-arm-kernel, devicetree,
	linux-kernel
In-Reply-To: <f73173b4-f44a-4d01-abec-3366b6561332@kernel.org>

Hi Krzysztof,

On Wed, Apr 1, 2026 at 9:28 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 01/04/2026 06:51, Alexey Klimov wrote:
> > Update Exynos850 entry to include new file
> > drivers/soc/samsung/exynos850-pmu.c. Add myself as M
> > there.
> >
> > Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> > ---
> >  MAINTAINERS | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index e14e6f874e05..4b28e92b4d9b 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -23601,6 +23601,7 @@ F:    include/dt-bindings/clock/samsung,exynos2200-cmu.h
> >
> >  SAMSUNG EXYNOS850 SoC SUPPORT
> >  M:   Sam Protsenko <semen.protsenko@linaro.org>
> > +M:   Alexey Klimov <alexey.klimov@linaro.org>
>
> I am surprised to see this because I did not find many reviews from your
> side before.
>

It was me who advised Alexey to add himself on the list, as he's doing
a lot of Exynos850 related work nowadays, and we expect him to
continue doing that. If you think it's too early, let's get back to
this once there are more patches submitted under his name.

Thanks!

> Please first engage in reviewing of this platform, before assigning
> yourself as a maintainer.
>
> Best regards,
> Krzysztof


^ permalink raw reply

* Re: [PATCH] firmware: arm_ffa: Use the correct buffer size during RXTX_MAP
From: Sudeep Holla @ 2026-04-01 16:21 UTC (permalink / raw)
  To: Sebastian Ene; +Cc: linux-arm-kernel, linux-kernel, android-kvm, Sudeep Holla
In-Reply-To: <20260401111738.323647-1-sebastianene@google.com>

On Wed, Apr 01, 2026 at 11:17:38AM +0000, Sebastian Ene wrote:
> Don't use the discovered buffer size from an FFA_FEATURES call directly
> since we can run on a system that has the PAGE_SIZE larger than the
> returned size which makes the alloc_pages_exact for the buffer to be
> rounded up.
> 
> Fixes: 61824feae5c0 ("firmware: arm_ffa: Fetch the Rx/Tx buffer size using ffa_features()")
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
> ---
>  drivers/firmware/arm_ffa/driver.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index f2f94d4d533e..d0c926aca120 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -2078,7 +2078,7 @@ static int __init ffa_init(void)
>  
>  	ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
>  			   virt_to_phys(drv_info->rx_buffer),
> -			   rxtx_bufsz / FFA_PAGE_SIZE);
> +			   DIV_ROUND_UP(rxtx_bufsz, PAGE_SIZE) / FFA_PAGE_SIZE);

Did you mean to use PAGE_ALIGN() instead of DIV_ROUND_UP() ?

The new pg_cnt calculation is dimensionally incorrect and evaluates to 0 for
all the supported buffer sizes, so FFA_RXTX_MAP is always called with an
invalid page count.

Example: with rxtx_bufsz = 4K, the expression becomes 1 / 4096 on 4K/16K/64K
page kernel, so pg_cnt == 0. Wouldn’t this  cause a boot-time regression for
FF-A driver init ? Have you tested this ? I am trying to understand what I
might be missing here.

-- 
Regards,
Sudeep


^ permalink raw reply

* [PATCH] KVM: arm64: vgic-v5: Fold PPI state for all exposed PPIs
From: Sascha Bischoff @ 2026-04-01 16:21 UTC (permalink / raw)
  To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	kvm@vger.kernel.org
  Cc: nd, maz@kernel.org, oliver.upton@linux.dev, Joey Gouly,
	Suzuki Poulose, yuzenghui@huawei.com, broonie@kernel.org

GICv5 supports up to 128 PPIs, which would introduce a large amount of
overhead if all of them were actively tracked. Rather than keeping
track of all 128 potential PPIs, we instead only consider the set of
architected PPIs (the first 64). Moreover, we further reduce that set
by only exposing a subset of the PPIs to a guest. In practice, this
means that only 4 PPIs are typically exposed to a guest - the SW_PPI,
PMUIRQ, and the timers.

When folding the PPI state, changed bits in the active or pending were
used to choose which state to sync back. However, this breaks badly
for Edge interrupts when exiting the guest before it has consumed the
edge. There is no change in pending state detected, and the edge is
lost forever.

Given the reduced set of PPIs exposed to the guest, and the issues
around tracking the edges, drop the tracking of changed state, and
instead iterate over the limited subset of PPIs exposed to the guest
directly.

This change drops the second copy of the PPI pending state used for
detecting edges in the pending state, and reworks
vgic_v5_fold_ppi_state() to iterate over the VM's PPI mask instead.

Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  9 +--------
 arch/arm64/kvm/hyp/vgic-v5-sr.c   |  6 +++---
 arch/arm64/kvm/vgic/vgic-v5.c     | 28 +++++-----------------------
 3 files changed, 9 insertions(+), 34 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a7dc0aac3b934..729bd32207fa6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -803,14 +803,7 @@ struct kvm_host_data {
 
 	/* PPI state tracking for GICv5-based guests */
 	struct {
-		/*
-		 * For tracking the PPI pending state, we need both the entry
-		 * state and exit state to correctly detect edges as it is
-		 * possible that an interrupt has been injected in software in
-		 * the interim.
-		 */
-		DECLARE_BITMAP(pendr_entry, VGIC_V5_NR_PRIVATE_IRQS);
-		DECLARE_BITMAP(pendr_exit, VGIC_V5_NR_PRIVATE_IRQS);
+		DECLARE_BITMAP(pendr, VGIC_V5_NR_PRIVATE_IRQS);
 
 		/* The saved state of the regs when leaving the guest */
 		DECLARE_BITMAP(activer_exit, VGIC_V5_NR_PRIVATE_IRQS);
diff --git a/arch/arm64/kvm/hyp/vgic-v5-sr.c b/arch/arm64/kvm/hyp/vgic-v5-sr.c
index 2c4304ffa9f33..47e6bcd437029 100644
--- a/arch/arm64/kvm/hyp/vgic-v5-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v5-sr.c
@@ -37,7 +37,7 @@ void __vgic_v5_save_ppi_state(struct vgic_v5_cpu_if *cpu_if)
 
 	bitmap_write(host_data_ptr(vgic_v5_ppi_state)->activer_exit,
 		     read_sysreg_s(SYS_ICH_PPI_ACTIVER0_EL2), 0, 64);
-	bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr_exit,
+	bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr,
 		     read_sysreg_s(SYS_ICH_PPI_PENDR0_EL2), 0, 64);
 
 	cpu_if->vgic_ppi_priorityr[0] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR0_EL2);
@@ -52,7 +52,7 @@ void __vgic_v5_save_ppi_state(struct vgic_v5_cpu_if *cpu_if)
 	if (VGIC_V5_NR_PRIVATE_IRQS == 128) {
 		bitmap_write(host_data_ptr(vgic_v5_ppi_state)->activer_exit,
 			     read_sysreg_s(SYS_ICH_PPI_ACTIVER1_EL2), 64, 64);
-		bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr_exit,
+		bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr,
 			     read_sysreg_s(SYS_ICH_PPI_PENDR1_EL2), 64, 64);
 
 		cpu_if->vgic_ppi_priorityr[8] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR8_EL2);
@@ -87,7 +87,7 @@ void __vgic_v5_restore_ppi_state(struct vgic_v5_cpu_if *cpu_if)
 		       SYS_ICH_PPI_ENABLER0_EL2);
 
 	/* Update the pending state of the NON-DVI'd PPIs, only */
-	bitmap_andnot(pendr, host_data_ptr(vgic_v5_ppi_state)->pendr_entry,
+	bitmap_andnot(pendr, host_data_ptr(vgic_v5_ppi_state)->pendr,
 		      cpu_if->vgic_ppi_dvir, VGIC_V5_NR_PRIVATE_IRQS);
 	write_sysreg_s(bitmap_read(pendr, 0, 64), SYS_ICH_PPI_PENDR0_EL2);
 
diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
index 8680a8354db9d..fdd39ea7f83ec 100644
--- a/arch/arm64/kvm/vgic/vgic-v5.c
+++ b/arch/arm64/kvm/vgic/vgic-v5.c
@@ -385,24 +385,14 @@ bool vgic_v5_has_pending_ppi(struct kvm_vcpu *vcpu)
 void vgic_v5_fold_ppi_state(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v5_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v5;
-	DECLARE_BITMAP(changed_active, VGIC_V5_NR_PRIVATE_IRQS);
-	DECLARE_BITMAP(changed_pending, VGIC_V5_NR_PRIVATE_IRQS);
-	DECLARE_BITMAP(changed_bits, VGIC_V5_NR_PRIVATE_IRQS);
-	unsigned long *activer, *pendr_entry, *pendr;
+	unsigned long *activer, *pendr;
 	int i;
 
 	activer = host_data_ptr(vgic_v5_ppi_state)->activer_exit;
-	pendr_entry = host_data_ptr(vgic_v5_ppi_state)->pendr_entry;
-	pendr = host_data_ptr(vgic_v5_ppi_state)->pendr_exit;
+	pendr = host_data_ptr(vgic_v5_ppi_state)->pendr;
 
-	bitmap_xor(changed_active, cpu_if->vgic_ppi_activer, activer,
-		   VGIC_V5_NR_PRIVATE_IRQS);
-	bitmap_xor(changed_pending, pendr_entry, pendr,
-		   VGIC_V5_NR_PRIVATE_IRQS);
-	bitmap_or(changed_bits, changed_active, changed_pending,
-		  VGIC_V5_NR_PRIVATE_IRQS);
-
-	for_each_set_bit(i, changed_bits, VGIC_V5_NR_PRIVATE_IRQS) {
+	for_each_set_bit(i, vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_mask,
+			 VGIC_V5_NR_PRIVATE_IRQS) {
 		u32 intid = vgic_v5_make_ppi(i);
 		struct vgic_irq *irq;
 
@@ -462,15 +452,7 @@ void vgic_v5_flush_ppi_state(struct kvm_vcpu *vcpu)
 	 * incoming changes are merged with the outgoing changes on the return
 	 * path.
 	 */
-	bitmap_copy(host_data_ptr(vgic_v5_ppi_state)->pendr_entry, pendr,
-		    VGIC_V5_NR_PRIVATE_IRQS);
-
-	/*
-	 * Make sure that we can correctly detect "edges" in the PPI
-	 * state. There's a path where we never actually enter the guest, and
-	 * failure to do this risks losing pending state
-	 */
-	bitmap_copy(host_data_ptr(vgic_v5_ppi_state)->pendr_exit, pendr,
+	bitmap_copy(host_data_ptr(vgic_v5_ppi_state)->pendr, pendr,
 		    VGIC_V5_NR_PRIVATE_IRQS);
 }
 
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v2 07/16] KVM: arm64: vgic-v5: Transfer edge pending state to ICH_PPI_PENDRx_EL2
From: Sascha Bischoff @ 2026-04-01 16:24 UTC (permalink / raw)
  To: maz@kernel.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
  Cc: Joey Gouly, yuzenghui@huawei.com, Suzuki Poulose,
	oupton@kernel.org, broonie@kernel.org, nd
In-Reply-To: <20260401103611.357092-8-maz@kernel.org>

On Wed, 2026-04-01 at 11:36 +0100, Marc Zyngier wrote:
> While it is perfectly correct to leave the pending state of a level
> interrupt as is when queuing it (it is, after all, only driven by
> the line), edge pending state must be transfered, as nothing will
> lower it.
> 
> Reviewed-by: Sascha Bischoff <sascha.bischoff@arm.com>
> Fixes: 4d591252bacb2 ("KVM: arm64: gic-v5: Implement PPI interrupt
> injection")
> Link:
> https://sashiko.dev/#/patchset/20260319154937.3619520-1-sascha.bischoff%40arm.com
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kvm/vgic/vgic-v5.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/vgic/vgic-v5.c
> b/arch/arm64/kvm/vgic/vgic-v5.c
> index 119d7d01d0e77..422741c86c6a8 100644
> --- a/arch/arm64/kvm/vgic/vgic-v5.c
> +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> @@ -445,8 +445,11 @@ void vgic_v5_flush_ppi_state(struct kvm_vcpu
> *vcpu)
>  
>  		irq = vgic_get_vcpu_irq(vcpu, intid);
>  
> -		scoped_guard(raw_spinlock_irqsave, &irq->irq_lock)
> +		scoped_guard(raw_spinlock_irqsave, &irq->irq_lock) {
>  			__assign_bit(i, pendr, irq_is_pending(irq));
> +			if (irq->config == VGIC_CONFIG_EDGE)
> +				irq->pending_latch = false;
> +		}
>  
>  		vgic_put_irq(vcpu->kvm, irq);
>  	}

With this change we end up losing edges (so, actually have the opposite
problem!). I'd missed this in the previous iteration, but have just
uncovered it during testing. It was hidden by clearing TWI when we have
a single task running, and hence wasn't picked up with the GICv5 PPI
selftest until I stressed the test system more heavily.

In vgic_v5_fold_ppi_state() we detect changes in the active or pending
state on guest exit. If there is no change, i.e., the guest hasn't
consumed the edge yet, we don't end up syncing it back to the
corresponding struct vgic_irq, and lose it forever.

The detection of changes on fold was introduced in order to reduce the
overhead back when we were syncing the state for all 128 potential
PPIs. Now that we've reduced the set to the 64 architected PPIs, and
actually only use a subset of those (SW_PPI, PMUIRQ, timers - up to 4
in total currently) I'm not sure that makes sense anymore.

I think it instead makes sense to iterate over the mask of PPIs exposed
to the guest and sync only those back to KVM's vgic_irq state. This
means that we first of all avoid losing any edges, and secondly are
able to drop the extra pending state tracking.

I've just posted a patch based on this series which addresses the issue
here: 

https://lore.kernel.org/linux-arm-kernel/20260401162152.932243-1-sascha.bischoff@arm.com

Thanks,
Sascha

^ permalink raw reply

* Re: [PATCH] iommu: Always fill in gather when unmapping
From: Robin Murphy @ 2026-04-01 16:33 UTC (permalink / raw)
  To: Jason Gunthorpe, Alexandre Ghiti, AngeloGioacchino Del Regno,
	Albert Ou, asahi, Baolin Wang, iommu, Janne Grunau,
	Jernej Skrabec, Joerg Roedel, Jean-Philippe Brucker,
	linux-arm-kernel, linux-mediatek, linux-riscv, linux-sunxi,
	Matthias Brugger, Neal Gompa, Orson Zhai, Palmer Dabbelt,
	Paul Walmsley, Samuel Holland, Sven Peter, virtualization,
	Chen-Yu Tsai, Will Deacon, Yong Wu, Chunyan Zhang
  Cc: Lu Baolu, Janusz Krzysztofik, Joerg Roedel, Jon Hunter, patches,
	Samiullah Khawaja, stable, Vasant Hegde
In-Reply-To: <0-v1-664d3acaabb9+78b-iommu_gather_always_jgg@nvidia.com>

On 2026-03-31 8:56 pm, Jason Gunthorpe wrote:
> The fixed commit assumed that the gather would always be populated if
> an iotlb_sync was required.
> 
> arm-smmu-v3, amd, VT-d, riscv, s390, mtk all use information from the
> gather during their iotlb_sync() and this approach works for them.
> 
> However, arm-smmu, qcom_iommu, ipmmu-vmsa, sun50i, sprd, virtio,
> apple-dart all ignore the gather during their iotlb_sync(). They
> mostly issue a full flush.
> 
> Unfortunately the latter set of drivers often don't bother to add
> anything to the gather since they don't intend on using it. Since the
> core code now blocks gathers that were never filled, this caused those
> drivers to stop getting their iotlb_sync() calls and breaks them.
> 
> Since it is impossible to tell the difference between gathers that are
> empty because there is nothing to do and gathers that are empty
> because they are not used, fill in the gathers for the missing cases.
> 
> io-pgtable might have intended to allow the driver to choose between
> gather or immediate flush because it passed gather to
> ops->tlb_add_page(), however no driver does anything with it.

Apart from arm-smmu-v3...

> mtk uses io-pgtable-arm-v7s but added the range to the gather in the
> unmap callback. Move this into the io-pgtable-arm unmap itself. That
> will fix all the armv7 using drivers (arm-smmu, qcom_iommu,
> ipmmu-vmsa).

io-pgtable-arm-v7s != io-pgtable-arm. You're *breaking* MTK (and failing
to fix the other v7s user, which is MSM).

> arm-smmu uses both ARM_V7S and ARM LPAE formats. The LPAE formats
> already have the gather population because SMMUv3 requires it, so it
> becomes consistent.

Huh? arm-smmu-v3 invokes iommu_iotlb_gather_add_page() itself, because
arm-smmu-v3 uses gathers; arm-smmu does not. io-pgtable-arm has nothing
to do with it. Invoking add range before add_page will end up defeating
the iommu_iotlb_gather_is_disjoint() check and making SMMUv3
overinvalidate between disjoint ranges.

I guess now I remember why we weren't validating gathers in core code
before :(

However, if it is for the sake of a core code check, why not just make
the core code robust itself?

Thanks,
Robin.

----->8-----
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 35db51780954..9ca23f89a279 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2714,6 +2714,10 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
  		pr_debug("unmapped: iova 0x%lx size 0x%zx\n",
  			 iova, unmapped_page);
  
+		/* If the driver itself isn't using the gather, mark it used */
+		if (iotlb_gather->end <= iotlb_gather->start)
+			iommu_iotlb_gather_add_range(&iotlb_gather, iova, unmapped_page);
+
  		iova += unmapped_page;
  		unmapped += unmapped_page;
  	}



^ permalink raw reply related

* Re: [GIT PULL 2/2] Broadcom devicetree-arm64 changes for 7.1
From: Arnd Bergmann @ 2026-04-01 16:33 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Florian Fainelli
  Cc: soc, Rob Herring, Gregor Herburger, Maíra Canal,
	Stefan Wahren, linux-arm-kernel, Kevin Hilman,
	bcm-kernel-feedback-list
In-Reply-To: <3f7879d0-9e5d-4c00-a5dc-4871a049afd0@kernel.org>

On Wed, Apr 1, 2026, at 16:47, Krzysztof Kozlowski wrote:
> On 01/04/2026 16:37, Arnd Bergmann wrote:
>> $ gpg --list-sigs 9BE46ADFE60625D891F72B8587D0969C44070704
>> pub   dsa1024/61579915B563760E 2008-09-16 [SCA] [expired: 2024-11-06]
>
> dsa1024 might be another answer... DSA1024 was deprecated by NIST in
> 2013, so maybe gnugp even drops it just like keys with too weak signatures?
>
> But another problem is that I do not see it in the `git log` of keyring
> at all which suggests it wasn't ever submitted.

Indeed, that also explains why the Broadcom tree is hosted on github
rather than git.kernel.org. While using the kernel.org hosting
is by no means a requirement, github does occasionally cause problems,
and I do get a bit annoyed when it takes ages to pull from that.

Florian, I don't know if there is a Broadcom specific policy that
requires you to use the corporate github account, but if you
are setting up a new key already, it may be a good time to
also move the hosting.

> I don't think DSA1024 can be accepted now in keyring, so this requires a
> new key, cross signed by the old one.

+1

      Arnd


^ permalink raw reply

* Re: [GIT PULL 2/2] Broadcom devicetree-arm64 changes for 7.1
From: Krzysztof Kozlowski @ 2026-04-01 16:38 UTC (permalink / raw)
  To: Arnd Bergmann, Florian Fainelli
  Cc: soc, Rob Herring, Gregor Herburger, Maíra Canal,
	Stefan Wahren, linux-arm-kernel, Kevin Hilman,
	bcm-kernel-feedback-list
In-Reply-To: <83a52edc-1d46-4eaf-996e-924ed3a00c83@app.fastmail.com>

On 01/04/2026 18:33, Arnd Bergmann wrote:
> On Wed, Apr 1, 2026, at 16:47, Krzysztof Kozlowski wrote:
>> On 01/04/2026 16:37, Arnd Bergmann wrote:
>>> $ gpg --list-sigs 9BE46ADFE60625D891F72B8587D0969C44070704
>>> pub   dsa1024/61579915B563760E 2008-09-16 [SCA] [expired: 2024-11-06]
>>
>> dsa1024 might be another answer... DSA1024 was deprecated by NIST in
>> 2013, so maybe gnugp even drops it just like keys with too weak signatures?
>>
>> But another problem is that I do not see it in the `git log` of keyring
>> at all which suggests it wasn't ever submitted.
> 
> Indeed, that also explains why the Broadcom tree is hosted on github
> rather than git.kernel.org. While using the kernel.org hosting
> is by no means a requirement, github does occasionally cause problems,

Kind of, but quoting Linus' policy - either kernel.org or properly
signed pulls by a key in the keyring.

Of course new SoCs/maintainers are exempted of that rule, but this does
not apply here.

> and I do get a bit annoyed when it takes ages to pull from that.
> 
> Florian, I don't know if there is a Broadcom specific policy that
> requires you to use the corporate github account, but if you
> are setting up a new key already, it may be a good time to
> also move the hosting.
> 
>> I don't think DSA1024 can be accepted now in keyring, so this requires a
>> new key, cross signed by the old one.

Just to clarify: not "cross signed", but simply signed by the old key.

> 
> +1
> 
>       Arnd


Best regards,
Krzysztof


^ permalink raw reply

* Re: [GIT PULL 2/2] Broadcom devicetree-arm64 changes for 7.1
From: Florian Fainelli @ 2026-04-01 16:41 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Arnd Bergmann
  Cc: soc, Rob Herring, Gregor Herburger, Maíra Canal,
	Stefan Wahren, linux-arm-kernel, Kevin Hilman,
	bcm-kernel-feedback-list
In-Reply-To: <8d8925ad-22eb-4b9b-b6eb-6ae7dc3b2073@kernel.org>

On 4/1/26 09:38, Krzysztof Kozlowski wrote:
> On 01/04/2026 18:33, Arnd Bergmann wrote:
>> On Wed, Apr 1, 2026, at 16:47, Krzysztof Kozlowski wrote:
>>> On 01/04/2026 16:37, Arnd Bergmann wrote:
>>>> $ gpg --list-sigs 9BE46ADFE60625D891F72B8587D0969C44070704
>>>> pub   dsa1024/61579915B563760E 2008-09-16 [SCA] [expired: 2024-11-06]
>>>
>>> dsa1024 might be another answer... DSA1024 was deprecated by NIST in
>>> 2013, so maybe gnugp even drops it just like keys with too weak signatures?
>>>
>>> But another problem is that I do not see it in the `git log` of keyring
>>> at all which suggests it wasn't ever submitted.
>>
>> Indeed, that also explains why the Broadcom tree is hosted on github
>> rather than git.kernel.org. While using the kernel.org hosting
>> is by no means a requirement, github does occasionally cause problems,
> 
> Kind of, but quoting Linus' policy - either kernel.org or properly
> signed pulls by a key in the keyring.
> 
> Of course new SoCs/maintainers are exempted of that rule, but this does
> not apply here.
> 
>> and I do get a bit annoyed when it takes ages to pull from that.
>>
>> Florian, I don't know if there is a Broadcom specific policy that
>> requires you to use the corporate github account, but if you
>> are setting up a new key already, it may be a good time to
>> also move the hosting.

OK, I will get going with moving the hosting to kernel.org. What about 
this specific pull request, will it go through or is relocating the 
hosting mandatory for it to be accepted?
-- 
Florian


^ permalink raw reply

* Re: [PATCH 5/5] lib/crc: arm: Enable arm64's NEON intrinsics implementation of crc64
From: Ard Biesheuvel @ 2026-04-01 16:48 UTC (permalink / raw)
  To: Eric Biggers; +Cc: linux-crypto, linux-arm-kernel, Demian Shulhan
In-Reply-To: <20260331224156.GB45047@quark>



On Wed, 1 Apr 2026, at 00:41, Eric Biggers wrote:
> On Mon, Mar 30, 2026 at 04:46:36PM +0200, Ard Biesheuvel wrote:
>> Enable big-endian support only on GCC - the code generated by Clang is
>> horribly broken.
> [...]
>> +#if defined(CONFIG_ARM) && defined(CONFIG_CC_IS_CLANG)
>> +static inline uint64x2_t pmull64(uint64x2_t a, uint64x2_t b)
>> +{
>> +	uint64_t l = vgetq_lane_u64(a, 0);
>> +	uint64_t m = vgetq_lane_u64(b, 0);
>> +	uint64x2_t result;
>> +
>> +	asm("vmull.p64	%q0, %1, %2" : "=w"(result) : "w"(l), "w"(m));
>> +
>> +	return result;
>> +}
>
> Perhaps omit big endian support, and use the inline asm implementation
> of these functions with both gcc and clang?  The more unique
> combinations need to be tested to cover all the code, the higher the
> chance of one being missed in testing.
>

Yeah that should work.

> Also, leaving shared code in lib/crc/arm64/ will be confusing.  How
> about lib/crc/arm-common/, and crc64_nvme_arm64_c => crc64_nvme_neon()?
> Or even just put crc64-neon.c directly in lib/crc/.
>

Yeah the latter seems the most straight-forward.


^ permalink raw reply

* Re: [GIT PULL 2/2] Broadcom devicetree-arm64 changes for 7.1
From: Mark Brown @ 2026-04-01 16:49 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Krzysztof Kozlowski, Arnd Bergmann, soc, Rob Herring,
	Gregor Herburger, Maíra Canal, Stefan Wahren,
	linux-arm-kernel, Kevin Hilman, bcm-kernel-feedback-list
In-Reply-To: <e060307f-5c85-468f-8f5d-6101dc0a2015@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 387 bytes --]

On Wed, Apr 01, 2026 at 09:41:03AM -0700, Florian Fainelli wrote:

> OK, I will get going with moving the hosting to kernel.org. What about this
> specific pull request, will it go through or is relocating the hosting
> mandatory for it to be accepted?

Whenever you get round to it please remember to let me know so I can
update where -next is fetching from (this is a common gotcha!).

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [GIT PULL 2/2] Broadcom devicetree-arm64 changes for 7.1
From: Arnd Bergmann @ 2026-04-01 16:50 UTC (permalink / raw)
  To: Florian Fainelli, Krzysztof Kozlowski
  Cc: soc, Rob Herring, Gregor Herburger, Maíra Canal,
	Stefan Wahren, linux-arm-kernel, Kevin Hilman,
	bcm-kernel-feedback-list
In-Reply-To: <e060307f-5c85-468f-8f5d-6101dc0a2015@broadcom.com>

On Wed, Apr 1, 2026, at 18:41, Florian Fainelli wrote:
> On 4/1/26 09:38, Krzysztof Kozlowski wrote:
>> On 01/04/2026 18:33, Arnd Bergmann wrote:
>>> On Wed, Apr 1, 2026, at 16:47, Krzysztof Kozlowski wrote:
>>>
>>> Florian, I don't know if there is a Broadcom specific policy that
>>> requires you to use the corporate github account, but if you
>>> are setting up a new key already, it may be a good time to
>>> also move the hosting.
>
> OK, I will get going with moving the hosting to kernel.org. What about 
> this specific pull request, will it go through or is relocating the 
> hosting mandatory for it to be accepted?

I've merged both now, should push them out later tonight.

     Arnd


^ permalink raw reply

* RE: [PATCH 01/11] arch: arm64: Export arch_smp_send_reschedule for mshv_vtl module
From: Michael Kelley @ 2026-04-01 16:54 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-2-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 

Nit: For the patch "Subject", the most common prefix for the file
arch/arm64/kernel/smp.c is "arm64: smp:".  I'd suggest using that
prefix for historical consistency.

> mshv_vtl_main.c calls smp_send_reschedule() which expands to
> arch_smp_send_reschedule(). When CONFIG_MSHV_VTL=m, the module cannot
> access this symbol since it is not exported on arm64.
> 
> smp_send_reschedule() is used in mshv_vtl_cancel() to interrupt a vCPU
> thread running on another CPU. When a vCPU is looping in
> mshv_vtl_ioctl_return_to_lower_vtl(), it checks a per-CPU cancel flag
> before each VTL0 entry. Setting cancel=1 alone is not enough if the
> target CPU thread is sleeping - the IPI from smp_send_reschedule() kicks
> the remote CPU out of idle/sleep so it re-checks the cancel flag and
> exits the loop promptly.
> 
> Other architectures (riscv, loongarch, powerpc) already export this
> symbol. Add the same EXPORT_SYMBOL_GPL for arm64. This is required
> for adding arm64 support in MSHV_VTL.
> 
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  arch/arm64/kernel/smp.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 1aa324104afb..26b1a4456ceb 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -1152,6 +1152,7 @@ void arch_smp_send_reschedule(int cpu)
>  {
>  	smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
>  }
> +EXPORT_SYMBOL_GPL(arch_smp_send_reschedule);
> 
>  #ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
>  void arch_send_wakeup_ipi(unsigned int cpu)
> --
> 2.43.0
> 

The "Subject" nit notwithstanding,

Reviewed-by: Michael Kelley <mhklinux@outlook.com>



^ permalink raw reply

* RE: [PATCH 02/11] Drivers: hv: Move hv_vp_assist_page to common files
From: Michael Kelley @ 2026-04-01 16:55 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-3-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 
> Move the logic to initialize and export hv_vp_assist_page from x86
> architecture code to Hyper-V common code to allow it to be used for
> upcoming arm64 support in MSHV_VTL driver.
> Note: This change also improves error handling - if VP assist page
> allocation fails, hyperv_init() now returns early instead of
> continuing with partial initialization.
> 
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  arch/x86/hyperv/hv_init.c      | 88 +---------------------------------
>  drivers/hv/hv_common.c         | 88 ++++++++++++++++++++++++++++++++++
>  include/asm-generic/mshyperv.h |  4 ++
>  include/hyperv/hvgdk_mini.h    |  2 +
>  4 files changed, 95 insertions(+), 87 deletions(-)
> 
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index 323adc93f2dc..75a98b5e451b 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -81,9 +81,6 @@ union hv_ghcb * __percpu *hv_ghcb_pg;
>  /* Storage to save the hypercall page temporarily for hibernation */
>  static void *hv_hypercall_pg_saved;
> 
> -struct hv_vp_assist_page **hv_vp_assist_page;
> -EXPORT_SYMBOL_GPL(hv_vp_assist_page);
> -
>  static int hyperv_init_ghcb(void)
>  {
>  	u64 ghcb_gpa;
> @@ -117,59 +114,12 @@ static int hyperv_init_ghcb(void)
> 
>  static int hv_cpu_init(unsigned int cpu)
>  {
> -	union hv_vp_assist_msr_contents msr = { 0 };
> -	struct hv_vp_assist_page **hvp;
>  	int ret;
> 
>  	ret = hv_common_cpu_init(cpu);
>  	if (ret)
>  		return ret;
> 
> -	if (!hv_vp_assist_page)
> -		return 0;
> -
> -	hvp = &hv_vp_assist_page[cpu];
> -	if (hv_root_partition()) {
> -		/*
> -		 * For root partition we get the hypervisor provided VP assist
> -		 * page, instead of allocating a new page.
> -		 */
> -		rdmsrq(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
> -		*hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
> -				PAGE_SIZE, MEMREMAP_WB);
> -	} else {
> -		/*
> -		 * The VP assist page is an "overlay" page (see Hyper-V TLFS's
> -		 * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
> -		 * out to make sure we always write the EOI MSR in
> -		 * hv_apic_eoi_write() *after* the EOI optimization is disabled
> -		 * in hv_cpu_die(), otherwise a CPU may not be stopped in the
> -		 * case of CPU offlining and the VM will hang.
> -		 */
> -		if (!*hvp) {
> -			*hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);
> -
> -			/*
> -			 * Hyper-V should never specify a VM that is a Confidential
> -			 * VM and also running in the root partition. Root partition
> -			 * is blocked to run in Confidential VM. So only decrypt assist
> -			 * page in non-root partition here.
> -			 */
> -			if (*hvp && !ms_hyperv.paravisor_present && hv_isolation_type_snp()) {
> -				WARN_ON_ONCE(set_memory_decrypted((unsigned long)(*hvp), 1));
> -				memset(*hvp, 0, PAGE_SIZE);
> -			}
> -		}
> -
> -		if (*hvp)
> -			msr.pfn = vmalloc_to_pfn(*hvp);
> -
> -	}
> -	if (!WARN_ON(!(*hvp))) {
> -		msr.enable = 1;
> -		wrmsrq(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
> -	}
> -
>  	/* Allow Hyper-V stimer vector to be injected from Hypervisor. */
>  	if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE)
>  		apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, true);
> @@ -286,23 +236,6 @@ static int hv_cpu_die(unsigned int cpu)
> 
>  	hv_common_cpu_die(cpu);
> 
> -	if (hv_vp_assist_page && hv_vp_assist_page[cpu]) {
> -		union hv_vp_assist_msr_contents msr = { 0 };
> -		if (hv_root_partition()) {
> -			/*
> -			 * For root partition the VP assist page is mapped to
> -			 * hypervisor provided page, and thus we unmap the
> -			 * page here and nullify it, so that in future we have
> -			 * correct page address mapped in hv_cpu_init.
> -			 */
> -			memunmap(hv_vp_assist_page[cpu]);
> -			hv_vp_assist_page[cpu] = NULL;
> -			rdmsrq(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
> -			msr.enable = 0;
> -		}
> -		wrmsrq(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
> -	}
> -
>  	if (hv_reenlightenment_cb == NULL)
>  		return 0;
> 
> @@ -460,21 +393,6 @@ void __init hyperv_init(void)
>  	if (hv_common_init())
>  		return;
> 
> -	/*
> -	 * The VP assist page is useless to a TDX guest: the only use we
> -	 * would have for it is lazy EOI, which can not be used with TDX.
> -	 */
> -	if (hv_isolation_type_tdx())
> -		hv_vp_assist_page = NULL;
> -	else
> -		hv_vp_assist_page = kzalloc_objs(*hv_vp_assist_page, nr_cpu_ids);
> -	if (!hv_vp_assist_page) {
> -		ms_hyperv.hints &= ~HV_X64_ENLIGHTENED_VMCS_RECOMMENDED;
> -
> -		if (!hv_isolation_type_tdx())
> -			goto common_free;
> -	}
> -
>  	if (ms_hyperv.paravisor_present && hv_isolation_type_snp()) {
>  		/* Negotiate GHCB Version. */
>  		if (!hv_ghcb_negotiate_protocol())
> @@ -483,7 +401,7 @@ void __init hyperv_init(void)
> 
>  		hv_ghcb_pg = alloc_percpu(union hv_ghcb *);
>  		if (!hv_ghcb_pg)
> -			goto free_vp_assist_page;
> +			goto free_ghcb_page;
>  	}
> 
>  	cpuhp = cpuhp_setup_state(CPUHP_AP_HYPERV_ONLINE, "x86/hyperv_init:online",
> @@ -613,10 +531,6 @@ void __init hyperv_init(void)
>  	cpuhp_remove_state(CPUHP_AP_HYPERV_ONLINE);
>  free_ghcb_page:
>  	free_percpu(hv_ghcb_pg);
> -free_vp_assist_page:
> -	kfree(hv_vp_assist_page);
> -	hv_vp_assist_page = NULL;
> -common_free:
>  	hv_common_free();
>  }
> 
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 6b67ac616789..d1ebc0ebd08f 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -28,7 +28,9 @@
>  #include <linux/slab.h>
>  #include <linux/dma-map-ops.h>
>  #include <linux/set_memory.h>
> +#include <linux/vmalloc.h>
>  #include <hyperv/hvhdk.h>
> +#include <hyperv/hvgdk.h>
>  #include <asm/mshyperv.h>

Need to add

#include <linux/io.h>

because of the memremap() and related calls that have been added.
io.h is probably being #include'd indirectly, but it is better to #include
it directly.

> 
>  u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
> @@ -78,6 +80,8 @@ static struct ctl_table_header *hv_ctl_table_hdr;
>  u8 * __percpu *hv_synic_eventring_tail;
>  EXPORT_SYMBOL_GPL(hv_synic_eventring_tail);
> 
> +struct hv_vp_assist_page **hv_vp_assist_page;
> +EXPORT_SYMBOL_GPL(hv_vp_assist_page);
>  /*
>   * Hyper-V specific initialization and shutdown code that is
>   * common across all architectures.  Called from architecture
> @@ -92,6 +96,9 @@ void __init hv_common_free(void)
>  	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
>  		hv_kmsg_dump_unregister();
> 
> +	kfree(hv_vp_assist_page);
> +	hv_vp_assist_page = NULL;
> +
>  	kfree(hv_vp_index);
>  	hv_vp_index = NULL;
> 
> @@ -394,6 +401,23 @@ int __init hv_common_init(void)
>  	for (i = 0; i < nr_cpu_ids; i++)
>  		hv_vp_index[i] = VP_INVAL;
> 
> +	/*
> +	 * The VP assist page is useless to a TDX guest: the only use we
> +	 * would have for it is lazy EOI, which can not be used with TDX.
> +	 */
> +	if (hv_isolation_type_tdx()) {
> +		hv_vp_assist_page = NULL;
> +	} else {
> +		hv_vp_assist_page = kzalloc_objs(*hv_vp_assist_page, nr_cpu_ids);
> +		if (!hv_vp_assist_page) {
> +#ifdef CONFIG_X86_64
> +			ms_hyperv.hints &= ~HV_X64_ENLIGHTENED_VMCS_RECOMMENDED;
> +#endif
> +			hv_common_free();
> +			return -ENOMEM;

Given that "failure to allocate memory" now returns an error that is
essentially fatal to hyperv_init(), is it still necessary to clear the flag in
ms_hyperv.hints?  I'd love to see that #ifdef go away. It's the only
#ifdef in hv_common.c, and I had worked hard in the past to avoid
such #ifdef's. :-)

> +		}
> +	}
> +
>  	return 0;
>  }
> 
> @@ -471,6 +495,8 @@ void __init ms_hyperv_late_init(void)
> 
>  int hv_common_cpu_init(unsigned int cpu)
>  {
> +	union hv_vp_assist_msr_contents msr = { 0 };
> +	struct hv_vp_assist_page **hvp;
>  	void **inputarg, **outputarg;
>  	u8 **synic_eventring_tail;
>  	u64 msr_vp_index;
> @@ -542,6 +568,50 @@ int hv_common_cpu_init(unsigned int cpu)
>  			ret = -ENOMEM;

The Sashiko AI comment here about a bug when ret is set to -ENOMEM
seems valid to me.

>  	}
> 
> +	if (!hv_vp_assist_page)
> +		return ret;
> +
> +	hvp = &hv_vp_assist_page[cpu];
> +	if (hv_root_partition()) {
> +		/*
> +		 * For root partition we get the hypervisor provided VP assist
> +		 * page, instead of allocating a new page.
> +		 */
> +		msr.as_uint64 = hv_get_msr(HV_SYN_REG_VP_ASSIST_PAGE);
> +		*hvp = memremap(msr.pfn << HV_VP_ASSIST_PAGE_ADDRESS_SHIFT,
> +				PAGE_SIZE, MEMREMAP_WB);

The Sashiko AI comment about potentially memremap'ing 64K instead of 4K can
be ignored. We know that the root partition can only run with a 4K page size,
and that is enforced in drivers/hv/Kconfig.

HV_VP_ASSIST_PAGE_ADDRESS_SHIFT is defined in asm-generic/mshyperv.h.
But there is also HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT in hvgdk_mini.h.
Is there a clean way to eliminate the duplication?

> +	} else {
> +		/*
> +		 * The VP assist page is an "overlay" page (see Hyper-V TLFS's
> +		 * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
> +		 * out to make sure we always write the EOI MSR in
> +		 * hv_apic_eoi_write() *after* the EOI optimization is disabled
> +		 * in hv_cpu_die(), otherwise a CPU may not be stopped in the
> +		 * case of CPU offlining and the VM will hang.
> +		 */

Somewhere in the comment above, I'd suggest adding a short "on x86/x64"
qualifier, as the comment doesn't apply on arm64 since it doesn't support
the AutoEOI optimization.  Maybe "Here it must be zeroed out to make sure
that on x86/x64 we always write the EOI MSR in ....".   

> +		if (!*hvp) {
> +			*hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);

The Sashiko AI comment about using "flags" instead of GFP_KERNEL seems valid.

> +
> +			/*
> +			 * Hyper-V should never specify a VM that is a Confidential
> +			 * VM and also running in the root partition. Root partition
> +			 * is blocked to run in Confidential VM. So only decrypt assist
> +			 * page in non-root partition here.
> +			 */
> +			if (*hvp && !ms_hyperv.paravisor_present && hv_isolation_type_snp()) {
> +				WARN_ON_ONCE(set_memory_decrypted((unsigned long)(*hvp), 1));
> +				memset(*hvp, 0, PAGE_SIZE);
> +			}
> +		}
> +
> +		if (*hvp)
> +			msr.pfn = vmalloc_to_pfn(*hvp);

The Sashiko AI comment about page size here seems valid. But what are the rules
about arm64 page sizes that are supported for VTL2, and how does they relate
to VTL0 allowing 4K, 16K, and 64K page size? What combinations are allowed?
For example, can a VTL2 built with 4K page size run with a VTL0 built with
64K page size? It would be nice to have the rules recorded somewhere in a
code comment, but I'm not sure of the best place.

But regardless of the rules, I'd suggest future-proofing by using
"page_to_hvpfn(vmalloc_to_page(*hvp))" so that the PFN generated is always
in terms of 4K page size as the Hyper-V host expects.

> +	}
> +	if (!WARN_ON(!(*hvp))) {
> +		msr.enable = 1;
> +		hv_set_msr(HV_SYN_REG_VP_ASSIST_PAGE, msr.as_uint64);
> +	}
> +
>  	return ret;
>  }
> 
> @@ -566,6 +636,24 @@ int hv_common_cpu_die(unsigned int cpu)
>  		*synic_eventring_tail = NULL;
>  	}
> 
> +	if (hv_vp_assist_page && hv_vp_assist_page[cpu]) {
> +		union hv_vp_assist_msr_contents msr = { 0 };
> +
> +		if (hv_root_partition()) {
> +			/*
> +			 * For root partition the VP assist page is mapped to
> +			 * hypervisor provided page, and thus we unmap the
> +			 * page here and nullify it, so that in future we have
> +			 * correct page address mapped in hv_cpu_init.
> +			 */
> +			memunmap(hv_vp_assist_page[cpu]);
> +			hv_vp_assist_page[cpu] = NULL;
> +			msr.as_uint64 = hv_get_msr(HV_SYN_REG_VP_ASSIST_PAGE);
> +			msr.enable = 0;
> +		}
> +		hv_set_msr(HV_SYN_REG_VP_ASSIST_PAGE, msr.as_uint64);
> +	}
> +
>  	return 0;
>  }
> 
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index d37b68238c97..108f135d4fd9 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -25,6 +25,7 @@
>  #include <linux/nmi.h>
>  #include <asm/ptrace.h>
>  #include <hyperv/hvhdk.h>
> +#include <hyperv/hvgdk.h>
> 
>  #define VTPM_BASE_ADDRESS 0xfed40000
> 
> @@ -299,6 +300,8 @@ do { \
>  #define hv_status_debug(status, fmt, ...) \
>  	hv_status_printk(debug, status, fmt, ##__VA_ARGS__)
> 
> +extern struct hv_vp_assist_page **hv_vp_assist_page;

This "extern" statement is added here so it is visible to both x86/x64 and arm64.
And that's correct.

But there is still some VP assist page stuff that has been left in the arch/x86
version of mshyperv.h.  That other stuff, including the inline function
hv_get_vp_assist_page(), should also be moved to asm-generic/mshyperv.h.
Given that the VP assist page support is now fully generic and not x86/x64
specific, it shouldn't occur anywhere in the arch/x86 version of mshyperv.h.

> +
>  const char *hv_result_to_string(u64 hv_status);
>  int hv_result_to_errno(u64 status);
>  void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die);
> @@ -377,6 +380,7 @@ static inline int hv_deposit_memory(u64 partition_id, u64 status)
>  	return hv_deposit_memory_node(NUMA_NO_NODE, partition_id, status);
>  }
> 
> +#define HV_VP_ASSIST_PAGE_ADDRESS_SHIFT	12
>  #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
>  u8 __init get_vtl(void);
>  #else
> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
> index 056ef7b6b360..be697ddb211a 100644
> --- a/include/hyperv/hvgdk_mini.h
> +++ b/include/hyperv/hvgdk_mini.h
> @@ -149,6 +149,7 @@ struct hv_u128 {
>  #define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT	12
>  #define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK	\
>  		(~((1ull << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
> +#define HV_SYN_REG_VP_ASSIST_PAGE              (HV_X64_MSR_VP_ASSIST_PAGE)
> 
>  /* Hyper-V Enlightened VMCS version mask in nested features CPUID */
>  #define HV_X64_ENLIGHTENED_VMCS_VERSION		0xff
> @@ -1185,6 +1186,7 @@ enum hv_register_name {
> 
>  #define HV_MSR_STIMER0_CONFIG	(HV_REGISTER_STIMER0_CONFIG)
>  #define HV_MSR_STIMER0_COUNT	(HV_REGISTER_STIMER0_COUNT)
> +#define HV_SYN_REG_VP_ASSIST_PAGE    (HV_REGISTER_VP_ASSIST_PAGE)

This defines a new register name prefix "HV_SYN_REG_" that isn't used
anywhere else. The prefixes for Hyper-V register names are already complex
to account to x86/x64 and arm64 differences, and the fact the x86/x64 has
synthetic MSRs, while arm64 does not. So introducing another prefix is
undesirable. Couldn't this just be HV_MSR_VP_ASSIST_PAGE using the
same structure as HV_MSR_STIMER0_COUNT (for example)?

> 
>  #endif /* CONFIG_ARM64 */
> 
> --
> 2.43.0
> 



^ permalink raw reply

* RE: [PATCH 03/11] Drivers: hv: Add support to setup percpu vmbus handler
From: Michael Kelley @ 2026-04-01 16:55 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-4-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 
> Add a wrapper function - hv_setup_percpu_vmbus_handler(), similar to
> hv_setup_vmbus_handler() to allow setting up custom per-cpu VMBus
> interrupt handler. This is required for arm64 support, to be added
> in MSHV_VTL driver, where per-cpu VMBus interrupt handler will be
> set to mshv_vtl_vmbus_isr() for VTL2 (Virtual Trust Level 2).

Needing both hv_setup_vmbus_handler() and
hv_setup_percpu_vmbus_handler() seems unfortunate. Here's an
alternate approach to consider:

1. I think the x86 VMBus sysvec handler and the vmbus_percpu_isr()
functions could both use the same vmbus_handler global variable.
Looking at your changes in this patch set, hv_setup_vmbus_handler()
and hv_setup_percpu_vmbus_handler() are used together and always
set the same value.

2. So move the global variable vmbus_handler out from arch/x86
and into hv_common.c, and export it. The x86 sysvec handler can
still reference it, and vmbus_percpu_isr() in vmbus_drv.c can
also reference it.  No need to have vmbus_percpu_isr() under
arch/arm64 or have a stub in hv_common.c.

3. hv_setup_vmbus_handler() and hv_remove_vmbus_handler()
also move to hv_common.c.  The __weak stubs go away.

With these changes, only hv_setup_vmbus_handler() needs to
be called, and it works for both x86 with the sysvec handler and
for arm64 with vmbus_percpu_isr().

I haven't coded this up, so maybe there's some problematic detail,
but the idea seems like it would work. If it does work, some of my
comments below are no longer applicable.

> 
> Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  arch/arm64/hyperv/mshyperv.c   | 13 +++++++++++++
>  drivers/hv/hv_common.c         | 11 +++++++++++
>  drivers/hv/vmbus_drv.c         |  7 +------
>  include/asm-generic/mshyperv.h |  3 +++
>  4 files changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index 4fdc26ade1d7..d4494ceeaad0 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -134,3 +134,16 @@ bool hv_is_hyperv_initialized(void)
>  	return hyperv_initialized;
>  }
>  EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
> +
> +static void (*vmbus_percpu_handler)(void);
> +void hv_setup_percpu_vmbus_handler(void (*handler)(void))
> +{
> +	vmbus_percpu_handler = handler;
> +}
> +
> +irqreturn_t vmbus_percpu_isr(int irq, void *dev_id)
> +{
> +	if (vmbus_percpu_handler)
> +		vmbus_percpu_handler();
> +	return IRQ_HANDLED;
> +}
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index d1ebc0ebd08f..a5064f558bf6 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -759,6 +759,17 @@ void __weak hv_setup_vmbus_handler(void (*handler)(void))
>  }
>  EXPORT_SYMBOL_GPL(hv_setup_vmbus_handler);
> 
> +irqreturn_t __weak vmbus_percpu_isr(int irq, void *dev_id)
> +{
> +	return IRQ_HANDLED;
> +}
> +EXPORT_SYMBOL_GPL(vmbus_percpu_isr);
> +
> +void __weak hv_setup_percpu_vmbus_handler(void (*handler)(void))
> +{
> +}
> +EXPORT_SYMBOL_GPL(hv_setup_percpu_vmbus_handler);

You've implemented hv_setup_percpu_vmbus_handler() following
the pattern of hv_setup_vmbus_handler(), which is reasonable.
But that turns out to be unnecessarily complicated. The existing
hv_setup_vmbus_handler() has a portion in
arch/x86/kernel/cpu/mshyperv.c as a special case because it uses a
hard-coded interrupt vector on x86/x64, and has its own custom
sysvec code. And there's a need for a __weak stub in hv_common.c
so that vmbus_drv.c will compile on arm64.

But hv_setup_percpu_vmbus_handler() does not have the same
requirements. It could be implemented entirely in vmbus_drv.c,
with no code under arch/x86 or arch/arm64, and no __weak stub
in hv_common.c.  vmbus_drv.c would just need to
EXPORT_SYMBOL_FOR_MODULES, like it already does with vmbus_isr.
I didn't code it up, but I think that approach would be simpler with
fewer piece-parts scattered all over. If so, it would be worth
breaking the symmetry with hv_setup_vmbus_handler().

> +
>  void __weak hv_remove_vmbus_handler(void)
>  {
>  }
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index bc4fc1951ae1..f99d4f2d3862 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -1413,12 +1413,6 @@ void vmbus_isr(void)
>  }
>  EXPORT_SYMBOL_FOR_MODULES(vmbus_isr, "mshv_vtl");
> 
> -static irqreturn_t vmbus_percpu_isr(int irq, void *dev_id)
> -{
> -	vmbus_isr();
> -	return IRQ_HANDLED;
> -}
> -
>  static void vmbus_percpu_work(struct work_struct *work)
>  {
>  	unsigned int cpu = smp_processor_id();
> @@ -1520,6 +1514,7 @@ static int vmbus_bus_init(void)
>  	if (vmbus_irq == -1) {
>  		hv_setup_vmbus_handler(vmbus_isr);
>  	} else {
> +		hv_setup_percpu_vmbus_handler(vmbus_isr);
>  		ret = request_percpu_irq(vmbus_irq, vmbus_percpu_isr,
>  				"Hyper-V VMbus", &vmbus_evt);
>  		if (ret) {
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index 108f135d4fd9..b147a12085e4 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -22,6 +22,7 @@
>  #include <linux/bitops.h>
>  #include <acpi/acpi_numa.h>
>  #include <linux/cpumask.h>
> +#include <linux/interrupt.h>
>  #include <linux/nmi.h>
>  #include <asm/ptrace.h>
>  #include <hyperv/hvhdk.h>
> @@ -179,6 +180,8 @@ static inline u64 hv_generate_guest_id(u64 kernel_version)
> 
>  int hv_get_hypervisor_version(union hv_hypervisor_version_info *info);
> 
> +irqreturn_t vmbus_percpu_isr(int irq, void *dev_id);
> +void hv_setup_percpu_vmbus_handler(void (*handler)(void));
>  void hv_setup_vmbus_handler(void (*handler)(void));
>  void hv_remove_vmbus_handler(void);
>  void hv_setup_stimer0_handler(void (*handler)(void));
> --
> 2.43.0
> 



^ permalink raw reply

* RE: [PATCH 05/11] drivers: hv: Export vmbus_interrupt for mshv_vtl module
From: Michael Kelley @ 2026-04-01 16:56 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-6-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 

Nit:  For the patch Subject, capitalize "Drivers:" in the prefix.

> vmbus_interrupt is used in mshv_vtl_main.c to set the SINT vector.
> When CONFIG_MSHV_VTL=m and CONFIG_HYPERV_VMBUS=y (built-in), the module
> cannot access vmbus_interrupt at load time since it is not exported.
> 
> Export it using EXPORT_SYMBOL_FOR_MODULES consistent with the existing
> pattern used for vmbus_isr.
> 
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  drivers/hv/vmbus_drv.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index f99d4f2d3862..de191799a8f6 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -57,6 +57,7 @@ static DEFINE_PER_CPU(long, vmbus_evt);
>  /* Values parsed from ACPI DSDT */
>  int vmbus_irq;
>  int vmbus_interrupt;
> +EXPORT_SYMBOL_FOR_MODULES(vmbus_interrupt, "mshv_vtl");
> 
>  /*
>   * If the Confidential VMBus is used, the data on the "wire" is not
> --
> 2.43.0
> 

Reviewed-by: Michael Kelley <mhklinux@outlook.com>



^ permalink raw reply

* RE: [PATCH 06/11] Drivers: hv: Make sint vector architecture neutral in MSHV_VTL
From: Michael Kelley @ 2026-04-01 16:57 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-7-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 
> Generalize Synthetic interrupt source vector (sint) to use
> vmbus_interrupt variable instead, which automatically takes care of
> architectures where HYPERVISOR_CALLBACK_VECTOR is not present (arm64).

Sashiko AI raised an interesting question about the startup timing --
whether the vmbus_platform_driver_probe() is guaranteed to have
set vmbus_interrupt before the VTL functions below run and use it.
What causes the mshv_vtl.ko module to be loaded, and hence run
mshv_vtl_init()?

> 
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  drivers/hv/mshv_vtl_main.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hv/mshv_vtl_main.c b/drivers/hv/mshv_vtl_main.c
> index b607b6e7e121..91517b45d526 100644
> --- a/drivers/hv/mshv_vtl_main.c
> +++ b/drivers/hv/mshv_vtl_main.c
> @@ -234,7 +234,7 @@ static void mshv_vtl_synic_enable_regs(unsigned int cpu)
>  	union hv_synic_sint sint;
> 
>  	sint.as_uint64 = 0;
> -	sint.vector = HYPERVISOR_CALLBACK_VECTOR;
> +	sint.vector = vmbus_interrupt;
>  	sint.masked = false;
>  	sint.auto_eoi = hv_recommend_using_aeoi();
> 
> @@ -753,7 +753,7 @@ static void mshv_vtl_synic_mask_vmbus_sint(void *info)
>  	const u8 *mask = info;
> 
>  	sint.as_uint64 = 0;
> -	sint.vector = HYPERVISOR_CALLBACK_VECTOR;
> +	sint.vector = vmbus_interrupt;
>  	sint.masked = (*mask != 0);
>  	sint.auto_eoi = hv_recommend_using_aeoi();
> 
> --
> 2.43.0
> 

Assuming there's no timing problem vs. the VMBus driver,

Reviewed-by: Michael Kelley <mhklinux@outlook.com>


^ permalink raw reply

* RE: [PATCH 07/11] arch: arm64: Add support for mshv_vtl_return_call
From: Michael Kelley @ 2026-04-01 16:57 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-8-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 

Nit: For historical consistency, use "arm64: hyperv:" as the prefix in the patch Subject.

> Add support for arm64 specific variant of mshv_vtl_return_call function
> to be able to add support for arm64 in MSHV_VTL driver. This would
> help enable the transition between Virtual Trust Levels (VTL) in
> MSHV_VTL when the kernel acts as a paravisor.

This commit message has a fair number of "filler" words. Suggest simplifying to:

Add the arm64 variant of mshv_vtl_return_call() to support the MSHV_VTL
driver on arm64.  This function enables the transition between Virtual Trust
Levels (VTLs) in MSHV_VTL when the kernel acts as a paravisor.

> 
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  arch/arm64/hyperv/Makefile        |   1 +
>  arch/arm64/hyperv/hv_vtl.c        | 144 ++++++++++++++++++++++++++++++
>  arch/arm64/include/asm/mshyperv.h |  13 +++
>  3 files changed, 158 insertions(+)
>  create mode 100644 arch/arm64/hyperv/hv_vtl.c
> 
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 87c31c001da9..9701a837a6e1 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-y		:= hv_core.o mshyperv.o
> +obj-$(CONFIG_HYPERV_VTL_MODE)	+= hv_vtl.o
> diff --git a/arch/arm64/hyperv/hv_vtl.c b/arch/arm64/hyperv/hv_vtl.c
> new file mode 100644
> index 000000000000..66318672c242
> --- /dev/null
> +++ b/arch/arm64/hyperv/hv_vtl.c
> @@ -0,0 +1,144 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2026, Microsoft, Inc.
> + *
> + * Authors:
> + *     Roman Kisel <romank@linux.microsoft.com>
> + *     Naman Jain <namjain@linux.microsoft.com>
> + */
> +
> +#include <asm/boot.h>
> +#include <asm/mshyperv.h>
> +#include <asm/cpu_ops.h>
> +
> +void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0)
> +{
> +	u64 base_ptr = (u64)vtl0->x;
> +
> +	/*
> +	 * VTL switch for ARM64 platform - managing VTL0's CPU context.
> +	 * We explicitly use the stack to save the base pointer, and use x16
> +	 * as our working register for accessing the context structure.
> +	 *
> +	 * Register Handling:
> +	 * - X0-X17: Saved/restored (general-purpose, shared for VTL communication)
> +	 * - X18: NOT touched - hypervisor-managed per-VTL (platform register)
> +	 * - X19-X30: Saved/restored (part of VTL0's execution context)
> +	 * - Q0-Q31: Saved/restored (128-bit NEON/floating-point registers, shared)
> +	 * - SP: Not in structure, hypervisor-managed per-VTL
> +	 *
> +	 * Note: X29 (FP) and X30 (LR) are in the structure and must be saved/restored
> +	 * as part of VTL0's complete execution state.

Could drop "Note:".  That's what comments are. :-)


> +	 */
> +	asm __volatile__ (
> +		/* Save base pointer to stack explicitly, then load into x16 */
> +		"str %0, [sp, #-16]!\n\t"     /* Push base pointer onto stack */
> +		"mov x16, %0\n\t"             /* Load base pointer into x16 */
> +		/* Volatile registers (Windows ARM64 ABI: x0-x15) */
> +		"ldp x0, x1, [x16]\n\t"
> +		"ldp x2, x3, [x16, #(2*8)]\n\t"

On the x86 side, there's machinery to generate a series of constants that are
the offsets of the individual fields in struct mshv_vtl_cpu_context. The x86
asm code then uses these constants. Here on the arm64 side, you've calculated
the offsets directly in the asm code. Any reason for the difference? I can see
it's fairly easy to eyeball the offsets here and compare against the registers
that are being loaded, where it's not so easy the way registers are named
on x86. So maybe the additional machinery that's helpful on the x86 side
is less necessary here. Just wondering ....

> +		"ldp x4, x5, [x16, #(4*8)]\n\t"
> +		"ldp x6, x7, [x16, #(6*8)]\n\t"
> +		"ldp x8, x9, [x16, #(8*8)]\n\t"
> +		"ldp x10, x11, [x16, #(10*8)]\n\t"
> +		"ldp x12, x13, [x16, #(12*8)]\n\t"
> +		"ldp x14, x15, [x16, #(14*8)]\n\t"
> +		/* x16 will be loaded last, after saving base pointer */
> +		"ldr x17, [x16, #(17*8)]\n\t"
> +		/* x18 is hypervisor-managed per-VTL - DO NOT LOAD */
> +
> +		/* General-purpose registers: x19-x30 */
> +		"ldp x19, x20, [x16, #(19*8)]\n\t"
> +		"ldp x21, x22, [x16, #(21*8)]\n\t"
> +		"ldp x23, x24, [x16, #(23*8)]\n\t"
> +		"ldp x25, x26, [x16, #(25*8)]\n\t"
> +		"ldp x27, x28, [x16, #(27*8)]\n\t"
> +
> +		/* Frame pointer and link register */
> +		"ldp x29, x30, [x16, #(29*8)]\n\t"
> +
> +		/* Shared NEON/FP registers: Q0-Q31 (128-bit) */
> +		"ldp q0, q1, [x16, #(32*8)]\n\t"
> +		"ldp q2, q3, [x16, #(32*8 + 2*16)]\n\t"
> +		"ldp q4, q5, [x16, #(32*8 + 4*16)]\n\t"
> +		"ldp q6, q7, [x16, #(32*8 + 6*16)]\n\t"
> +		"ldp q8, q9, [x16, #(32*8 + 8*16)]\n\t"
> +		"ldp q10, q11, [x16, #(32*8 + 10*16)]\n\t"
> +		"ldp q12, q13, [x16, #(32*8 + 12*16)]\n\t"
> +		"ldp q14, q15, [x16, #(32*8 + 14*16)]\n\t"
> +		"ldp q16, q17, [x16, #(32*8 + 16*16)]\n\t"
> +		"ldp q18, q19, [x16, #(32*8 + 18*16)]\n\t"
> +		"ldp q20, q21, [x16, #(32*8 + 20*16)]\n\t"
> +		"ldp q22, q23, [x16, #(32*8 + 22*16)]\n\t"
> +		"ldp q24, q25, [x16, #(32*8 + 24*16)]\n\t"
> +		"ldp q26, q27, [x16, #(32*8 + 26*16)]\n\t"
> +		"ldp q28, q29, [x16, #(32*8 + 28*16)]\n\t"
> +		"ldp q30, q31, [x16, #(32*8 + 30*16)]\n\t"
> +
> +		/* Now load x16 itself */
> +		"ldr x16, [x16, #(16*8)]\n\t"
> +
> +		/* Return to the lower VTL */
> +		"hvc #3\n\t"
> +
> +		/* Save context after return - reload base pointer from stack */
> +		"stp x16, x17, [sp, #-16]!\n\t" /* Save x16, x17 temporarily */
> +		"ldr x16, [sp, #16]\n\t"        /* Reload base pointer (skip saved x16,x17) */
> +
> +		/* Volatile registers */
> +		"stp x0, x1, [x16]\n\t"
> +		"stp x2, x3, [x16, #(2*8)]\n\t"
> +		"stp x4, x5, [x16, #(4*8)]\n\t"
> +		"stp x6, x7, [x16, #(6*8)]\n\t"
> +		"stp x8, x9, [x16, #(8*8)]\n\t"
> +		"stp x10, x11, [x16, #(10*8)]\n\t"
> +		"stp x12, x13, [x16, #(12*8)]\n\t"
> +		"stp x14, x15, [x16, #(14*8)]\n\t"
> +		"ldp x0, x1, [sp], #16\n\t"      /* Recover saved x16, x17 */
> +		"stp x0, x1, [x16, #(16*8)]\n\t"
> +		/* x18 is hypervisor-managed - DO NOT SAVE */
> +
> +		/* General-purpose registers: x19-x30 */
> +		"stp x19, x20, [x16, #(19*8)]\n\t"
> +		"stp x21, x22, [x16, #(21*8)]\n\t"
> +		"stp x23, x24, [x16, #(23*8)]\n\t"
> +		"stp x25, x26, [x16, #(25*8)]\n\t"
> +		"stp x27, x28, [x16, #(27*8)]\n\t"
> +		"stp x29, x30, [x16, #(29*8)]\n\t"  /* Frame pointer and link register */
> +
> +		/* Shared NEON/FP registers: Q0-Q31 (128-bit) */
> +		"stp q0, q1, [x16, #(32*8)]\n\t"
> +		"stp q2, q3, [x16, #(32*8 + 2*16)]\n\t"
> +		"stp q4, q5, [x16, #(32*8 + 4*16)]\n\t"
> +		"stp q6, q7, [x16, #(32*8 + 6*16)]\n\t"
> +		"stp q8, q9, [x16, #(32*8 + 8*16)]\n\t"
> +		"stp q10, q11, [x16, #(32*8 + 10*16)]\n\t"
> +		"stp q12, q13, [x16, #(32*8 + 12*16)]\n\t"
> +		"stp q14, q15, [x16, #(32*8 + 14*16)]\n\t"
> +		"stp q16, q17, [x16, #(32*8 + 16*16)]\n\t"
> +		"stp q18, q19, [x16, #(32*8 + 18*16)]\n\t"
> +		"stp q20, q21, [x16, #(32*8 + 20*16)]\n\t"
> +		"stp q22, q23, [x16, #(32*8 + 22*16)]\n\t"
> +		"stp q24, q25, [x16, #(32*8 + 24*16)]\n\t"
> +		"stp q26, q27, [x16, #(32*8 + 26*16)]\n\t"
> +		"stp q28, q29, [x16, #(32*8 + 28*16)]\n\t"
> +		"stp q30, q31, [x16, #(32*8 + 30*16)]\n\t"
> +
> +		/* Clean up stack - pop base pointer */
> +		"add sp, sp, #16\n\t"
> +
> +		: /* No outputs */
> +		: /* Input */ "r"(base_ptr)
> +		: /* Clobber list - x16 used as base, x18 is hypervisor-managed (not touched) */
> +		"memory", "cc",
> +		"x0", "x1", "x2", "x3", "x4", "x5",
> +		"x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
> +		"x14", "x15", "x16", "x17", "x19", "x20", "x21",
> +		"x22", "x23", "x24", "x25", "x26", "x27", "x28",
> +		"x29", "x30",
> +		"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
> +		"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
> +		"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
> +		"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31");
> +}
> +EXPORT_SYMBOL(mshv_vtl_return_call);
> diff --git a/arch/arm64/include/asm/mshyperv.h
> b/arch/arm64/include/asm/mshyperv.h
> index 804068e0941b..de7f3a41a8ea 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -60,6 +60,17 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
>  				ARM_SMCCC_SMC_64,		\
>  				ARM_SMCCC_OWNER_VENDOR_HYP,	\
>  				HV_SMCCC_FUNC_NUMBER)
> +
> +struct mshv_vtl_cpu_context {
> +/*
> + * NOTE: x18 is managed by the hypervisor. It won't be reloaded from this array.
> + * It is included here for convenience in the common case.

I'm not getting your point in this last sentence. What is the "common case"?

You could also drop the "NOTE: " prefix.

> + */
> +	__u64 x[31];
> +	__u64 rsvd;
> +	__uint128_t q[32];
> +};

struct mshv_vtl_run reserves 1024 bytes for cpu_context. It would be nice to
have a compile-time check that the size of struct mshv_vtl_cpu_context fits in
that 1024 bytes. That check might be better added where struct mshv_vtl_run
is defined so that it works for both x86 and arm64.

> +
>  #ifdef CONFIG_HYPERV_VTL_MODE
>  /*
>   * Get/Set the register. If the function returns `1`, that must be done via
> @@ -69,6 +80,8 @@ static inline int hv_vtl_get_set_reg(struct hv_register_assoc *regs, bool set, u
>  {
>  	return 1;
>  }
> +
> +void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0);

This declaration now duplicated in mshyperv.h under arch/arm64 and under
arch/x86.  Instead, it should be added to asm-generic/mshyperv.h, and
removed from the arch/x86 mshyperv.h, so that there's only a single
instance of the declaration.

>  #endif
> 
>  #include <asm-generic/mshyperv.h>
> --
> 2.43.0
> 



^ permalink raw reply

* RE: [PATCH 08/11] Drivers: hv: mshv_vtl: Move register page config to arch-specific files
From: Michael Kelley @ 2026-04-01 16:58 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-9-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 
> Move mshv_vtl_configure_reg_page() implementation from
> drivers/hv/mshv_vtl_main.c to arch-specific files:
> - arch/x86/hyperv/hv_vtl.c: full implementation with register page setup
> - arch/arm64/hyperv/hv_vtl.c: stub implementation (unsupported)
> 
> Move common type definitions to include/asm-generic/mshyperv.h:
> - struct mshv_vtl_per_cpu
> - union hv_synic_overlay_page_msr
> 
> Move hv_call_get_vp_registers() and hv_call_set_vp_registers()
> declarations to include/asm-generic/mshyperv.h since these functions
> are used by multiple modules.
> 
> While at it, remove the unnecessary stub implementations in #else
> case for mshv_vtl_return* functions in arch/x86/include/asm/mshyperv.h.

Seems like this patch is doing multiple things. The reg page configuration
changes are more substantial and should probably be in a patch by
themselves. The other changes are more trivial and maybe are OK
grouped into a single patch, but you could also consider breaking them
out.

> 
> This is essential for adding support for ARM64 in MSHV_VTL.
> 
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  arch/arm64/hyperv/hv_vtl.c        |  8 +++++
>  arch/arm64/include/asm/mshyperv.h |  3 ++
>  arch/x86/hyperv/hv_vtl.c          | 32 ++++++++++++++++++++
>  arch/x86/include/asm/mshyperv.h   |  7 ++---
>  drivers/hv/mshv.h                 |  8 -----
>  drivers/hv/mshv_vtl_main.c        | 49 +++----------------------------
>  include/asm-generic/mshyperv.h    | 42 ++++++++++++++++++++++++++
>  7 files changed, 92 insertions(+), 57 deletions(-)
> 
> diff --git a/arch/arm64/hyperv/hv_vtl.c b/arch/arm64/hyperv/hv_vtl.c
> index 66318672c242..d699138427c1 100644
> --- a/arch/arm64/hyperv/hv_vtl.c
> +++ b/arch/arm64/hyperv/hv_vtl.c
> @@ -10,6 +10,7 @@
>  #include <asm/boot.h>
>  #include <asm/mshyperv.h>
>  #include <asm/cpu_ops.h>
> +#include <linux/export.h>
> 
>  void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0)
>  {
> @@ -142,3 +143,10 @@ void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0)
>  		"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31");
>  }
>  EXPORT_SYMBOL(mshv_vtl_return_call);
> +
> +bool hv_vtl_configure_reg_page(struct mshv_vtl_per_cpu *per_cpu)
> +{
> +	pr_debug("Register page not supported on ARM64\n");
> +	return false;
> +}
> +EXPORT_SYMBOL_GPL(hv_vtl_configure_reg_page);
> diff --git a/arch/arm64/include/asm/mshyperv.h
> b/arch/arm64/include/asm/mshyperv.h
> index de7f3a41a8ea..36803f0386cc 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -61,6 +61,8 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
>  				ARM_SMCCC_OWNER_VENDOR_HYP,	\
>  				HV_SMCCC_FUNC_NUMBER)
> 
> +struct mshv_vtl_per_cpu;
> +
>  struct mshv_vtl_cpu_context {
>  /*
>   * NOTE: x18 is managed by the hypervisor. It won't be reloaded from this array.
> @@ -82,6 +84,7 @@ static inline int hv_vtl_get_set_reg(struct hv_register_assoc *regs,
> bool set, u
>  }
> 
>  void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0);
> +bool hv_vtl_configure_reg_page(struct mshv_vtl_per_cpu *per_cpu);

I think this declaration could be added in asm-generic/mshyperv.h so that it
is shared by x86 and arm64. That also obviates the need for the forward
ref to struct mshv_vtl_per_cpu that you've added here.

>  #endif
> 
>  #include <asm-generic/mshyperv.h>
> diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
> index 72a0bb4ae0c7..ede290985d41 100644
> --- a/arch/x86/hyperv/hv_vtl.c
> +++ b/arch/x86/hyperv/hv_vtl.c
> @@ -20,6 +20,7 @@
>  #include <uapi/asm/mtrr.h>
>  #include <asm/debugreg.h>
>  #include <linux/export.h>
> +#include <linux/hyperv.h>
>  #include <../kernel/smpboot.h>
>  #include "../../kernel/fpu/legacy.h"
> 
> @@ -259,6 +260,37 @@ int __init hv_vtl_early_init(void)
>  	return 0;
>  }
> 
> +static const union hv_input_vtl input_vtl_zero;
> +
> +bool hv_vtl_configure_reg_page(struct mshv_vtl_per_cpu *per_cpu)
> +{
> +	struct hv_register_assoc reg_assoc = {};
> +	union hv_synic_overlay_page_msr overlay = {};
> +	struct page *reg_page;
> +
> +	reg_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL);
> +	if (!reg_page) {
> +		WARN(1, "failed to allocate register page\n");
> +		return false;
> +	}
> +
> +	overlay.enabled = 1;
> +	overlay.pfn = page_to_hvpfn(reg_page);
> +	reg_assoc.name = HV_X64_REGISTER_REG_PAGE;
> +	reg_assoc.value.reg64 = overlay.as_uint64;
> +
> +	if (hv_call_set_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> +				     1, input_vtl_zero, &reg_assoc)) {
> +		WARN(1, "failed to setup register page\n");
> +		__free_page(reg_page);
> +		return false;
> +	}
> +
> +	per_cpu->reg_page = reg_page;
> +	return true;

As Sashiko AI noted, the memory allocated for the reg_page never gets freed.

> +}
> +EXPORT_SYMBOL_GPL(hv_vtl_configure_reg_page);
> +
>  DEFINE_STATIC_CALL_NULL(__mshv_vtl_return_hypercall, void (*)(void));
> 
>  void mshv_vtl_return_call_init(u64 vtl_return_offset)
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index d5355a5b7517..d592fea49cdb 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -271,6 +271,8 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg) {
> return 0; }
>  static inline int hv_apicid_to_vp_index(u32 apic_id) { return -EINVAL; }
>  #endif /* CONFIG_HYPERV */
> 
> +struct mshv_vtl_per_cpu;
> +
>  struct mshv_vtl_cpu_context {
>  	union {
>  		struct {
> @@ -305,13 +307,10 @@ void mshv_vtl_return_call_init(u64 vtl_return_offset);
>  void mshv_vtl_return_hypercall(void);
>  void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0);
>  int hv_vtl_get_set_reg(struct hv_register_assoc *regs, bool set, u64 shared);
> +bool hv_vtl_configure_reg_page(struct mshv_vtl_per_cpu *per_cpu);

Same as for arm64. Add a shared declaration in asm-generic/mshyperv.h.

>  #else
>  static inline void __init hv_vtl_init_platform(void) {}
>  static inline int __init hv_vtl_early_init(void) { return 0; }
> -static inline void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) {}
> -static inline void mshv_vtl_return_call_init(u64 vtl_return_offset) {}
> -static inline void mshv_vtl_return_hypercall(void) {}
> -static inline void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) {}
>  #endif
> 
>  #include <asm-generic/mshyperv.h>
> diff --git a/drivers/hv/mshv.h b/drivers/hv/mshv.h
> index d4813df92b9c..0fcb7f9ba6a9 100644
> --- a/drivers/hv/mshv.h
> +++ b/drivers/hv/mshv.h
> @@ -14,14 +14,6 @@
>  	memchr_inv(&((STRUCT).MEMBER), \
>  		   0, sizeof_field(typeof(STRUCT), MEMBER))
> 
> -int hv_call_get_vp_registers(u32 vp_index, u64 partition_id, u16 count,
> -			     union hv_input_vtl input_vtl,
> -			     struct hv_register_assoc *registers);
> -
> -int hv_call_set_vp_registers(u32 vp_index, u64 partition_id, u16 count,
> -			     union hv_input_vtl input_vtl,
> -			     struct hv_register_assoc *registers);
> -
>  int hv_call_get_partition_property(u64 partition_id, u64 property_code,
>  				   u64 *property_value);
> 
> diff --git a/drivers/hv/mshv_vtl_main.c b/drivers/hv/mshv_vtl_main.c
> index 91517b45d526..c79d24317b8e 100644
> --- a/drivers/hv/mshv_vtl_main.c
> +++ b/drivers/hv/mshv_vtl_main.c
> @@ -78,21 +78,6 @@ struct mshv_vtl {
>  	u64 id;
>  };
> 
> -struct mshv_vtl_per_cpu {
> -	struct mshv_vtl_run *run;
> -	struct page *reg_page;
> -};
> -
> -/* SYNIC_OVERLAY_PAGE_MSR - internal, identical to hv_synic_simp */
> -union hv_synic_overlay_page_msr {
> -	u64 as_uint64;
> -	struct {
> -		u64 enabled: 1;
> -		u64 reserved: 11;
> -		u64 pfn: 52;
> -	} __packed;
> -};
> -
>  static struct mutex mshv_vtl_poll_file_lock;
>  static union hv_register_vsm_page_offsets mshv_vsm_page_offsets;
>  static union hv_register_vsm_capabilities mshv_vsm_capabilities;
> @@ -201,34 +186,6 @@ static struct page *mshv_vtl_cpu_reg_page(int cpu)
>  	return *per_cpu_ptr(&mshv_vtl_per_cpu.reg_page, cpu);
>  }
> 
> -static void mshv_vtl_configure_reg_page(struct mshv_vtl_per_cpu *per_cpu)
> -{
> -	struct hv_register_assoc reg_assoc = {};
> -	union hv_synic_overlay_page_msr overlay = {};
> -	struct page *reg_page;
> -
> -	reg_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL);
> -	if (!reg_page) {
> -		WARN(1, "failed to allocate register page\n");
> -		return;
> -	}
> -
> -	overlay.enabled = 1;
> -	overlay.pfn = page_to_hvpfn(reg_page);
> -	reg_assoc.name = HV_X64_REGISTER_REG_PAGE;
> -	reg_assoc.value.reg64 = overlay.as_uint64;
> -
> -	if (hv_call_set_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> -				     1, input_vtl_zero, &reg_assoc)) {
> -		WARN(1, "failed to setup register page\n");
> -		__free_page(reg_page);
> -		return;
> -	}
> -
> -	per_cpu->reg_page = reg_page;
> -	mshv_has_reg_page = true;
> -}
> -
>  static void mshv_vtl_synic_enable_regs(unsigned int cpu)
>  {
>  	union hv_synic_sint sint;
> @@ -329,8 +286,10 @@ static int mshv_vtl_alloc_context(unsigned int cpu)
>  	if (!per_cpu->run)
>  		return -ENOMEM;
> 
> -	if (mshv_vsm_capabilities.intercept_page_available)
> -		mshv_vtl_configure_reg_page(per_cpu);
> +	if (mshv_vsm_capabilities.intercept_page_available) {
> +		if (hv_vtl_configure_reg_page(per_cpu))
> +			mshv_has_reg_page = true;

As Sashiko AI noted, it doesn't work to use the global mshv_has_reg_page
to indicate the success of configuring the reg page, which is a per-cpu
operation. But this bug existed before this patch set, so maybe it should
be fixed as a preliminary patch.

> +	}
> 
>  	mshv_vtl_synic_enable_regs(cpu);
> 
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index b147a12085e4..b53fcc071596 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -383,8 +383,50 @@ static inline int hv_deposit_memory(u64 partition_id, u64 status)
>  	return hv_deposit_memory_node(NUMA_NO_NODE, partition_id, status);
>  }
> 
> +#if IS_ENABLED(CONFIG_MSHV_ROOT) || IS_ENABLED(CONFIG_MSHV_VTL)
> +int hv_call_get_vp_registers(u32 vp_index, u64 partition_id, u16 count,
> +			     union hv_input_vtl input_vtl,
> +			     struct hv_register_assoc *registers);
> +
> +int hv_call_set_vp_registers(u32 vp_index, u64 partition_id, u16 count,
> +			     union hv_input_vtl input_vtl,
> +			     struct hv_register_assoc *registers);
> +#else
> +static inline int hv_call_get_vp_registers(u32 vp_index, u64 partition_id,
> +					   u16 count,
> +					   union hv_input_vtl input_vtl,
> +					   struct hv_register_assoc *registers)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int hv_call_set_vp_registers(u32 vp_index, u64 partition_id,
> +					   u16 count,
> +					   union hv_input_vtl input_vtl,
> +					   struct hv_register_assoc *registers)
> +{
> +	return -EOPNOTSUPP;
> +}
> +#endif /* CONFIG_MSHV_ROOT || CONFIG_MSHV_VTL */
> +
>  #define HV_VP_ASSIST_PAGE_ADDRESS_SHIFT	12
> +
>  #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
> +struct mshv_vtl_per_cpu {
> +	struct mshv_vtl_run *run;
> +	struct page *reg_page;
> +};
> +
> +/* SYNIC_OVERLAY_PAGE_MSR - internal, identical to hv_synic_simp */
> +union hv_synic_overlay_page_msr {
> +	u64 as_uint64;
> +	struct {
> +		u64 enabled: 1;
> +		u64 reserved: 11;
> +		u64 pfn: 52;
> +	} __packed;
> +};
> +
>  u8 __init get_vtl(void);
>  #else
>  static inline u8 get_vtl(void) { return 0; }
> --
> 2.43.0
> 

Sashiko AI noted another existing bug in mshv_vtl_init(), which is that
the error path does kfree(mem_dev) when it should do
put_device(mem_dev).  See the comment in the header of
device_initialize().



^ permalink raw reply

* RE: [PATCH 09/11] Drivers: hv: mshv_vtl: Let userspace do VSM configuration
From: Michael Kelley @ 2026-04-01 16:58 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-10-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 
> The kernel currently sets the VSM configuration register, thereby
> imposing certain VSM configuration on the userspace (OpenVMM).
> 
> The userspace (OpenVMM) has the capability to configure this register,
> and it is already doing it using the generic hypercall interface.
> The configuration can vary based on the use case or architectures, so
> let userspace take care of configuring it and remove this logic in the
> kernel driver.
> 
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  drivers/hv/mshv_vtl_main.c | 29 -----------------------------
>  1 file changed, 29 deletions(-)
> 
> diff --git a/drivers/hv/mshv_vtl_main.c b/drivers/hv/mshv_vtl_main.c
> index c79d24317b8e..4c9ae65ad3e8 100644
> --- a/drivers/hv/mshv_vtl_main.c
> +++ b/drivers/hv/mshv_vtl_main.c
> @@ -222,30 +222,6 @@ static int mshv_vtl_get_vsm_regs(void)
>  	return ret;
>  }
> 
> -static int mshv_vtl_configure_vsm_partition(struct device *dev)
> -{
> -	union hv_register_vsm_partition_config config;
> -	struct hv_register_assoc reg_assoc;
> -
> -	config.as_uint64 = 0;
> -	config.default_vtl_protection_mask = HV_MAP_GPA_PERMISSIONS_MASK;
> -	config.enable_vtl_protection = 1;
> -	config.zero_memory_on_reset = 1;
> -	config.intercept_vp_startup = 1;
> -	config.intercept_cpuid_unimplemented = 1;
> -
> -	if (mshv_vsm_capabilities.intercept_page_available) {
> -		dev_dbg(dev, "using intercept page\n");
> -		config.intercept_page = 1;
> -	}
> -
> -	reg_assoc.name = HV_REGISTER_VSM_PARTITION_CONFIG;
> -	reg_assoc.value.reg64 = config.as_uint64;
> -
> -	return hv_call_set_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> -				       1, input_vtl_zero, &reg_assoc);
> -}
> -
>  static void mshv_vtl_vmbus_isr(void)
>  {
>  	struct hv_per_cpu_context *per_cpu;
> @@ -1168,11 +1144,6 @@ static int __init mshv_vtl_init(void)
>  		ret = -ENODEV;
>  		goto free_dev;
>  	}
> -	if (mshv_vtl_configure_vsm_partition(dev)) {
> -		dev_emerg(dev, "VSM configuration failed !!\n");
> -		ret = -ENODEV;
> -		goto free_dev;
> -	}
> 
>  	mshv_vtl_return_call_init(mshv_vsm_page_offsets.vtl_return_offset);
>  	ret = hv_vtl_setup_synic();
> --
> 2.43.0
> 

Reviewed-by: Michael Kelley <mhklinux@outlook.com>



^ permalink raw reply

* RE: [PATCH 10/11] Drivers: hv: Add support for arm64 in MSHV_VTL
From: Michael Kelley @ 2026-04-01 16:58 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, Michael Kelley,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <20260316121241.910764-11-namjain@linux.microsoft.com>

From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
> 
> Add necessary support to make MSHV_VTL work for arm64 architecture.
> * Add stub implementation for mshv_vtl_return_call_init(): not required
>   for arm64
> * Remove fpu/legacy.h header inclusion, as this is not required
> * handle HV_REGISTER_VSM_CODE_PAGE_OFFSETS register: not supported
>   in arm64
> * Configure custom percpu_vmbus_handler by using
>   hv_setup_percpu_vmbus_handler()
> * Handle hugepage functions by config checks
> 
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  arch/arm64/include/asm/mshyperv.h |  2 ++
>  drivers/hv/mshv_vtl_main.c        | 21 ++++++++++++++-------
>  2 files changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/mshyperv.h
> b/arch/arm64/include/asm/mshyperv.h
> index 36803f0386cc..027a7f062d70 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -83,6 +83,8 @@ static inline int hv_vtl_get_set_reg(struct hv_register_assoc *regs, bool set, u
>  	return 1;
>  }
> 
> +static inline void mshv_vtl_return_call_init(u64 vtl_return_offset) {}
> +
>  void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0);
>  bool hv_vtl_configure_reg_page(struct mshv_vtl_per_cpu *per_cpu);
>  #endif
> diff --git a/drivers/hv/mshv_vtl_main.c b/drivers/hv/mshv_vtl_main.c
> index 4c9ae65ad3e8..5702fe258500 100644
> --- a/drivers/hv/mshv_vtl_main.c
> +++ b/drivers/hv/mshv_vtl_main.c
> @@ -23,8 +23,6 @@
>  #include <trace/events/ipi.h>
>  #include <uapi/linux/mshv.h>
>  #include <hyperv/hvhdk.h>
> -
> -#include "../../kernel/fpu/legacy.h"

Was there a particular code change that made this unnecessary? Or was it
unnecessary from the start of this source code file? Just curious ....

>  #include "mshv.h"
>  #include "mshv_vtl.h"
>  #include "hyperv_vmbus.h"
> @@ -206,18 +204,21 @@ static void mshv_vtl_synic_enable_regs(unsigned int cpu)
>  static int mshv_vtl_get_vsm_regs(void)
>  {
>  	struct hv_register_assoc registers[2];
> -	int ret, count = 2;
> +	int ret, count = 0;
> 
> -	registers[0].name = HV_REGISTER_VSM_CODE_PAGE_OFFSETS;
> -	registers[1].name = HV_REGISTER_VSM_CAPABILITIES;
> +	registers[count++].name = HV_REGISTER_VSM_CAPABILITIES;
> +	/* Code page offset register is not supported on ARM */
> +	if (IS_ENABLED(CONFIG_X86_64))
> +		registers[count++].name = HV_REGISTER_VSM_CODE_PAGE_OFFSETS;
> 
>  	ret = hv_call_get_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
>  				       count, input_vtl_zero, registers);
>  	if (ret)
>  		return ret;
> 
> -	mshv_vsm_page_offsets.as_uint64 = registers[0].value.reg64;
> -	mshv_vsm_capabilities.as_uint64 = registers[1].value.reg64;
> +	mshv_vsm_capabilities.as_uint64 = registers[0].value.reg64;
> +	if (IS_ENABLED(CONFIG_X86_64))
> +		mshv_vsm_page_offsets.as_uint64 = registers[1].value.reg64;
> 
>  	return ret;
>  }

This function has gotten somewhat messy to handle the x86 and arm64
differences. Let me suggest a different approach. Have this function only
get the VSM capabilities register, as that is generic across x86 and
arm64. Then, update x86 mshv_vtl_return_call_init() to get the
PAGE_OFFSETS register and then immediately use the value to update
the static call. The global variable mshv_vms_page_offsets is no longer
necessary.

My suggestion might be little more code because hv_call_get_vp_registers()
is invoked in two different places. But it cleanly separates the two use
cases, and keeps the x86 hackery under arch/x86.

> @@ -280,10 +281,13 @@ static int hv_vtl_setup_synic(void)
> 
>  	/* Use our isr to first filter out packets destined for userspace */
>  	hv_setup_vmbus_handler(mshv_vtl_vmbus_isr);
> +	/* hv_setup_vmbus_handler() is stubbed for ARM64, add per-cpu VMBus handlers instead */
> +	hv_setup_percpu_vmbus_handler(mshv_vtl_vmbus_isr);
> 
>  	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hyperv/vtl:online",
>  				mshv_vtl_alloc_context, NULL);
>  	if (ret < 0) {
> +		hv_setup_percpu_vmbus_handler(vmbus_isr);
>  		hv_setup_vmbus_handler(vmbus_isr);
>  		return ret;
>  	}
> @@ -296,6 +300,7 @@ static int hv_vtl_setup_synic(void)
>  static void hv_vtl_remove_synic(void)
>  {
>  	cpuhp_remove_state(mshv_vtl_cpuhp_online);
> +	hv_setup_percpu_vmbus_handler(vmbus_isr);
>  	hv_setup_vmbus_handler(vmbus_isr);
>  }
> 
> @@ -1080,10 +1085,12 @@ static vm_fault_t mshv_vtl_low_huge_fault(struct vm_fault *vmf, unsigned int ord
>  			ret = vmf_insert_pfn_pmd(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE);
>  		return ret;
> 
> +#if defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
>  	case PUD_ORDER:
>  		if (can_fault(vmf, PUD_SIZE, &pfn))
>  			ret = vmf_insert_pfn_pud(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE);
>  		return ret;
> +#endif
> 
>  	default:
>  		return VM_FAULT_SIGBUS;
> --
> 2.43.0
> 



^ permalink raw reply


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