On 5/17/23 10:31, Zhuojia Shen wrote:
DC CVAP and DC CVADP instructions can be executed in EL0 on Linux,
either directly when SCTLR_EL1.UCI == 1 or emulated by the kernel (see
user_cache_maint_handler() in arch/arm64/kernel/traps.c).
This patch enables execution of the two instructions in user mode
emulation.
Signed-off-by: Zhuojia Shen <chaosdefinit...@hotmail.com>
---
target/arm/helper.c | 6 ++--
tests/tcg/aarch64/Makefile.target | 11 ++++++++
tests/tcg/aarch64/dcpodp-1.c | 47 +++++++++++++++++++++++++++++++
tests/tcg/aarch64/dcpodp-2.c | 47 +++++++++++++++++++++++++++++++
tests/tcg/aarch64/dcpop-1.c | 47 +++++++++++++++++++++++++++++++
tests/tcg/aarch64/dcpop-2.c | 47 +++++++++++++++++++++++++++++++
6 files changed, 201 insertions(+), 4 deletions(-)
create mode 100644 tests/tcg/aarch64/dcpodp-1.c
create mode 100644 tests/tcg/aarch64/dcpodp-2.c
create mode 100644 tests/tcg/aarch64/dcpop-1.c
create mode 100644 tests/tcg/aarch64/dcpop-2.c
I recommend splitting the tests to a second patch.
+++ b/tests/tcg/aarch64/dcpodp-1.c
@@ -0,0 +1,47 @@
+/* Test execution of DC CVADP instruction */
+
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef HWCAP2_DCPODP
+#define HWCAP2_DCPODP (1 << 0)
+#endif
+
+static void signal_handler(int sig)
+{
+ exit(EXIT_FAILURE);
+}
+
+static int do_dc_cvadp(void)
+{
+ struct sigaction sa = {
+ .sa_handler = signal_handler,
+ };
+
+ if (sigaction(SIGILL, &sa, NULL) < 0) {
+ perror("sigaction");
+ return EXIT_FAILURE;
+ }
+ if (sigaction(SIGSEGV, &sa, NULL) < 0) {
+ perror("sigaction");
+ return EXIT_FAILURE;
+ }
+
+ asm volatile("dc cvadp, %0\n\t" :: "r"(&sa));
+
+ return EXIT_SUCCESS;
+}
...
diff --git a/tests/tcg/aarch64/dcpodp-2.c b/tests/tcg/aarch64/dcpodp-2.c
new file mode 100644
index 0000000000..3245d7883d
--- /dev/null
+++ b/tests/tcg/aarch64/dcpodp-2.c
@@ -0,0 +1,47 @@
+/* Test execution of DC CVADP instruction on unmapped address */
+
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef HWCAP2_DCPODP
+#define HWCAP2_DCPODP (1 << 0)
+#endif
+
+static void signal_handler(int sig)
+{
+ exit(EXIT_SUCCESS);
+}
+
+static int do_dc_cvadp(void)
+{
+ struct sigaction sa = {
+ .sa_handler = signal_handler,
+ };
+
+ if (sigaction(SIGILL, &sa, NULL) < 0) {
+ perror("sigaction");
+ return EXIT_FAILURE;
+ }
This isn't: if SIGILL, exit with success.
You don't actually need to register anything for SIGILL, in either test, because SIGILL is
a fine exit for failure. So is SIGSEGV for test 1.
Also, you could merge all 4 tests and save some CI time.
r~