* [PATCH RFC v2 2/4] drm/i915/display/dp: Adopt dp_connector helpers to expose link training state
From: Kory Maincent @ 2026-06-19 14:08 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Dmitry Baryshkov, Daniel Stone
Cc: Thomas Petazzoni, Mark Yacoub, Sean Paul, Manasi Navare,
Drew Davenport, Louis Chauvet, Luca Ceresoli, dri-devel,
linux-kernel, intel-gfx, intel-xe, linux-mediatek,
linux-arm-kernel, Kory Maincent
In-Reply-To: <20260619-feat_link_cap-v2-0-a3dec4c02ad9@bootlin.com>
Switch the i915 DP connector initialization from
drm_connector_init_with_ddc() to drm_connector_dp_init_with_ddc(),
providing the source link capabilities (supported lane counts, link rates
and DSC support).
Add intel_dp_report_link_train() to collect the negotiated link
parameters (rate, lane count and DSC enable) and report them via
drm_dp_set_max_link_params() and drm_dp_set_cur_link_params() once
link training completes successfully.
Reset the link properties via drm_dp_reset_link_params()
when the connector is reported as disconnected or when the display device
is disabled, so the exposed state always reflects the current link status.
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Changes in v2:
- Remove voltage swing and pre emphasis properties.
---
drivers/gpu/drm/i915/display/intel_dp.c | 26 ++++++++++++++++++----
.../gpu/drm/i915/display/intel_dp_link_training.c | 17 ++++++++++++++
2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f01a6eed38395..46c06c76952e0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6414,8 +6414,10 @@ intel_dp_detect(struct drm_connector *_connector,
drm_WARN_ON(display->drm,
!drm_modeset_is_locked(&display->drm->mode_config.connection_mutex));
- if (!intel_display_device_enabled(display))
+ if (!intel_display_device_enabled(display)) {
+ drm_dp_sink_reset_link_caps(_connector);
return connector_status_disconnected;
+ }
if (!intel_display_driver_check_access(display))
return connector->base.status;
@@ -6465,6 +6467,8 @@ intel_dp_detect(struct drm_connector *_connector,
intel_dp_tunnel_disconnect(intel_dp);
+ drm_dp_sink_reset_link_caps(_connector);
+
goto out_unset_edid;
}
@@ -7240,10 +7244,12 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(dig_port);
+ struct drm_connector_dp_link_caps link_caps;
struct intel_dp *intel_dp = &dig_port->dp;
struct intel_encoder *encoder = &dig_port->base;
struct drm_device *dev = encoder->base.dev;
enum port port = encoder->port;
+ u32 *rates;
int type;
if (drm_WARN(dev, dig_port->max_lanes < 1,
@@ -7291,8 +7297,21 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",
encoder->base.base.id, encoder->base.name);
- drm_connector_init_with_ddc(dev, &connector->base, &intel_dp_connector_funcs,
- type, &intel_dp->aux.ddc);
+ intel_dp_set_source_rates(intel_dp);
+ link_caps.nlanes = 4;
+ link_caps.nlink_rates = intel_dp->num_source_rates;
+ rates = kmemdup_array(intel_dp->source_rates, intel_dp->num_source_rates,
+ sizeof(*rates), GFP_KERNEL);
+ if (!rates)
+ goto fail;
+
+ link_caps.link_rates = rates;
+ link_caps.dsc = HAS_DSC(display);
+
+ drm_connector_dp_init_with_ddc(dev, &connector->base, &intel_dp_connector_funcs,
+ &link_caps, type, &intel_dp->aux.ddc);
+ kfree(rates);
+
drm_connector_helper_add(&connector->base, &intel_dp_connector_helper_funcs);
if (!HAS_GMCH(display) && DISPLAY_VER(display) < 12)
@@ -7315,7 +7334,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
goto fail;
}
- intel_dp_set_source_rates(intel_dp);
intel_dp_set_common_rates(intel_dp);
intel_dp_reset_link_params(intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index a26094223f780..25e0e957fe36d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -1231,6 +1231,18 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp,
return sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION ? 1 : 0;
}
+static void intel_dp_report_link_train(struct intel_dp *intel_dp)
+{
+ struct intel_connector *connector = intel_dp->attached_connector;
+
+ drm_dp_set_max_link_params(&connector->base, intel_dp->link_rate,
+ intel_dp->lane_count);
+
+ drm_dp_set_cur_link_params(&connector->base, intel_dp->link_rate,
+ intel_dp->lane_count,
+ connector->dp.dsc_decompression_enabled);
+}
+
/**
* intel_dp_stop_link_train - stop link training
* @intel_dp: DP struct
@@ -1259,6 +1271,9 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp,
intel_dp_program_link_training_pattern(intel_dp, crtc_state, DP_PHY_DPRX,
DP_TRAINING_PATTERN_DISABLE);
+ if (!intel_dp->is_mst)
+ intel_dp_report_link_train(intel_dp);
+
if (intel_dp_is_uhbr(crtc_state)) {
ret = poll_timeout_us(ret = intel_dp_128b132b_intra_hop(intel_dp, crtc_state),
ret == 0,
@@ -1772,6 +1787,8 @@ void intel_dp_start_link_train(struct intel_atomic_state *state,
*/
int lttpr_count;
+ drm_dp_sink_set_link_caps(&intel_dp->attached_connector->base, &intel_dp->aux);
+
intel_hpd_block(encoder);
lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
--
2.43.0
^ permalink raw reply related
* [PATCH RFC v2 0/4] Add support for DisplayPort link training information report
From: Kory Maincent @ 2026-06-19 14:08 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Dmitry Baryshkov, Daniel Stone
Cc: Thomas Petazzoni, Mark Yacoub, Sean Paul, Manasi Navare,
Drew Davenport, Louis Chauvet, Luca Ceresoli, dri-devel,
linux-kernel, intel-gfx, intel-xe, linux-mediatek,
linux-arm-kernel, Kory Maincent
DisplayPort link training negotiates the physical-layer parameters needed
for a reliable connection: lane count, link rate, and optionally Display
Stream Compression (DSC). Currently, each driver exposes this state in
its own way, often through driver-specific debugfs entries, with no
standard interface for userspace diagnostic and monitoring tools.
This series introduces generic, managed and unmanaged DisplayPort
connector initialization helpers, for exposing DP link capabilities and
state as standard sysfs entries, modeled after the existing HDMI helper
drmm_connector_hdmi_init().
The aim of such development is to guide users to select the most suitable
DisplayPort connector for their needs. For example, if you have a USB-C
hub with lesser capabilities than your computer’s native DisplayPort
connector (such as HBR2 versus HBR3 support), the system could recommend
connecting high-resolution displays directly to the computer’s port
instead of through the hub to ensure optimal performance.
These new drmm_connector_dp_init() and drm_connector_dp_init_with_ddc()
helpers initialize a DP connector and expose link training capabilities
and state to userspace via sysfs attributes under dp_link.
Additional helpers are provided to manage link capabilities and parameters
at runtime.
Two drivers are updated as reference implementations: i915 (direct
connector path) and MediaTek (via the bridge connector framework using a
new DRM_BRIDGE_OP_DP flag).
The changes updating the i915 driver to use DRM managed resources have been
removed due to cleanup path issues. The core problem is that some functions
do not consistently propagate errors through their call paths (whether this
is intentional or not) making it difficult to properly handle cleanup of
DRM objects (planes, encoders, connectors). A potential solution would be
to implement something similar to devres_group for each DRM object type,
but this represents a substantial undertaking that falls outside the scope
of this patch series.
The MST case in i915 driver is not supported yet.
Patch 1: Introduce the core drmm_connector_dp_init() framework
Patch 2: Wire the i915 DP connector to use the new helpers
Patch 3: Introduce DRM_BRIDGE_OP_DP and wire bridge connectors
Patch 4: Wire the MediaTek DP bridge to the new helpers [untested]
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Changes in v2:
- Removed work converting i915 to DRM managed resource
- Remove voltage swing and pre-emphasis properties
- Expose link training state via sysfs dp_link/ group instead of
connector properties
- Add comprehensive sysfs attributes for both source and sink capabilities
- Add new helpers for managing sink capabilities and for current link
parameters
- Link to v1: https://lore.kernel.org/r/20260409-feat_link_cap-v1-0-7069e8199ce2@bootlin.com
---
Kory Maincent (4):
drm: Introduce DisplayPort connector helpers with link training state
drm/i915/display/dp: Adopt dp_connector helpers to expose link training state
drm/bridge: Wire drmm_connector_dp_init() via new DRM_BRIDGE_OP_DP flag
drm/mediatek: Use dp_connector helpers to report link training state
drivers/gpu/drm/display/drm_bridge_connector.c | 24 ++++
drivers/gpu/drm/display/drm_dp_helper.c | 144 +++++++++++++++++++++
drivers/gpu/drm/drm_connector.c | 122 +++++++++++++++++
drivers/gpu/drm/drm_sysfs.c | 100 ++++++++++++++
drivers/gpu/drm/i915/display/intel_dp.c | 26 +++-
.../gpu/drm/i915/display/intel_dp_link_training.c | 17 +++
drivers/gpu/drm/mediatek/mtk_dp.c | 23 ++++
include/drm/display/drm_dp_helper.h | 7 +
include/drm/drm_bridge.h | 13 ++
include/drm/drm_connector.h | 105 +++++++++++++++
10 files changed, 577 insertions(+), 4 deletions(-)
---
base-commit: 4d75f8bd845c10f126e0e66bcdd264e1f9772bde
change-id: 20260226-feat_link_cap-20cbb6f31d40
Best regards,
--
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Jason Gunthorpe @ 2026-06-19 14:06 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: Alexey Kardashevskiy, Catalin Marinas, iommu, linux-arm-kernel,
linux-kernel, linux-coco, Robin Murphy, Marek Szyprowski,
Will Deacon, Marc Zyngier, Steven Price, Suzuki K Poulose,
Jiri Pirko, Mostafa Saleh, Petr Tesarik, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <yq5aldcaejos.fsf@kernel.org>
On Fri, Jun 19, 2026 at 02:36:19PM +0100, Aneesh Kumar K.V wrote:
> >> Agreed. If the device can do encrypted DMA and requires bouncing, it
> >> should bounce through encrypted pools. We don't support encrypted pools
> >> now and that means, we mark the option ("mem_encrypt=on iommu=pt
> >> swiotlb=force") not supported for now?
> >
> > ?? if you don't have a CC system then the swiotlb is "encrypted"
> > meaning ordinary struct page system memory.
> >
> > The hypervisor should not be triggering any CC special stuff here, it
> > is not a CC guest.
> >
> > Agree we don't need to worry about swiotlb=force with a trusted device
> > in the GUEST for now, but it should be something to fix eventually.
> >
>
> If i understand this correctly, the setup Alexey is referring to here is
> bare metal system with memory encryption enabled and dma address doesn't
> need C bit cleared because it is handled in iommu.
This is how I understand it too, if the iommu is turned on then it can
take the high PA with the C bit set and map it to an IOVA that matches
the device's dma limit.
> ( I consider this as memory encryption that is handled
> transparently, device can access any address because that encryption
> details are now managed by iommu).
Compared to the guest side there are some important host side differences:
- On the host the iommu can fix it because this is only a matter of
IOVA range not access control. On a guest even a IOMMU cannot
permit access to private memory
- On the host the state of the device is driven by the dma limit
which is not set until after the driver probes. On guest the state is
set by the tsm and device security level before the driver
probes
- Both flows end up using pgprot_decrypted and set_memory_decrypted()
to create their special pools, but for completely different
reasons.
- The memory coming from the special swiotlb pool must NOT be used by
a trusted device on a CC guest, while there is no problem for any
device to use it on the host.
> Thinking about this more, I guess we should mark the swiotlb as
> cc_shared only with CC_ATTR_GUEST_MEM_ENCRYPT instead of
> CC_ATTR_MEM_ENCRYPT as we have below.
The name cc_shared should be used for GUEST scenarios only.
I guess there is some merit in keeping swiotlb using "decrypted" to
mean it usinig pgprot_decrypted and set_memory_decyped() which AMD
gives meaning to on both host and guest.
IDK what AMD should do on the host by default. I guess it should setup
a swiotlb pool of low dma addrs "unencrypted", but not "cc_shared"?
But if we are operating on the host then this pool is not limited to
only T=0 devices, every device can "safely" use it. (ignoring this
destroys the security memory encryption on bare metal was supposed to
provide)
> Now we have the case of host memory encryption where the C-bit needs to
> be cleared in dma_addr_t. That requires special handling in the kernel, and
> I believe we need to mark swiotlb as unencrypted in this configuration.
I think we need to split the two things up, they have different
behaviors and need different flags and labels to make it all work
right.
> I am still not clear whether there is a config option or runtime check
> we can use to identify this case.
The dma api has to detect, after the driver sets the dma limit, that
none of system memory is usable when:
- The direct path is being used
- phys to dma for 0 is outside the dma limit
Then it should assume the arch has setup a swiotlb pool for it to use
to fix the high memory problem.
Similar hackery would be needed in the dma alloc path to know that
decrypted can be used to fix the high memory problem like for GUEST.
I guess some 'dev_cannot_reach_memory(dev)' sort of test in a
few key places? Setup with a static branch to be a nop on everything
but AMD, compiled out on every other arch.
Jason
^ permalink raw reply
* Re: [PATCH v2 2/5] docs: media: add documentation for media client usage stats
From: Nicolas Dufresne @ 2026-06-19 14:04 UTC (permalink / raw)
To: Hans Verkuil, Detlev Casanova, Mauro Carvalho Chehab,
Benjamin Gaignard, Philipp Zabel, Ezequiel Garcia, Heiko Stuebner
Cc: linux-media, linux-kernel, linux-rockchip, kernel,
linux-arm-kernel, Christopher Healy
In-Reply-To: <755cf7c1-6bcc-45d1-afea-192d393256af@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 9829 bytes --]
Hi,
Le vendredi 19 juin 2026 à 14:58 +0200, Hans Verkuil a écrit :
> Hi Detlev,
>
> Interesting, I had never heard of fdinfo, so if nothing else, I learned something new!
>
> On 17/06/2026 20:10, Detlev Casanova wrote:
> > From: Christopher Healy <healych@amazon.com>
> >
> > Document the media fdinfo interface for per-file-descriptor usage
> > statistics exposed by stateless V4L2 codec drivers via
> > /proc/<pid>/fdinfo/<fd>.
> >
> > This interface is designed for stateless (request API based) codec
> > devices where the kernel driver has per-job visibility into hardware
> > execution. Stateful codecs cannot support all of this because their
> > firmware manages job scheduling opaquely.
> >
> > The specification defines media- prefixed keys for engine utilization
> > time, and operating frequency, following the same conventions as the DRM
> > fdinfo mechanism documented in drm-usage-stats.rst.
> >
> > More fields can be added later.
> >
> > Signed-off-by: Christopher Healy <healych@amazon.com>
> > Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
> > ---
> > .../userspace-api/media/drivers/index.rst | 1 +
> > .../media/drivers/media-usage-stats.rst | 85 ++++++++++++++++++++++
> > 2 files changed, 86 insertions(+)
> >
> > diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst
> > index 02967c9b18d6..61879738836c 100644
> > --- a/Documentation/userspace-api/media/drivers/index.rst
> > +++ b/Documentation/userspace-api/media/drivers/index.rst
> > @@ -34,6 +34,7 @@ For more details see the file COPYING in the source distribution of Linux.
> > imx-uapi
> > mali-c55
> > max2175
> > + media-usage-stats
> > npcm-video
> > omap3isp-uapi
> > thp7312
> > diff --git a/Documentation/userspace-api/media/drivers/media-usage-stats.rst b/Documentation/userspace-api/media/drivers/media-usage-stats.rst
> > new file mode 100644
> > index 000000000000..d3dc07002f62
> > --- /dev/null
> > +++ b/Documentation/userspace-api/media/drivers/media-usage-stats.rst
> > @@ -0,0 +1,85 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +.. _media-usage-stats:
> > +
> > +==========================
> > +Media client usage stats
>
> stats -> statistics
>
> But are these really statistics? Isn't it just the current status?
> In many ways this feature looks to me similar to what VIDIOC_LOG_STATUS does,
> except in a nicer format. When VIDIOC_LOG_STATUS was first added, fdinfo
> didn't exist yet.
>
> And I wouldn't call it 'Media client': it's specific to stateless V4L2
> codec drivers.
While it is currently implemented for sateless m2m codec drivers as example
(because we can't implement this everywhere at once really, its not practical),
there is no reason why we cannot track to a process fdinfo memory usage
associated with other video devices. In fact, I would pretty much want to see
capture devices showing up in v4l2top, as these are using a lot of memory too,
specially the new camera pipelines. And this is also perfectly suitable for
stateful codec, converters, everything.
So please, let's agree this is not "stateless V4L2 codec drivers" specific.
About VIDIOC_LOG_STATUS, this is effectively broken for m2m, only the owning
session process could call that. Its also pretty bad for tools to have to
monitor the dmesg and filter it up. fdinfo on the other end, does not require
opening the device and permissions are very clear, and bound to user process.
>
> > +==========================
> > +
> > +Stateless V4L2 codec drivers can optionally expose per-file-descriptor usage
> > +statistics via ``/proc/<pid>/fdinfo/<fd>``. This is analogous to the DRM fdinfo
> > +mechanism documented in :ref:`drm-client-usage-stats`, but uses the ``media-``
> > +key prefix for V4L2 media devices.
> > +
> > +This interface is specific to stateless (request API based) codec devices,
> > +including both decoders and encoders. With stateless codecs, the kernel driver
> > +explicitly submits each frame to the hardware and receives a completion
> > +interrupt, providing a clean per-job boundary that can be attributed to the
> > +submitting file descriptor.
> > +
> > +Stateful codec devices cannot support this interface because their firmware
> > +manages job scheduling internally. The kernel driver submits bitstream data
> > +but has no visibility into per-frame hardware execution timing.
> > +
> > +Implementation
> > +==============
> > +
> > +The V4L2 core provides the plumbing: drivers implement the ``show_fdinfo``
> > +callback in ``struct v4l2_file_operations``, and the core wires it into the
> > +kernel ``struct file_operations`` so that ``/proc/<pid>/fdinfo/<fd>`` output
> > +includes the driver-provided keys.
> > +
> > +File format specification
> > +=========================
> > +
> > +- File shall contain one key value pair per one line of text.
> > +- Colon character (``:``) must be used to delimit keys and values.
> > +- All standardised keys shall be prefixed with ``media-``.
> > +- Driver-specific keys shall be prefixed with ``driver_name-``.
> > +
> > +Mandatory keys
> > +--------------
> > +
> > +- media-driver: <valstr>
>
> I'd pick 'v4l2-driver'. Since 'media-driver' is too generic for this
> since that encompasses also DVB/CEC/RC drivers.
>
> > +
> > + String shall contain the name of the media driver.
>
> 'V4L2 stateless codec driver'
With that said, we can refine, but not in that direction.
>
> > +
> > +- media-type: <valstr>
>
> Poor name.
>
> > +
> > + String shall identify the type of media engine exposed through this file
> > + descriptor. Standard values are ``decoder`` and ``encoder``.
>
> I think I would use 'stateless-decoder' and 'stateless-encoder'. It's more
> specific than de/encoder since that can be stateful as well.
>
> So I am missing the big picture here: right now this patch adds support for
> this for stateless codecs, but what happens in the future if this is also
> added for regular video capture devices, ISPs, etc.?
We should work further on the type system, then we'd simply have to extend it.
Different type of driver will provide different key/value pair. We should well
document which key are mandatory for the type (or for all type, like giving a
name for general identification purpose).
Of course, the current proposal is very torward processing cores, hence the one
to one match with what GPUs present in fdinfo today in mainline, such are
frequency, core utilization time, etc.
Though, DMA devices such as capture may expose more of a bandwidth kind of
information. I really don't want to make up too may cases, so owners of these
don't feel like this is mandated though. As we develop software using our
drivers, we should be able to figure-out what kind of things are important to
monitor. For CODECs, we have two majors things. a) core utilization (which can
be with a timer like this one, but ideally using cycle counters, or firmware
provided data). b) memory usage.
>
> The naming here matters, it has to have some sort of scheme so it can be
> extended to other types of drivers. So a 'media' prefix is too generic,
> and it also looks like it refers to the /dev/mediaX device.
>
> > +
> > +Utilization keys
> > +----------------
> > +
> > +- media-engine-usage: <uint> ns
>
> 'Media Engine': very vague.
>
> > +
> > + Time in nanoseconds that the hardware engine spent busy processing work
>
> Cumulative since creating the file handle? Or since the last read?
>
> > + belonging to this file descriptor. The engine being measured is identified
> > + by the ``media-type`` key.
> > +
> > + Values are not required to be constantly monotonic if it makes the driver
> > + implementation easier, but are required to catch up with the previously
> > + reported larger value within a reasonable period.
>
> Does this make sense for codecs?
>
> I can tell that this is heavily influenced by the drm documentation, but that
> does not necessarily translate to V4L2.
I would guess this is bound to usage of cycle counter, which we definitely have
in some codec HW exposing. As the frequency fluctuate, I suppose there is ways
you can get your calculation a bit off, as this is being sampled. Basically, the
frequence change is not strictly tracked by our drivers, which is ok. But I also
don't seen why we wouldn't keep the counters monotonic, its really easy to do.
>
> > +
> > +Frequency keys
> > +--------------
> > +
> > +- media-maxfreq: <uint> Hz
> > +
> > + Maximum operating frequency of the main engine clock.
> > +
> > +- media-curfreq: <uint> Hz
> > +
> > + Current operating frequency of the main engine clock.
>
> 'Main engine clock'?
The word "engine" seems indeed alien in this subsystem. It is referring to a
system where you open one devices, so you have one fdinfo, but multiple cores.
Each cores may be running at it owns frequency. But I think this is a little too
vague to my taste.
Hope this feedback does not cross to many wires, but tagging this as specific to
stateless codec drivers did spark a little in my head. And we are really in need
for a way to monitor our drivers.
Nicolas
>
> > +
> > +Example output
> > +==============
> > +
> > +::
> > +
> > + media-driver: hantro-vpu
> > + media-type: decoder
> > + media-engine-usage: 123456789 ns
> > + media-maxfreq: 600000000 Hz
> > + media-curfreq: 600000000 Hz
> >
>
> Regards,
>
> Hans
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v4 0/4] arm64: cross-CPU NMI via SDEI
From: Catalin Marinas @ 2026-06-19 14:00 UTC (permalink / raw)
To: Kiryl Shutsemau
Cc: Will Deacon, James Morse, Mark Rutland, Marc Zyngier,
Doug Anderson, Petr Mladek, Thomas Gleixner, Andrew Morton,
Baoquan He, Puranjay Mohan, Usama Arif, Breno Leitao,
Julien Thierry, Lecopzer Chen, Sumit Garg, kernel-team, kexec,
linux-arm-kernel, linux-kernel, Kiryl Shutsemau (Meta)
In-Reply-To: <cover.1781709543.git.kas@kernel.org>
Hi Kiryl,
On Wed, Jun 17, 2026 at 08:20:01PM +0100, Kiryl Shutsemau wrote:
> - GICv3 pseudo-NMI (interrupt priority masking). Its cost is on the
> interrupt mask/unmask hot path: local_irq_enable() becomes an
> ICC_PMR_EL1 write plus a synchronising barrier, and exception
> entry/exit save and restore the PMR, paid on every CPU whether or not
> an NMI is ever delivered. In our measurements, enabling pseudo-NMI
> costs up to ~5% on real workloads, and ~66% on a syscall-in-a-loop
> microbenchmark. A fleet-wide ~5% regression is not acceptable, so
> these systems run with pseudo-NMI disabled.
Does your firmware set ICC_CTLR_EL1.PMHE? I'd be curious to see the
numbers if the DSB was omitted on the enable path.
> This series adds a third delivery backend that costs nothing on the hot
> path: SDEI. Firmware delivers an SDEI event into a CPU regardless of its
> DAIF state, so interrupt masking stays the cheap PSTATE.DAIF operation and
> the firmware round-trip is paid only at the rare moment a CPU must be
> interrupted.
The direction of travel is to deprecated SDEI. I wouldn't add more stuff
on top of this interface.
(I haven't looked at the patches yet; Marc/Mark/James are more
knowledgeable than me in this area)
--
Catalin
^ permalink raw reply
* Re: [PATCH v7 11/30] drm/display: bridge_connector: Wire up HDMI 2.0 scrambler callbacks
From: Maxime Ripard @ 2026-06-19 13:58 UTC (permalink / raw)
To: Cristian Ciocaltea
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Sandy Huang,
Heiko Stübner, Andy Yan, Daniel Stone, Dave Stevenson,
Maíra Canal, Raspberry Pi Kernel Maintenance, kernel,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <b14af457-0799-43cc-80b5-7ffff5901f24@collabora.com>
[-- Attachment #1: Type: text/plain, Size: 6479 bytes --]
On Fri, Jun 12, 2026 at 11:42:06PM +0300, Cristian Ciocaltea wrote:
> On 6/12/26 11:52 AM, Maxime Ripard wrote:
> > On Tue, Jun 02, 2026 at 01:44:11AM +0300, Cristian Ciocaltea wrote:
> >> Connect the bridge connector's .scrambler_{enable|disable} callbacks to
> >> the underlying bridge's .hdmi_scrambler_{enable|disable} funcs when
> >> DRM_BRIDGE_OP_HDMI_SCRAMBLER is advertised.
> >>
> >> This completes the bridge connector plumbing so that the SCDC
> >> scrambling helpers can control source-side scrambling through the
> >> bridge chain.
> >>
> >> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> >> ---
> >> drivers/gpu/drm/display/drm_bridge_connector.c | 41 +++++++++++++++++++++++++-
> >> 1 file changed, 40 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
> >> index 9d21b1b57b0d..d048ab49eade 100644
> >> --- a/drivers/gpu/drm/display/drm_bridge_connector.c
> >> +++ b/drivers/gpu/drm/display/drm_bridge_connector.c
> >> @@ -555,6 +555,32 @@ static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connec
> >> return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len);
> >> }
> >>
> >> +static int drm_bridge_connector_scrambler_enable(struct drm_connector *connector)
> >> +{
> >> + struct drm_bridge_connector *bridge_connector =
> >> + to_drm_bridge_connector(connector);
> >> + struct drm_bridge *bridge;
> >> +
> >> + bridge = bridge_connector->bridge_hdmi;
> >> + if (!bridge)
> >> + return -EINVAL;
> >> +
> >> + return bridge->funcs->hdmi_scrambler_enable(bridge);
> >> +}
> >> +
> >> +static int drm_bridge_connector_scrambler_disable(struct drm_connector *connector)
> >> +{
> >> + struct drm_bridge_connector *bridge_connector =
> >> + to_drm_bridge_connector(connector);
> >> + struct drm_bridge *bridge;
> >> +
> >> + bridge = bridge_connector->bridge_hdmi;
> >> + if (!bridge)
> >> + return -EINVAL;
> >> +
> >> + return bridge->funcs->hdmi_scrambler_disable(bridge);
> >> +}
> >> +
> >> static const struct drm_edid *
> >> drm_bridge_connector_read_edid(struct drm_connector *connector)
> >> {
> >> @@ -580,7 +606,7 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
> >> .clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe,
> >> .write_infoframe = drm_bridge_connector_write_hdmi_infoframe,
> >> },
> >> - /* audio, hdr_drm and spd are set dynamically during init */
> >> + /* scrambler, audio, hdr_drm and spd are set dynamically during init */
> >> };
> >>
> >> static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_audio_infoframe = {
> >> @@ -886,6 +912,11 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
> >> !bridge->funcs->hdmi_clear_spd_infoframe))
> >> return ERR_PTR(-EINVAL);
> >>
> >> + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SCRAMBLER &&
> >> + (!bridge->funcs->hdmi_scrambler_enable ||
> >> + !bridge->funcs->hdmi_scrambler_disable))
> >> + return ERR_PTR(-EINVAL);
> >> +
> >> bridge_connector->bridge_hdmi = drm_bridge_get(bridge);
> >>
> >> if (bridge->supported_formats)
> >> @@ -990,6 +1021,14 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
> >> bridge_connector->hdmi_funcs.spd =
> >> drm_bridge_connector_hdmi_spd_infoframe;
> >>
> >> + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SCRAMBLER) {
> >> + bridge_connector->hdmi_funcs.scrambler_enable =
> >> + drm_bridge_connector_scrambler_enable;
> >> + bridge_connector->hdmi_funcs.scrambler_disable =
> >> + drm_bridge_connector_scrambler_disable;
> >> + connector->hdmi.scrambler_supported = true;
> >> + }
> >> +
> >
> > I think we're taking this backwards. The scrambler support isn't
> > optional: either the controller supports HDMI < 2.0, and then it doesn't
> > exist, or it supports >= 2.0 and then it's mandatory.
> >
> > You're considering it optional here, when it's never actually optional
> > (unlike YUV420 for example)
> >
> > I still think we should list, somehow, the capabilities of the
> > controller to the helpers, like max tmds rate supported, formats, etc.
> > We've so far put everything as an argument to drmm_connector_hdmi_init
> > but it becomes a bit overloaded, and I wonder if introducing a callback
> > wouldn't solve this, kind of like what we have for planes and formats.
>
>
> What about introducing something like:
>
> struct drm_connector_hdmi_caps {
> ...
> unsigned int supported_formats;
> enum hdmi_version supported_hdmi_ver;
> };
>
> struct drm_connector_hdmi_funcs {
> ...
> int (*get_caps)(struct drm_connector *connector,
> struct drm_connector_hdmi_caps *caps);
> ...
> };
>
> int drmm_connector_hdmi_init(struct drm_device *dev, ...)
> {
> ...
> if (hdmi_funcs->get_caps) {
> struct drm_connector_hdmi_caps caps = { };
>
> ret = hdmi_funcs->get_caps(connector, &caps);
> if (ret)
> return ret;
>
> connector->hdmi.supported_formats = caps.supported_formats;
> ...
> if (caps.supported_hdmi_ver > HDMI_2_0)
> connector->hdmi.frl_supported = true;
> else if (caps.supported_hdmi_ver == HDMI_2_0)
> connector->hdmi.scrambler_supported = true;
> }
> ...
> }
That's what I initially had in mind, but it feels a bit over-the-top
when looking at it. I think I'd really like something that drivers
cannot forget about, screw up and/or mess with, so for example report
HDMI 2.1 but force disable FRL support, or report HDMI 1.4 but support
YUV420.
Adding more arguments to drm_connector_hdmi_init could work I guess, but
it won't scale to everything we need. Expecting the callers to fill
drm_connector_hdmi won't work either. So I somewhat think a get_caps
like we discussed is the less bad solution, but I'm definitely open to
suggestions.
> Not sure if max_tmds_char_rate should be listed as a capability, as we already
> have the .tmds_char_rate_valid() callback.
I guess it would make sense to move it there and consolidate
atomic_check / mode_valid checks, but I don't think it should be a
prerequisite for this patch either.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
* Re: [PATCH] pmdomain: bcm: bcm2835-power: Raise ASB poll timeout to 100us
From: Maíra Canal @ 2026-06-19 13:57 UTC (permalink / raw)
To: Stefan Wahren, Ulf Hansson, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden
Cc: linux-pm, linux-rpi-kernel, linux-arm-kernel, kernel-dev
In-Reply-To: <eba66b9e-520e-4afc-8973-d54b22919d2c@igalia.com>
Hi,
On 31/05/26 09:18, Maíra Canal wrote:
> Hi Stefan,
>
> On 31/05/26 07:41, Stefan Wahren wrote:
>> Hi Maíra,
>>
>> Am 30.05.26 um 22:46 schrieb Maíra Canal:
>>> Commit 18605b1b936b ("pmdomain: bcm: bcm2835-power: Increase ASB control
>>> timeout") raised the ASB handshake polling budget from 1us to 5us.
>>> Surveying the pmdomain subsystem, 5us is still one of the smallest
>>> polling
>>> budgets by a wide margin. Comparable handshakes in other drivers use:
>>>
>>> - 100us : starfive jh71xx-pmu, apple pmgr-pwrstate
>>> - 1ms : renesas rcar-sysc, rmobile-sysc (power-on)
>>> - 10ms : renesas rcar-gen4-sysc, sunxi sun55i-pck600
>>> - 1s : mediatek mtk-pm-domains, mtk-scpsys
>>>
>>> Raise the BCM2835 timeout to 100us, matching analogous drivers. 100us is
>>> still negligible relative to a power-domain transition and gives the V3D
>>> master ASB substantially more headroom to drain under heavy workloads,
>>> assuring us that the timeout is enough for any scenario.
>> tbh I'm not convinced by this explanation. Starting with a timeout
>> comparison across different pmdomain driver looks strange to me.
>>
>> My expectation that the reason for such a patch is that there is some
>> kind of scenario to trigger unexpected timeouts.
>> If this is the case, please provide more information about the
>> scenario (specific platform, scenario, link to the bug report).
>
> The context: I was debugging this issue [1] and initially I had the
> intuition that it could be related to a timeout in the ASB polling loop.
> As I don't have access to the BCM2835 SoC datasheet (the public one
> doesn't have PM information), I started to check other driver's
> handshake timeout to see if ours was comparable to similar drivers. As
> you can see, our timeout is much smaller.
>
> In the end, issue [1] wasn't related to the pmdomain driver, so I don't
> have a specific scenario to trigger this issue. Even though, I sent this
> patch considering the comparison to other drivers with the goal to be
> conservative and use a larger timeout that could accommodate an extreme
> scenario. However, if you believe it's unreasonable, I'm okay dropping
> this patch.
>
> Ideally, it would be great to have information from Broadcom on what's
> the largest possible time required to perform a power transition. Maybe
> Florian could help us with that?
>
Gentle ping, any ideas about this?
Best regards,
- Maíra
> [1] https://lore.kernel.org/dri-devel/20260530-v3d-fix-rpi4-freezes-
> v1-0-c2c8307da6ce@igalia.com/T/
>
>>
>> I'm not against the change in general, but please start your commit
>> message with the problem and not with the solution.
>>
>> A related question, does it make sense to add an error message here
>> for the timeout case just like in the rest of the driver?
>
> Before commit 18605b1b936b, I was getting a "Failed to disable ASB
> master for v3d" error message, so I believe the error message already
> exists where the function is called.
>
> Thanks for your feedback!
>
> Best regards,
> - Maíra
>
>>
>> Best regards
>>
>>>
>>> Signed-off-by: Maíra Canal <mcanal@igalia.com>
>>> ---
>>> drivers/pmdomain/bcm/bcm2835-power.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/pmdomain/bcm/bcm2835-power.c b/drivers/pmdomain/
>>> bcm/bcm2835-power.c
>>> index b76d74e3849b..d507bb675e29 100644
>>> --- a/drivers/pmdomain/bcm/bcm2835-power.c
>>> +++ b/drivers/pmdomain/bcm/bcm2835-power.c
>>> @@ -175,7 +175,7 @@ static int bcm2835_asb_control(struct
>>> bcm2835_power *power, u32 reg, bool enable
>>> writel(PM_PASSWORD | val, base + reg);
>>> if (readl_poll_timeout_atomic(base + reg, val,
>>> - !!(val & ASB_ACK) != enable, 0, 5))
>>> + !!(val & ASB_ACK) != enable, 0, 100))
>>> return -ETIMEDOUT;
>>> return 0;
>>
>
^ permalink raw reply
* Re: [PATCH v2 4/5] arm64: defconfig: Drop unused Ethernet vendors
From: Arnd Bergmann @ 2026-06-19 13:54 UTC (permalink / raw)
To: Krzysztof Kozlowski, Geert Uytterhoeven
Cc: linux-kernel, linux-arm-kernel, Catalin Marinas, Will Deacon,
Alexandre Belloni, Linus Walleij, Drew Fustini, soc
In-Reply-To: <ed070807-d2dd-4f0b-9ba1-8d2c8c93c30e@oss.qualcomm.com>
On Fri, Jun 19, 2026, at 15:11, Krzysztof Kozlowski wrote:
> On 19/06/2026 12:12, Geert Uytterhoeven wrote:
>>> +# CONFIG_NET_VENDOR_ACTIONS is not set
>>> +# CONFIG_NET_VENDOR_ADAPTEC is not set
>>> +# CONFIG_NET_VENDOR_AGERE is not set
>>> +# CONFIG_NET_VENDOR_ALACRITECH is not set
>>> +# CONFIG_NET_VENDOR_ALLWINNER is not set
>>
>> [...]
>>
>> I am not sure this new policy is a good idea: none of this affects
>
> I would not call it new policy. Just an idea which got accepted. :)
I think when we originally added the CONFIG_NET_VENDOR_xxx symbols,
the idea would be that we would one day change them to
default-disabled, but that never happened, and generally causes
more problems than it solves.
Arnd
^ permalink raw reply
* Re: [PATCH] arm64: uapi: Use __u128 instead of __uint128_t in UAPI headers
From: Arnd Bergmann @ 2026-06-19 13:52 UTC (permalink / raw)
To: Will Deacon, linux-arm-kernel
Cc: Nick Desaulniers, Steffen Eiden, Andreas Grapentin,
Catalin Marinas, Dave Martin, Mark Rutland, Marc Zyngier
In-Reply-To: <20260619130835.5678-1-will@kernel.org>
On Fri, Jun 19, 2026, at 15:08, Will Deacon wrote:
> The arm64 UAPI exposes '__uint128_t' types in the members of
> 'struct user_fpsimd_state', 'struct user_pac_address_keys' and in the
> signal frame via 'struct fpsimd_context'. Since the alignment of such
> a type appears to be non-portable (16 bytes on arm64, 8 bytes on s390),
> prefer the '__u128' typedef from uapi/linux/types.h, which makes the
> alignment explicit and allows the definitions to be reused by other
> host architectures.
>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Nick Desaulniers <nick.desaulniers+lkml@gmail.com>
> Cc: Steffen Eiden <seiden@linux.ibm.com>
> Cc: Andreas Grapentin <gra@linux.ibm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dave Martin <dave.martin@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Will Deacon <will@kernel.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> I think it's a straightforward change, but the only thing that makes me
> pause for thought is whether there are toolchains out there which accept
> __uint128_t but not __int128. Then again, if that crops up as an issue
> we can probably just tweak the typedef we have in uapi/linux/types.h.
clang-3.1 and gcc-4.6 support both and are 15 years old, older versions
only do __uint128_t. I agree that this should be fine.
Arnd
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Aneesh Kumar K.V @ 2026-06-19 13:44 UTC (permalink / raw)
To: Jason Gunthorpe, Alexey Kardashevskiy
Cc: Catalin Marinas, iommu, linux-arm-kernel, linux-kernel,
linux-coco, Robin Murphy, Marek Szyprowski, Will Deacon,
Marc Zyngier, Steven Price, Suzuki K Poulose, Jiri Pirko,
Mostafa Saleh, Petr Tesarik, Dan Williams, Xu Yilun, linuxppc-dev,
linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260619120309.GI231643@ziepe.ca>
Jason Gunthorpe <jgg@ziepe.ca> writes:
> On Fri, Jun 19, 2026 at 12:05:45PM +1000, Alexey Kardashevskiy wrote:
>
>> > > > > IMHO that's an AMD issue, not with the design of this series..
>> > > > >
>> > > > > The series is right, a device that is !force_dma_decrypted() must be
>> > > > > considerd to be a trusted device and we must never place any DMA
>> > > > > mappings for a trusted device into shared memory.
>> > > >
>> > > > swiotlb=force forces swiotlb, not decryption.
>> >
>> > If force_dma_decrypted() == true then swiotlb must allocate from a
>> > decrypted memory pool. It is right there in the name!
>> >
>> > The hypervisor environment should *never* set force_dma_decrypted()
>> > because all devices can access all hypervisor memory, up to their IOVA
>> > limits.
>>
>> True. But we do not have encrypted swiotlb pool today, right?
>
> "encrypted" is just normal struct page memory, that's the default for
> swiotlb.
>
> I think it was a big mistake for the AMD SME stuff to overload the
> decrypted/encrypted CC stuff which should mean shared/private in a
> guest context to also mean things about physical memory encryption in
> the host. It is really confusing.
>
> The SME side is just a bad arch choice, the real world doesn't work
> well if you set high address bits in your dma_addr_t. I think AMD
> needs to use those restricted swiotlb pool where it allocates this
> very special "SME Disabled" memory that will have a low
> dma_addr_t. Then alloc and bouncing will get memory with a suitable
> dma_addr_t. This has nothing to do with force_dma_unencrypted() which
> is only a CC guest concept and nothing else in the OS should ever
> touch decrypted memory.
Agreed. This would make the code much simpler.
-aneesh
^ permalink raw reply
* Re: [RFC PATCH 6/6] arm64: mm: support PMD page coalescing in the linear map
From: Ryan Roberts @ 2026-06-19 13:40 UTC (permalink / raw)
To: Adrian Barnaś, linux-arm-kernel
Cc: linux-mm, Catalin Marinas, Will Deacon, David Hildenbrand,
Mike Rapoport (Microsoft), Ard Biesheuvel, Christoph Lameter,
Yang Shi, Brendan Jackman
In-Reply-To: <20260611130144.1385343-7-abarnas@google.com>
On 11/06/2026 14:01, Adrian Barnaś wrote:
> Implement PMD block coalescing to merge fragmented linear mapping regions
> back into huge pages when restoring the read-only attribute.
>
> When memory allocated with VM_ALLOW_HUGE_VMAP (such as for the execmem
> ROX cache) has its permissions modified, the PMD block mapping is split
> into individual PTEs. Without this change, when that memory have its RO
> attribute subsequently cleared and set the mapping remains permanently
> fragmented into 4K pages.
I'd like to make sure I understand this correctly: So the execmem ROX cache is
allocated using vmalloc_huge such that all it's backing memory are PMD-sized
pages. It is initially poisoned with a faulting instruction and marked ROX. When
a module is loaded, it's text is copied into a portion of the ROX cache and
executed from there? To do that, the required number of (4K) pages are allocated
from ROX cache, and the permissions are changed on that sub-region to RW,
meaning we have to split the mapping from a PMD to (cont)PTEs in both vmalloc
space and in the linear map. After the text is copied, the sub-region is
switched back to ROX. But without that change, the 2M region is now mapped by
(cont)PTEs for all of time?
>
> Signed-off-by: Adrian Barnaś <abarnas@google.com>
> ---
> arch/arm64/include/asm/mmu.h | 1 +
> arch/arm64/mm/mmu.c | 95 ++++++++++++++++++++++++++++++++++++
> arch/arm64/mm/pageattr.c | 7 +++
> 3 files changed, 103 insertions(+)
>
> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> index 137a173df1ff..19158bacb2df 100644
> --- a/arch/arm64/include/asm/mmu.h
> +++ b/arch/arm64/include/asm/mmu.h
> @@ -80,6 +80,7 @@ extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
> extern void mark_linear_text_alias_ro(void);
> extern int split_kernel_leaf_mapping(unsigned long start, unsigned long end);
> extern void linear_map_maybe_split_to_ptes(void);
> +void try_collapse_kernel_pmd(unsigned long addr);
>
> /*
> * This check is triggered during the early boot before the cpufeature
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index a6a00accf4f9..d74226fa1c9b 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -769,6 +769,101 @@ static inline bool force_pte_mapping(void)
>
> static DEFINE_MUTEX(pgtable_split_lock);
>
> +static inline bool __pte_can_be_collapsed(pte_t pte, unsigned long pfn, pgprot_t prot)
> +{
> + if (!pte_valid(pte))
> + return false;
> + if (pte_pfn(pte) != pfn)
> + return false;
> + if ((pgprot_val(pte_pgprot(pte)) & ~PTE_CONT) != pgprot_val(prot))
Do we want to permit differing values for access and dirty? We do for user
space, but I think for kernel, those bits are always set? In which case, what
you're doing is correct.
> + return false;
> +
> + return true;
> +}
> +
> +static void __try_collapse_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr)
> +{
> + pte_t *ptep;
> + pte_t first_pte;
> + unsigned long pfn;
> + pgprot_t prot;
> + int i;
> +
> + ptep = (pte_t *)pmd_page_vaddr(pmd);
> + first_pte = __ptep_get(ptep);
> +
> + if (!pte_valid(first_pte))
> + return;
> +
> + prot = pte_pgprot(first_pte);
> + prot = __pgprot(pgprot_val(prot) & ~PTE_CONT);
> + pfn = pte_pfn(first_pte);
> +
> + if (!IS_ALIGNED(pfn, PMD_SIZE >> PAGE_SHIFT))
> + return;
> +
> + for (i = 1; i < PTRS_PER_PTE; i++) {
> + if (!__pte_can_be_collapsed(__ptep_get(ptep + i), pfn + i, prot))
> + return;
> + }
> +
> + set_pmd(pmdp, pmd_mkhuge(pfn_pmd(pfn, prot)));
> +
> + __flush_tlb_kernel_pgtable(addr);
> +
nit: suggest adding the same comment that other sites has, since this is not
obvious:
/* See comment in pud_free_pmd_page for static key logic */
> + if (static_branch_unlikely(&arm64_ptdump_lock_key)) {
> + mmap_read_lock(&init_mm);
> + mmap_read_unlock(&init_mm);
> + }
> +
> + pte_free_kernel(NULL, ptep);
Ooh, fun. Per my comments below we definitely have opportunity for racy pte
table accesses (beyond ptdump). I _think_ if you fix that then this will be safe.
> +}
> +
> +void try_collapse_kernel_pmd(unsigned long addr)
> +{
> + pgd_t *pgdp;
> + p4d_t *p4dp;
> + pud_t *pudp;
> + pmd_t *pmdp;
> + pmd_t pmd;
> +
> + /*
> + * collapse_pmd expects exact address of block to be collapsed
> + */
> + if (WARN_ON(ALIGN_DOWN(addr, PMD_SIZE) != addr))
> + return;
> +
> + mutex_lock(&pgtable_split_lock);
I don't think this is safe in general. Let's say we have a 2M region split into
512 x 4K PTEs. It's possible that the first 1M is one object and the second 1M
is another object. Different CPUs could set_memory_*() on those 2 objects
concurrently. If one of them then calls this function, we could end up
collapsing the whole 2M while the other is trying to modify the PTEs and they
will race.
Note that splitting _is_ safe (and protected by this lock) because you'd have 2
objects backed by the same PMD, so they would both have to split before
modifying the PTEs.
I think you'd need to ensure mutual exclusion at a higher level if doing this;
probably execmem is the place that can ensure that no objects within a 2M region
are racily trying to modify their permissions?
> +
> + pgdp = pgd_offset_k(addr);
> + if (pgd_none(READ_ONCE(*pgdp)))
nit: use the getters (e.g. pXdp_get()) instead of READ_ONCE().
> + goto out;
> +
> + p4dp = p4d_offset(pgdp, addr);
> + if (p4d_none(READ_ONCE(*p4dp)))
> + goto out;
> +
> + pudp = pud_offset(p4dp, addr);
> + if (pud_none(READ_ONCE(*pudp)))
> + goto out;
> +
> + if (pud_leaf(READ_ONCE(*pudp)))
> + goto out;
> +
> + pmdp = pmd_offset(pudp, addr);
> + pmd = pmdp_get(pmdp);
> +
> + if (!pmd_table(pmd))
> + goto out;
> +
> + lazy_mmu_mode_enable();
> + __try_collapse_pmd(pmdp, pmd, addr);
> + lazy_mmu_mode_disable();
> +
> +out:
> + mutex_unlock(&pgtable_split_lock);
> +}
> +
> int split_kernel_leaf_mapping(unsigned long start, unsigned long end)
> {
> int ret;
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index eaefdf90b0d5..11e0b60264c3 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -200,6 +200,13 @@ static int change_memory_common(unsigned long addr, int numpages,
> if (ret)
> return ret;
> }
The loop here in the unchanged code, calls __change_memory_common() for each
PAGE_SIZE page in the linear alias. Perhaps it should be area->page_order aware?
That way, if we are changing the permissions of the whole 2M chunk of vmalloc
space and it's backed by a 2M page, then we won't split the mapping to PTEs in
the linear map. Similarly, if we are changing permissions on a sub-region of the
2M area, we might be able to split only as far as contpte and still have some
performance benefit?
> + /*
> + * When setting a read-only flag on the linear region, the memory
> + * may have been backed by a PMD before being split. Try to
> + * collapse it back into a PMD to restore huge page performance.
> + */
> + if (pgprot_val(set_mask) == PTE_RDONLY && area->flags & VM_ALLOW_HUGE_VMAP)
> + try_collapse_kernel_pmd((u64)page_address(area->pages[0]));
try_collapse_kernel_pmd() requires a PMD-aligned address. VM_ALLOW_HUGE_VMAP
doesn't guarrantee that - it only says that it's _allowed_ to be huge (and 64K
would still be huge). vmalloc may have failed to allocate a PMD-sized page and
reverted to something smaller (64K contpte or 4K). You need to look at
area->page_order, I think.
You're only calling this for the linear alias. Don't you want to call it for the
vmalloc range too? I assume the module text executes using the vmalloc address
so you'd want it mapped by a single PMD for best performance?
But in general, I don't really like the idea of special-casing a collapse to pmd
here for just execmem. I think we should either investigate a general purpose
collapse mechanism or execmem should have extra hooks added to request specific
collapse.
Thanks,
Ryan
> }
>
> /*
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Aneesh Kumar K.V @ 2026-06-19 13:36 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Alexey Kardashevskiy, Catalin Marinas, iommu, linux-arm-kernel,
linux-kernel, linux-coco, Robin Murphy, Marek Szyprowski,
Will Deacon, Marc Zyngier, Steven Price, Suzuki K Poulose,
Jiri Pirko, Mostafa Saleh, Petr Tesarik, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260619122148.GL231643@ziepe.ca>
Jason Gunthorpe <jgg@ziepe.ca> writes:
> On Fri, Jun 19, 2026 at 01:14:13PM +0100, Aneesh Kumar K.V wrote:
>> > And this is more insane logic. The right fix is to allocate the
>> > swiotlb bounce from the *encrypted* pools when running on the
>> > hypervisor which requires undoing this abuse of force_dma_decrypted().
>> >
>>
>> Agreed. If the device can do encrypted DMA and requires bouncing, it
>> should bounce through encrypted pools. We don't support encrypted pools
>> now and that means, we mark the option ("mem_encrypt=on iommu=pt
>> swiotlb=force") not supported for now?
>
> ?? if you don't have a CC system then the swiotlb is "encrypted"
> meaning ordinary struct page system memory.
>
> The hypervisor should not be triggering any CC special stuff here, it
> is not a CC guest.
>
> Agree we don't need to worry about swiotlb=force with a trusted device
> in the GUEST for now, but it should be something to fix eventually.
>
If i understand this correctly, the setup Alexey is referring to here is
bare metal system with memory encryption enabled and dma address doesn't
need C bit cleared because it is handled in iommu. ( I consider this as
memory encryption that is handled transparently, device can access any
address because that encryption details are now managed by iommu).
Thinking about this more, I guess we should mark the swiotlb as
cc_shared only with CC_ATTR_GUEST_MEM_ENCRYPT instead of
CC_ATTR_MEM_ENCRYPT as we have below.
/*
* if platform support memory encryption, swiotlb buffers are
* shared by default.
*/
if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
io_tlb_default_mem.cc_shared = true;
else
io_tlb_default_mem.cc_shared = false;
....
if (io_tlb_default_mem.cc_shared)
set_memory_decrypted((unsigned long)mem->vaddr, bytes >> PAGE_SHIFT);
So we consider swiotlb as encrypted pool in such config.
Now we have the case of host memory encryption where the C-bit needs to
be cleared in dma_addr_t. That requires special handling in the kernel, and
I believe we need to mark swiotlb as unencrypted in this configuration.
I am still not clear whether there is a config option or runtime check
we can use to identify this case.
-aneesh
^ permalink raw reply
* Re: [PATCH v2 5/8] KVM: arm64: Add host and hypervisor vCPU lookup primitives
From: Vincent Donnefort @ 2026-06-19 13:31 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, kvmarm, linux-arm-kernel,
linux-kernel, Catalin Marinas, Will Deacon, Joey Gouly,
Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Quentin Perret,
Sebastian Ene, Hyunwoo Kim
In-Reply-To: <20260619070719.812227-6-tabba@google.com>
On Fri, Jun 19, 2026 at 08:07:16AM +0100, Fuad Tabba wrote:
> From: Marc Zyngier <maz@kernel.org>
>
> The nVHE hypervisor repeatedly resolves a host vCPU into the EL2
> address space and validates that the loaded hyp vCPU matches it, with
> that logic open-coded in each handler.
>
> Add __get_host_hyp_vcpus() and the get_host_hyp_vcpus() macro, which
> translate the host vCPU into the hypervisor's address space and, when
> pKVM is enabled, also return the loaded hyp vCPU if it matches. If pKVM
> is enabled but the loaded hyp vCPU does not correspond to the requested
> host vCPU, both the host and hyp vCPU are returned as NULL. Convert
> handle___kvm_vcpu_run() to use it.
>
> No functional change intended.
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> Co-developed-by: Fuad Tabba <tabba@google.com>
> Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 52 ++++++++++++++++++++++--------
> 1 file changed, 38 insertions(+), 14 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 1d01c6e547f5..8923f594c264 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -212,14 +212,45 @@ static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
> pkvm_put_hyp_vcpu(hyp_vcpu);
> }
>
> -static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
> +static struct kvm_vcpu *__get_host_hyp_vcpus(struct kvm_vcpu *arg,
> + struct pkvm_hyp_vcpu **hyp_vcpup)
> {
> - DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 1);
> - int ret;
> + struct kvm_vcpu *host_vcpu = kern_hyp_va(arg);
> + struct pkvm_hyp_vcpu *hyp_vcpu = NULL;
>
> if (unlikely(is_protected_kvm_enabled())) {
> - struct pkvm_hyp_vcpu *hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> + hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
>
> + if (!hyp_vcpu || hyp_vcpu->host_vcpu != host_vcpu) {
> + hyp_vcpu = NULL;
> + host_vcpu = NULL;
> + }
> + }
> +
> + *hyp_vcpup = hyp_vcpu;
> + return host_vcpu;
> +}
> +
> +#define get_host_hyp_vcpus(ctxt, regnr, hyp_vcpup) \
> + ({ \
> + DECLARE_REG(struct kvm_vcpu *, __vcpu, ctxt, regnr); \
> + __get_host_hyp_vcpus(__vcpu, hyp_vcpup); \
> + })
> +
> +static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
> +{
> + struct pkvm_hyp_vcpu *hyp_vcpu;
> + struct kvm_vcpu *host_vcpu;
> + int ret;
> +
> + host_vcpu = get_host_hyp_vcpus(host_ctxt, 1, &hyp_vcpu);
> +
> + if (!host_vcpu) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + if (unlikely(hyp_vcpu)) {
> /*
> * KVM (and pKVM) doesn't support SME guests for now, and
> * ensures that SME features aren't enabled in pstate when
> @@ -231,23 +262,16 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
> goto out;
> }
>
> - if (!hyp_vcpu) {
> - ret = -EINVAL;
> - goto out;
> - }
> -
> flush_hyp_vcpu(hyp_vcpu);
>
> ret = __kvm_vcpu_run(&hyp_vcpu->vcpu);
>
> sync_hyp_vcpu(hyp_vcpu);
> } else {
> - struct kvm_vcpu *vcpu = kern_hyp_va(host_vcpu);
> -
> /* The host is fully trusted, run its vCPU directly. */
> - fpsimd_lazy_switch_to_guest(vcpu);
> - ret = __kvm_vcpu_run(vcpu);
> - fpsimd_lazy_switch_to_host(vcpu);
> + fpsimd_lazy_switch_to_guest(host_vcpu);
> + ret = __kvm_vcpu_run(host_vcpu);
> + fpsimd_lazy_switch_to_host(host_vcpu);
> }
> out:
> cpu_reg(host_ctxt, 1) = ret;
> --
> 2.55.0.rc0.738.g0c8ab3ebcc-goog
>
^ permalink raw reply
* Re: [PATCH v2 4/8] KVM: arm64: Move PSCI helper functions to a shared header
From: Vincent Donnefort @ 2026-06-19 13:30 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, kvmarm, linux-arm-kernel,
linux-kernel, Catalin Marinas, Will Deacon, Joey Gouly,
Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Quentin Perret,
Sebastian Ene, Hyunwoo Kim
In-Reply-To: <20260619070719.812227-5-tabba@google.com>
On Fri, Jun 19, 2026 at 08:07:15AM +0100, Fuad Tabba wrote:
> Move kvm_psci_valid_affinity() and kvm_psci_narrow_to_32bit() from
> psci.c to include/kvm/arm_psci.h, and move psci_affinity_mask() there
> too, renaming it kvm_psci_affinity_mask() now that it is no longer
> file-local. A follow-up series handles some protected-guest PSCI calls
> at EL2 using these helpers.
>
> No functional change intended.
>
> Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/kvm/psci.c | 30 +-----------------------------
> include/kvm/arm_psci.h | 27 +++++++++++++++++++++++++++
> 2 files changed, 28 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
> index 3b5dbe9a0a0e..e3db84400d1f 100644
> --- a/arch/arm64/kvm/psci.c
> +++ b/arch/arm64/kvm/psci.c
> @@ -21,16 +21,6 @@
> * as described in ARM document number ARM DEN 0022A.
> */
>
> -#define AFFINITY_MASK(level) ~((0x1UL << ((level) * MPIDR_LEVEL_BITS)) - 1)
> -
> -static unsigned long psci_affinity_mask(unsigned long affinity_level)
> -{
> - if (affinity_level <= 3)
> - return MPIDR_HWID_BITMASK & AFFINITY_MASK(affinity_level);
> -
> - return 0;
> -}
> -
> static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
> {
> /*
> @@ -51,12 +41,6 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
> return PSCI_RET_SUCCESS;
> }
>
> -static inline bool kvm_psci_valid_affinity(struct kvm_vcpu *vcpu,
> - unsigned long affinity)
> -{
> - return !(affinity & ~MPIDR_HWID_BITMASK);
> -}
> -
> static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
> {
> struct vcpu_reset_state *reset_state;
> @@ -135,7 +119,7 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
> return PSCI_RET_INVALID_PARAMS;
>
> /* Determine target affinity mask */
> - target_affinity_mask = psci_affinity_mask(lowest_affinity_level);
> + target_affinity_mask = kvm_psci_affinity_mask(lowest_affinity_level);
> if (!target_affinity_mask)
> return PSCI_RET_INVALID_PARAMS;
>
> @@ -220,18 +204,6 @@ static void kvm_psci_system_suspend(struct kvm_vcpu *vcpu)
> run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
> }
>
> -static void kvm_psci_narrow_to_32bit(struct kvm_vcpu *vcpu)
> -{
> - int i;
> -
> - /*
> - * Zero the input registers' upper 32 bits. They will be fully
> - * zeroed on exit, so we're fine changing them in place.
> - */
> - for (i = 1; i < 4; i++)
> - vcpu_set_reg(vcpu, i, lower_32_bits(vcpu_get_reg(vcpu, i)));
> -}
> -
> static unsigned long kvm_psci_check_allowed_function(struct kvm_vcpu *vcpu, u32 fn)
> {
> /*
> diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h
> index cbaec804eb83..f86a006d6713 100644
> --- a/include/kvm/arm_psci.h
> +++ b/include/kvm/arm_psci.h
> @@ -38,6 +38,33 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu)
> return KVM_ARM_PSCI_0_1;
> }
>
> +/* Narrow the PSCI register arguments (r1 to r3) to 32 bits. */
> +static inline void kvm_psci_narrow_to_32bit(struct kvm_vcpu *vcpu)
> +{
> + int i;
> +
> + /*
> + * Zero the input registers' upper 32 bits. They will be fully
> + * zeroed on exit, so we're fine changing them in place.
> + */
> + for (i = 1; i < 4; i++)
> + vcpu_set_reg(vcpu, i, lower_32_bits(vcpu_get_reg(vcpu, i)));
> +}
> +
> +static inline bool kvm_psci_valid_affinity(struct kvm_vcpu *vcpu,
> + unsigned long affinity)
> +{
> + return !(affinity & ~MPIDR_HWID_BITMASK);
> +}
> +
> +static inline unsigned long kvm_psci_affinity_mask(unsigned long affinity_level)
> +{
> + if (affinity_level <= 3)
> + return MPIDR_HWID_BITMASK &
> + ~((0x1UL << (affinity_level * MPIDR_LEVEL_BITS)) - 1);
> +
> + return 0;
> +}
>
> int kvm_psci_call(struct kvm_vcpu *vcpu);
>
> --
> 2.55.0.rc0.738.g0c8ab3ebcc-goog
>
^ permalink raw reply
* Re: [PATCH v2 3/8] KVM: arm64: Factor out reusable vCPU reset helpers
From: Vincent Donnefort @ 2026-06-19 13:29 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, kvmarm, linux-arm-kernel,
linux-kernel, Catalin Marinas, Will Deacon, Joey Gouly,
Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Quentin Perret,
Sebastian Ene, Hyunwoo Kim
In-Reply-To: <20260619070719.812227-4-tabba@google.com>
On Fri, Jun 19, 2026 at 08:07:14AM +0100, Fuad Tabba wrote:
> Pull the reusable pieces out of kvm_reset_vcpu(): expose the reset
> PSTATE values in kvm_arm.h, and split the core register reset and the
> PSCI-driven reset into kvm_reset_vcpu_core() and kvm_reset_vcpu_psci().
> A follow-up series reuses these to reset protected vCPUs at EL2.
>
> No functional change intended.
>
> Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/include/asm/kvm_arm.h | 12 ++++++
> arch/arm64/include/asm/kvm_emulate.h | 57 ++++++++++++++++++++++++++
> arch/arm64/kvm/reset.c | 60 ++--------------------------
> 3 files changed, 72 insertions(+), 57 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 3f9233b5a130..aba4ec09acd2 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -348,4 +348,16 @@
> { PSR_AA32_MODE_UND, "32-bit UND" }, \
> { PSR_AA32_MODE_SYS, "32-bit SYS" }
>
> +/*
> + * ARMv8 Reset Values
> + */
> +#define VCPU_RESET_PSTATE_EL1 (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
> + PSR_F_BIT | PSR_D_BIT)
> +
> +#define VCPU_RESET_PSTATE_EL2 (PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
> + PSR_F_BIT | PSR_D_BIT)
> +
> +#define VCPU_RESET_PSTATE_SVC (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
> + PSR_AA32_I_BIT | PSR_AA32_F_BIT)
> +
> #endif /* __ARM64_KVM_ARM_H__ */
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 80b30fead3d1..2385d8855fcf 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -704,4 +704,61 @@ static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu)
> vcpu->arch.hcrx_el2 |= HCRX_EL2_EnASR;
> }
> }
> +
> +/* Reset a vcpu's core registers. */
> +static inline void kvm_reset_vcpu_core(struct kvm_vcpu *vcpu)
> +{
> + u32 pstate;
> +
> + if (vcpu_el1_is_32bit(vcpu))
> + pstate = VCPU_RESET_PSTATE_SVC;
> + else if (vcpu_has_nv(vcpu))
> + pstate = VCPU_RESET_PSTATE_EL2;
> + else
> + pstate = VCPU_RESET_PSTATE_EL1;
> +
> + /* Reset core registers */
> + memset(vcpu_gp_regs(vcpu), 0, sizeof(*vcpu_gp_regs(vcpu)));
> + memset(&vcpu->arch.ctxt.fp_regs, 0, sizeof(vcpu->arch.ctxt.fp_regs));
> + vcpu->arch.ctxt.spsr_abt = 0;
> + vcpu->arch.ctxt.spsr_und = 0;
> + vcpu->arch.ctxt.spsr_irq = 0;
> + vcpu->arch.ctxt.spsr_fiq = 0;
> + vcpu_gp_regs(vcpu)->pstate = pstate;
> +}
> +
> +/* PSCI reset handling for a vcpu. */
> +static inline void kvm_reset_vcpu_psci(struct kvm_vcpu *vcpu,
> + struct vcpu_reset_state *reset_state)
> +{
> + unsigned long target_pc = reset_state->pc;
> +
> + /* Gracefully handle Thumb2 entry point */
> + if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) {
> + target_pc &= ~1UL;
> + vcpu_set_thumb(vcpu);
> + }
> +
> + /* Propagate caller endianness */
> + if (reset_state->be)
> + kvm_vcpu_set_be(vcpu);
> +
> + *vcpu_pc(vcpu) = target_pc;
> +
> + /*
> + * We may come from a state where either a PC update was
> + * pending (SMC call resulting in PC being increpented to
> + * skip the SMC) or a pending exception. Make sure we get
> + * rid of all that, as this cannot be valid out of reset.
> + *
> + * Note that clearing the exception mask also clears PC
> + * updates, but that's an implementation detail, and we
> + * really want to make it explicit.
> + */
> + vcpu_clear_flag(vcpu, PENDING_EXCEPTION);
> + vcpu_clear_flag(vcpu, EXCEPT_MASK);
> + vcpu_clear_flag(vcpu, INCREMENT_PC);
> + vcpu_set_reg(vcpu, 0, reset_state->r0);
> +}
> +
> #endif /* __ARM64_KVM_EMULATE_H__ */
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index b963fd975aac..10eb7249aa9e 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -34,18 +34,6 @@
> static u32 __ro_after_init kvm_ipa_limit;
> unsigned int __ro_after_init kvm_host_sve_max_vl;
>
> -/*
> - * ARMv8 Reset Values
> - */
> -#define VCPU_RESET_PSTATE_EL1 (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
> - PSR_F_BIT | PSR_D_BIT)
> -
> -#define VCPU_RESET_PSTATE_EL2 (PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
> - PSR_F_BIT | PSR_D_BIT)
> -
> -#define VCPU_RESET_PSTATE_SVC (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
> - PSR_AA32_I_BIT | PSR_AA32_F_BIT)
> -
> unsigned int __ro_after_init kvm_sve_max_vl;
>
> int __init kvm_arm_init_sve(void)
> @@ -191,7 +179,6 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> {
> struct vcpu_reset_state reset_state;
> bool loaded;
> - u32 pstate;
>
> spin_lock(&vcpu->arch.mp_state_lock);
> reset_state = vcpu->arch.reset_state;
> @@ -210,21 +197,8 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> kvm_vcpu_reset_sve(vcpu);
> }
>
> - if (vcpu_el1_is_32bit(vcpu))
> - pstate = VCPU_RESET_PSTATE_SVC;
> - else if (vcpu_has_nv(vcpu))
> - pstate = VCPU_RESET_PSTATE_EL2;
> - else
> - pstate = VCPU_RESET_PSTATE_EL1;
> -
> /* Reset core registers */
> - memset(vcpu_gp_regs(vcpu), 0, sizeof(*vcpu_gp_regs(vcpu)));
> - memset(&vcpu->arch.ctxt.fp_regs, 0, sizeof(vcpu->arch.ctxt.fp_regs));
> - vcpu->arch.ctxt.spsr_abt = 0;
> - vcpu->arch.ctxt.spsr_und = 0;
> - vcpu->arch.ctxt.spsr_irq = 0;
> - vcpu->arch.ctxt.spsr_fiq = 0;
> - vcpu_gp_regs(vcpu)->pstate = pstate;
> + kvm_reset_vcpu_core(vcpu);
>
> /* Reset system registers */
> kvm_reset_sys_regs(vcpu);
> @@ -233,36 +207,8 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> * Additional reset state handling that PSCI may have imposed on us.
> * Must be done after all the sys_reg reset.
> */
> - if (reset_state.reset) {
> - unsigned long target_pc = reset_state.pc;
> -
> - /* Gracefully handle Thumb2 entry point */
> - if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) {
> - target_pc &= ~1UL;
> - vcpu_set_thumb(vcpu);
> - }
> -
> - /* Propagate caller endianness */
> - if (reset_state.be)
> - kvm_vcpu_set_be(vcpu);
> -
> - *vcpu_pc(vcpu) = target_pc;
> -
> - /*
> - * We may come from a state where either a PC update was
> - * pending (SMC call resulting in PC being increpented to
> - * skip the SMC) or a pending exception. Make sure we get
> - * rid of all that, as this cannot be valid out of reset.
> - *
> - * Note that clearing the exception mask also clears PC
> - * updates, but that's an implementation detail, and we
> - * really want to make it explicit.
> - */
> - vcpu_clear_flag(vcpu, PENDING_EXCEPTION);
> - vcpu_clear_flag(vcpu, EXCEPT_MASK);
> - vcpu_clear_flag(vcpu, INCREMENT_PC);
> - vcpu_set_reg(vcpu, 0, reset_state.r0);
> - }
> + if (reset_state.reset)
> + kvm_reset_vcpu_psci(vcpu, &reset_state);
>
> /* Reset timer */
> kvm_timer_vcpu_reset(vcpu);
> --
> 2.55.0.rc0.738.g0c8ab3ebcc-goog
>
^ permalink raw reply
* Re: [PATCH] Bluetooth: btmtksdio: fix infinite loop in btmtksdio_txrx_work()
From: Takashi Iwai @ 2026-06-19 13:27 UTC (permalink / raw)
To: Sean Wang
Cc: Sergey Senozhatsky, Marcel Holtmann, Luiz Augusto von Dentz,
Mark-yw Chen, Sean Wang, Tomasz Figa, linux-bluetooth,
linux-kernel, linux-arm-kernel, linux-mediatek, stable
In-Reply-To: <CAGp9LzpBUReZtrTEKgUr-+yvB+3tcs5hw7ziC4WaMRFNa2AYpg@mail.gmail.com>
On Wed, 10 Jun 2026 08:52:31 +0200,
Sean Wang wrote:
>
> Hi,
>
> On Tue, Jun 9, 2026 at 7:19 AM Sergey Senozhatsky
> <senozhatsky@chromium.org> wrote:
> >
> > Every once in a while we see a hung btmtksdio_flush() task:
> >
> > INFO: task kworker/u17:0:189 blocked for more than 122 seconds.
> > __cancel_work_timer+0x3f4/0x460
> > cancel_work_sync+0x1c/0x2c
> > btmtksdio_flush+0x2c/0x40
> > hci_dev_open_sync+0x10c4/0x2190
> > [..]
> >
> > It all boils down to incorrect time_is_before_jiffies() usage in
> > btmtksdio_txrx_work(). The btmtksdio_txrx_work() loop is expected
> > to be terminated if running for longer than 5*HZ. However the
> > timeout check is twisted: time_is_before_jiffies(old_jiffies + 5*HZ)
> > evaluates to true when old_jiffies + 5*HZ is in the past i.e. when a
> > timeout has occurred. Using OR with time_is_before_jiffies(txrx_timeout)
> > means that:
> > - before the 5-second timeout: the condition is `int_status || false`,
> > so it loops as long as there are pending interrupts.
> > - after the 5-second timeout: the condition becomes `int_status || true`,
> > which is always true.
> >
> > When the loop becomes infinite btmtksdio_txrx_work() loop never
> > terminates and never releases the SDIO host.
> >
> > Fix loop termination condition to actually enforce a 5*HZ timeout.
> >
> > Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> > ---
> > drivers/bluetooth/btmtksdio.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
> > index 5b0fab7b89b5..c6f80c419e90 100644
> > --- a/drivers/bluetooth/btmtksdio.c
> > +++ b/drivers/bluetooth/btmtksdio.c
> > @@ -620,7 +620,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
> > if (btmtksdio_rx_packet(bdev, rx_size) < 0)
> > bdev->hdev->stat.err_rx++;
> > }
> > - } while (int_status || time_is_before_jiffies(txrx_timeout));
> > + } while (int_status && time_is_after_jiffies(txrx_timeout));
>
> yes, loop continues only while there is interrupt work and the timeout
> deadline is still in the future
I stumbled on this while backporting to distro kernels, and I wonder
whether this change is correct.
IIUC, this essentially makes the loop exiting right after the first
cycle; the patch changed from time_is_before_jiffies() to *_after_*(),
not only the logical OR to AND, and *_after_*() returns false, so the
whole condition becomes false, too.
thanks,
Takashi
^ permalink raw reply
* Re: [PATCH v2 2/8] KVM: arm64: Make vcpu_{read,write}_sys_reg available to HYP code
From: Vincent Donnefort @ 2026-06-19 13:26 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, kvmarm, linux-arm-kernel,
linux-kernel, Catalin Marinas, Will Deacon, Joey Gouly,
Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Quentin Perret,
Sebastian Ene, Hyunwoo Kim
In-Reply-To: <20260619070719.812227-3-tabba@google.com>
On Fri, Jun 19, 2026 at 08:07:13AM +0100, Fuad Tabba wrote:
> The vcpu_{read,write}_sys_reg() accessors are host-only, so helpers
> built on them such as kvm_vcpu_set_be()/kvm_vcpu_is_be() cannot be
> shared with hyp code. exception.c already wraps them in
> __vcpu_{read,write}_sys_reg(), which pick the host- or hyp-side accessor
> via has_vhe() and so are valid in any context.
>
> Move those wrappers to kvm_emulate.h as kvm_vcpu_{read,write}_sys_reg()
> and switch the callers over, so a follow-up series can share that
> emulation code at EL2.
>
> No functional change intended.
>
> Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/include/asm/kvm_emulate.h | 22 +++++++++++++++---
> arch/arm64/kvm/hyp/exception.c | 34 ++++++++--------------------
> 2 files changed, 28 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 5bf3d7e1d92c..80b30fead3d1 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -506,6 +506,22 @@ static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
> return __vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
> }
>
> +static inline u64 kvm_vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
> +{
> + if (has_vhe())
> + return vcpu_read_sys_reg(vcpu, reg);
> +
> + return __vcpu_sys_reg(vcpu, reg);
> +}
> +
> +static inline void kvm_vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
> +{
> + if (has_vhe())
> + vcpu_write_sys_reg(vcpu, val, reg);
> + else
> + __vcpu_assign_sys_reg(vcpu, reg, val);
> +}
> +
> static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
> {
> if (vcpu_mode_is_32bit(vcpu)) {
> @@ -516,9 +532,9 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
>
> r = vcpu_has_nv(vcpu) ? SCTLR_EL2 : SCTLR_EL1;
>
> - sctlr = vcpu_read_sys_reg(vcpu, r);
> + sctlr = kvm_vcpu_read_sys_reg(vcpu, r);
> sctlr |= SCTLR_ELx_EE;
> - vcpu_write_sys_reg(vcpu, sctlr, r);
> + kvm_vcpu_write_sys_reg(vcpu, sctlr, r);
> }
> }
>
> @@ -533,7 +549,7 @@ static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
> r = is_hyp_ctxt(vcpu) ? SCTLR_EL2 : SCTLR_EL1;
> bit = vcpu_mode_priv(vcpu) ? SCTLR_ELx_EE : SCTLR_EL1_E0E;
>
> - return vcpu_read_sys_reg(vcpu, r) & bit;
> + return kvm_vcpu_read_sys_reg(vcpu, r) & bit;
> }
>
> static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,
> diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
> index bef40ddb16db..2cb68dc7d441 100644
> --- a/arch/arm64/kvm/hyp/exception.c
> +++ b/arch/arm64/kvm/hyp/exception.c
> @@ -20,22 +20,6 @@
> #error Hypervisor code only!
> #endif
>
> -static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
> -{
> - if (has_vhe())
> - return vcpu_read_sys_reg(vcpu, reg);
> -
> - return __vcpu_sys_reg(vcpu, reg);
> -}
> -
> -static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
> -{
> - if (has_vhe())
> - vcpu_write_sys_reg(vcpu, val, reg);
> - else
> - __vcpu_assign_sys_reg(vcpu, reg, val);
> -}
> -
> static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
> u64 val)
> {
> @@ -101,14 +85,14 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
>
> switch (target_mode) {
> case PSR_MODE_EL1h:
> - vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL1);
> - sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
> - __vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1);
> + vbar = kvm_vcpu_read_sys_reg(vcpu, VBAR_EL1);
> + sctlr = kvm_vcpu_read_sys_reg(vcpu, SCTLR_EL1);
> + kvm_vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1);
> break;
> case PSR_MODE_EL2h:
> - vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL2);
> - sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL2);
> - __vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL2);
> + vbar = kvm_vcpu_read_sys_reg(vcpu, VBAR_EL2);
> + sctlr = kvm_vcpu_read_sys_reg(vcpu, SCTLR_EL2);
> + kvm_vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL2);
> break;
> default:
> /* Don't do that */
> @@ -185,7 +169,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
> */
> static unsigned long get_except32_cpsr(struct kvm_vcpu *vcpu, u32 mode)
> {
> - u32 sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
> + u32 sctlr = kvm_vcpu_read_sys_reg(vcpu, SCTLR_EL1);
> unsigned long old, new;
>
> old = *vcpu_cpsr(vcpu);
> @@ -281,7 +265,7 @@ static void enter_exception32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
> {
> unsigned long spsr = *vcpu_cpsr(vcpu);
> bool is_thumb = (spsr & PSR_AA32_T_BIT);
> - u32 sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
> + u32 sctlr = kvm_vcpu_read_sys_reg(vcpu, SCTLR_EL1);
> u32 return_address;
>
> *vcpu_cpsr(vcpu) = get_except32_cpsr(vcpu, mode);
> @@ -305,7 +289,7 @@ static void enter_exception32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
> if (sctlr & (1 << 13))
> vect_offset += 0xffff0000;
> else /* always have security exceptions */
> - vect_offset += __vcpu_read_sys_reg(vcpu, VBAR_EL1);
> + vect_offset += kvm_vcpu_read_sys_reg(vcpu, VBAR_EL1);
>
> *vcpu_pc(vcpu) = vect_offset;
> }
> --
> 2.55.0.rc0.738.g0c8ab3ebcc-goog
>
^ permalink raw reply
* Re: [PATCH v2 1/8] KVM: arm64: Extract MPIDR computation into a shared header
From: Vincent Donnefort @ 2026-06-19 13:24 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, kvmarm, linux-arm-kernel,
linux-kernel, Catalin Marinas, Will Deacon, Joey Gouly,
Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Quentin Perret,
Sebastian Ene, Hyunwoo Kim
In-Reply-To: <20260619070719.812227-2-tabba@google.com>
On Fri, Jun 19, 2026 at 08:07:12AM +0100, Fuad Tabba wrote:
> Extract the vCPU MPIDR computation embedded in reset_mpidr() into a
> kvm_calculate_mpidr() inline in sys_regs.h, so it can be computed
> without duplicating the logic. A follow-up series reuses it to reset
> protected vCPUs at EL2.
>
> No functional change intended.
>
> Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/kvm/sys_regs.c | 14 +-------------
> arch/arm64/kvm/sys_regs.h | 19 +++++++++++++++++++
> 2 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 33c921df19b5..674fabe1d40d 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -976,21 +976,9 @@ static u64 reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
>
> static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
> {
> - u64 mpidr;
> + u64 mpidr = kvm_calculate_mpidr(vcpu);
>
> - /*
> - * Map the vcpu_id into the first three affinity level fields of
> - * the MPIDR. We limit the number of VCPUs in level 0 due to a
> - * limitation to 16 CPUs in that level in the ICC_SGIxR registers
> - * of the GICv3 to be able to address each CPU directly when
> - * sending IPIs.
> - */
> - mpidr = (vcpu->vcpu_id & 0x0f) << MPIDR_LEVEL_SHIFT(0);
> - mpidr |= ((vcpu->vcpu_id >> 4) & 0xff) << MPIDR_LEVEL_SHIFT(1);
> - mpidr |= ((vcpu->vcpu_id >> 12) & 0xff) << MPIDR_LEVEL_SHIFT(2);
> - mpidr |= (1ULL << 31);
> vcpu_write_sys_reg(vcpu, mpidr, MPIDR_EL1);
> -
> return mpidr;
> }
>
> diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
> index 2a983664220c..bd56a45abbf9 100644
> --- a/arch/arm64/kvm/sys_regs.h
> +++ b/arch/arm64/kvm/sys_regs.h
> @@ -222,6 +222,25 @@ find_reg(const struct sys_reg_params *params, const struct sys_reg_desc table[],
> return __inline_bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg);
> }
>
> +static inline u64 kvm_calculate_mpidr(const struct kvm_vcpu *vcpu)
> +{
> + u64 mpidr;
> +
> + /*
> + * Map the vcpu_id into the first three affinity level fields of
> + * the MPIDR. We limit the number of VCPUs in level 0 due to a
> + * limitation to 16 CPUs in that level in the ICC_SGIxR registers
> + * of the GICv3 to be able to address each CPU directly when
> + * sending IPIs.
> + */
> + mpidr = (vcpu->vcpu_id & 0x0f) << MPIDR_LEVEL_SHIFT(0);
> + mpidr |= ((vcpu->vcpu_id >> 4) & 0xff) << MPIDR_LEVEL_SHIFT(1);
> + mpidr |= ((vcpu->vcpu_id >> 12) & 0xff) << MPIDR_LEVEL_SHIFT(2);
> + mpidr |= (1ULL << 31);
> +
> + return mpidr;
> +}
> +
> const struct sys_reg_desc *get_reg_by_id(u64 id,
> const struct sys_reg_desc table[],
> unsigned int num);
> --
> 2.55.0.rc0.738.g0c8ab3ebcc-goog
>
^ permalink raw reply
* [PATCH v2 2/2] arm: dts: xilinx: Add support for MYIR MYS-7Z020-V2 board
From: Liu Yu @ 2026-06-19 13:23 UTC (permalink / raw)
To: Michal Simek
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-arm-kernel, Liu Yu
In-Reply-To: <20260619132355.1776-1-f78fk@live.com>
Add device tree support for the MYIR MYS-7Z020-V2 board based on
the Xilinx Zynq-7000 XC7Z020 SoC.
The board supports:
- UART serial console
- MicroSD card interface
- Gigabit Ethernet
- QSPI NOR flash
- GPIO-based user LEDs and push-button
Link: https://www.myirtech.com/list.asp?id=708
Signed-off-by: Liu Yu <f78fk@live.com>
---
arch/arm/boot/dts/xilinx/Makefile | 1 +
.../arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts | 232 ++++++++++++++++++
2 files changed, 233 insertions(+)
create mode 100644 arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
diff --git a/arch/arm/boot/dts/xilinx/Makefile b/arch/arm/boot/dts/xilinx/Makefile
index 9233e539b192..6c59116013f1 100644
--- a/arch/arm/boot/dts/xilinx/Makefile
+++ b/arch/arm/boot/dts/xilinx/Makefile
@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-cc108.dtb \
zynq-ebaz4205.dtb \
zynq-microzed.dtb \
+ zynq-mys-7z020-v2.dtb \
zynq-parallella.dtb \
zynq-zc702.dtb \
zynq-zc706.dtb \
diff --git a/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts b/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
new file mode 100644
index 000000000000..b55133133e2f
--- /dev/null
+++ b/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 Liu Yu <f78fk@live.com>
+ */
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "zynq-7000.dtsi"
+
+/ {
+ model = "MYIR MYS-7Z020-V2 Board";
+ compatible = "myir,mys-7z020-v2", "xlnx,zynq-7000";
+
+ aliases {
+ ethernet0 = &gem0;
+ mmc0 = &sdhci0;
+ serial0 = &uart1;
+ spi0 = &qspi;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ key-user {
+ label = "USR";
+ gpios = <&gpio0 50 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-blue {
+ label = "led_blue";
+ gpios = <&gpio0 115 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led-green {
+ label = "led_green";
+ gpios = <&gpio0 114 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led-red {
+ label = "led_red";
+ gpios = <&gpio0 116 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ usr-led1 {
+ label = "usr_led1";
+ gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ usr-led2 {
+ label = "usr_led2";
+ gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <0x7>;
+ };
+ };
+};
+
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
+&pinctrl0 {
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_0_grp", "gpio0_9_grp", "gpio0_50_grp";
+ };
+ conf {
+ groups = "gpio0_0_grp", "gpio0_9_grp", "gpio0_50_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ conf-pull-up {
+ pins = "MIO0", "MIO9", "MIO50";
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+ mux-cd {
+ groups = "gpio0_46_grp";
+ function = "sdio0_cd";
+ };
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ conf-cd {
+ pins = "MIO46";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+};
+
+&qspi {
+ num-cs = <1>;
+
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "qspi-boot";
+ reg = <0x0 0x80000>;
+ };
+
+ partition@80000 {
+ label = "qspi-bootenv";
+ reg = <0x80000 0x20000>;
+ };
+
+ partition@a0000 {
+ label = "qspi-bitstream";
+ reg = <0xa0000 0x460000>;
+ };
+
+ partition@500000 {
+ label = "qspi-kernel";
+ reg = <0x500000 0x480000>;
+ };
+
+ partition@980000 {
+ label = "qspi-devicetree";
+ reg = <0x980000 0x10000>;
+ };
+
+ partition@990000 {
+ label = "qspi-rootfs";
+ reg = <0x990000 0x600000>;
+ };
+
+ partition@f90000 {
+ label = "data";
+ reg = <0xf90000 0x70000>;
+ };
+ };
+ };
+};
+
+&sdhci0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
+ disable-wp;
+
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+
+ status = "okay";
+};
+
--
2.43.0
^ permalink raw reply related
* [PATCH v2 1/2] dt-bindings: soc: xilinx: Add MYIR MYS-7Z020-V2 board
From: Liu Yu @ 2026-06-19 13:23 UTC (permalink / raw)
To: Michal Simek
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-arm-kernel, Liu Yu
In-Reply-To: <20260619132355.1776-1-f78fk@live.com>
Add compatible string for the MYIR MYS-7Z020-V2 board, based on
the Xilinx Zynq-7000 XC7Z020 SoC.
Signed-off-by: Liu Yu <f78fk@live.com>
---
Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
index c9f99e0df2b3..72a84b628da3 100644
--- a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
+++ b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
@@ -23,6 +23,7 @@ properties:
- digilent,zynq-zybo
- digilent,zynq-zybo-z7
- ebang,ebaz4205
+ - myir,mys-7z020-v2
- myir,zynq-zturn-v5
- myir,zynq-zturn
- xlnx,zynq-cc108
--
2.43.0
^ permalink raw reply related
* [PATCH v2 0/2] arm: dts: xilinx: Add MYIR MYS-7Z020-V2 board support
From: Liu Yu @ 2026-06-19 13:23 UTC (permalink / raw)
To: Michal Simek
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-arm-kernel, Liu Yu
In-Reply-To: <20260619102214.223121-1-f78fk@live.com>
This series adds basic device tree and binding documentation support
for the MYIR MYS-7Z020-V2 development board, which is based on the
Xilinx Zynq-7000 (XC7Z020) SoC.
The first patch introduces the device tree file enabling essential
hardware support such as the serial console, MicroSD, Gigabit Ethernet,
QSPI flash, and user LEDs/buttons. The second patch adds the corresponding
compatible string to the Xilinx SoC bindings documentation.
Changes in v2:
- Add missing pinmux configuration (sdio0_cd) for MIO46 to correctly
route the hardware SD card detect signal, resolving the automated
review warning.
Liu Yu (2):
dt-bindings: soc: xilinx: Add MYIR MYS-7Z020-V2 board
arm: dts: xilinx: Add support for MYIR MYS-7Z020-V2 board
.../bindings/soc/xilinx/xilinx.yaml | 1 +
arch/arm/boot/dts/xilinx/Makefile | 1 +
.../arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts | 232 ++++++++++++++++++
3 files changed, 234 insertions(+)
create mode 100644 arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
--
2.43.0
^ permalink raw reply
* Re: [RFC PATCH 0/2] kasan: hw_tags: Add option to tag only at allocation time
From: Catalin Marinas @ 2026-06-19 13:19 UTC (permalink / raw)
To: Harry Yoo
Cc: Dev Jain, ryabinin.a.a, akpm, corbet, glider, andreyknvl, dvyukov,
vincenzo.frascino, kasan-dev, linux-mm, linux-kernel, skhan,
workflows, linux-doc, linux-arm-kernel, ryan.roberts,
anshuman.khandual, kaleshsingh, 21cnbao, david, will
In-Reply-To: <b1502a60-09a1-4699-886b-93d041de7023@kernel.org>
On Thu, Jun 18, 2026 at 10:35:15PM +0900, Harry Yoo wrote:
> On 6/12/26 1:44 PM, Dev Jain wrote:
> > Introduce a boot option to tag only at allocation time of the objects. This
> > reduces KASAN MTE overhead, the tradeoff being reduced ability of
> > catching bugs.
>
> I think most of overhead when enabling MTE comes from loading and
> validing tags for every memory access (either in SYNC or ASYNC mode),
> rather than from storing tags.
I guess it depends on the workload. Lots of allocations for short-lived
buffers (e.g. network traffic) may notice the additional tagging more
than the actual tag checking.
Of course, it would be nice to get some numbers from those who have
access to MTE capable hardware.
> > Now, when a memory object will be freed, it will retain the random tag it
> > had at allocation time. This compromises on catching UAF bugs, till the
> > time the object is not reallocated, at which point it will have a new
> > random tag.
> >
> > Hence, not catching "use-after-free-before-reallocation" and not catching
> > "double-free" will be the compromise for reduced KASAN overhead.
>
> I doubt users who care about security enough to enable HW_TAGS KASAN
> are willing to compromise on security just to save a few instructions
> to store tags in the free path.
>
> To me, it looks like too much of a compromise on security for little
> performance gain.
I don't think there's much compromise on security for use-after-free.
The buffer will be re-tagged later so use-after-realloc should be
caught, especially if we ensure that a different tag will be used (I
don't think Dev's patches do this).
Of course, if you want MTE as a debug/bug-finding feature, tagging on
both allocation and freeing is highly recommended. This patchset is
aimed for those wanting to run MTE in production and squeeze a bit more
performance out of it (with the compromise of not detecting
use-after-free, only prevent access after re-allocation).
--
Catalin
^ permalink raw reply
* [PATCH v3 net] net: airoha: Fix TX scheduler queue mask loop upper bound
From: Wayen Yan @ 2026-06-19 13:12 UTC (permalink / raw)
To: netdev
Cc: lorenzo, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
In airoha_qdma_set_chan_tx_sched(), the loop clearing queue mask was
using AIROHA_NUM_TX_RING (32) instead of AIROHA_NUM_QOS_QUEUES (8).
Each channel has 8 queues, and TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)
computes BIT(i + (channel * 8)). With i ranging 0..31, this causes:
- channel 0: clears bit 0..31 (all 4 channels) instead of 0..7
- channel 1: clears bit 8..31 (channels 1-3) instead of 8..15
- channel 2: clears bit 16..31 (channels 2-3) instead of 16..23
- channel 3: clears bit 24..31 (channel 3 only) - correct by accident
While BIT(32+) on arm64 produces 64-bit values truncated to 0 in u32
mask parameter, the loop still incorrectly clears queues within the
same channel beyond queue 7.
Even though this is functionally harmless (the register resets to 0
and is only ever cleared, never set — so clearing extra bits is a
no-op), the loop bound is semantically wrong and should be fixed for
correctness and clarity.
Fix by using AIROHA_NUM_QOS_QUEUES (8) as the loop upper bound.
Fixes: ef1ca9271313 ("net: airoha: Add sched HTB offload support")
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Wayen Yan <win847@gmail.com>
---
Changes in v3:
- Rebase on top of current net tree (Lorenzo pointed out v2 was
not based on latest net HEAD).
- No code changes from v2.
drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 64dde6464f..47fb32517a 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2395,7 +2395,7 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
struct airoha_gdm_dev *dev = netdev_priv(netdev);
int i;
- for (i = 0; i < AIROHA_NUM_TX_RING; i++)
+ for (i = 0; i < AIROHA_NUM_QOS_QUEUES; i++)
airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
--
2.51.0
^ permalink raw reply related
* Re: [PATCH v2 8/8] KVM: arm64: Implement lazy vCPU state sync for non-protected guests
From: Vincent Donnefort @ 2026-06-19 13:12 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, kvmarm, linux-arm-kernel,
linux-kernel, Catalin Marinas, Will Deacon, Joey Gouly,
Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Quentin Perret,
Sebastian Ene, Hyunwoo Kim
In-Reply-To: <20260619070719.812227-9-tabba@google.com>
On Fri, Jun 19, 2026 at 08:07:19AM +0100, Fuad Tabba wrote:
> pKVM copies a non-protected guest's register context between the host
> and the hypervisor on every world switch, even when the host never
> inspects it. Defer the copy: on entry, flush the host context into the
> hyp vCPU only when the host marked it dirty (PKVM_HOST_STATE_DIRTY); on
> exit, leave it in the hyp vCPU and copy it back only when the host needs
> it, via a __pkvm_vcpu_sync_state hypercall on trap handling or at vcpu
> put. A protected guest's context is copied as before, since lazy sync
> only helps where the host is trusted to see the guest's registers.
>
> PC and PSTATE are the exception: they are copied back on every exit so
> the kvm_exit tracepoint reports the guest's real exit PC, and the run
> loop's vcpu_mode_is_bad_32bit() and SError-masking checks evaluate the
> guest's current PSTATE rather than the value left by the previous sync.
>
> handle_exit_early() can also inject an SError, which writes the guest
> context (ESR_EL1) outside the trap-handling path. For a non-protected
> guest it therefore syncs the context from the hyp vCPU and marks it
> dirty, as handle_trap_exceptions() does, so the injection reaches the
> hyp vCPU on re-entry rather than being dropped.
>
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
> arch/arm64/include/asm/kvm_asm.h | 1 +
> arch/arm64/include/asm/kvm_host.h | 2 +
> arch/arm64/kvm/arm.c | 7 +++
> arch/arm64/kvm/handle_exit.c | 30 +++++++++++
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 86 ++++++++++++++++++++++++++++--
> 5 files changed, 121 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 043495f7fc78..6e1135b3ded4 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -113,6 +113,7 @@ enum __kvm_host_smccc_func {
> __KVM_HOST_SMCCC_FUNC___pkvm_finalize_teardown_vm,
> __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
> __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
> + __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_sync_state,
> __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
>
> MARKER(__KVM_HOST_SMCCC_FUNC_MAX)
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 2faa60df847d..caa39ee5125f 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -1068,6 +1068,8 @@ struct kvm_vcpu_arch {
> #define INCREMENT_PC __vcpu_single_flag(iflags, BIT(1))
> /* Target EL/MODE (not a single flag, but let's abuse the macro) */
> #define EXCEPT_MASK __vcpu_single_flag(iflags, GENMASK(3, 1))
> +/* Host-set: the hyp flushes the non-protected vCPU state in on entry */
> +#define PKVM_HOST_STATE_DIRTY __vcpu_single_flag(iflags, BIT(4))
>
> /* Helpers to encode exceptions with minimum fuss */
> #define __EXCEPT_MASK_VAL unpack_vcpu_flag(EXCEPT_MASK)
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 3732ee9eb0d4..4e89558d8027 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -733,6 +733,10 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> if (is_protected_kvm_enabled()) {
> kvm_call_hyp(__vgic_v3_save_aprs, &vcpu->arch.vgic_cpu.vgic_v3);
> kvm_call_hyp_nvhe(__pkvm_vcpu_put);
> +
> + /* __pkvm_vcpu_put implies a sync of the state */
> + if (!kvm_vm_is_protected(vcpu->kvm))
> + vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> }
>
> kvm_vcpu_put_debug(vcpu);
> @@ -964,6 +968,9 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> return ret;
>
> if (is_protected_kvm_enabled()) {
> + /* Start with the vcpu in a dirty state */
> + if (!kvm_vm_is_protected(vcpu->kvm))
> + vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> ret = pkvm_create_hyp_vm(kvm);
> if (ret)
> return ret;
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 54aedf93c78b..8963621bcdd1 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -422,6 +422,20 @@ static int handle_trap_exceptions(struct kvm_vcpu *vcpu)
> {
> int handled;
>
> + /*
> + * If we run a non-protected VM when protection is enabled
> + * system-wide, resync the state from the hypervisor and mark
> + * it as dirty on the host side if it wasn't dirty already
> + * (which could happen if preemption has taken place).
> + */
> + if (is_protected_kvm_enabled() && !kvm_vm_is_protected(vcpu->kvm)) {
> + guard(preempt)();
> + if (!(vcpu_get_flag(vcpu, PKVM_HOST_STATE_DIRTY))) {
> + kvm_call_hyp_nvhe(__pkvm_vcpu_sync_state);
> + vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> + }
> + }
> +
Could we remove this update here and let handle_exit_early() do the sync
regardless of the SError injection? One of the main point of handle_exit_early()
is to do things under !prempt().
> /*
> * See ARM ARM B1.14.1: "Hyp traps on instructions
> * that fail their condition code check"
> @@ -489,6 +503,22 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
> /* For exit types that need handling before we can be preempted */
> void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index)
> {
> + bool inject_serror = ARM_SERROR_PENDING(exception_index) ||
> + ARM_EXCEPTION_CODE(exception_index) == ARM_EXCEPTION_EL1_SERROR;
> +
> + /*
> + * An SError injected below writes the host ctxt; for a non-protected
> + * guest, sync from the hyp vCPU and keep it dirty so it isn't dropped.
> + */
> + if (is_protected_kvm_enabled()) {
Should we test !kvm_vm_is_protected(vcpu->kvm) here, as the
PKVM_HOST_STATE_DIRTY is only updated for p-guests everywhere else?
> + vcpu_clear_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> +
> + if (inject_serror && !kvm_vm_is_protected(vcpu->kvm)) {
> + kvm_call_hyp_nvhe(__pkvm_vcpu_sync_state);
> + vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> + }
> + }
> +
> if (ARM_SERROR_PENDING(exception_index)) {
> if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN)) {
> u64 disr = kvm_vcpu_get_disr(vcpu);
[...]
^ permalink raw reply
* Re: [PATCH v2 4/5] arm64: defconfig: Drop unused Ethernet vendors
From: Krzysztof Kozlowski @ 2026-06-19 13:11 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-kernel, linux-arm-kernel, Catalin Marinas, Will Deacon,
Arnd Bergmann, Alexandre Belloni, Linus Walleij, Drew Fustini,
soc
In-Reply-To: <CAMuHMdVH6-5ZAjTyF3m=wF5-XiSDqwcgRhZWxJv6y0FoCnk4MA@mail.gmail.com>
On 19/06/2026 12:12, Geert Uytterhoeven wrote:
>> +# CONFIG_NET_VENDOR_ACTIONS is not set
>> +# CONFIG_NET_VENDOR_ADAPTEC is not set
>> +# CONFIG_NET_VENDOR_AGERE is not set
>> +# CONFIG_NET_VENDOR_ALACRITECH is not set
>> +# CONFIG_NET_VENDOR_ALLWINNER is not set
>
> [...]
>
> I am not sure this new policy is a good idea: none of this affects
I would not call it new policy. Just an idea which got accepted. :)
> actual kernel size, but it does increase defconfig size, and churn.
> E.g. for the m68k defconfig, I dropped all these disablements
> several years ago.
>
> I don't use menufconfig, so just my 2€c...
I understand, feedback accepted. Patch got merged, so you know...
To share my point: I don't edit defconfig by hand but through
menuconfig+savedefconfig, thus size of defconfig is acceptable to me
price to pay for smaller menuconfig choices.
Best regards,
Krzysztof
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox