* [PATCH v2 1/3] nxp: Prepare macros for KVM changes
2025-06-18 6:58 [PATCH v2 0/3] Fix io accessors for KVM Ilias Apalodimas
@ 2025-06-18 6:58 ` Ilias Apalodimas
2025-06-18 14:07 ` Tom Rini
2025-06-18 6:58 ` [PATCH v2 2/3] arm: io.h: Fix io accessors for KVM Ilias Apalodimas
` (4 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Ilias Apalodimas @ 2025-06-18 6:58 UTC (permalink / raw)
To: trini
Cc: jerome.forissier, mikko.rapeli, Ilias Apalodimas,
Rayagonda Kokatanur, Tuomas Tynkkynen, Jagan Teki, Casey Connolly,
Tien Fong Chee, Patrick Rudolph, Simon Glass, Boyan Karatotev,
Alif Zakuan Yuslaimi, Oliver Gaskell, Duje Mihanović,
Liya Huang, Raymond Mao, Heinrich Schuchardt, Patrick Delaunay,
Venkatesh Yadav Abbarapu, Ashok Reddy Soma, Marek Vasut, u-boot
A following patch is replacing our IO accessors with
do { ... } while(0) ones in order to make them usable with KVM.
That leads to an error eventually looking like this:
arch/arm/include/asm/io.h:62:9: error: expected expression before 'do'
62 | do { \
| ^~
arch/arm/include/asm/io.h:211:41: note: in expansion of macro '__raw_writel'
211 | #define out_arch(type,endian,a,v) __raw_write##type(cpu_to_##endian(v),a)
| ^~~~~~~~~~~
arch/arm/include/asm/io.h:223:25: note: in expansion of macro 'out_arch'
223 | #define out_be32(a,v) out_arch(l,be32,a,v)
| ^~~~~~~~
drivers/spi/fsl_dspi.c:127:17: note: in expansion of macro 'out_be32'
127 | out_be32(addr, val) : out_le32(addr, val);
| ^~~~~~~~
So adjust the current macros and code to be compatible with the upcoming
change.
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
drivers/spi/fsl_dspi.c | 6 ++++--
include/fsl_ifc.h | 24 ++++++++++++------------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index f2393c041f44..545561ad1169 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -123,8 +123,10 @@ static uint dspi_read32(uint flags, uint *addr)
static void dspi_write32(uint flags, uint *addr, uint val)
{
- flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ?
- out_be32(addr, val) : out_le32(addr, val);
+ if (flags & DSPI_FLAG_REGMAP_ENDIAN_BIG)
+ out_be32(addr, val);
+ else
+ out_le32(addr, val);
}
static void dspi_halt(struct fsl_dspi_priv *priv, u8 halt)
diff --git a/include/fsl_ifc.h b/include/fsl_ifc.h
index 3ac226879303..1c363115beb2 100644
--- a/include/fsl_ifc.h
+++ b/include/fsl_ifc.h
@@ -803,29 +803,29 @@ void init_final_memctl_regs(void);
((struct fsl_ifc_fcm *)CFG_SYS_IFC_ADDR)
#define get_ifc_cspr_ext(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext)
#define get_ifc_cspr(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr)
#define get_ifc_csor_ext(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext)
#define get_ifc_csor(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor)
#define get_ifc_amask(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask)
#define get_ifc_ftim(i, j) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j]))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j])
#define set_ifc_cspr_ext(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v)
#define set_ifc_cspr(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v)
#define set_ifc_csor_ext(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v)
#define set_ifc_csor(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v)
#define set_ifc_amask(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v)
#define set_ifc_ftim(i, j, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v)
enum ifc_chip_sel {
IFC_CS0,
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 1/3] nxp: Prepare macros for KVM changes
2025-06-18 6:58 ` [PATCH v2 1/3] nxp: Prepare macros for KVM changes Ilias Apalodimas
@ 2025-06-18 14:07 ` Tom Rini
0 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2025-06-18 14:07 UTC (permalink / raw)
To: Ilias Apalodimas
Cc: jerome.forissier, mikko.rapeli, Rayagonda Kokatanur,
Tuomas Tynkkynen, Jagan Teki, Casey Connolly, Tien Fong Chee,
Patrick Rudolph, Simon Glass, Boyan Karatotev,
Alif Zakuan Yuslaimi, Oliver Gaskell, Duje Mihanović,
Liya Huang, Raymond Mao, Heinrich Schuchardt, Patrick Delaunay,
Venkatesh Yadav Abbarapu, Ashok Reddy Soma, Marek Vasut, u-boot
[-- Attachment #1: Type: text/plain, Size: 1224 bytes --]
On Wed, Jun 18, 2025 at 09:58:12AM +0300, Ilias Apalodimas wrote:
> A following patch is replacing our IO accessors with
> do { ... } while(0) ones in order to make them usable with KVM.
>
> That leads to an error eventually looking like this:
> arch/arm/include/asm/io.h:62:9: error: expected expression before 'do'
> 62 | do { \
> | ^~
> arch/arm/include/asm/io.h:211:41: note: in expansion of macro '__raw_writel'
> 211 | #define out_arch(type,endian,a,v) __raw_write##type(cpu_to_##endian(v),a)
> | ^~~~~~~~~~~
> arch/arm/include/asm/io.h:223:25: note: in expansion of macro 'out_arch'
> 223 | #define out_be32(a,v) out_arch(l,be32,a,v)
> | ^~~~~~~~
> drivers/spi/fsl_dspi.c:127:17: note: in expansion of macro 'out_be32'
> 127 | out_be32(addr, val) : out_le32(addr, val);
> | ^~~~~~~~
>
> So adjust the current macros and code to be compatible with the upcoming
> change.
>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 2/3] arm: io.h: Fix io accessors for KVM
2025-06-18 6:58 [PATCH v2 0/3] Fix io accessors for KVM Ilias Apalodimas
2025-06-18 6:58 ` [PATCH v2 1/3] nxp: Prepare macros for KVM changes Ilias Apalodimas
@ 2025-06-18 6:58 ` Ilias Apalodimas
2025-06-18 6:58 ` [PATCH v2 3/3] qemu: arm: Enable virtualizable IO accessors Ilias Apalodimas
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Ilias Apalodimas @ 2025-06-18 6:58 UTC (permalink / raw)
To: trini
Cc: jerome.forissier, mikko.rapeli, Ilias Apalodimas,
Rayagonda Kokatanur, Tuomas Tynkkynen, Jagan Teki, Casey Connolly,
Tien Fong Chee, Patrick Rudolph, Simon Glass, Peter Robinson,
Alif Zakuan Yuslaimi, Liya Huang, Boyan Karatotev, Oliver Gaskell,
Duje Mihanović, Raymond Mao, Heinrich Schuchardt,
Patrick Delaunay, Venkatesh Yadav Abbarapu, Ashok Reddy Soma,
Marek Vasut, u-boot
commit 2e2c2a5e72a8 ("arm: qemu: override flash accessors to use virtualizable instructions")
explains why we can't have instructions with multiple output registers
when running under QEMU + KVM and the instruction leads to an exception
to the hypervisor.
USB XHCI is such a case (MMIO) where a ldr w1, [x0], #4 is emitted for
xhci_start() which works fine with QEMU but crashes for QEMU + KVM.
These instructions cannot be emulated by KVM as they do not produce
syndrome information data that KVM can use to infer the destination
register, the faulting address, whether it was a load or store, or
if it's a 32 or 64 bit general-purpose register.
As a result an external abort is injected from QEMU, via ext_dabt_pending
to KVM and we end up throwing an exception that looks like
U-Boot 2025.07-rc4 (Jun 10 2025 - 12:00:15 +0000)
[...]
Register 8001040 NbrPorts 8
Starting the controller
"Synchronous Abort" handler, esr 0x96000010, far 0x10100040
elr: 000000000005b1c8 lr : 000000000005b1ac (reloc)
elr: 00000000476fc1c8 lr : 00000000476fc1ac
x0 : 0000000010100040 x1 : 0000000000000001
x2 : 0000000000000000 x3 : 0000000000003e80
x4 : 0000000000000000 x5 : 00000000477a5694
x6 : 0000000000000038 x7 : 000000004666f360
x8 : 0000000000000000 x9 : 00000000ffffffd8
x10: 000000000000000d x11: 0000000000000006
x12: 0000000046560a78 x13: 0000000046560dd0
x14: 00000000ffffffff x15: 000000004666eed2
x16: 00000000476ee2f0 x17: 0000000000000000
x18: 0000000046660dd0 x19: 000000004666f480
x20: 0000000000000000 x21: 0000000010100040
x22: 0000000010100000 x23: 0000000000000000
x24: 0000000000000000 x25: 0000000000000000
x26: 0000000000000000 x27: 0000000000000000
x28: 0000000000000000 x29: 000000004666f360
Code: d5033fbf aa1503e0 5287d003 52800002 (b8004401)
Resetting CPU ...
There are two problems making this the default.
- It will emit ldr + add or str + add instead of ldr/str(post increment)
in somne cases
- Some platforms that depend on TPL/SPL grow in size enough so that the
binary doesn't fit anymore.
So let's add proper I/O accessors add a Kconfig option
to turn it off by default apart from our QEMU builds.
Reported-by: Mikko Rapeli <mikko.rapeli@linaro.org>
Tested-by: Mikko Rapeli <mikko.rapeli@linaro.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
arch/arm/Kconfig | 12 +++
arch/arm/include/asm/io.h | 152 ++++++++++++++++++++++++++++----------
2 files changed, 124 insertions(+), 40 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6ff3f2750ea8..f6430a5aaf07 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -108,6 +108,18 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE
The value subtracted from CONFIG_TEXT_BASE to calculate the
TEXT_OFFSET value written to the Linux kernel image header.
+config KVM_VIRT_INS
+ bool "Emit virtualizable instructions"
+ help
+ Instructions in the ARM ISA that have multiple output registers,
+ can't be used if the instruction leads to an exception to the hypervisor.
+ These instructions cannot be emulated by KVM because they do not produce
+ syndrome information data that KVM can use to infer the destination
+ register, the faulting address, whether it was a load or store,
+ if it's a 32 or 64 bit general-purpose register amongst other things.
+ Use this to produce virtualizable instructions if you plan to run U-Boot
+ with KVM.
+
config NVIC
bool
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 89b1015bc4d3..85ec0e6937e8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -20,23 +20,108 @@ static inline void sync(void)
{
}
-/* Generic virtual read/write. */
-#define __arch_getb(a) (*(volatile unsigned char *)(a))
-#define __arch_getw(a) (*(volatile unsigned short *)(a))
-#define __arch_getl(a) (*(volatile unsigned int *)(a))
-#define __arch_getq(a) (*(volatile unsigned long long *)(a))
+#ifdef CONFIG_ARM64
+#define __W "w"
+#else
+#define __W
+#endif
+
+#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
+#define __R "l"
+#define __RM "=l"
+#else
+#define __R "r"
+#define __RM "=r"
+#endif
-#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
-#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
-#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
-#define __arch_putq(v,a) (*(volatile unsigned long long *)(a) = (v))
+#ifdef CONFIG_KVM_VIRT_INS
+/*
+ * The __raw_writeX/__raw_readX below should be converted to static inline
+ * functions. However doing so produces a lot of compilation warnings when
+ * called with a raw address. Convert these once the callers have been fixed.
+ */
+#define __raw_writeb(val, addr) \
+ do { \
+ asm volatile("strb %" __W "0, [%1]" \
+ : \
+ : __R ((u8)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readb(addr) \
+ ({ \
+ u32 __val; \
+ asm volatile("ldrb %" __W "0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+
+#define __raw_writew(val, addr) \
+ do { \
+ asm volatile("strh %" __W "0, [%1]" \
+ : \
+ : __R ((u16)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readw(addr) \
+ ({ \
+ u32 __val; \
+ asm volatile("ldrh %" __W "0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+
+#define __raw_writel(val, addr) \
+ do { \
+ asm volatile("str %" __W "0, [%1]" \
+ : \
+ : __R ((u32)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readl(addr) \
+ ({ \
+ u32 __val; \
+ asm volatile("ldr %" __W "0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+
+#define __raw_writeq(val, addr) \
+ do { \
+ asm volatile("str %0, [%1]" \
+ : \
+ : __R ((u64)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readq(addr) \
+ ({ \
+ u64 __val; \
+ asm volatile("ldr %0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+#else
+/* Generic virtual read/write. */
+#define __raw_readb(a) (*(volatile unsigned char *)(a))
+#define __raw_readw(a) (*(volatile unsigned short *)(a))
+#define __raw_readl(a) (*(volatile unsigned int *)(a))
+#define __raw_readq(a) (*(volatile unsigned long long *)(a))
+
+#define __raw_writeb(v, a) (*(volatile unsigned char *)(a) = (v))
+#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v))
+#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v))
+#define __raw_writeq(v, a) (*(volatile unsigned long long *)(a) = (v))
+#endif
static inline void __raw_writesb(unsigned long addr, const void *data,
int bytelen)
{
uint8_t *buf = (uint8_t *)data;
while(bytelen--)
- __arch_putb(*buf++, addr);
+ __raw_writeb(*buf++, addr);
}
static inline void __raw_writesw(unsigned long addr, const void *data,
@@ -44,7 +129,7 @@ static inline void __raw_writesw(unsigned long addr, const void *data,
{
uint16_t *buf = (uint16_t *)data;
while(wordlen--)
- __arch_putw(*buf++, addr);
+ __raw_writew(*buf++, addr);
}
static inline void __raw_writesl(unsigned long addr, const void *data,
@@ -52,40 +137,30 @@ static inline void __raw_writesl(unsigned long addr, const void *data,
{
uint32_t *buf = (uint32_t *)data;
while(longlen--)
- __arch_putl(*buf++, addr);
+ __raw_writel(*buf++, addr);
}
static inline void __raw_readsb(unsigned long addr, void *data, int bytelen)
{
uint8_t *buf = (uint8_t *)data;
while(bytelen--)
- *buf++ = __arch_getb(addr);
+ *buf++ = __raw_readb(addr);
}
static inline void __raw_readsw(unsigned long addr, void *data, int wordlen)
{
uint16_t *buf = (uint16_t *)data;
while(wordlen--)
- *buf++ = __arch_getw(addr);
+ *buf++ = __raw_readw(addr);
}
static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
{
uint32_t *buf = (uint32_t *)data;
while(longlen--)
- *buf++ = __arch_getl(addr);
+ *buf++ = __raw_readl(addr);
}
-#define __raw_writeb(v,a) __arch_putb(v,a)
-#define __raw_writew(v,a) __arch_putw(v,a)
-#define __raw_writel(v,a) __arch_putl(v,a)
-#define __raw_writeq(v,a) __arch_putq(v,a)
-
-#define __raw_readb(a) __arch_getb(a)
-#define __raw_readw(a) __arch_getw(a)
-#define __raw_readl(a) __arch_getl(a)
-#define __raw_readq(a) __arch_getq(a)
-
/*
* TODO: The kernel offers some more advanced versions of barriers, it might
* have some advantages to use them instead of the simple one here.
@@ -98,15 +173,15 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define smp_processor_id() 0
-#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; })
-#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; })
-#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; })
-#define writeq(v,c) ({ u64 __v = v; __iowmb(); __arch_putq(__v,c); __v; })
+#define writeb(v, c) ({ u8 __v = v; __iowmb(); writeb_relaxed(__v, c); __v; })
+#define writew(v, c) ({ u16 __v = v; __iowmb(); writew_relaxed(__v, c); __v; })
+#define writel(v, c) ({ u32 __v = v; __iowmb(); writel_relaxed(__v, c); __v; })
+#define writeq(v, c) ({ u64 __v = v; __iowmb(); writeq_relaxed(__v, c); __v; })
-#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; })
-#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; })
-#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; })
-#define readq(c) ({ u64 __v = __arch_getq(c); __iormb(); __v; })
+#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
+#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
+#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
+#define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(); __v; })
/*
* Relaxed I/O memory access primitives. These follow the Device memory
@@ -121,13 +196,10 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define readq_relaxed(c) ({ u64 __r = le64_to_cpu((__force __le64) \
__raw_readq(c)); __r; })
-#define writeb_relaxed(v, c) ((void)__raw_writeb((v), (c)))
-#define writew_relaxed(v, c) ((void)__raw_writew((__force u16) \
- cpu_to_le16(v), (c)))
-#define writel_relaxed(v, c) ((void)__raw_writel((__force u32) \
- cpu_to_le32(v), (c)))
-#define writeq_relaxed(v, c) ((void)__raw_writeq((__force u64) \
- cpu_to_le64(v), (c)))
+#define writeb_relaxed(v, c) __raw_writeb((v), (c))
+#define writew_relaxed(v, c) __raw_writew((__force u16)cpu_to_le16(v), (c))
+#define writel_relaxed(v, c) __raw_writel((__force u32)cpu_to_le32(v), (c))
+#define writeq_relaxed(v, c) __raw_writeq((__force u64)cpu_to_le64(v), (c))
/*
* The compiler seems to be incapable of optimising constants
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 3/3] qemu: arm: Enable virtualizable IO accessors
2025-06-18 6:58 [PATCH v2 0/3] Fix io accessors for KVM Ilias Apalodimas
2025-06-18 6:58 ` [PATCH v2 1/3] nxp: Prepare macros for KVM changes Ilias Apalodimas
2025-06-18 6:58 ` [PATCH v2 2/3] arm: io.h: Fix io accessors for KVM Ilias Apalodimas
@ 2025-06-18 6:58 ` Ilias Apalodimas
2025-06-18 9:59 ` [PATCH v2 0/3] Fix io accessors for KVM Mikko Rapeli
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Ilias Apalodimas @ 2025-06-18 6:58 UTC (permalink / raw)
To: trini
Cc: jerome.forissier, mikko.rapeli, Ilias Apalodimas,
Rayagonda Kokatanur, Tuomas Tynkkynen, Jagan Teki, Casey Connolly,
Tien Fong Chee, Patrick Rudolph, Simon Glass, Peter Robinson,
Oliver Gaskell, Boyan Karatotev, Alif Zakuan Yuslaimi,
Duje Mihanović, Liya Huang, Raymond Mao, Heinrich Schuchardt,
Patrick Delaunay, Venkatesh Yadav Abbarapu, Ashok Reddy Soma,
Marek Vasut, u-boot
We recently added IO accessors that will work with KVM for any MMIO
access that casues an exception to the hypervisor. Enable them by
default for QEMU.
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
configs/qemu_arm64_defconfig | 1 +
configs/qemu_arm_defconfig | 1 +
2 files changed, 2 insertions(+)
diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig
index 72bd255eafa3..39afb837e411 100644
--- a/configs/qemu_arm64_defconfig
+++ b/configs/qemu_arm64_defconfig
@@ -1,4 +1,5 @@
CONFIG_ARM=y
+CONFIG_KVM_VIRT_INS=y
CONFIG_ARCH_QEMU=y
CONFIG_SYS_MALLOC_LEN=0x1000000
CONFIG_BLOBLIST_SIZE_RELOC=0x2000
diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig
index f13001390d4d..92ba48f6af97 100644
--- a/configs/qemu_arm_defconfig
+++ b/configs/qemu_arm_defconfig
@@ -1,4 +1,5 @@
CONFIG_ARM=y
+CONFIG_KVM_VIRT_INS=y
CONFIG_ARM_SMCCC=y
CONFIG_ARCH_QEMU=y
CONFIG_SYS_MALLOC_LEN=0x1000000
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 0/3] Fix io accessors for KVM
2025-06-18 6:58 [PATCH v2 0/3] Fix io accessors for KVM Ilias Apalodimas
` (2 preceding siblings ...)
2025-06-18 6:58 ` [PATCH v2 3/3] qemu: arm: Enable virtualizable IO accessors Ilias Apalodimas
@ 2025-06-18 9:59 ` Mikko Rapeli
2025-06-18 11:03 ` Jerome Forissier
2025-06-27 19:10 ` Tom Rini
5 siblings, 0 replies; 9+ messages in thread
From: Mikko Rapeli @ 2025-06-18 9:59 UTC (permalink / raw)
To: Ilias Apalodimas
Cc: trini, jerome.forissier, Rayagonda Kokatanur, Tuomas Tynkkynen,
Jagan Teki, Casey Connolly, Tien Fong Chee, Simon Glass,
Patrick Rudolph, Liya Huang, Boyan Karatotev,
Alif Zakuan Yuslaimi, Oliver Gaskell, Duje Mihanović,
Heinrich Schuchardt, Raymond Mao, Patrick Delaunay,
Ashok Reddy Soma, Venkatesh Yadav Abbarapu, Marek Vasut, u-boot,
Peter Robinson
Hi,
Tested on yocto poky master branch using u-boot master branch
commit 17012e3068d047ad71460f039eeb0c3be63f82a0 and these
patches. qemu KVM boot on aarch64 works again with USB devices
enabled in qemu system.
Tested-by: Mikko Rapeli <mikko.rapeli@linaro.org>
Cheers,
-Mikko
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v2 0/3] Fix io accessors for KVM
2025-06-18 6:58 [PATCH v2 0/3] Fix io accessors for KVM Ilias Apalodimas
` (3 preceding siblings ...)
2025-06-18 9:59 ` [PATCH v2 0/3] Fix io accessors for KVM Mikko Rapeli
@ 2025-06-18 11:03 ` Jerome Forissier
2025-06-18 12:04 ` Ilias Apalodimas
2025-06-27 19:10 ` Tom Rini
5 siblings, 1 reply; 9+ messages in thread
From: Jerome Forissier @ 2025-06-18 11:03 UTC (permalink / raw)
To: Ilias Apalodimas, trini
Cc: mikko.rapeli, Rayagonda Kokatanur, Tuomas Tynkkynen, Jagan Teki,
Casey Connolly, Tien Fong Chee, Simon Glass, Patrick Rudolph,
Liya Huang, Boyan Karatotev, Alif Zakuan Yuslaimi, Oliver Gaskell,
Duje Mihanović, Heinrich Schuchardt, Raymond Mao,
Patrick Delaunay, Ashok Reddy Soma, Venkatesh Yadav Abbarapu,
Marek Vasut, u-boot
On 6/18/25 08:58, Ilias Apalodimas wrote:
> Instructions that lead ito an exception in the hypervisor can't modify two
> CPU registers at once for the ARM ISA.
>
> These instructions cannot be emulated by KVM as they do not produce
> syndrome information data that KVM can use to infer the destination
> register, the faulting address, whether it was a load or store, or
> if it's a 32 or 64 bit general-purpose register.
> As a result an external abort is injected from QEMU, via ext_dabt_pending.
>
> Patch #1 prepares some function for the modified macros
> Patch #2 modifies the macros
> Patch #3 enables the functionality for armv7/8 QEMU
Again, IMHO this is more complex than necessary because you're combining
the KVM fix with some code refactoring. Patch #1 can be dropped altogether
and patch #2 can be simplified (from "2 files changed, 123 insertions(+),
39 deletions(-)" to "2 files changed, 97 insertions(+)". Unless I missed
something? Please see [1]. Of course it also passes the LVM test ;)
[1] https://source.denx.de/u-boot/custodians/u-boot-net/-/pipelines/26751.
--
Jerome
>
> Changes since v1:
> - Split the function modification in its own patch
> - Don't limit the changes to v8 only
>
> Ilias Apalodimas (3):
> nxp: Prepare macros for KVM changes
> arm: io.h: Fix io accessors for KVM
> qemu: arm: Enable virtualizable IO accesors
>
> arch/arm/Kconfig | 12 +++
> arch/arm/include/asm/io.h | 152 ++++++++++++++++++++++++++---------
> configs/qemu_arm64_defconfig | 1 +
> configs/qemu_arm_defconfig | 1 +
> drivers/spi/fsl_dspi.c | 6 +-
> include/fsl_ifc.h | 24 +++---
> 6 files changed, 142 insertions(+), 54 deletions(-)
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v2 0/3] Fix io accessors for KVM
2025-06-18 11:03 ` Jerome Forissier
@ 2025-06-18 12:04 ` Ilias Apalodimas
0 siblings, 0 replies; 9+ messages in thread
From: Ilias Apalodimas @ 2025-06-18 12:04 UTC (permalink / raw)
To: Jerome Forissier
Cc: trini, mikko.rapeli, Rayagonda Kokatanur, Tuomas Tynkkynen,
Jagan Teki, Casey Connolly, Tien Fong Chee, Simon Glass,
Patrick Rudolph, Liya Huang, Boyan Karatotev,
Alif Zakuan Yuslaimi, Oliver Gaskell, Duje Mihanović,
Heinrich Schuchardt, Raymond Mao, Patrick Delaunay,
Ashok Reddy Soma, Venkatesh Yadav Abbarapu, Marek Vasut, u-boot
Hi Jerome,
On Wed, 18 Jun 2025 at 14:03, Jerome Forissier
<jerome.forissier@linaro.org> wrote:
>
>
>
> On 6/18/25 08:58, Ilias Apalodimas wrote:
> > Instructions that lead ito an exception in the hypervisor can't modify two
> > CPU registers at once for the ARM ISA.
> >
> > These instructions cannot be emulated by KVM as they do not produce
> > syndrome information data that KVM can use to infer the destination
> > register, the faulting address, whether it was a load or store, or
> > if it's a 32 or 64 bit general-purpose register.
> > As a result an external abort is injected from QEMU, via ext_dabt_pending.
> >
> > Patch #1 prepares some function for the modified macros
> > Patch #2 modifies the macros
> > Patch #3 enables the functionality for armv7/8 QEMU
>
> Again, IMHO this is more complex than necessary because you're combining
> the KVM fix with some code refactoring. Patch #1 can be dropped altogether
> and patch #2 can be simplified (from "2 files changed, 123 insertions(+),
> 39 deletions(-)" to "2 files changed, 97 insertions(+)". Unless I missed
> something? Please see [1]. Of course it also passes the LVM test ;)
No you aren't. I just kept it as is because Tom said he was fine and
makes the final code easier to read, rather than having 2 macros doing
the same thing.
Thanks
/Ilias
>
> [1] https://source.denx.de/u-boot/custodians/u-boot-net/-/pipelines/26751.
>
> --
> Jerome
>
> >
> > Changes since v1:
> > - Split the function modification in its own patch
> > - Don't limit the changes to v8 only
> >
> > Ilias Apalodimas (3):
> > nxp: Prepare macros for KVM changes
> > arm: io.h: Fix io accessors for KVM
> > qemu: arm: Enable virtualizable IO accesors
> >
> > arch/arm/Kconfig | 12 +++
> > arch/arm/include/asm/io.h | 152 ++++++++++++++++++++++++++---------
> > configs/qemu_arm64_defconfig | 1 +
> > configs/qemu_arm_defconfig | 1 +
> > drivers/spi/fsl_dspi.c | 6 +-
> > include/fsl_ifc.h | 24 +++---
> > 6 files changed, 142 insertions(+), 54 deletions(-)
> >
> > --
> > 2.43.0
> >
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/3] Fix io accessors for KVM
2025-06-18 6:58 [PATCH v2 0/3] Fix io accessors for KVM Ilias Apalodimas
` (4 preceding siblings ...)
2025-06-18 11:03 ` Jerome Forissier
@ 2025-06-27 19:10 ` Tom Rini
5 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2025-06-27 19:10 UTC (permalink / raw)
To: Ilias Apalodimas
Cc: jerome.forissier, mikko.rapeli, Rayagonda Kokatanur,
Tuomas Tynkkynen, Jagan Teki, Casey Connolly, Tien Fong Chee,
Simon Glass, Patrick Rudolph, Liya Huang, Boyan Karatotev,
Alif Zakuan Yuslaimi, Oliver Gaskell, Duje Mihanović,
Heinrich Schuchardt, Raymond Mao, Patrick Delaunay,
Ashok Reddy Soma, Venkatesh Yadav Abbarapu, Marek Vasut, u-boot
On Wed, 18 Jun 2025 09:58:11 +0300, Ilias Apalodimas wrote:
> Instructions that lead ito an exception in the hypervisor can't modify two
> CPU registers at once for the ARM ISA.
>
> These instructions cannot be emulated by KVM as they do not produce
> syndrome information data that KVM can use to infer the destination
> register, the faulting address, whether it was a load or store, or
> if it's a 32 or 64 bit general-purpose register.
> As a result an external abort is injected from QEMU, via ext_dabt_pending.
>
> [...]
Applied to u-boot/next, thanks!
[1/3] nxp: Prepare macros for KVM changes
commit: b56c0632ad62415a40216d6f4de850e870163a6f
[2/3] arm: io.h: Fix io accessors for KVM
commit: dc512700ad46c16531ac57dbe5bba78d7153961d
[3/3] qemu: arm: Enable virtualizable IO accessors
commit: fcc60481ae755cf289bb96ccef81294b0b443654
--
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread