Skip to content

Commit 57a9635

Browse files
Yicong Yangwilldeacon
authored andcommitted
kselftest/arm64: Add HWCAP test for FEAT_LS64
Add tests for FEAT_LS64. Issue related instructions if feature presents, no SIGILL should be received. When such instructions operate on Device memory or non-cacheable memory, we may received a SIGBUS during the test (w/o FEAT_LS64WB). Just ignore it since we only tested whether the instruction itself can be issued as expected on platforms declaring the support of such features. Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Oliver Upton <oupton@kernel.org> Signed-off-by: Yicong Yang <yangyicong@hisilicon.com> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> Signed-off-by: Will Deacon <will@kernel.org>
1 parent 2a369c4 commit 57a9635

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

  • tools/testing/selftests/arm64/abi

tools/testing/selftests/arm64/abi/hwcap.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <stdlib.h>
1212
#include <string.h>
1313
#include <unistd.h>
14+
#include <linux/auxvec.h>
15+
#include <linux/compiler.h>
1416
#include <sys/auxv.h>
1517
#include <sys/prctl.h>
1618
#include <asm/hwcap.h>
@@ -595,6 +597,45 @@ static void lrcpc3_sigill(void)
595597
: "=r" (data0), "=r" (data1) : "r" (src) :);
596598
}
597599

600+
static void ignore_signal(int sig, siginfo_t *info, void *context)
601+
{
602+
ucontext_t *uc = context;
603+
604+
uc->uc_mcontext.pc += 4;
605+
}
606+
607+
static void ls64_sigill(void)
608+
{
609+
struct sigaction ign, old;
610+
char src[64] __aligned(64) = { 1 };
611+
612+
/*
613+
* LS64 requires target memory to be Device/Non-cacheable (if
614+
* FEAT_LS64WB not supported) and the completer supports these
615+
* instructions, otherwise we'll receive a SIGBUS. Since we are only
616+
* testing the ABI here, so just ignore the SIGBUS and see if we can
617+
* execute the instructions without receiving a SIGILL. Restore the
618+
* handler of SIGBUS after this test.
619+
*/
620+
ign.sa_sigaction = ignore_signal;
621+
ign.sa_flags = SA_SIGINFO | SA_RESTART;
622+
sigemptyset(&ign.sa_mask);
623+
sigaction(SIGBUS, &ign, &old);
624+
625+
register void *xn asm ("x8") = src;
626+
register u64 xt_1 asm ("x0");
627+
628+
/* LD64B x0, [x8] */
629+
asm volatile(".inst 0xf83fd100" : "=r" (xt_1) : "r" (xn)
630+
: "x1", "x2", "x3", "x4", "x5", "x6", "x7");
631+
632+
/* ST64B x0, [x8] */
633+
asm volatile(".inst 0xf83f9100" : : "r" (xt_1), "r" (xn)
634+
: "x1", "x2", "x3", "x4", "x5", "x6", "x7");
635+
636+
sigaction(SIGBUS, &old, NULL);
637+
}
638+
598639
static const struct hwcap_data {
599640
const char *name;
600641
unsigned long at_hwcap;
@@ -1134,6 +1175,14 @@ static const struct hwcap_data {
11341175
.hwcap_bit = HWCAP3_MTE_STORE_ONLY,
11351176
.cpuinfo = "mtestoreonly",
11361177
},
1178+
{
1179+
.name = "LS64",
1180+
.at_hwcap = AT_HWCAP3,
1181+
.hwcap_bit = HWCAP3_LS64,
1182+
.cpuinfo = "ls64",
1183+
.sigill_fn = ls64_sigill,
1184+
.sigill_reliable = true,
1185+
},
11371186
};
11381187

11391188
typedef void (*sighandler_fn)(int, siginfo_t *, void *);

0 commit comments

Comments
 (0)