Linux-HyperV List
 help / color / mirror / Atom feed
* Re: [PATCH 4/6] mshv: limit SynIC management to MSHV-owned resources
From: Anirudh Rayabharam @ 2026-04-02 16:13 UTC (permalink / raw)
  To: Jork Loeser
  Cc: linux-hyperv, x86, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Arnd Bergmann,
	Roman Kisel, Michael Kelley, linux-kernel, linux-arch
In-Reply-To: <20260327201920.2100427-5-jloeser@linux.microsoft.com>

On Fri, Mar 27, 2026 at 01:19:15PM -0700, Jork Loeser wrote:
> The SynIC is shared between VMBus and MSHV. VMBus owns the message
> page (SIMP), event flags page (SIEFP), global enable (SCONTROL), and
> SINT2. MSHV adds SINT0, SINT5, and the event ring page (SIRBP).
> 
> Currently mshv_synic_init() redundantly enables SIMP, SIEFP, and
> SCONTROL that VMBus already configured, and mshv_synic_cleanup()
> disables all of them. This is wrong because MSHV can be torn down
> while VMBus is still active. In particular, a kexec reboot notifier
> tears down MSHV first. Disabling SCONTROL, SIMP, and SIEFP out from
> under VMBus causes its later cleanup to write SynIC MSRs while SynIC
> is disabled, which the hypervisor does not tolerate.
> 
> Restrict MSHV to managing only the resources it owns:
> - SINT0, SINT5: mask on cleanup, unmask on init
> - SIRBP: enable/disable as before
> - SIMP, SIEFP, SCONTROL: on L1VH leave entirely to VMBus (it
>   already enabled them); on root partition VMBus doesn't run, so
>   MSHV must enable/disable them

Maybe it's time to extract all the synic management stuff to a separate
file to act like synic "driver" which facilitates synic access to
mutiple users i.e. mshv & vmbus.

Thanks,
Anirudh.


^ permalink raw reply

* Re: [PATCH 1/6] Drivers: hv: vmbus: fix hyperv_cpuhp_online variable shadowing
From: Anirudh Rayabharam @ 2026-04-02 15:55 UTC (permalink / raw)
  To: Jork Loeser
  Cc: linux-hyperv, x86, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Arnd Bergmann,
	Roman Kisel, Michael Kelley, linux-kernel, linux-arch
In-Reply-To: <20260327201920.2100427-2-jloeser@linux.microsoft.com>

On Fri, Mar 27, 2026 at 01:19:12PM -0700, Jork Loeser wrote:
> vmbus_alloc_synic_and_connect() declares a local 'int
> hyperv_cpuhp_online' that shadows the file-scope global of the same
> name. The cpuhp state returned by cpuhp_setup_state() is stored in
> the local, leaving the global at 0 (CPUHP_OFFLINE). When
> hv_kexec_handler() or hv_machine_shutdown() later call
> cpuhp_remove_state(hyperv_cpuhp_online) they pass 0, which hits the
> BUG_ON in __cpuhp_remove_state_cpuslocked().
> 
> Remove the local declaration so the cpuhp state is stored in the
> file-scope global where hv_kexec_handler() and hv_machine_shutdown()
> expect it.
> 
> Fixes: 2647c96649ba ("Drivers: hv: Support establishing the confidential VMBus connection")
> Signed-off-by: Jork Loeser <jloeser@linux.microsoft.com>
> ---
>  drivers/hv/vmbus_drv.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index 3e7a52918ce0..301273d61892 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -1430,7 +1430,6 @@ static int vmbus_alloc_synic_and_connect(void)
>  {
>  	int ret, cpu;
>  	struct work_struct __percpu *works;
> -	int hyperv_cpuhp_online;
>  
>  	ret = hv_synic_alloc();
>  	if (ret < 0)
> -- 
> 2.43.0
> 

Reviewed-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>


^ permalink raw reply

* Re: [PATCH] mshv: Add tracepoint for GPA intercept handling
From: Anirudh Rayabharam @ 2026-04-02 15:45 UTC (permalink / raw)
  To: Stanislav Kinsburskii
  Cc: kys, haiyangz, wei.liu, decui, longli, linux-hyperv, linux-kernel
In-Reply-To: <177439679671.175364.15362688285596134992.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>

On Tue, Mar 24, 2026 at 11:59:59PM +0000, Stanislav Kinsburskii wrote:
> Provide visibility into GPA intercept operations for debugging and
> performance analysis of Microsoft Hypervisor guest memory management.
> 
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> ---
>  drivers/hv/mshv_root_main.c |    6 ++++--
>  drivers/hv/mshv_trace.h     |   29 +++++++++++++++++++++++++++++
>  2 files changed, 33 insertions(+), 2 deletions(-)

Reviewed-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>


^ permalink raw reply

* Re: [PATCH] mshv: Fix infinite fault loop on permission-denied GPA intercepts
From: Anirudh Rayabharam @ 2026-04-02 15:44 UTC (permalink / raw)
  To: Stanislav Kinsburskii
  Cc: kys, haiyangz, wei.liu, decui, longli, linux-hyperv, linux-kernel
In-Reply-To: <177439665824.171668.3582744847973205980.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>

On Tue, Mar 24, 2026 at 11:57:40PM +0000, Stanislav Kinsburskii wrote:
> Prevent infinite fault loops when guests access memory regions without
> proper permissions. Currently, mshv_handle_gpa_intercept() attempts to
> remap pages for all faults on movable memory regions, regardless of
> whether the access type is permitted. When a guest writes to a read-only
> region, the remap succeeds but the region remains read-only, causing
> immediate re-fault and spinning the vCPU indefinitely.
> 
> Validate intercept access type against region permissions before
> attempting remaps. Reject writes to non-writable regions and executes to
> non-executable regions early, returning false to let the VMM handle the
> intercept appropriately.
> 
> This also closes a potential DoS vector where malicious guests could
> intentionally trigger these fault loops to consume host resources.
> 
> Fixes: b9a66cd5ccbb ("mshv: Add support for movable memory regions")
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> ---
>  drivers/hv/mshv_root_main.c |   15 ++++++++++++---
>  include/hyperv/hvgdk_mini.h |    6 ++++++
>  include/hyperv/hvhdk.h      |    4 ++--
>  3 files changed, 20 insertions(+), 5 deletions(-)

Reviewed-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>


^ permalink raw reply

* Re: [PATCH 3/8] firmware: sysfb: Make CONFIG_SYSFB a user-selectable option
From: Thomas Zimmermann @ 2026-04-02 15:27 UTC (permalink / raw)
  To: Arnd Bergmann, Javier Martinez Canillas, Ard Biesheuvel,
	Ilias Apalodimas, Huacai Chen, WANG Xuerui, Maarten Lankhorst,
	Maxime Ripard, Dave Airlie, Simona Vetter, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, longli, Helge Deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev
In-Reply-To: <d3d7c545-3b07-4881-a16d-45b6f039de19@app.fastmail.com>

Hi

Am 02.04.26 um 16:59 schrieb Arnd Bergmann:
> On Thu, Apr 2, 2026, at 16:10, Thomas Zimmermann wrote:
>> Am 02.04.26 um 15:08 schrieb Arnd Bergmann:
>>> On Thu, Apr 2, 2026, at 11:09, Thomas Zimmermann wrote:
>>> I don't really like this part of the series and would prefer
>>> to keep CONFIG_SYSFB hidden as much as possible as an x86
>>> (and EFI) specific implementation detail, with the hope
>>> of eventually seperating out the x86 bits from the EFI ones.
>> You mean, you want to use the EFI-provided framebuffers without the
>> intermediate step of going through sysfb_primary_display?
>>
>> In that case, CONFIG_SYSFB would become an x86-internal thing, right?
> The part that is still needed from sysfb is the arbitration
> between DRM_EFI and the PCI device driver for the same hardware,
> so I think some part of sysfb is clearly needed, in particular
> the sysfb_disable() function that removes the EFI framebuffer
> when there is a conflicting simpledrm or hardware specific
> driver.

We do most of that in the aperture-helper module. (see 
<linux/aperture.h>). Calling sysfb_disable() from there is a workaround 
for some corner cases. We can have an EFI-specific function that does 
the same.

BTW, simpledrm-on-EFI/VESA is considered obsolete and should preferably 
be removed from that driver. Simpledrm should become a driver for 
Devicetree nodes of type simple-framebuffer (as it originally has been 
intended).

>
> The parts that I want to keep out of that is anything
> related to the x86 boot protocol, non-EFI framebuffers,
> text console, and kexec handoff, which we don't need on
> non-x86 UEFI systems.
>
> I don't mind the idea of having a sysfb_primary_display
> in the EFI code if that helps keep EFI sane on x86,
> but it would be good to make that local to
> drivers/firmware/efi and (eventually) detached from
> include/uapi/linux/screen_info.h.

Efidrm retrieves the framebuffer settings from the contained struct 
screen_info. Disconnecting from screen_info would require separate 
graphics drivers for x86 and non-x86. If we split off EFI from sysfb, 
we'd likely need a sysfbdrm driver of some sort. Just saying.

I think we'd also have to duplicate the framebuffer-relocation code that 
currently works on anything using struct screen_info (see patch 5).

>
>>> In general, I am always in favor of properly using Kconfig
>>> dependencies over 'select' statements, for the same reasons
>>> you describe, but I don't want the the x86 logic for
>>> the legacy VESA and VGA console handling to leak into more
>>> architectures than necessary.
>>>
>>> Do you think we could instead move the sysfb_init()
>>> function into the same two places that contain the
>>> sysfb_primary_display definition (arch/x86/kernel/setup.c,
>>> drivers/firmware/efi/efi-init.c) and simplify the efi version
>>> to take out the x86 bits? That would reduce the rest
>>> of sysfb-primary.c to the logic to unregister the device,
>>> and that could then be selected by both x86 and EFI.
>> No, I'm more than happy that sysfb finally consolidates all the
>> init-framebuffer setup and detection that floated around in the kernel.
>> I would not want it to be duplicated again.
>>
>> For now, we could certainly keep CONFIG_SYSFB hidden and autoselected.
>> Although I think this will require soem sort of solution at a later point.
> Can you clarify which problem you are trying to solve
> with that?

One thing is that some users simply what control over their kernel build.

I also think that there might be systems that want to use 
sysfb_primary_display (plus the relocation feature), but not create the 
framebuffer device. Say for efi-earlycon. It needs user-control over the 
SYSFB option to do that.

As a side-effect, user-configurable SYSFB gives us a nice place to put 
SYSFB_SIMPLEFB and FIRMWARE_EDID; two options that currently float 
around in the config somewhat arbitrarily.

Best regards
Thomas

>
>       Arnd

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* [PATCH 2/4] drivers: hv: use ATTRIBUTE_GROUPS helper
From: Thomas Weißschuh @ 2026-04-02 15:18 UTC (permalink / raw)
  To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li
  Cc: linux-hyperv, linux-kernel, Thomas Weißschuh
In-Reply-To: <20260402-sysfs-const-hv-v1-0-a467d6f7726e@weissschuh.net>

The current logic is equivalent to the helper.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 drivers/hv/vmbus_drv.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 5f9b7cc9080c..d41b39ab628d 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -645,10 +645,7 @@ static struct attribute *vmbus_bus_attrs[] = {
 	&bus_attr_hibernation.attr,
 	NULL,
 };
-static const struct attribute_group vmbus_bus_group = {
-	.attrs = vmbus_bus_attrs,
-};
-__ATTRIBUTE_GROUPS(vmbus_bus);
+ATTRIBUTE_GROUPS(vmbus_bus);
 
 /*
  * vmbus_uevent - add uevent for our device

-- 
2.53.0


^ permalink raw reply related

* [PATCH 1/4] drivers: hv: mark chan_attr_ring_buffer as const
From: Thomas Weißschuh @ 2026-04-02 15:18 UTC (permalink / raw)
  To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li
  Cc: linux-hyperv, linux-kernel, Thomas Weißschuh
In-Reply-To: <20260402-sysfs-const-hv-v1-0-a467d6f7726e@weissschuh.net>

The structure is never modified, mark it as const.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 drivers/hv/vmbus_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index bc4fc1951ae1..5f9b7cc9080c 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1959,7 +1959,7 @@ static int hv_mmap_ring_buffer_wrapper(struct file *filp, struct kobject *kobj,
 	return channel->mmap_ring_buffer(channel, vma);
 }
 
-static struct bin_attribute chan_attr_ring_buffer = {
+static const struct bin_attribute chan_attr_ring_buffer = {
 	.attr = {
 		.name = "ring",
 		.mode = 0600,
@@ -1985,7 +1985,7 @@ static struct attribute *vmbus_chan_attrs[] = {
 	NULL
 };
 
-static const struct bin_attribute *vmbus_chan_bin_attrs[] = {
+static const struct bin_attribute *const vmbus_chan_bin_attrs[] = {
 	&chan_attr_ring_buffer,
 	NULL
 };

-- 
2.53.0


^ permalink raw reply related

* [PATCH 4/4] drivers: hv: mark channel attributes as const
From: Thomas Weißschuh @ 2026-04-02 15:18 UTC (permalink / raw)
  To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li
  Cc: linux-hyperv, linux-kernel, Thomas Weißschuh
In-Reply-To: <20260402-sysfs-const-hv-v1-0-a467d6f7726e@weissschuh.net>

These attributes are never modified, mark them as const.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 drivers/hv/vmbus_drv.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index ecce6b72a2a2..7ca038c1e5aa 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1864,7 +1864,7 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
 
 	return ret ?: count;
 }
-static VMBUS_CHAN_ATTR(cpu, 0644, target_cpu_show, target_cpu_store);
+static const VMBUS_CHAN_ATTR(cpu, 0644, target_cpu_show, target_cpu_store);
 
 static ssize_t channel_pending_show(struct vmbus_channel *channel,
 				    char *buf)
@@ -1873,7 +1873,7 @@ static ssize_t channel_pending_show(struct vmbus_channel *channel,
 		       channel_pending(channel,
 				       vmbus_connection.monitor_pages[1]));
 }
-static VMBUS_CHAN_ATTR(pending, 0444, channel_pending_show, NULL);
+static const VMBUS_CHAN_ATTR(pending, 0444, channel_pending_show, NULL);
 
 static ssize_t channel_latency_show(struct vmbus_channel *channel,
 				    char *buf)
@@ -1882,19 +1882,19 @@ static ssize_t channel_latency_show(struct vmbus_channel *channel,
 		       channel_latency(channel,
 				       vmbus_connection.monitor_pages[1]));
 }
-static VMBUS_CHAN_ATTR(latency, 0444, channel_latency_show, NULL);
+static const VMBUS_CHAN_ATTR(latency, 0444, channel_latency_show, NULL);
 
 static ssize_t channel_interrupts_show(struct vmbus_channel *channel, char *buf)
 {
 	return sprintf(buf, "%llu\n", channel->interrupts);
 }
-static VMBUS_CHAN_ATTR(interrupts, 0444, channel_interrupts_show, NULL);
+static const VMBUS_CHAN_ATTR(interrupts, 0444, channel_interrupts_show, NULL);
 
 static ssize_t channel_events_show(struct vmbus_channel *channel, char *buf)
 {
 	return sprintf(buf, "%llu\n", channel->sig_events);
 }
-static VMBUS_CHAN_ATTR(events, 0444, channel_events_show, NULL);
+static const VMBUS_CHAN_ATTR(events, 0444, channel_events_show, NULL);
 
 static ssize_t channel_intr_in_full_show(struct vmbus_channel *channel,
 					 char *buf)
@@ -1902,7 +1902,7 @@ static ssize_t channel_intr_in_full_show(struct vmbus_channel *channel,
 	return sprintf(buf, "%llu\n",
 		       (unsigned long long)channel->intr_in_full);
 }
-static VMBUS_CHAN_ATTR(intr_in_full, 0444, channel_intr_in_full_show, NULL);
+static const VMBUS_CHAN_ATTR(intr_in_full, 0444, channel_intr_in_full_show, NULL);
 
 static ssize_t channel_intr_out_empty_show(struct vmbus_channel *channel,
 					   char *buf)
@@ -1910,7 +1910,7 @@ static ssize_t channel_intr_out_empty_show(struct vmbus_channel *channel,
 	return sprintf(buf, "%llu\n",
 		       (unsigned long long)channel->intr_out_empty);
 }
-static VMBUS_CHAN_ATTR(intr_out_empty, 0444, channel_intr_out_empty_show, NULL);
+static const VMBUS_CHAN_ATTR(intr_out_empty, 0444, channel_intr_out_empty_show, NULL);
 
 static ssize_t channel_out_full_first_show(struct vmbus_channel *channel,
 					   char *buf)
@@ -1918,7 +1918,7 @@ static ssize_t channel_out_full_first_show(struct vmbus_channel *channel,
 	return sprintf(buf, "%llu\n",
 		       (unsigned long long)channel->out_full_first);
 }
-static VMBUS_CHAN_ATTR(out_full_first, 0444, channel_out_full_first_show, NULL);
+static const VMBUS_CHAN_ATTR(out_full_first, 0444, channel_out_full_first_show, NULL);
 
 static ssize_t channel_out_full_total_show(struct vmbus_channel *channel,
 					   char *buf)
@@ -1926,14 +1926,14 @@ static ssize_t channel_out_full_total_show(struct vmbus_channel *channel,
 	return sprintf(buf, "%llu\n",
 		       (unsigned long long)channel->out_full_total);
 }
-static VMBUS_CHAN_ATTR(out_full_total, 0444, channel_out_full_total_show, NULL);
+static const VMBUS_CHAN_ATTR(out_full_total, 0444, channel_out_full_total_show, NULL);
 
 static ssize_t subchannel_monitor_id_show(struct vmbus_channel *channel,
 					  char *buf)
 {
 	return sprintf(buf, "%u\n", channel->offermsg.monitorid);
 }
-static VMBUS_CHAN_ATTR(monitor_id, 0444, subchannel_monitor_id_show, NULL);
+static const VMBUS_CHAN_ATTR(monitor_id, 0444, subchannel_monitor_id_show, NULL);
 
 static ssize_t subchannel_id_show(struct vmbus_channel *channel,
 				  char *buf)
@@ -1941,7 +1941,7 @@ static ssize_t subchannel_id_show(struct vmbus_channel *channel,
 	return sprintf(buf, "%u\n",
 		       channel->offermsg.offer.sub_channel_index);
 }
-static VMBUS_CHAN_ATTR_RO(subchannel_id);
+static const VMBUS_CHAN_ATTR_RO(subchannel_id);
 
 static int hv_mmap_ring_buffer_wrapper(struct file *filp, struct kobject *kobj,
 				       const struct bin_attribute *attr,
@@ -1963,7 +1963,7 @@ static const struct bin_attribute chan_attr_ring_buffer = {
 	},
 	.mmap = hv_mmap_ring_buffer_wrapper,
 };
-static struct attribute *vmbus_chan_attrs[] = {
+static const struct attribute *const vmbus_chan_attrs[] = {
 	&chan_attr_out_mask.attr,
 	&chan_attr_in_mask.attr,
 	&chan_attr_read_avail.attr,
@@ -1992,7 +1992,7 @@ static const struct bin_attribute *const vmbus_chan_bin_attrs[] = {
  * each attribute, and returns 0 if an attribute is not visible.
  */
 static umode_t vmbus_chan_attr_is_visible(struct kobject *kobj,
-					  struct attribute *attr, int idx)
+					  const struct attribute *attr, int idx)
 {
 	const struct vmbus_channel *channel =
 		container_of(kobj, struct vmbus_channel, kobj);
@@ -2030,9 +2030,9 @@ static size_t vmbus_chan_bin_size(struct kobject *kobj,
 }
 
 static const struct attribute_group vmbus_chan_group = {
-	.attrs = vmbus_chan_attrs,
+	.attrs_const = vmbus_chan_attrs,
 	.bin_attrs = vmbus_chan_bin_attrs,
-	.is_visible = vmbus_chan_attr_is_visible,
+	.is_visible_const = vmbus_chan_attr_is_visible,
 	.is_bin_visible = vmbus_chan_bin_attr_is_visible,
 	.bin_size = vmbus_chan_bin_size,
 };

-- 
2.53.0


^ permalink raw reply related

* [PATCH 0/4] drivers: hv: mark some sysfs attribute as const
From: Thomas Weißschuh @ 2026-04-02 15:18 UTC (permalink / raw)
  To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li
  Cc: linux-hyperv, linux-kernel, Thomas Weißschuh

The sysfs attribute structures are never modified.
Mark them as const where possible.

This excludes the device attributes for now, as these will have their
own migration.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
Thomas Weißschuh (4):
      drivers: hv: mark chan_attr_ring_buffer as const
      drivers: hv: use ATTRIBUTE_GROUPS helper
      drivers: hv: mark bus attributes as const
      drivers: hv: mark channel attributes as const

 drivers/hv/vmbus_drv.c | 43 ++++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 23 deletions(-)
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260331-sysfs-const-hv-cad05718c68a

Best regards,
--  
Thomas Weißschuh <linux@weissschuh.net>


^ permalink raw reply

* [PATCH 3/4] drivers: hv: mark bus attributes as const
From: Thomas Weißschuh @ 2026-04-02 15:18 UTC (permalink / raw)
  To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li
  Cc: linux-hyperv, linux-kernel, Thomas Weißschuh
In-Reply-To: <20260402-sysfs-const-hv-v1-0-a467d6f7726e@weissschuh.net>

This attribute is never modified, mark it as const.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 drivers/hv/vmbus_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index d41b39ab628d..ecce6b72a2a2 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -639,9 +639,9 @@ static ssize_t hibernation_show(const struct bus_type *bus, char *buf)
 	return sprintf(buf, "%d\n", !!hv_is_hibernation_supported());
 }
 
-static BUS_ATTR_RO(hibernation);
+static const BUS_ATTR_RO(hibernation);
 
-static struct attribute *vmbus_bus_attrs[] = {
+static const struct attribute *const vmbus_bus_attrs[] = {
 	&bus_attr_hibernation.attr,
 	NULL,
 };

-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH 3/8] firmware: sysfb: Make CONFIG_SYSFB a user-selectable option
From: Arnd Bergmann @ 2026-04-02 14:59 UTC (permalink / raw)
  To: Thomas Zimmermann, Javier Martinez Canillas, Ard Biesheuvel,
	Ilias Apalodimas, Huacai Chen, WANG Xuerui, Maarten Lankhorst,
	Maxime Ripard, Dave Airlie, Simona Vetter, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, longli, Helge Deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev
In-Reply-To: <3e466158-c2e5-4e23-934f-dcdbb71ad41f@suse.de>

On Thu, Apr 2, 2026, at 16:10, Thomas Zimmermann wrote:
> Am 02.04.26 um 15:08 schrieb Arnd Bergmann:
>> On Thu, Apr 2, 2026, at 11:09, Thomas Zimmermann wrote:
>> I don't really like this part of the series and would prefer
>> to keep CONFIG_SYSFB hidden as much as possible as an x86
>> (and EFI) specific implementation detail, with the hope
>> of eventually seperating out the x86 bits from the EFI ones.
>
> You mean, you want to use the EFI-provided framebuffers without the 
> intermediate step of going through sysfb_primary_display?
>
> In that case, CONFIG_SYSFB would become an x86-internal thing, right?

The part that is still needed from sysfb is the arbitration
between DRM_EFI and the PCI device driver for the same hardware,
so I think some part of sysfb is clearly needed, in particular
the sysfb_disable() function that removes the EFI framebuffer
when there is a conflicting simpledrm or hardware specific
driver.

The parts that I want to keep out of that is anything
related to the x86 boot protocol, non-EFI framebuffers,
text console, and kexec handoff, which we don't need on
non-x86 UEFI systems.

I don't mind the idea of having a sysfb_primary_display
in the EFI code if that helps keep EFI sane on x86,
but it would be good to make that local to
drivers/firmware/efi and (eventually) detached from
include/uapi/linux/screen_info.h.

>> In general, I am always in favor of properly using Kconfig
>> dependencies over 'select' statements, for the same reasons
>> you describe, but I don't want the the x86 logic for
>> the legacy VESA and VGA console handling to leak into more
>> architectures than necessary.
>>
>> Do you think we could instead move the sysfb_init()
>> function into the same two places that contain the
>> sysfb_primary_display definition (arch/x86/kernel/setup.c,
>> drivers/firmware/efi/efi-init.c) and simplify the efi version
>> to take out the x86 bits? That would reduce the rest
>> of sysfb-primary.c to the logic to unregister the device,
>> and that could then be selected by both x86 and EFI.
>
> No, I'm more than happy that sysfb finally consolidates all the 
> init-framebuffer setup and detection that floated around in the kernel. 
> I would not want it to be duplicated again.
>
> For now, we could certainly keep CONFIG_SYSFB hidden and autoselected. 
> Although I think this will require soem sort of solution at a later point.

Can you clarify which problem you are trying to solve
with that?

     Arnd

^ permalink raw reply

* Re: [PATCH 3/8] firmware: sysfb: Make CONFIG_SYSFB a user-selectable option
From: Thomas Zimmermann @ 2026-04-02 14:10 UTC (permalink / raw)
  To: Arnd Bergmann, Javier Martinez Canillas, Ard Biesheuvel,
	Ilias Apalodimas, Huacai Chen, WANG Xuerui, Maarten Lankhorst,
	Maxime Ripard, Dave Airlie, Simona Vetter, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, longli, Helge Deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev
In-Reply-To: <78f76717-8f1e-41d6-92f7-261df96b84b6@app.fastmail.com>

Hi

Am 02.04.26 um 15:08 schrieb Arnd Bergmann:
> On Thu, Apr 2, 2026, at 11:09, Thomas Zimmermann wrote:
>> Add a descriptive string and help text to CONFIG_SYSFB, so that users
>> can modify it. Flip all implicit selects in the Kconfig options into
>> dependencies. This avoids cyclic dependencies in the config.
>>
>> Enabling CONFIG_SYSFB makes the kernel provide a device for the firmware
>> framebuffer. As this can (slightly) affect system behavior, having a
>> user-facing option seems preferable. Some users might also want to set
>> every detail of their kernel config.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> I don't really like this part of the series and would prefer
> to keep CONFIG_SYSFB hidden as much as possible as an x86
> (and EFI) specific implementation detail, with the hope
> of eventually seperating out the x86 bits from the EFI ones.

You mean, you want to use the EFI-provided framebuffers without the 
intermediate step of going through sysfb_primary_display?

In that case, CONFIG_SYSFB would become an x86-internal thing, right?

>
> In general, I am always in favor of properly using Kconfig
> dependencies over 'select' statements, for the same reasons
> you describe, but I don't want the the x86 logic for
> the legacy VESA and VGA console handling to leak into more
> architectures than necessary.
>
> Do you think we could instead move the sysfb_init()
> function into the same two places that contain the
> sysfb_primary_display definition (arch/x86/kernel/setup.c,
> drivers/firmware/efi/efi-init.c) and simplify the efi version
> to take out the x86 bits? That would reduce the rest
> of sysfb-primary.c to the logic to unregister the device,
> and that could then be selected by both x86 and EFI.

No, I'm more than happy that sysfb finally consolidates all the 
init-framebuffer setup and detection that floated around in the kernel. 
I would not want it to be duplicated again.

For now, we could certainly keep CONFIG_SYSFB hidden and autoselected. 
Although I think this will require soem sort of solution at a later point.

Best regards
Thomas

>
>        Arnd

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* Re: [PATCH 3/8] firmware: sysfb: Make CONFIG_SYSFB a user-selectable option
From: Arnd Bergmann @ 2026-04-02 13:08 UTC (permalink / raw)
  To: Thomas Zimmermann, Javier Martinez Canillas, Ard Biesheuvel,
	Ilias Apalodimas, Huacai Chen, WANG Xuerui, Maarten Lankhorst,
	Maxime Ripard, Dave Airlie, Simona Vetter, K. Y. Srinivasan,
	Haiyang Zhang, Wei Liu, Dexuan Cui, longli, Helge Deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev
In-Reply-To: <20260402092305.208728-4-tzimmermann@suse.de>

On Thu, Apr 2, 2026, at 11:09, Thomas Zimmermann wrote:
> Add a descriptive string and help text to CONFIG_SYSFB, so that users
> can modify it. Flip all implicit selects in the Kconfig options into
> dependencies. This avoids cyclic dependencies in the config.
>
> Enabling CONFIG_SYSFB makes the kernel provide a device for the firmware
> framebuffer. As this can (slightly) affect system behavior, having a
> user-facing option seems preferable. Some users might also want to set
> every detail of their kernel config.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

I don't really like this part of the series and would prefer
to keep CONFIG_SYSFB hidden as much as possible as an x86
(and EFI) specific implementation detail, with the hope
of eventually seperating out the x86 bits from the EFI ones.

In general, I am always in favor of properly using Kconfig
dependencies over 'select' statements, for the same reasons
you describe, but I don't want the the x86 logic for
the legacy VESA and VGA console handling to leak into more
architectures than necessary.

Do you think we could instead move the sysfb_init()
function into the same two places that contain the
sysfb_primary_display definition (arch/x86/kernel/setup.c,
drivers/firmware/efi/efi-init.c) and simplify the efi version
to take out the x86 bits? That would reduce the rest
of sysfb-primary.c to the logic to unregister the device,
and that could then be selected by both x86 and EFI.

      Arnd

^ permalink raw reply

* RE: [PATCH 1/8] hv: Select CONFIG_SYSFB only for CONFIG_HYPERV_VMBUS
From: Saurabh Singh Sengar @ 2026-04-02 10:50 UTC (permalink / raw)
  To: Thomas Zimmermann, javierm@redhat.com, arnd@arndb.de,
	ardb@kernel.org, ilias.apalodimas@linaro.org,
	chenhuacai@kernel.org, kernel@xen0n.name,
	maarten.lankhorst@linux.intel.com, mripard@kernel.org,
	airlied@gmail.com, simona@ffwll.ch, KY Srinivasan, Haiyang Zhang,
	wei.liu@kernel.org, Dexuan Cui, Long Li, deller@gmx.de
  Cc: linux-arm-kernel@lists.infradead.org, loongarch@lists.linux.dev,
	linux-efi@vger.kernel.org, linux-riscv@lists.infradead.org,
	dri-devel@lists.freedesktop.org, linux-hyperv@vger.kernel.org,
	linux-fbdev@vger.kernel.org, Michael Kelley, Saurabh Sengar,
	stable@vger.kernel.org
In-Reply-To: <20260402092305.208728-2-tzimmermann@suse.de>

> Hyperv's sysfb access only exists in the VMBUS support. Therefore only select
> CONFIG_SYSFB for CONFIG_HYPERV_VMBUS. Avoids sysfb code on systems
> that don't need it.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> Fixes: 96959283a58d ("Drivers: hv: Always select CONFIG_SYSFB for Hyper-V
> guests")
> Cc: Michael Kelley <mhklinux@outlook.com>
> Cc: Saurabh Sengar <ssengar@linux.microsoft.com>
> Cc: Wei Liu <wei.liu@kernel.org>
> Cc: "K. Y. Srinivasan" <kys@microsoft.com>
> Cc: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: Dexuan Cui <decui@microsoft.com>
> Cc: Long Li <longli@microsoft.com>
> Cc: linux-hyperv@vger.kernel.org
> Cc: <stable@vger.kernel.org> # v6.16+
> ---
>  drivers/hv/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig index
> 7937ac0cbd0f..2d0b3fcb0ff8 100644
> --- a/drivers/hv/Kconfig
> +++ b/drivers/hv/Kconfig
> @@ -9,7 +9,6 @@ config HYPERV
>  	select PARAVIRT
>  	select X86_HV_CALLBACK_VECTOR if X86
>  	select OF_EARLY_FLATTREE if OF
> -	select SYSFB if EFI && !HYPERV_VTL_MODE
>  	select IRQ_MSI_LIB if X86
>  	help
>  	  Select this option to run Linux as a Hyper-V client operating @@ -62,6
> +61,7 @@ config HYPERV_VMBUS
>  	tristate "Microsoft Hyper-V VMBus driver"
>  	depends on HYPERV
>  	default HYPERV
> +	select SYSFB if EFI && !HYPERV_VTL_MODE
>  	help
>  	  Select this option to enable Hyper-V Vmbus driver.
> 
> --
> 2.53.0

Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>


^ permalink raw reply

* [PATCH 5/8] firmware: sysfb: Implement screen_info relocation for primary display
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

Move the relocation tracking for screen_info from the screen_info
helpers to sysfb. The relocation code operates on sysfb_primary_display,
which belongs to sysfb. The remaining screen_info helpers are now free
from global state.

Adapt some symbol names. Now prefer early returns in the helper
sysfb_apply_screen_info_fixup() over nested branching. Also return an
errno code from sysfb_apply_screen_info_fixup() if the relocation
failed. In this case, do not create a device for the framebuffer.
The original code advertised this behavior in a comment but never
implemented it.

Framebuffer aperture relocation can happen during boot if the PCI
graphics device is located behind a PCI bridge. If the bridge's sub-
bus gets relocated, the framebuffer aperture moves accordingly. The
helper for tracking these relocations fixes up the values stored in
sysfb_primary_display so that they refer to the correct address range
again. Generic system-framebuffer drivers would not work otherwise.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/firmware/sysfb.h         |   5 ++
 drivers/firmware/sysfb_pci.c     | 111 +++++++++++++++++++++++++++++++
 drivers/firmware/sysfb_primary.c |   9 ++-
 drivers/video/screen_info_pci.c  | 110 ------------------------------
 include/linux/screen_info.h      |   3 -
 5 files changed, 123 insertions(+), 115 deletions(-)

diff --git a/drivers/firmware/sysfb.h b/drivers/firmware/sysfb.h
index 9f7fe2e03f68..1eaa3b0fa364 100644
--- a/drivers/firmware/sysfb.h
+++ b/drivers/firmware/sysfb.h
@@ -8,8 +8,13 @@
 struct pci_dev;
 
 #ifdef CONFIG_PCI
+int sysfb_apply_screen_info_fixups(void);
 bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev);
 #else
+static inline int sysfb_apply_screen_info_fixups(void)
+{
+	return 0;
+}
 static inline bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
 {
 	return false;
diff --git a/drivers/firmware/sysfb_pci.c b/drivers/firmware/sysfb_pci.c
index 8f3adeef4fb1..d972750c6bc6 100644
--- a/drivers/firmware/sysfb_pci.c
+++ b/drivers/firmware/sysfb_pci.c
@@ -1,9 +1,120 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <linux/pci.h>
+#include <linux/printk.h>
+#include <linux/screen_info.h>
+#include <linux/sysfb.h>
 
 #include "sysfb.h"
 
+static struct pci_dev *sysfb_lfb_pdev;
+static size_t sysfb_lfb_bar;
+static resource_size_t sysfb_lfb_res_start; // original start of resource
+static resource_size_t sysfb_lfb_offset; // framebuffer offset within resource
+
+static bool __sysfb_relocation_is_valid(const struct screen_info *si, struct resource *pr)
+{
+	u64 size = __screen_info_lfb_size(si, screen_info_video_type(si));
+
+	if (sysfb_lfb_offset > resource_size(pr))
+		return false;
+	if (size > resource_size(pr))
+		return false;
+	if (resource_size(pr) - size < sysfb_lfb_offset)
+		return false;
+
+	return true;
+}
+
+int sysfb_apply_screen_info_fixups(void)
+{
+	struct screen_info *si = &sysfb_primary_display.screen;
+	struct resource *pr;
+
+	if (!sysfb_lfb_pdev)
+		return 0; /* primary display is not on a PCI device */
+
+	pr = &sysfb_lfb_pdev->resource[sysfb_lfb_bar];
+
+	if (pr->start == sysfb_lfb_res_start)
+		return 0; /* no relocation took place */
+
+	if (!__sysfb_relocation_is_valid(si, pr))
+		return -ENXIO;
+
+	/*
+	 * Only update base if we have an actual relocation to a valid I/O range.
+	 */
+	__screen_info_set_lfb_base(si, pr->start + sysfb_lfb_offset);
+	pr_info("Relocating firmware framebuffer to offset %pa[d] within %pr\n",
+		&sysfb_lfb_offset, pr);
+
+	return 0;
+}
+
+static int __screen_info_lfb_pci_bus_region(const struct screen_info *si, unsigned int type,
+					    struct pci_bus_region *r)
+{
+	u64 base, size;
+
+	base = __screen_info_lfb_base(si);
+	if (!base)
+		return -EINVAL;
+
+	size = __screen_info_lfb_size(si, type);
+	if (!size)
+		return -EINVAL;
+
+	r->start = base;
+	r->end = base + size - 1;
+
+	return 0;
+}
+
+static void sysfb_fixup_lfb(struct pci_dev *pdev)
+{
+	unsigned int type;
+	struct pci_bus_region bus_region;
+	int ret;
+	struct resource r = {
+		.flags = IORESOURCE_MEM,
+	};
+	const struct resource *pr;
+	const struct screen_info *si = &sysfb_primary_display.screen;
+
+	if (sysfb_lfb_pdev)
+		return; // already found
+
+	type = screen_info_video_type(si);
+	if (!__screen_info_has_lfb(type))
+		return; // only applies to EFI; maybe VESA
+
+	ret = __screen_info_lfb_pci_bus_region(si, type, &bus_region);
+	if (ret < 0)
+		return;
+
+	/*
+	 * Translate the PCI bus address to resource. Account for an offset if
+	 * the framebuffer is behind a PCI host bridge.
+	 */
+	pcibios_bus_to_resource(pdev->bus, &r, &bus_region);
+
+	pr = pci_find_resource(pdev, &r);
+	if (!pr)
+		return;
+
+	/*
+	 * We've found a PCI device with the framebuffer resource. Store away
+	 * the parameters to track relocation of the framebuffer aperture.
+	 */
+	sysfb_lfb_pdev = pdev;
+	sysfb_lfb_bar = pr - pdev->resource;
+	sysfb_lfb_offset = r.start - pr->start;
+	sysfb_lfb_res_start = bus_region.start;
+}
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16,
+			       sysfb_fixup_lfb);
+
 bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
 {
 	/*
diff --git a/drivers/firmware/sysfb_primary.c b/drivers/firmware/sysfb_primary.c
index ab8d7fc468bb..298f87a43a7e 100644
--- a/drivers/firmware/sysfb_primary.c
+++ b/drivers/firmware/sysfb_primary.c
@@ -32,6 +32,7 @@
 #include <linux/pci.h>
 #include <linux/platform_data/simplefb.h>
 #include <linux/platform_device.h>
+#include <linux/printk.h>
 #include <linux/screen_info.h>
 #include <linux/sysfb.h>
 
@@ -127,11 +128,15 @@ static __init int sysfb_init(void)
 	struct simplefb_platform_data mode;
 	const char *name;
 	bool compatible;
-	int ret = 0;
+	int ret;
 
-	screen_info_apply_fixups();
+	ret = sysfb_apply_screen_info_fixups();
 
 	mutex_lock(&disable_lock);
+	if (ret) {
+		pr_warn("Invalid relocation, disabling system framebuffer\n");
+		disabled = true; /* screen_info relocation failed */
+	}
 	if (disabled)
 		goto unlock_mutex;
 
diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c
index 8f34d8a74f09..d8985a54ce71 100644
--- a/drivers/video/screen_info_pci.c
+++ b/drivers/video/screen_info_pci.c
@@ -1,117 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/pci.h>
-#include <linux/printk.h>
 #include <linux/screen_info.h>
-#include <linux/string.h>
-#include <linux/sysfb.h>
-
-static struct pci_dev *screen_info_lfb_pdev;
-static size_t screen_info_lfb_bar;
-static resource_size_t screen_info_lfb_res_start; // original start of resource
-static resource_size_t screen_info_lfb_offset; // framebuffer offset within resource
-
-static bool __screen_info_relocation_is_valid(const struct screen_info *si, struct resource *pr)
-{
-	u64 size = __screen_info_lfb_size(si, screen_info_video_type(si));
-
-	if (screen_info_lfb_offset > resource_size(pr))
-		return false;
-	if (size > resource_size(pr))
-		return false;
-	if (resource_size(pr) - size < screen_info_lfb_offset)
-		return false;
-
-	return true;
-}
-
-void screen_info_apply_fixups(void)
-{
-	struct screen_info *si = &sysfb_primary_display.screen;
-
-	if (screen_info_lfb_pdev) {
-		struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar];
-
-		if (pr->start != screen_info_lfb_res_start) {
-			if (__screen_info_relocation_is_valid(si, pr)) {
-				/*
-				 * Only update base if we have an actual
-				 * relocation to a valid I/O range.
-				 */
-				__screen_info_set_lfb_base(si, pr->start + screen_info_lfb_offset);
-				pr_info("Relocating firmware framebuffer to offset %pa[d] within %pr\n",
-					&screen_info_lfb_offset, pr);
-			} else {
-				pr_warn("Invalid relocating, disabling firmware framebuffer\n");
-			}
-		}
-	}
-}
-
-static int __screen_info_lfb_pci_bus_region(const struct screen_info *si, unsigned int type,
-					    struct pci_bus_region *r)
-{
-	u64 base, size;
-
-	base = __screen_info_lfb_base(si);
-	if (!base)
-		return -EINVAL;
-
-	size = __screen_info_lfb_size(si, type);
-	if (!size)
-		return -EINVAL;
-
-	r->start = base;
-	r->end = base + size - 1;
-
-	return 0;
-}
-
-static void screen_info_fixup_lfb(struct pci_dev *pdev)
-{
-	unsigned int type;
-	struct pci_bus_region bus_region;
-	int ret;
-	struct resource r = {
-		.flags = IORESOURCE_MEM,
-	};
-	const struct resource *pr;
-	const struct screen_info *si = &sysfb_primary_display.screen;
-
-	if (screen_info_lfb_pdev)
-		return; // already found
-
-	type = screen_info_video_type(si);
-	if (!__screen_info_has_lfb(type))
-		return; // only applies to EFI; maybe VESA
-
-	ret = __screen_info_lfb_pci_bus_region(si, type, &bus_region);
-	if (ret < 0)
-		return;
-
-	/*
-	 * Translate the PCI bus address to resource. Account
-	 * for an offset if the framebuffer is behind a PCI host
-	 * bridge.
-	 */
-	pcibios_bus_to_resource(pdev->bus, &r, &bus_region);
-
-	pr = pci_find_resource(pdev, &r);
-	if (!pr)
-		return;
-
-	/*
-	 * We've found a PCI device with the framebuffer
-	 * resource. Store away the parameters to track
-	 * relocation of the framebuffer aperture.
-	 */
-	screen_info_lfb_pdev = pdev;
-	screen_info_lfb_bar = pr - pdev->resource;
-	screen_info_lfb_offset = r.start - pr->start;
-	screen_info_lfb_res_start = bus_region.start;
-}
-DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16,
-			       screen_info_fixup_lfb);
 
 static struct pci_dev *__screen_info_pci_dev(struct resource *res)
 {
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index c022403c599a..2adbe25b88d8 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -140,11 +140,8 @@ u32 __screen_info_lfb_bits_per_pixel(const struct screen_info *si);
 int screen_info_pixel_format(const struct screen_info *si, struct pixel_format *f);
 
 #if defined(CONFIG_PCI)
-void screen_info_apply_fixups(void);
 struct pci_dev *screen_info_pci_dev(const struct screen_info *si);
 #else
-static inline void screen_info_apply_fixups(void)
-{ }
 static inline struct pci_dev *screen_info_pci_dev(const struct screen_info *si)
 {
 	return NULL;
-- 
2.53.0


^ permalink raw reply related

* [PATCH 8/8] firmware: sysfb: Move CONFIG_FIRMWARE_EDID to firmware options
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

Move the Kconfig option for CONFIG_FIRMWARE_EDID to the firmware
subsystem. The option controls architecture and firmware code, so
it fits here better than in video.

Also make it depend on CONFIG_SYSFB. The EDID data is stored in
sysfb_primary_display and only useful with a sysfb framebuffer. This
further allows for removing an explicit test for CONFIG_FIRMWARE_EDID
from the EFI init code. For loongson, select CONFIG_SYSFB in the
defconfig files.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 arch/loongarch/configs/loongson32_defconfig |  1 +
 arch/loongarch/configs/loongson64_defconfig |  1 +
 drivers/firmware/Kconfig                    | 20 ++++++++++++++++++++
 drivers/firmware/efi/efi-init.c             |  2 +-
 drivers/video/Kconfig                       | 19 -------------------
 5 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/arch/loongarch/configs/loongson32_defconfig b/arch/loongarch/configs/loongson32_defconfig
index 276b1577e0be..1c0897723247 100644
--- a/arch/loongarch/configs/loongson32_defconfig
+++ b/arch/loongarch/configs/loongson32_defconfig
@@ -786,6 +786,7 @@ CONFIG_DRM_VIRTIO_GPU=m
 CONFIG_DRM_LOONGSON=y
 CONFIG_FB=y
 CONFIG_FB_RADEON=y
+CONFIG_SYSFB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_PLATFORM=m
diff --git a/arch/loongarch/configs/loongson64_defconfig b/arch/loongarch/configs/loongson64_defconfig
index a14db1a95e7e..38340537dfd4 100644
--- a/arch/loongarch/configs/loongson64_defconfig
+++ b/arch/loongarch/configs/loongson64_defconfig
@@ -816,6 +816,7 @@ CONFIG_DRM_VIRTIO_GPU=m
 CONFIG_DRM_LOONGSON=y
 CONFIG_FB=y
 CONFIG_FB_RADEON=y
+CONFIG_SYSFB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_PLATFORM=m
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 52f8253a46b1..edfb171d9eab 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -225,6 +225,26 @@ config SYSFB_SIMPLEFB
 
 	  If unsure, say Y.
 
+config FIRMWARE_EDID
+	bool "Enable firmware EDID"
+	depends on SYSFB
+	depends on EFI_GENERIC_STUB || X86
+	help
+	  This enables access to the EDID transferred from the firmware.
+	  On EFI systems, the EDID comes from the same device as the
+	  primary GOP. On x86 with BIOS, it comes from the VESA BIOS.
+	  DRM display drivers will be able to export the information
+	  to userspace.
+
+	  Also enable this if DDC/I2C transfers do not work for your driver
+	  and if you are using nvidiafb, i810fb or savagefb.
+
+	  In general, choosing Y for this option is safe.  If you
+	  experience extremely long delays while booting before you get
+	  something on your display, try setting this to N.  Matrox cards in
+	  combination with certain motherboards and monitors are known to
+	  suffer from this problem.
+
 config TH1520_AON_PROTOCOL
 	tristate "Always-On firmware protocol"
 	depends on ARCH_THEAD || COMPILE_TEST
diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index 002518b642ed..c4088fb8482b 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -60,7 +60,7 @@ extern __weak const efi_config_table_type_t efi_arch_tables[];
  * x86 defines its own instance of sysfb_primary_display and uses
  * it even without EFI, everything else can get them from here.
  */
-#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_FIRMWARE_EDID))
+#if !defined(CONFIG_X86) && defined(CONFIG_SYSFB)
 struct sysfb_display_info sysfb_primary_display __section(".data");
 EXPORT_SYMBOL_GPL(sysfb_primary_display);
 #endif
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index a7144d275f54..1c9ac3b029a7 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -62,25 +62,6 @@ config HDMI
 
 endif # HAS_IOMEM
 
-config FIRMWARE_EDID
-	bool "Enable firmware EDID"
-	depends on EFI_GENERIC_STUB || X86
-	help
-	  This enables access to the EDID transferred from the firmware.
-	  On EFI systems, the EDID comes from the same device as the
-	  primary GOP. On x86 with BIOS, it comes from the VESA BIOS.
-	  DRM display drivers will be able to export the information
-	  to userspace.
-
-	  Also enable this if DDC/I2C transfers do not work for your driver
-	  and if you are using nvidiafb, i810fb or savagefb.
-
-	  In general, choosing Y for this option is safe.  If you
-	  experience extremely long delays while booting before you get
-	  something on your display, try setting this to N.  Matrox cards in
-	  combination with certain motherboards and monitors are known to
-	  suffer from this problem.
-
 if VT
 	source "drivers/video/console/Kconfig"
 endif
-- 
2.53.0


^ permalink raw reply related

* [PATCH 7/8] firmware: efi: Make CONFIG_EFI_EARLYCON depend on CONFIG_SYSFB; clean up
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

Efi-earlycon uses sysfb_primary_display. Therefore make it depend on
the corresponding config symbol. With this in place, go through the
source files and reduce tests to CONFIG_SYSFB. Efi-earlycon is now
just another regular user of sysfb.

This also enables the screen_info relocation feature for efi-earlycon.
Systems might move the framebuffer aperture while booting the kernel. PCI
bridges sometimes do this as part of relocating the sub-bus aperture.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 arch/arm64/kernel/image-vars.h                | 2 +-
 arch/loongarch/kernel/efi.c                   | 4 ++--
 arch/loongarch/kernel/image-vars.h            | 2 +-
 arch/riscv/kernel/image-vars.h                | 2 +-
 drivers/firmware/efi/Kconfig                  | 3 ++-
 drivers/firmware/efi/efi-init.c               | 6 ++----
 drivers/firmware/efi/libstub/efi-stub-entry.c | 4 +---
 7 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index d7b0d12b1015..7e0e61385286 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -37,7 +37,7 @@ PROVIDE(__efistub__text			= _text);
 PROVIDE(__efistub__end			= _end);
 PROVIDE(__efistub___inittext_end       	= __inittext_end);
 PROVIDE(__efistub__edata		= _edata);
-#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB)
+#if defined(CONFIG_SYSFB)
 PROVIDE(__efistub_sysfb_primary_display	= sysfb_primary_display);
 #endif
 PROVIDE(__efistub__ctype		= _ctype);
diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c
index 69dd83f8082f..6c25e2ecf45f 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -74,7 +74,7 @@ bool efi_poweroff_required(void)
 
 unsigned long __initdata primary_display_table = EFI_INVALID_TABLE_ADDR;
 
-#if defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)
+#if defined(CONFIG_SYSFB)
 struct sysfb_display_info sysfb_primary_display __section(".data");
 EXPORT_SYMBOL_GPL(sysfb_primary_display);
 #endif
@@ -129,7 +129,7 @@ void __init efi_init(void)
 
 	set_bit(EFI_CONFIG_TABLES, &efi.flags);
 
-	if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB))
+	if (IS_ENABLED(CONFIG_SYSFB))
 		init_primary_display();
 
 	if (boot_memmap == EFI_INVALID_TABLE_ADDR)
diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h
index e557ebd46c2b..c43f9326f344 100644
--- a/arch/loongarch/kernel/image-vars.h
+++ b/arch/loongarch/kernel/image-vars.h
@@ -11,7 +11,7 @@ __efistub_strcmp		= strcmp;
 __efistub_kernel_entry		= kernel_entry;
 __efistub_kernel_asize		= kernel_asize;
 __efistub_kernel_fsize		= kernel_fsize;
-#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB)
+#if defined(CONFIG_SYSFB)
 __efistub_sysfb_primary_display	= sysfb_primary_display;
 #endif
 
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index 3bd9d06a8b8f..3ab2529c4154 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -28,7 +28,7 @@ __efistub__start_kernel		= _start_kernel;
 __efistub__end			= _end;
 __efistub__edata		= _edata;
 __efistub___init_text_end	= __init_text_end;
-#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB)
+#if defined(CONFIG_SYSFB)
 __efistub_sysfb_primary_display	= sysfb_primary_display;
 #endif
 
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 29e0729299f5..925ded080eb4 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -219,8 +219,9 @@ config EFI_DISABLE_PCI_DMA
 config EFI_EARLYCON
 	def_bool y
 	depends on SERIAL_EARLYCON && !ARM
-	select FONT_SUPPORT
+	depends on SYSFB
 	select ARCH_USE_MEMREMAP_PROT
+	select FONT_SUPPORT
 
 config EFI_CUSTOM_SSDT_OVERLAYS
 	bool "Load custom ACPI SSDT overlay from an EFI variable"
diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index 6103b1a082d2..002518b642ed 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -60,7 +60,7 @@ extern __weak const efi_config_table_type_t efi_arch_tables[];
  * x86 defines its own instance of sysfb_primary_display and uses
  * it even without EFI, everything else can get them from here.
  */
-#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_FIRMWARE_EDID))
+#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_FIRMWARE_EDID))
 struct sysfb_display_info sysfb_primary_display __section(".data");
 EXPORT_SYMBOL_GPL(sysfb_primary_display);
 #endif
@@ -271,8 +271,6 @@ void __init efi_init(void)
 	memblock_reserve(data.phys_map & PAGE_MASK,
 			 PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
 
-	if (IS_ENABLED(CONFIG_X86) ||
-	    IS_ENABLED(CONFIG_SYSFB) ||
-	    IS_ENABLED(CONFIG_EFI_EARLYCON))
+	if (IS_ENABLED(CONFIG_X86) || IS_ENABLED(CONFIG_SYSFB))
 		init_primary_display();
 }
diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c
index aa85e910fe59..214fa4d84df0 100644
--- a/drivers/firmware/efi/libstub/efi-stub-entry.c
+++ b/drivers/firmware/efi/libstub/efi-stub-entry.c
@@ -19,9 +19,7 @@ struct sysfb_display_info *alloc_primary_display(void)
 	if (IS_ENABLED(CONFIG_ARM))
 		return __alloc_primary_display();
 
-	if (IS_ENABLED(CONFIG_X86) ||
-	    IS_ENABLED(CONFIG_EFI_EARLYCON) ||
-	    IS_ENABLED(CONFIG_SYSFB))
+	if (IS_ENABLED(CONFIG_X86) || IS_ENABLED(CONFIG_SYSFB))
 		return kernel_image_addr(&sysfb_primary_display);
 
 	return NULL;
-- 
2.53.0


^ permalink raw reply related

* [PATCH 3/8] firmware: sysfb: Make CONFIG_SYSFB a user-selectable option
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

Add a descriptive string and help text to CONFIG_SYSFB, so that users
can modify it. Flip all implicit selects in the Kconfig options into
dependencies. This avoids cyclic dependencies in the config.

Enabling CONFIG_SYSFB makes the kernel provide a device for the firmware
framebuffer. As this can (slightly) affect system behavior, having a
user-facing option seems preferable. Some users might also want to set
every detail of their kernel config.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/firmware/Kconfig      | 18 ++++++++++++++++--
 drivers/gpu/drm/sysfb/Kconfig |  4 ++--
 drivers/hv/Kconfig            |  2 +-
 drivers/video/fbdev/Kconfig   |  5 +++--
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index bbd2155d8483..52f8253a46b1 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -179,14 +179,28 @@ config MTK_ADSP_IPC
 	  Client might use shared memory to exchange information with ADSP.
 
 config SYSFB
-	bool
+	bool "Enable system framebuffer provided by boot loader"
 	select BOOT_VESA_SUPPORT
 	select SCREEN_INFO
+	help
+	  Use the system framebuffer provided by the boot loader. This will
+	  create a device representing the framebuffer. The output depends on
+	  EFI, VESA, VGA, or some other firmware-based interface.
+
+	  The firmware or boot loader sets the display resolution and color
+	  mode. See your boot loader's documentation on how to do this. On
+	  some systems the display can also be configured during boot with
+	  the kernel's video= or vga= parameters.
+
+	  Besides this option, you also have to enable a compatible graphics
+	  driver, such as efidrm or vesadrm.
+
+	  If unsure, say Y.
 
 config SYSFB_SIMPLEFB
 	bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
+	depends on SYSFB
 	depends on X86 || EFI
-	select SYSFB
 	help
 	  Firmwares often provide initial graphics framebuffers so the BIOS,
 	  bootloader or kernel can show basic video-output during boot for
diff --git a/drivers/gpu/drm/sysfb/Kconfig b/drivers/gpu/drm/sysfb/Kconfig
index 2559ead6cf1f..74be3c8e6657 100644
--- a/drivers/gpu/drm/sysfb/Kconfig
+++ b/drivers/gpu/drm/sysfb/Kconfig
@@ -26,12 +26,12 @@ config DRM_COREBOOTDRM
 config DRM_EFIDRM
 	tristate "EFI framebuffer driver"
 	depends on DRM && MMU && EFI && (!SYSFB_SIMPLEFB || COMPILE_TEST)
+	depends on SYSFB
 	select APERTURE_HELPERS
 	select DRM_CLIENT_SELECTION
 	select DRM_GEM_SHMEM_HELPER
 	select DRM_KMS_HELPER
 	select DRM_SYSFB_HELPER
-	select SYSFB
 	help
 	  DRM driver for EFI framebuffers.
 
@@ -76,12 +76,12 @@ config DRM_SIMPLEDRM
 config DRM_VESADRM
 	tristate "VESA framebuffer driver"
 	depends on DRM && MMU && X86 && (!SYSFB_SIMPLEFB || COMPILE_TEST)
+	depends on SYSFB
 	select APERTURE_HELPERS
 	select DRM_CLIENT_SELECTION
 	select DRM_GEM_SHMEM_HELPER
 	select DRM_KMS_HELPER
 	select DRM_SYSFB_HELPER
-	select SYSFB
 	help
 	  DRM driver for VESA framebuffers.
 
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 2d0b3fcb0ff8..af0ac6516159 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -60,8 +60,8 @@ config HYPERV_BALLOON
 config HYPERV_VMBUS
 	tristate "Microsoft Hyper-V VMBus driver"
 	depends on HYPERV
+	depends on SYSFB if EFI && !HYPERV_VTL_MODE
 	default HYPERV
-	select SYSFB if EFI && !HYPERV_VTL_MODE
 	help
 	  Select this option to enable Hyper-V Vmbus driver.
 
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index ac9ac4287c6a..6f55bec8c207 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -333,6 +333,7 @@ config FB_IMSTT
 config FB_VGA16
 	tristate "VGA 16-color graphics support"
 	depends on FB && X86
+	depends on SYSFB
 	select APERTURE_HELPERS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
@@ -424,9 +425,9 @@ config FB_UVESA
 config FB_VESA
 	bool "VESA VGA graphics support"
 	depends on (FB = y) && X86
+	depends on SYSFB
 	select APERTURE_HELPERS
 	select FB_IOMEM_HELPERS
-	select SYSFB
 	help
 	  This is the frame buffer device driver for generic VESA 2.0
 	  compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -436,10 +437,10 @@ config FB_VESA
 config FB_EFI
 	bool "EFI-based Framebuffer Support"
 	depends on (FB = y) && EFI
+	depends on SYSFB
 	select APERTURE_HELPERS
 	select DRM_PANEL_ORIENTATION_QUIRKS
 	select FB_IOMEM_HELPERS
-	select SYSFB
 	help
 	  This is the EFI frame buffer device driver. If the firmware on
 	  your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
-- 
2.53.0


^ permalink raw reply related

* [PATCH 6/8] firmware: sysfb: Avoid forward-declaring sysfb_parent_dev()
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

Move sysfb_parent_dev() to the top of the source file to avoid
the extra declaration. No functional changes.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/firmware/sysfb_primary.c | 36 +++++++++++++++-----------------
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/firmware/sysfb_primary.c b/drivers/firmware/sysfb_primary.c
index 298f87a43a7e..a7f8cede60ad 100644
--- a/drivers/firmware/sysfb_primary.c
+++ b/drivers/firmware/sysfb_primary.c
@@ -42,7 +42,23 @@ static struct platform_device *pd;
 static DEFINE_MUTEX(disable_lock);
 static bool disabled;
 
-static struct device *sysfb_parent_dev(const struct screen_info *si);
+static struct device *sysfb_parent_dev(const struct screen_info *si)
+{
+	struct pci_dev *pdev;
+
+	pdev = screen_info_pci_dev(si);
+	if (IS_ERR(pdev)) {
+		return ERR_CAST(pdev);
+	} else if (pdev) {
+		if (!sysfb_pci_dev_is_enabled(pdev)) {
+			pci_dev_put(pdev);
+			return ERR_PTR(-ENODEV);
+		}
+		return &pdev->dev;
+	}
+
+	return NULL;
+}
 
 static bool sysfb_unregister(void)
 {
@@ -101,24 +117,6 @@ bool sysfb_handles_screen_info(void)
 }
 EXPORT_SYMBOL_GPL(sysfb_handles_screen_info);
 
-static struct device *sysfb_parent_dev(const struct screen_info *si)
-{
-	struct pci_dev *pdev;
-
-	pdev = screen_info_pci_dev(si);
-	if (IS_ERR(pdev)) {
-		return ERR_CAST(pdev);
-	} else if (pdev) {
-		if (!sysfb_pci_dev_is_enabled(pdev)) {
-			pci_dev_put(pdev);
-			return ERR_PTR(-ENODEV);
-		}
-		return &pdev->dev;
-	}
-
-	return NULL;
-}
-
 static __init int sysfb_init(void)
 {
 	struct sysfb_display_info *dpy = &sysfb_primary_display;
-- 
2.53.0


^ permalink raw reply related

* [PATCH 2/8] firmware: efi: Never declare sysfb_primary_display on x86
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann, kernel test robot
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

The x86 architecture comes with its own instance of the global
state variable sysfb_primary_display. Never declare it in the EFI
subsystem. Fix the test for CONFIG_FIRMWARE_EDID accordingly.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: e65ca1646311 ("efi: export sysfb_primary_display for EDID")
Cc: kernel test robot <lkp@intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: linux-efi@vger.kernel.org
---
 drivers/firmware/efi/efi-init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index 5a595d026f58..6103b1a082d2 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -60,7 +60,7 @@ extern __weak const efi_config_table_type_t efi_arch_tables[];
  * x86 defines its own instance of sysfb_primary_display and uses
  * it even without EFI, everything else can get them from here.
  */
-#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)) || defined(CONFIG_FIRMWARE_EDID)
+#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_FIRMWARE_EDID))
 struct sysfb_display_info sysfb_primary_display __section(".data");
 EXPORT_SYMBOL_GPL(sysfb_primary_display);
 #endif
-- 
2.53.0


^ permalink raw reply related

* [PATCH 1/8] hv: Select CONFIG_SYSFB only for CONFIG_HYPERV_VMBUS
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann, Michael Kelley,
	Saurabh Sengar, stable
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

Hyperv's sysfb access only exists in the VMBUS support. Therefore
only select CONFIG_SYSFB for CONFIG_HYPERV_VMBUS. Avoids sysfb code
on systems that don't need it.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 96959283a58d ("Drivers: hv: Always select CONFIG_SYSFB for Hyper-V guests")
Cc: Michael Kelley <mhklinux@outlook.com>
Cc: Saurabh Sengar <ssengar@linux.microsoft.com>
Cc: Wei Liu <wei.liu@kernel.org>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Dexuan Cui <decui@microsoft.com>
Cc: Long Li <longli@microsoft.com>
Cc: linux-hyperv@vger.kernel.org
Cc: <stable@vger.kernel.org> # v6.16+
---
 drivers/hv/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 7937ac0cbd0f..2d0b3fcb0ff8 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -9,7 +9,6 @@ config HYPERV
 	select PARAVIRT
 	select X86_HV_CALLBACK_VECTOR if X86
 	select OF_EARLY_FLATTREE if OF
-	select SYSFB if EFI && !HYPERV_VTL_MODE
 	select IRQ_MSI_LIB if X86
 	help
 	  Select this option to run Linux as a Hyper-V client operating
@@ -62,6 +61,7 @@ config HYPERV_VMBUS
 	tristate "Microsoft Hyper-V VMBus driver"
 	depends on HYPERV
 	default HYPERV
+	select SYSFB if EFI && !HYPERV_VTL_MODE
 	help
 	  Select this option to enable Hyper-V Vmbus driver.
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH 4/8] firmware: sysfb: Split sysfb.c into sysfb_primary.c and sysfb_pci.c
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann
In-Reply-To: <20260402092305.208728-1-tzimmermann@suse.de>

Move the init code for the primary graphics device and the PCI-helpers
into separate source files. Only build the PCI helpers if CONFIG_PCI is
set. Prepares sysfb for additional PCI helpers.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/firmware/Makefile                     |  7 ++++--
 drivers/firmware/sysfb.h                      | 19 ++++++++++++++
 drivers/firmware/sysfb_pci.c                  | 21 ++++++++++++++++
 drivers/firmware/{sysfb.c => sysfb_primary.c} | 25 ++-----------------
 4 files changed, 47 insertions(+), 25 deletions(-)
 create mode 100644 drivers/firmware/sysfb.h
 create mode 100644 drivers/firmware/sysfb_pci.c
 rename drivers/firmware/{sysfb.c => sysfb_primary.c} (92%)

diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4ddec2820c96..5b0592c078df 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -16,13 +16,16 @@ obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
 obj-$(CONFIG_MTK_ADSP_IPC)	+= mtk-adsp-ipc.o
 obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
 obj-$(CONFIG_FW_CFG_SYSFS)	+= qemu_fw_cfg.o
-obj-$(CONFIG_SYSFB)		+= sysfb.o
-obj-$(CONFIG_SYSFB_SIMPLEFB)	+= sysfb_simplefb.o
 obj-$(CONFIG_TH1520_AON_PROTOCOL) += thead,th1520-aon.o
 obj-$(CONFIG_TI_SCI_PROTOCOL)	+= ti_sci.o
 obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
 obj-$(CONFIG_TURRIS_MOX_RWTM)	+= turris-mox-rwtm.o
 
+sysfb-y				:= sysfb_primary.o
+sysfb-$(CONFIG_PCI)		+= sysfb_pci.o
+sysfb-$(CONFIG_SYSFB_SIMPLEFB)	+= sysfb_simplefb.o
+obj-$(CONFIG_SYSFB)		+= sysfb.o
+
 obj-y				+= arm_ffa/
 obj-y				+= arm_scmi/
 obj-y				+= broadcom/
diff --git a/drivers/firmware/sysfb.h b/drivers/firmware/sysfb.h
new file mode 100644
index 000000000000..9f7fe2e03f68
--- /dev/null
+++ b/drivers/firmware/sysfb.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef FIRMWARE_SYSFB_H
+#define FIRMWARE_SYSFB_H
+
+#include <linux/types.h>
+
+struct pci_dev;
+
+#ifdef CONFIG_PCI
+bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev);
+#else
+static inline bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
+{
+	return false;
+}
+#endif
+
+#endif
diff --git a/drivers/firmware/sysfb_pci.c b/drivers/firmware/sysfb_pci.c
new file mode 100644
index 000000000000..8f3adeef4fb1
--- /dev/null
+++ b/drivers/firmware/sysfb_pci.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/pci.h>
+
+#include "sysfb.h"
+
+bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
+{
+	/*
+	 * TODO: Try to integrate this code into the PCI subsystem
+	 */
+	int ret;
+	u16 command;
+
+	ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return false;
+	if (!(command & PCI_COMMAND_MEMORY))
+		return false;
+	return true;
+}
diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb_primary.c
similarity index 92%
rename from drivers/firmware/sysfb.c
rename to drivers/firmware/sysfb_primary.c
index 8833582c1883..ab8d7fc468bb 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb_primary.c
@@ -35,6 +35,8 @@
 #include <linux/screen_info.h>
 #include <linux/sysfb.h>
 
+#include "sysfb.h"
+
 static struct platform_device *pd;
 static DEFINE_MUTEX(disable_lock);
 static bool disabled;
@@ -98,29 +100,6 @@ bool sysfb_handles_screen_info(void)
 }
 EXPORT_SYMBOL_GPL(sysfb_handles_screen_info);
 
-#if defined(CONFIG_PCI)
-static bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
-{
-	/*
-	 * TODO: Try to integrate this code into the PCI subsystem
-	 */
-	int ret;
-	u16 command;
-
-	ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
-	if (ret != PCIBIOS_SUCCESSFUL)
-		return false;
-	if (!(command & PCI_COMMAND_MEMORY))
-		return false;
-	return true;
-}
-#else
-static bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
-{
-	return false;
-}
-#endif
-
 static struct device *sysfb_parent_dev(const struct screen_info *si)
 {
 	struct pci_dev *pdev;
-- 
2.53.0


^ permalink raw reply related

* [PATCH 0/8] firmware: sysfb: Consolidate config/code wrt. sysfb_primary_screen
From: Thomas Zimmermann @ 2026-04-02  9:09 UTC (permalink / raw)
  To: javierm, arnd, ardb, ilias.apalodimas, chenhuacai, kernel,
	maarten.lankhorst, mripard, airlied, simona, kys, haiyangz,
	wei.liu, decui, longli, deller
  Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
	linux-hyperv, linux-fbdev, Thomas Zimmermann

The global state sysfb_primary_screen holds information about the
framebuffer provided by EFI/BIOS systems. It is part of the sysfb
module, but used in several places without direct connection to
sysfb. Fix this by making users of sysfb_primary_screen depend on
CONFIG_SYSFB. Fix a few issues in the process.

Patches 1 and 2 fix general errors in the Kconfig rules. In any case,
these patches should be considered even without the rest of the series.

Patch 3 makes CONFIG_SYSFB a user-controlled option, which gives users
more control over the configuration.

Patches 4 to 6 slightly refactor the sysfb code. The PCI helpers are
now in a separate source file. Support for relocating the PCI framebuffer
is now located in sysfb, where it belongs.

Patches 7 and 8 make earlycon and the firmware EDID depend on sysfb. Both
rely on sysfb_primary_display to work correctly.

Smoke-tested with bochs on qemu. Built with/without CONFIG_SYSFB enabled.

Note: vgaarb still guards sysfb_primary_display with CONFIG_X86 instead
of CONFIG_SYSFB. That works reliably and is left in place, as a change to
guard with SYSFB_SYSFB might affect non-x86 systems in unknown ways.

Thomas Zimmermann (8):
  hv: Select CONFIG_SYSFB only for CONFIG_HYPERV_VMBUS
  firmware: efi: Never declare sysfb_primary_display on x86
  firmware: sysfb: Make CONFIG_SYSFB a user-selectable option
  firmware: sysfb: Split sysfb.c into sysfb_primary.c and sysfb_pci.c
  firmware: sysfb: Implement screen_info relocation for primary display
  firmware: sysfb: Avoid forward-declaring sysfb_parent_dev()
  firmware: efi: Make CONFIG_EFI_EARLYCON depend on CONFIG_SYSFB; clean
    up
  firmware: sysfb: Move CONFIG_FIRMWARE_EDID to firmware options

 arch/arm64/kernel/image-vars.h                |   2 +-
 arch/loongarch/configs/loongson32_defconfig   |   1 +
 arch/loongarch/configs/loongson64_defconfig   |   1 +
 arch/loongarch/kernel/efi.c                   |   4 +-
 arch/loongarch/kernel/image-vars.h            |   2 +-
 arch/riscv/kernel/image-vars.h                |   2 +-
 drivers/firmware/Kconfig                      |  38 ++++-
 drivers/firmware/Makefile                     |   7 +-
 drivers/firmware/efi/Kconfig                  |   3 +-
 drivers/firmware/efi/efi-init.c               |   6 +-
 drivers/firmware/efi/libstub/efi-stub-entry.c |   4 +-
 drivers/firmware/sysfb.h                      |  24 ++++
 drivers/firmware/sysfb_pci.c                  | 132 ++++++++++++++++++
 drivers/firmware/{sysfb.c => sysfb_primary.c} |  70 ++++------
 drivers/gpu/drm/sysfb/Kconfig                 |   4 +-
 drivers/hv/Kconfig                            |   2 +-
 drivers/video/Kconfig                         |  19 ---
 drivers/video/fbdev/Kconfig                   |   5 +-
 drivers/video/screen_info_pci.c               | 110 ---------------
 include/linux/screen_info.h                   |   3 -
 20 files changed, 241 insertions(+), 198 deletions(-)
 create mode 100644 drivers/firmware/sysfb.h
 create mode 100644 drivers/firmware/sysfb_pci.c
 rename drivers/firmware/{sysfb.c => sysfb_primary.c} (90%)


base-commit: 5d36e6d54e963f0c1137aaf2249d2baa781f08c2
-- 
2.53.0


^ permalink raw reply

* Re: [PATCH 00/11] Drivers: hv: Add ARM64 support in mshv_vtl
From: Naman Jain @ 2026-04-02  4:01 UTC (permalink / raw)
  To: Michael Kelley, 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, 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: <SN6PR02MB4157E4E088F39106979BE4EDD450A@SN6PR02MB4157.namprd02.prod.outlook.com>



On 4/1/2026 10:24 PM, Michael Kelley wrote:
> From: Naman Jain <namjain@linux.microsoft.com> Sent: Tuesday, March 17, 2026 9:23 PM
>>
>> On 3/18/2026 3:33 AM, Michael Kelley wrote:
>>> From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
>>>>
>>>> The series intends to add support for ARM64 to mshv_vtl driver.
> 
> No need to be tentative. :-)  Just write as:
> 
> "The series adds support for ARM64 to the mshv_vtl driver."
> 
>>>> For this, common Hyper-V code is refactored, necessary support is added,
>>>> mshv_vtl_main.c is refactored and then finally support is added in
>>>> Kconfig.
>>>>
>>>> Based on commit 1f318b96cc84 ("Linux 7.0-rc3")
>>>
>>> There's now an online LLM-based tool that is automatically reviewing
>>> kernel patches. For this patch set, the results are here:
>>>
>>> https://sashiko.dev/#/patchset/20260316121241.910764-1-namjain%40linux.microsoft.com
>>>
>>> It has flagged several things that are worth checking, but I haven't
>>> reviewed them to see if they are actually valid.
>>>
>>> FWIW, the announcement about sashiko.dev is here:
>>>
>>> https://lore.kernel.org/lkml/7ia4o6kmpj5s.fsf@castle.c.googlers.com/
>>>
>>> Michael
>>
>>
>> Thanks for sharing Michael,
>> I'll check it out and do the needful.
>>
> 
> I've done a full review of this patch set and provided comments in the
> individual patches. Some of my comments reference the Sashiko AI
> comments, but there are still some Sashiko AI comments to consider
> that I haven't referenced.
> 
> FWIW, the Sashiko AI comments are quite good -- it found some things
> here that I missed on my own, and in my earlier reviews of the original VTL
> code. :-(
> 
> Michael


Thank you so much Michael for reviewing these. I was also trying to 
address review comments from Sashiko, and noticed some of them were 
false positives in the sense that these were existing issues and not 
introduced by arm64 changes. I thought of keeping them separate from the 
scope of this series for future.

I'll review your comments and address them.

Regards,
Naman

^ permalink raw reply

* [PATCH 7/7] mshv: Allocate pfns array only for pinned regions
From: Stanislav Kinsburskii @ 2026-04-01 22:13 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli; +Cc: linux-hyperv, linux-kernel
In-Reply-To: <177508151446.215674.7844504277869257435.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>

Convert pfns to a pointer allocated only for pinned regions that
actually need it for share/unshare/evict operations. Unpinned
regions use NULL since HMM handles their mappings dynamically.

The pfns array was previously a flexible array member, forcing
allocation for all regions regardless of memory type. This wastes
significant memory for unpinned HMM-managed regions which don't
need persistent PFN tracking - a 1GB region wastes 2MB for an
unused array.

This also allows using kzalloc for the main structure instead of
vzalloc, improving allocation efficiency and cache locality.

Simplify unpinned region invalidation by calling the hypervisor
directly rather than tracking PFNs. The tradeoff of skipping huge
page optimization is acceptable since invalidation ranges are
typically small and not performance-critical.

Add NULL checks where pfns array is required and update cleanup
to handle conditional allocation.

Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
---
 drivers/hv/mshv_regions.c |   50 ++++++++++++++++++++++++++-------------------
 drivers/hv/mshv_root.h    |    6 ++++-
 2 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/hv/mshv_regions.c b/drivers/hv/mshv_regions.c
index 3c2a35f3bc31..e3a6ade4919e 100644
--- a/drivers/hv/mshv_regions.c
+++ b/drivers/hv/mshv_regions.c
@@ -243,7 +243,7 @@ struct mshv_region *mshv_region_create(enum mshv_region_type type,
 	int ret = 0;
 	u64 i;
 
-	region = vzalloc(sizeof(*region) + sizeof(unsigned long) * nr_pfns);
+	region = kzalloc_obj(*region);
 	if (!region)
 		return ERR_PTR(-ENOMEM);
 
@@ -255,6 +255,13 @@ struct mshv_region *mshv_region_create(enum mshv_region_type type,
 						   &mshv_region_mni_ops);
 		break;
 	case MSHV_REGION_TYPE_MEM_PINNED:
+		region->mreg_pfns = vzalloc(sizeof(unsigned long) * nr_pfns);
+		if (!region->mreg_pfns) {
+			ret = -ENOMEM;
+			break;
+		}
+		for (i = 0; i < nr_pfns; i++)
+			region->mreg_pfns[i] = MSHV_INVALID_PFN;
 		break;
 	case MSHV_REGION_TYPE_MMIO:
 		region->mreg_mmio_pfn = mmio_pfn;
@@ -276,16 +283,13 @@ struct mshv_region *mshv_region_create(enum mshv_region_type type,
 	if (flags & BIT(MSHV_SET_MEM_BIT_EXECUTABLE))
 		region->hv_map_flags |= HV_MAP_GPA_EXECUTABLE;
 
-	for (i = 0; i < nr_pfns; i++)
-		region->mreg_pfns[i] = MSHV_INVALID_PFN;
-
 	mutex_init(&region->mreg_mutex);
 	kref_init(&region->mreg_refcount);
 
 	return region;
 
 free_region:
-	vfree(region);
+	kfree(region);
 	return ERR_PTR(ret);
 }
 
@@ -312,6 +316,9 @@ static int mshv_region_share(struct mshv_region *region)
 {
 	u32 flags = HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED;
 
+	if (!region->mreg_pfns)
+		return -EINVAL;
+
 	return mshv_region_process_range(region, flags,
 					 0, region->nr_pfns,
 					 region->mreg_pfns,
@@ -340,6 +347,9 @@ static int mshv_region_unshare(struct mshv_region *region)
 {
 	u32 flags = HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE;
 
+	if (!region->mreg_pfns)
+		return -EINVAL;
+
 	return mshv_region_process_range(region, flags,
 					 0, region->nr_pfns,
 					 region->mreg_pfns,
@@ -394,13 +404,11 @@ static void mshv_region_invalidate_pfns(struct mshv_region *region,
 {
 	u64 i;
 
-	for (i = pfn_offset; i < pfn_offset + pfn_count; i++) {
-		if (!pfn_valid(region->mreg_pfns[i]))
-			continue;
-
-		if (region->mreg_type == MSHV_REGION_TYPE_MEM_PINNED)
-			unpin_user_page(pfn_to_page(region->mreg_pfns[i]));
+	if (region->mreg_type != MSHV_REGION_TYPE_MEM_PINNED)
+		return;
 
+	for (i = pfn_offset; i < pfn_offset + pfn_count; i++) {
+		unpin_user_page(pfn_to_page(region->mreg_pfns[i]));
 		region->mreg_pfns[i] = MSHV_INVALID_PFN;
 	}
 }
@@ -506,7 +514,8 @@ static void mshv_region_destroy(struct kref *ref)
 
 	mshv_region_invalidate(region);
 
-	vfree(region);
+	vfree(region->mreg_pfns);
+	kfree(region);
 }
 
 void mshv_region_put(struct mshv_region *region)
@@ -616,10 +625,9 @@ static int mshv_region_hmm_fault_and_lock(struct mshv_region *region,
  *   leaving missing pages as invalid PFN markers.
  *   Used for initial region setup.
  *
- * Collected PFNs are stored in region->mreg_pfns[] with HMM bookkeeping
- * flags cleared, then the range is mapped into the hypervisor. Present
- * PFNs get mapped with region access permissions; missing PFNs (zero
- * entries) get mapped with no-access permissions.
+ * HMM bookkeeping flags are stripped from collected PFNs before mapping.
+ * Present PFNs get mapped with region access permissions; missing PFNs
+ * (marked as MSHV_INVALID_PFN) get mapped with no-access permissions.
  *
  * Return: 0 on success, negative errno on failure.
  */
@@ -648,15 +656,17 @@ static int mshv_region_collect_and_map(struct mshv_region *region,
 		goto out;
 
 	for (i = 0; i < pfn_count; i++) {
-		if (!(pfns[i] & HMM_PFN_VALID))
+		if (!(pfns[i] & HMM_PFN_VALID)) {
+			pfns[i] = MSHV_INVALID_PFN;
 			continue;
+		}
 		/* Drop HMM_PFN_* flags to ensure PFNs are valid. */
-		region->mreg_pfns[pfn_offset + i] = pfns[i] & ~HMM_PFN_FLAGS;
+		pfns[i] &= ~HMM_PFN_FLAGS;
 	}
 
 	ret = mshv_region_remap_pfns(region, region->hv_map_flags,
 				     pfn_offset, pfn_count,
-				     region->mreg_pfns + pfn_offset);
+				     pfns);
 
 	mutex_unlock(&region->mreg_mutex);
 out:
@@ -770,8 +780,6 @@ static bool mshv_region_interval_invalidate(struct mmu_interval_notifier *mni,
 	if (ret)
 		goto out_unlock;
 
-	mshv_region_invalidate_pfns(region, pfn_offset, pfn_count);
-
 	mutex_unlock(&region->mreg_mutex);
 
 	return true;
diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index 97659ba55418..e43bdbf1ada8 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -92,8 +92,10 @@ struct mshv_region {
 	enum mshv_region_type mreg_type;
 	struct mmu_interval_notifier mreg_mni;
 	struct mutex mreg_mutex;	/* protects region PFNs remapping */
-	u64 mreg_mmio_pfn;
-	unsigned long mreg_pfns[];
+	union {
+		unsigned long *mreg_pfns;
+		u64 mreg_mmio_pfn;
+	};
 };
 
 struct mshv_irq_ack_notifier {



^ permalink raw reply related


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