* [PULL 01/11] hw/arm_sysctl: fix extracting 31th bit of val
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
@ 2025-01-13 13:53 ` Peter Maydell
2025-01-13 13:53 ` [PULL 02/11] hw/misc: cast rpm to uint64_t Peter Maydell
` (10 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:53 UTC (permalink / raw)
To: qemu-devel
From: Anastasia Belova <abelova@astralinux.ru>
1 << 31 is casted to uint64_t while bitwise and with val.
So this value may become 0xffffffff80000000 but only
31th "start" bit is required.
This is not possible in practice because the MemoryRegionOps
uses the default max access size of 4 bytes and so none
of the upper bytes of val will be set, but the bitfield
extract API is clearer anyway.
Use the bitfield extract() API instead.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
Message-id: 20241220125429.7552-1-abelova@astralinux.ru
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[PMM: add clarification to commit message]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/misc/arm_sysctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
index 016a302e679..01663407eca 100644
--- a/hw/misc/arm_sysctl.c
+++ b/hw/misc/arm_sysctl.c
@@ -520,7 +520,7 @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
* as zero.
*/
s->sys_cfgctrl = val & ~((3 << 18) | (1 << 31));
- if (val & (1 << 31)) {
+ if (extract64(val, 31, 1)) {
/* Start bit set -- actually do something */
unsigned int dcc = extract32(s->sys_cfgctrl, 26, 4);
unsigned int function = extract32(s->sys_cfgctrl, 20, 6);
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 02/11] hw/misc: cast rpm to uint64_t
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
2025-01-13 13:53 ` [PULL 01/11] hw/arm_sysctl: fix extracting 31th bit of val Peter Maydell
@ 2025-01-13 13:53 ` Peter Maydell
2025-01-13 13:54 ` [PULL 03/11] tests/qtest/boot-serial-test: Improve ASM comments of PL011 tests Peter Maydell
` (9 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:53 UTC (permalink / raw)
To: qemu-devel
From: Tigran Sogomonian <tsogomonian@astralinux.ru>
The value of an arithmetic expression
'rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION' is a subject
to overflow because its operands are not cast to
a larger data type before performing arithmetic. Thus, need
to cast rpm to uint64_t.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Tigran Sogomonian <tsogomonian@astralinux.ru>
Reviewed-by: Patrick Leis <venture@google.com>
Reviewed-by: Hao Wu <wuhaotsh@google.com>
Message-id: 20241226130311.1349-1-tsogomonian@astralinux.ru
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/misc/npcm7xx_mft.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/misc/npcm7xx_mft.c b/hw/misc/npcm7xx_mft.c
index 9fcc69fe5c5..e565cac05d8 100644
--- a/hw/misc/npcm7xx_mft.c
+++ b/hw/misc/npcm7xx_mft.c
@@ -172,8 +172,9 @@ static NPCM7xxMFTCaptureState npcm7xx_mft_compute_cnt(
* RPM = revolution/min. The time for one revlution (in ns) is
* MINUTE_TO_NANOSECOND / RPM.
*/
- count = clock_ns_to_ticks(clock, (60 * NANOSECONDS_PER_SECOND) /
- (rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION));
+ count = clock_ns_to_ticks(clock,
+ (uint64_t)(60 * NANOSECONDS_PER_SECOND) /
+ ((uint64_t)rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION));
}
if (count > NPCM7XX_MFT_MAX_CNT) {
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 03/11] tests/qtest/boot-serial-test: Improve ASM comments of PL011 tests
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
2025-01-13 13:53 ` [PULL 01/11] hw/arm_sysctl: fix extracting 31th bit of val Peter Maydell
2025-01-13 13:53 ` [PULL 02/11] hw/misc: cast rpm to uint64_t Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 04/11] tests/qtest/boot-serial-test: Reduce for() loop in " Peter Maydell
` (8 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Re-indent ASM comments adding the 'loop:' label.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
tests/qtest/boot-serial-test.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index 3b92fa5d506..a71d2857807 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -70,18 +70,18 @@ static const uint8_t kernel_plml605[] = {
};
static const uint8_t bios_raspi2[] = {
- 0x08, 0x30, 0x9f, 0xe5, /* ldr r3,[pc,#8] Get base */
- 0x54, 0x20, 0xa0, 0xe3, /* mov r2,#'T' */
- 0x00, 0x20, 0xc3, 0xe5, /* strb r2,[r3] */
- 0xfb, 0xff, 0xff, 0xea, /* b loop */
- 0x00, 0x10, 0x20, 0x3f, /* 0x3f201000 = UART0 base addr */
+ 0x08, 0x30, 0x9f, 0xe5, /* loop: ldr r3, [pc, #8] Get &UART0 */
+ 0x54, 0x20, 0xa0, 0xe3, /* mov r2, #'T' */
+ 0x00, 0x20, 0xc3, 0xe5, /* strb r2, [r3] *TXDAT = 'T' */
+ 0xfb, 0xff, 0xff, 0xea, /* b -12 (loop) */
+ 0x00, 0x10, 0x20, 0x3f, /* UART0: 0x3f201000 */
};
static const uint8_t kernel_aarch64[] = {
- 0x81, 0x0a, 0x80, 0x52, /* mov w1, #0x54 */
- 0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 */
- 0x41, 0x00, 0x00, 0x39, /* strb w1, [x2] */
- 0xfd, 0xff, 0xff, 0x17, /* b -12 (loop) */
+ 0x81, 0x0a, 0x80, 0x52, /* loop: mov w1, #'T' */
+ 0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
+ 0x41, 0x00, 0x00, 0x39, /* strb w1, [x2] *TXDAT = 'T' */
+ 0xfd, 0xff, 0xff, 0x17, /* b -12 (loop) */
};
static const uint8_t kernel_nrf51[] = {
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 04/11] tests/qtest/boot-serial-test: Reduce for() loop in PL011 tests
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (2 preceding siblings ...)
2025-01-13 13:54 ` [PULL 03/11] tests/qtest/boot-serial-test: Improve ASM comments of PL011 tests Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 05/11] tests/qtest/boot-serial-test: Reorder pair of instructions in PL011 test Peter Maydell
` (7 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Since registers are not modified, we don't need
to refill their values. Directly jump to the previous
store instruction to keep filling the TXDAT register.
The equivalent C code remains:
while (true) {
*UART_DATA = 'T';
}
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
tests/qtest/boot-serial-test.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index a71d2857807..553575ca75c 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -70,18 +70,18 @@ static const uint8_t kernel_plml605[] = {
};
static const uint8_t bios_raspi2[] = {
- 0x08, 0x30, 0x9f, 0xe5, /* loop: ldr r3, [pc, #8] Get &UART0 */
+ 0x08, 0x30, 0x9f, 0xe5, /* ldr r3, [pc, #8] Get &UART0 */
0x54, 0x20, 0xa0, 0xe3, /* mov r2, #'T' */
- 0x00, 0x20, 0xc3, 0xe5, /* strb r2, [r3] *TXDAT = 'T' */
- 0xfb, 0xff, 0xff, 0xea, /* b -12 (loop) */
+ 0x00, 0x20, 0xc3, 0xe5, /* loop: strb r2, [r3] *TXDAT = 'T' */
+ 0xff, 0xff, 0xff, 0xea, /* b -4 (loop) */
0x00, 0x10, 0x20, 0x3f, /* UART0: 0x3f201000 */
};
static const uint8_t kernel_aarch64[] = {
- 0x81, 0x0a, 0x80, 0x52, /* loop: mov w1, #'T' */
+ 0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
- 0x41, 0x00, 0x00, 0x39, /* strb w1, [x2] *TXDAT = 'T' */
- 0xfd, 0xff, 0xff, 0x17, /* b -12 (loop) */
+ 0x41, 0x00, 0x00, 0x39, /* loop: strb w1, [x2] *TXDAT = 'T' */
+ 0xff, 0xff, 0xff, 0x17, /* b -4 (loop) */
};
static const uint8_t kernel_nrf51[] = {
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 05/11] tests/qtest/boot-serial-test: Reorder pair of instructions in PL011 test
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (3 preceding siblings ...)
2025-01-13 13:54 ` [PULL 04/11] tests/qtest/boot-serial-test: Reduce for() loop in " Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 06/11] tests/qtest/boot-serial-test: Initialize PL011 Control register Peter Maydell
` (6 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
In the next commit we are going to use a different value
for the $w1 register, maintaining the same $x2 value. In
order to keep the next commit trivial to review, set $x2
before $w1.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
tests/qtest/boot-serial-test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index 553575ca75c..bcfa504826c 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -78,8 +78,8 @@ static const uint8_t bios_raspi2[] = {
};
static const uint8_t kernel_aarch64[] = {
- 0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
+ 0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
0x41, 0x00, 0x00, 0x39, /* loop: strb w1, [x2] *TXDAT = 'T' */
0xff, 0xff, 0xff, 0x17, /* b -4 (loop) */
};
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 06/11] tests/qtest/boot-serial-test: Initialize PL011 Control register
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (4 preceding siblings ...)
2025-01-13 13:54 ` [PULL 05/11] tests/qtest/boot-serial-test: Reorder pair of instructions in PL011 test Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 07/11] target/arm: Move minor arithmetic helpers out of helper.c Peter Maydell
` (5 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
The tests using the PL011 UART of the virt and raspi machines
weren't properly enabling the UART and its transmitter previous
to sending characters. Follow the PL011 manual initialization
recommendation by setting the proper bits of the control register.
Update the ASM code prefixing:
*UART_CTRL = UART_ENABLE | TX_ENABLE;
to:
while (true) {
*UART_DATA = 'T';
}
Note, since commit 51b61dd4d56 ("hw/char/pl011: Warn when using
disabled transmitter") incomplete PL011 initialization can be
logged using the '-d guest_errors' command line option.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
tests/qtest/boot-serial-test.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index bcfa504826c..ffa9e780ad6 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -70,15 +70,20 @@ static const uint8_t kernel_plml605[] = {
};
static const uint8_t bios_raspi2[] = {
- 0x08, 0x30, 0x9f, 0xe5, /* ldr r3, [pc, #8] Get &UART0 */
+ 0x10, 0x30, 0x9f, 0xe5, /* ldr r3, [pc, #16] Get &UART0 */
+ 0x10, 0x20, 0x9f, 0xe5, /* ldr r2, [pc, #16] Get &CR */
+ 0xb0, 0x23, 0xc3, 0xe1, /* strh r2, [r3, #48] Set CR */
0x54, 0x20, 0xa0, 0xe3, /* mov r2, #'T' */
0x00, 0x20, 0xc3, 0xe5, /* loop: strb r2, [r3] *TXDAT = 'T' */
0xff, 0xff, 0xff, 0xea, /* b -4 (loop) */
0x00, 0x10, 0x20, 0x3f, /* UART0: 0x3f201000 */
+ 0x01, 0x01, 0x00, 0x00, /* CR: 0x101 = UARTEN|TXE */
};
static const uint8_t kernel_aarch64[] = {
0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
+ 0x21, 0x20, 0x80, 0x52, /* mov w1, 0x101 CR = UARTEN|TXE */
+ 0x41, 0x60, 0x00, 0x79, /* strh w1, [x2, #48] Set CR */
0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
0x41, 0x00, 0x00, 0x39, /* loop: strb w1, [x2] *TXDAT = 'T' */
0xff, 0xff, 0xff, 0x17, /* b -4 (loop) */
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 07/11] target/arm: Move minor arithmetic helpers out of helper.c
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (5 preceding siblings ...)
2025-01-13 13:54 ` [PULL 06/11] tests/qtest/boot-serial-test: Initialize PL011 Control register Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 08/11] target/arm: add new property to select pauth-qarma5 Peter Maydell
` (4 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
helper.c includes some small TCG helper functions used for mostly
arithmetic instructions. These are TCG only and there's no need for
them to be in the large and unwieldy helper.c. Move them out to
their own source file in the tcg/ subdirectory, together with the
op_addsub.h multiply-included template header that they use.
Since we are moving op_addsub.h, we take the opportunity to
give it a name which matches our convention for files which
are not true header files but which are #included from other
C files: op_addsub.c.inc.
(Ironically, this means that helper.c no longer contains
any TCG helper function definitions at all.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250110131211.2546314-1-peter.maydell@linaro.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
---
target/arm/helper.c | 285 -----------------
target/arm/tcg/arith_helper.c | 296 ++++++++++++++++++
.../arm/{op_addsub.h => tcg/op_addsub.c.inc} | 0
target/arm/tcg/meson.build | 1 +
4 files changed, 297 insertions(+), 285 deletions(-)
create mode 100644 target/arm/tcg/arith_helper.c
rename target/arm/{op_addsub.h => tcg/op_addsub.c.inc} (100%)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5b595f951b4..63997678513 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -17,11 +17,9 @@
#include "qemu/main-loop.h"
#include "qemu/timer.h"
#include "qemu/bitops.h"
-#include "qemu/crc32c.h"
#include "qemu/qemu-print.h"
#include "exec/exec-all.h"
#include "exec/translation-block.h"
-#include <zlib.h> /* for crc32 */
#include "hw/irq.h"
#include "system/cpu-timers.h"
#include "system/kvm.h"
@@ -10984,289 +10982,6 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
};
}
-/*
- * Note that signed overflow is undefined in C. The following routines are
- * careful to use unsigned types where modulo arithmetic is required.
- * Failure to do so _will_ break on newer gcc.
- */
-
-/* Signed saturating arithmetic. */
-
-/* Perform 16-bit signed saturating addition. */
-static inline uint16_t add16_sat(uint16_t a, uint16_t b)
-{
- uint16_t res;
-
- res = a + b;
- if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
- if (a & 0x8000) {
- res = 0x8000;
- } else {
- res = 0x7fff;
- }
- }
- return res;
-}
-
-/* Perform 8-bit signed saturating addition. */
-static inline uint8_t add8_sat(uint8_t a, uint8_t b)
-{
- uint8_t res;
-
- res = a + b;
- if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
- if (a & 0x80) {
- res = 0x80;
- } else {
- res = 0x7f;
- }
- }
- return res;
-}
-
-/* Perform 16-bit signed saturating subtraction. */
-static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
-{
- uint16_t res;
-
- res = a - b;
- if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
- if (a & 0x8000) {
- res = 0x8000;
- } else {
- res = 0x7fff;
- }
- }
- return res;
-}
-
-/* Perform 8-bit signed saturating subtraction. */
-static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
-{
- uint8_t res;
-
- res = a - b;
- if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
- if (a & 0x80) {
- res = 0x80;
- } else {
- res = 0x7f;
- }
- }
- return res;
-}
-
-#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
-#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
-#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
-#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
-#define PFX q
-
-#include "op_addsub.h"
-
-/* Unsigned saturating arithmetic. */
-static inline uint16_t add16_usat(uint16_t a, uint16_t b)
-{
- uint16_t res;
- res = a + b;
- if (res < a) {
- res = 0xffff;
- }
- return res;
-}
-
-static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
-{
- if (a > b) {
- return a - b;
- } else {
- return 0;
- }
-}
-
-static inline uint8_t add8_usat(uint8_t a, uint8_t b)
-{
- uint8_t res;
- res = a + b;
- if (res < a) {
- res = 0xff;
- }
- return res;
-}
-
-static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
-{
- if (a > b) {
- return a - b;
- } else {
- return 0;
- }
-}
-
-#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
-#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
-#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
-#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
-#define PFX uq
-
-#include "op_addsub.h"
-
-/* Signed modulo arithmetic. */
-#define SARITH16(a, b, n, op) do { \
- int32_t sum; \
- sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
- RESULT(sum, n, 16); \
- if (sum >= 0) \
- ge |= 3 << (n * 2); \
- } while (0)
-
-#define SARITH8(a, b, n, op) do { \
- int32_t sum; \
- sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
- RESULT(sum, n, 8); \
- if (sum >= 0) \
- ge |= 1 << n; \
- } while (0)
-
-
-#define ADD16(a, b, n) SARITH16(a, b, n, +)
-#define SUB16(a, b, n) SARITH16(a, b, n, -)
-#define ADD8(a, b, n) SARITH8(a, b, n, +)
-#define SUB8(a, b, n) SARITH8(a, b, n, -)
-#define PFX s
-#define ARITH_GE
-
-#include "op_addsub.h"
-
-/* Unsigned modulo arithmetic. */
-#define ADD16(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
- RESULT(sum, n, 16); \
- if ((sum >> 16) == 1) \
- ge |= 3 << (n * 2); \
- } while (0)
-
-#define ADD8(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
- RESULT(sum, n, 8); \
- if ((sum >> 8) == 1) \
- ge |= 1 << n; \
- } while (0)
-
-#define SUB16(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
- RESULT(sum, n, 16); \
- if ((sum >> 16) == 0) \
- ge |= 3 << (n * 2); \
- } while (0)
-
-#define SUB8(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
- RESULT(sum, n, 8); \
- if ((sum >> 8) == 0) \
- ge |= 1 << n; \
- } while (0)
-
-#define PFX u
-#define ARITH_GE
-
-#include "op_addsub.h"
-
-/* Halved signed arithmetic. */
-#define ADD16(a, b, n) \
- RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
-#define SUB16(a, b, n) \
- RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
-#define ADD8(a, b, n) \
- RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
-#define SUB8(a, b, n) \
- RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
-#define PFX sh
-
-#include "op_addsub.h"
-
-/* Halved unsigned arithmetic. */
-#define ADD16(a, b, n) \
- RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
-#define SUB16(a, b, n) \
- RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
-#define ADD8(a, b, n) \
- RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
-#define SUB8(a, b, n) \
- RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
-#define PFX uh
-
-#include "op_addsub.h"
-
-static inline uint8_t do_usad(uint8_t a, uint8_t b)
-{
- if (a > b) {
- return a - b;
- } else {
- return b - a;
- }
-}
-
-/* Unsigned sum of absolute byte differences. */
-uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
-{
- uint32_t sum;
- sum = do_usad(a, b);
- sum += do_usad(a >> 8, b >> 8);
- sum += do_usad(a >> 16, b >> 16);
- sum += do_usad(a >> 24, b >> 24);
- return sum;
-}
-
-/* For ARMv6 SEL instruction. */
-uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
-{
- uint32_t mask;
-
- mask = 0;
- if (flags & 1) {
- mask |= 0xff;
- }
- if (flags & 2) {
- mask |= 0xff00;
- }
- if (flags & 4) {
- mask |= 0xff0000;
- }
- if (flags & 8) {
- mask |= 0xff000000;
- }
- return (a & mask) | (b & ~mask);
-}
-
-/*
- * CRC helpers.
- * The upper bytes of val (above the number specified by 'bytes') must have
- * been zeroed out by the caller.
- */
-uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
-{
- uint8_t buf[4];
-
- stl_le_p(buf, val);
-
- /* zlib crc32 converts the accumulator and output to one's complement. */
- return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
-}
-
-uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
-{
- uint8_t buf[4];
-
- stl_le_p(buf, val);
-
- /* Linux crc32c converts the output to one's complement. */
- return crc32c(acc, buf, bytes) ^ 0xffffffff;
-}
/*
* Return the exception level to which FP-disabled exceptions should
diff --git a/target/arm/tcg/arith_helper.c b/target/arm/tcg/arith_helper.c
new file mode 100644
index 00000000000..9a555c7966c
--- /dev/null
+++ b/target/arm/tcg/arith_helper.c
@@ -0,0 +1,296 @@
+/*
+ * ARM generic helpers for various arithmetical operations.
+ *
+ * This code is licensed under the GNU GPL v2 or later.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "qemu/crc32c.h"
+#include <zlib.h> /* for crc32 */
+
+/*
+ * Note that signed overflow is undefined in C. The following routines are
+ * careful to use unsigned types where modulo arithmetic is required.
+ * Failure to do so _will_ break on newer gcc.
+ */
+
+/* Signed saturating arithmetic. */
+
+/* Perform 16-bit signed saturating addition. */
+static inline uint16_t add16_sat(uint16_t a, uint16_t b)
+{
+ uint16_t res;
+
+ res = a + b;
+ if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
+ if (a & 0x8000) {
+ res = 0x8000;
+ } else {
+ res = 0x7fff;
+ }
+ }
+ return res;
+}
+
+/* Perform 8-bit signed saturating addition. */
+static inline uint8_t add8_sat(uint8_t a, uint8_t b)
+{
+ uint8_t res;
+
+ res = a + b;
+ if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
+ if (a & 0x80) {
+ res = 0x80;
+ } else {
+ res = 0x7f;
+ }
+ }
+ return res;
+}
+
+/* Perform 16-bit signed saturating subtraction. */
+static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
+{
+ uint16_t res;
+
+ res = a - b;
+ if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
+ if (a & 0x8000) {
+ res = 0x8000;
+ } else {
+ res = 0x7fff;
+ }
+ }
+ return res;
+}
+
+/* Perform 8-bit signed saturating subtraction. */
+static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
+{
+ uint8_t res;
+
+ res = a - b;
+ if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
+ if (a & 0x80) {
+ res = 0x80;
+ } else {
+ res = 0x7f;
+ }
+ }
+ return res;
+}
+
+#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
+#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
+#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
+#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
+#define PFX q
+
+#include "op_addsub.c.inc"
+
+/* Unsigned saturating arithmetic. */
+static inline uint16_t add16_usat(uint16_t a, uint16_t b)
+{
+ uint16_t res;
+ res = a + b;
+ if (res < a) {
+ res = 0xffff;
+ }
+ return res;
+}
+
+static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
+{
+ if (a > b) {
+ return a - b;
+ } else {
+ return 0;
+ }
+}
+
+static inline uint8_t add8_usat(uint8_t a, uint8_t b)
+{
+ uint8_t res;
+ res = a + b;
+ if (res < a) {
+ res = 0xff;
+ }
+ return res;
+}
+
+static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
+{
+ if (a > b) {
+ return a - b;
+ } else {
+ return 0;
+ }
+}
+
+#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
+#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
+#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
+#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
+#define PFX uq
+
+#include "op_addsub.c.inc"
+
+/* Signed modulo arithmetic. */
+#define SARITH16(a, b, n, op) do { \
+ int32_t sum; \
+ sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
+ RESULT(sum, n, 16); \
+ if (sum >= 0) \
+ ge |= 3 << (n * 2); \
+ } while (0)
+
+#define SARITH8(a, b, n, op) do { \
+ int32_t sum; \
+ sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
+ RESULT(sum, n, 8); \
+ if (sum >= 0) \
+ ge |= 1 << n; \
+ } while (0)
+
+
+#define ADD16(a, b, n) SARITH16(a, b, n, +)
+#define SUB16(a, b, n) SARITH16(a, b, n, -)
+#define ADD8(a, b, n) SARITH8(a, b, n, +)
+#define SUB8(a, b, n) SARITH8(a, b, n, -)
+#define PFX s
+#define ARITH_GE
+
+#include "op_addsub.c.inc"
+
+/* Unsigned modulo arithmetic. */
+#define ADD16(a, b, n) do { \
+ uint32_t sum; \
+ sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
+ RESULT(sum, n, 16); \
+ if ((sum >> 16) == 1) \
+ ge |= 3 << (n * 2); \
+ } while (0)
+
+#define ADD8(a, b, n) do { \
+ uint32_t sum; \
+ sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
+ RESULT(sum, n, 8); \
+ if ((sum >> 8) == 1) \
+ ge |= 1 << n; \
+ } while (0)
+
+#define SUB16(a, b, n) do { \
+ uint32_t sum; \
+ sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
+ RESULT(sum, n, 16); \
+ if ((sum >> 16) == 0) \
+ ge |= 3 << (n * 2); \
+ } while (0)
+
+#define SUB8(a, b, n) do { \
+ uint32_t sum; \
+ sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
+ RESULT(sum, n, 8); \
+ if ((sum >> 8) == 0) \
+ ge |= 1 << n; \
+ } while (0)
+
+#define PFX u
+#define ARITH_GE
+
+#include "op_addsub.c.inc"
+
+/* Halved signed arithmetic. */
+#define ADD16(a, b, n) \
+ RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
+#define SUB16(a, b, n) \
+ RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
+#define ADD8(a, b, n) \
+ RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
+#define SUB8(a, b, n) \
+ RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
+#define PFX sh
+
+#include "op_addsub.c.inc"
+
+/* Halved unsigned arithmetic. */
+#define ADD16(a, b, n) \
+ RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
+#define SUB16(a, b, n) \
+ RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
+#define ADD8(a, b, n) \
+ RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
+#define SUB8(a, b, n) \
+ RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
+#define PFX uh
+
+#include "op_addsub.c.inc"
+
+static inline uint8_t do_usad(uint8_t a, uint8_t b)
+{
+ if (a > b) {
+ return a - b;
+ } else {
+ return b - a;
+ }
+}
+
+/* Unsigned sum of absolute byte differences. */
+uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
+{
+ uint32_t sum;
+ sum = do_usad(a, b);
+ sum += do_usad(a >> 8, b >> 8);
+ sum += do_usad(a >> 16, b >> 16);
+ sum += do_usad(a >> 24, b >> 24);
+ return sum;
+}
+
+/* For ARMv6 SEL instruction. */
+uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
+{
+ uint32_t mask;
+
+ mask = 0;
+ if (flags & 1) {
+ mask |= 0xff;
+ }
+ if (flags & 2) {
+ mask |= 0xff00;
+ }
+ if (flags & 4) {
+ mask |= 0xff0000;
+ }
+ if (flags & 8) {
+ mask |= 0xff000000;
+ }
+ return (a & mask) | (b & ~mask);
+}
+
+/*
+ * CRC helpers.
+ * The upper bytes of val (above the number specified by 'bytes') must have
+ * been zeroed out by the caller.
+ */
+uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
+{
+ uint8_t buf[4];
+
+ stl_le_p(buf, val);
+
+ /* zlib crc32 converts the accumulator and output to one's complement. */
+ return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
+}
+
+uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
+{
+ uint8_t buf[4];
+
+ stl_le_p(buf, val);
+
+ /* Linux crc32c converts the output to one's complement. */
+ return crc32c(acc, buf, bytes) ^ 0xffffffff;
+}
diff --git a/target/arm/op_addsub.h b/target/arm/tcg/op_addsub.c.inc
similarity index 100%
rename from target/arm/op_addsub.h
rename to target/arm/tcg/op_addsub.c.inc
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
index 09238989c5a..1f9077c372c 100644
--- a/target/arm/tcg/meson.build
+++ b/target/arm/tcg/meson.build
@@ -40,6 +40,7 @@ arm_ss.add(files(
'tlb_helper.c',
'vec_helper.c',
'tlb-insns.c',
+ 'arith_helper.c',
))
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 08/11] target/arm: add new property to select pauth-qarma5
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (6 preceding siblings ...)
2025-01-13 13:54 ` [PULL 07/11] target/arm: Move minor arithmetic helpers out of helper.c Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 09/11] tests/tcg/aarch64: force qarma5 for pauth-3 test Peter Maydell
` (3 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Before changing default pauth algorithm, we need to make sure current
default one (QARMA5) can still be selected.
$ qemu-system-aarch64 -cpu max,pauth-qarma5=on ...
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241219183211.3493974-2-pierrick.bouvier@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
docs/system/arm/cpu-features.rst | 5 ++++-
target/arm/cpu.h | 1 +
target/arm/arm-qmp-cmds.c | 2 +-
target/arm/cpu64.c | 20 ++++++++++++++------
tests/qtest/arm-cpu-features.c | 15 +++++++++++----
5 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index a5fb929243c..d69ebc2b852 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -219,7 +219,10 @@ Below is the list of TCG VCPU features and their descriptions.
``pauth-qarma3``
When ``pauth`` is enabled, select the architected QARMA3 algorithm.
-Without either ``pauth-impdef`` or ``pauth-qarma3`` enabled,
+``pauth-qarma5``
+ When ``pauth`` is enabled, select the architected QARMA5 algorithm.
+
+Without ``pauth-impdef``, ``pauth-qarma3`` or ``pauth-qarma5`` enabled,
the architected QARMA5 algorithm is used. The architected QARMA5
and QARMA3 algorithms have good cryptographic properties, but can
be quite slow to emulate. The impdef algorithm used by QEMU is
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 12b84665427..01d9ff1781a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1062,6 +1062,7 @@ struct ArchCPU {
bool prop_pauth;
bool prop_pauth_impdef;
bool prop_pauth_qarma3;
+ bool prop_pauth_qarma5;
bool prop_lpa2;
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 3cc8cc738bb..33cea080d11 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -94,7 +94,7 @@ static const char *cpu_model_advertised_features[] = {
"sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
"sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
"kvm-no-adjvtime", "kvm-steal-time",
- "pauth", "pauth-impdef", "pauth-qarma3",
+ "pauth", "pauth-impdef", "pauth-qarma3", "pauth-qarma5",
NULL
};
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index dca83e45181..6ee0af69121 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -520,9 +520,12 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
}
if (cpu->prop_pauth) {
- if (cpu->prop_pauth_impdef && cpu->prop_pauth_qarma3) {
+ if ((cpu->prop_pauth_impdef && cpu->prop_pauth_qarma3) ||
+ (cpu->prop_pauth_impdef && cpu->prop_pauth_qarma5) ||
+ (cpu->prop_pauth_qarma3 && cpu->prop_pauth_qarma5)) {
error_setg(errp,
- "cannot enable both pauth-impdef and pauth-qarma3");
+ "cannot enable pauth-impdef, pauth-qarma3 and "
+ "pauth-qarma5 at the same time");
return;
}
@@ -532,13 +535,15 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
} else if (cpu->prop_pauth_qarma3) {
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, features);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 1);
- } else {
+ } else { /* default is pauth-qarma5 */
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
}
- } else if (cpu->prop_pauth_impdef || cpu->prop_pauth_qarma3) {
- error_setg(errp, "cannot enable pauth-impdef or "
- "pauth-qarma3 without pauth");
+ } else if (cpu->prop_pauth_impdef ||
+ cpu->prop_pauth_qarma3 ||
+ cpu->prop_pauth_qarma5) {
+ error_setg(errp, "cannot enable pauth-impdef, pauth-qarma3 or "
+ "pauth-qarma5 without pauth");
error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
}
}
@@ -553,6 +558,8 @@ static const Property arm_cpu_pauth_impdef_property =
DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
static const Property arm_cpu_pauth_qarma3_property =
DEFINE_PROP_BOOL("pauth-qarma3", ARMCPU, prop_pauth_qarma3, false);
+static Property arm_cpu_pauth_qarma5_property =
+ DEFINE_PROP_BOOL("pauth-qarma5", ARMCPU, prop_pauth_qarma5, false);
void aarch64_add_pauth_properties(Object *obj)
{
@@ -573,6 +580,7 @@ void aarch64_add_pauth_properties(Object *obj)
} else {
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_qarma3_property);
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_qarma5_property);
}
}
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
index cfd6f773535..98d6c970ea5 100644
--- a/tests/qtest/arm-cpu-features.c
+++ b/tests/qtest/arm-cpu-features.c
@@ -419,21 +419,28 @@ static void pauth_tests_default(QTestState *qts, const char *cpu_type)
assert_has_feature_enabled(qts, cpu_type, "pauth");
assert_has_feature_disabled(qts, cpu_type, "pauth-impdef");
assert_has_feature_disabled(qts, cpu_type, "pauth-qarma3");
+ assert_has_feature_disabled(qts, cpu_type, "pauth-qarma5");
assert_set_feature(qts, cpu_type, "pauth", false);
assert_set_feature(qts, cpu_type, "pauth", true);
assert_set_feature(qts, cpu_type, "pauth-impdef", true);
assert_set_feature(qts, cpu_type, "pauth-impdef", false);
assert_set_feature(qts, cpu_type, "pauth-qarma3", true);
assert_set_feature(qts, cpu_type, "pauth-qarma3", false);
+ assert_set_feature(qts, cpu_type, "pauth-qarma5", true);
+ assert_set_feature(qts, cpu_type, "pauth-qarma5", false);
assert_error(qts, cpu_type,
- "cannot enable pauth-impdef or pauth-qarma3 without pauth",
+ "cannot enable pauth-impdef, pauth-qarma3 or pauth-qarma5 without pauth",
"{ 'pauth': false, 'pauth-impdef': true }");
assert_error(qts, cpu_type,
- "cannot enable pauth-impdef or pauth-qarma3 without pauth",
+ "cannot enable pauth-impdef, pauth-qarma3 or pauth-qarma5 without pauth",
"{ 'pauth': false, 'pauth-qarma3': true }");
assert_error(qts, cpu_type,
- "cannot enable both pauth-impdef and pauth-qarma3",
- "{ 'pauth': true, 'pauth-impdef': true, 'pauth-qarma3': true }");
+ "cannot enable pauth-impdef, pauth-qarma3 or pauth-qarma5 without pauth",
+ "{ 'pauth': false, 'pauth-qarma5': true }");
+ assert_error(qts, cpu_type,
+ "cannot enable pauth-impdef, pauth-qarma3 and pauth-qarma5 at the same time",
+ "{ 'pauth': true, 'pauth-impdef': true, 'pauth-qarma3': true,"
+ " 'pauth-qarma5': true }");
}
static void test_query_cpu_model_expansion(const void *data)
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 09/11] tests/tcg/aarch64: force qarma5 for pauth-3 test
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (7 preceding siblings ...)
2025-01-13 13:54 ` [PULL 08/11] target/arm: add new property to select pauth-qarma5 Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 10/11] target/arm: change default pauth algorithm to impdef Peter Maydell
` (2 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
The pauth-3 test explicitly tests that a computation of the
pointer-authentication produces the expected result. This means that
it must be run with the QARMA5 algorithm.
Explicitly set the pauth algorithm when running this test, so that it
doesn't break when we change the default algorithm the 'max' CPU
uses.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
tests/tcg/aarch64/Makefile.softmmu-target | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
index d08d9b01ded..9c52475b7ae 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -91,6 +91,9 @@ EXTRA_RUNS+=run-memory-replay
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
pauth-3: CFLAGS += $(CROSS_CC_HAS_ARMV8_3)
+# This test explicitly checks the output of the pauth operation so we
+# must force the use of the QARMA5 algorithm for it.
+run-pauth-3: QEMU_BASE_MACHINE=-M virt -cpu max,pauth-qarma5=on -display none
else
pauth-3:
$(call skip-test, "BUILD of $@", "missing compiler support")
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 10/11] target/arm: change default pauth algorithm to impdef
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (8 preceding siblings ...)
2025-01-13 13:54 ` [PULL 09/11] tests/tcg/aarch64: force qarma5 for pauth-3 test Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 13:54 ` [PULL 11/11] docs/system/arm/virt: mention specific migration information Peter Maydell
2025-01-13 16:01 ` [PULL 00/11] target-arm queue Stefan Hajnoczi
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Pointer authentication on aarch64 is pretty expensive (up to 50% of
execution time) when running a virtual machine with tcg and -cpu max
(which enables pauth=on).
The advice is always: use pauth-impdef=on.
Our documentation even mentions it "by default" in
docs/system/introduction.rst.
Thus, we change the default to use impdef by default. This does not
affect kvm or hvf acceleration, since pauth algorithm used is the one
from host cpu.
This change is retro compatible, in terms of cli, with previous
versions, as the semantic of using -cpu max,pauth-impdef=on, and -cpu
max,pauth-qarma3=on is preserved.
The new option introduced in previous patch and matching old default is
-cpu max,pauth-qarma5=on.
It is retro compatible with migration as well, by defining a backcompat
property, that will use qarma5 by default for virt machine <= 9.2.
Tested by saving and restoring a vm from qemu 9.2.0 into qemu-master
(10.0) for cpus neoverse-n2 and max.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241219183211.3493974-3-pierrick.bouvier@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
docs/system/arm/cpu-features.rst | 2 +-
docs/system/introduction.rst | 2 +-
target/arm/cpu.h | 3 +++
hw/core/machine.c | 4 +++-
target/arm/cpu.c | 2 ++
target/arm/cpu64.c | 22 ++++++++++++++++------
6 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index d69ebc2b852..37d5dfd15b3 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -223,7 +223,7 @@ Below is the list of TCG VCPU features and their descriptions.
When ``pauth`` is enabled, select the architected QARMA5 algorithm.
Without ``pauth-impdef``, ``pauth-qarma3`` or ``pauth-qarma5`` enabled,
-the architected QARMA5 algorithm is used. The architected QARMA5
+the QEMU impdef algorithm is used. The architected QARMA5
and QARMA3 algorithms have good cryptographic properties, but can
be quite slow to emulate. The impdef algorithm used by QEMU is
non-cryptographic but significantly faster.
diff --git a/docs/system/introduction.rst b/docs/system/introduction.rst
index 746707eb00e..338d3745c3c 100644
--- a/docs/system/introduction.rst
+++ b/docs/system/introduction.rst
@@ -169,7 +169,7 @@ would default to it anyway.
.. code::
- -cpu max,pauth-impdef=on \
+ -cpu max \
-smp 4 \
-accel tcg \
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 01d9ff1781a..9a6e8e589cc 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -972,6 +972,9 @@ struct ArchCPU {
/* QOM property to indicate we should use the back-compat CNTFRQ default */
bool backcompat_cntfrq;
+ /* QOM property to indicate we should use the back-compat QARMA5 default */
+ bool backcompat_pauth_default_use_qarma5;
+
/* Specify the number of cores in this CPU cluster. Used for the L2CTLR
* register.
*/
diff --git a/hw/core/machine.c b/hw/core/machine.c
index c949af97668..c23b3994964 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -36,7 +36,9 @@
#include "hw/virtio/virtio-iommu.h"
#include "audio/audio.h"
-GlobalProperty hw_compat_9_2[] = {};
+GlobalProperty hw_compat_9_2[] = {
+ {"arm-cpu", "backcompat-pauth-default-use-qarma5", "true"},
+};
const size_t hw_compat_9_2_len = G_N_ELEMENTS(hw_compat_9_2);
GlobalProperty hw_compat_9_1[] = {
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index dcedadc89ea..dc0231233a6 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2653,6 +2653,8 @@ static const Property arm_cpu_properties[] = {
DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
/* True to default to the backward-compat old CNTFRQ rather than 1Ghz */
DEFINE_PROP_BOOL("backcompat-cntfrq", ARMCPU, backcompat_cntfrq, false),
+ DEFINE_PROP_BOOL("backcompat-pauth-default-use-qarma5", ARMCPU,
+ backcompat_pauth_default_use_qarma5, false),
};
static const gchar *arm_gdb_arch_name(CPUState *cs)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 6ee0af69121..8188ede5cc8 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -529,15 +529,25 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
return;
}
- if (cpu->prop_pauth_impdef) {
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, features);
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 1);
+ bool use_default = !cpu->prop_pauth_qarma5 &&
+ !cpu->prop_pauth_qarma3 &&
+ !cpu->prop_pauth_impdef;
+
+ if (cpu->prop_pauth_qarma5 ||
+ (use_default &&
+ cpu->backcompat_pauth_default_use_qarma5)) {
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
} else if (cpu->prop_pauth_qarma3) {
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, features);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 1);
- } else { /* default is pauth-qarma5 */
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
+ } else if (cpu->prop_pauth_impdef ||
+ (use_default &&
+ !cpu->backcompat_pauth_default_use_qarma5)) {
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, features);
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 1);
+ } else {
+ g_assert_not_reached();
}
} else if (cpu->prop_pauth_impdef ||
cpu->prop_pauth_qarma3 ||
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PULL 11/11] docs/system/arm/virt: mention specific migration information
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (9 preceding siblings ...)
2025-01-13 13:54 ` [PULL 10/11] target/arm: change default pauth algorithm to impdef Peter Maydell
@ 2025-01-13 13:54 ` Peter Maydell
2025-01-13 16:01 ` [PULL 00/11] target-arm queue Stefan Hajnoczi
11 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2025-01-13 13:54 UTC (permalink / raw)
To: qemu-devel
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Message-id: 20241219183211.3493974-4-pierrick.bouvier@linaro.org
[PMM: Removed a paragraph about using non-versioned models.]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
docs/system/arm/virt.rst | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
index f87adeb444c..766a7455f03 100644
--- a/docs/system/arm/virt.rst
+++ b/docs/system/arm/virt.rst
@@ -19,6 +19,10 @@ of the 5.0 release and ``virt-5.0`` of the 5.1 release. Migration
is not guaranteed to work between different QEMU releases for
the non-versioned ``virt`` machine type.
+VM migration is not guaranteed when using ``-cpu max``, as features
+supported may change between QEMU versions. To ensure your VM can be
+migrated, it is recommended to use another cpu model instead.
+
Supported devices
"""""""""""""""""
--
2.34.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PULL 00/11] target-arm queue
2025-01-13 13:53 [PULL 00/11] target-arm queue Peter Maydell
` (10 preceding siblings ...)
2025-01-13 13:54 ` [PULL 11/11] docs/system/arm/virt: mention specific migration information Peter Maydell
@ 2025-01-13 16:01 ` Stefan Hajnoczi
11 siblings, 0 replies; 31+ messages in thread
From: Stefan Hajnoczi @ 2025-01-13 16:01 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/10.0 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread