mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 09:33:31 +02:00
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>
This commit is contained in:
parent
2a369c4942
commit
57a96356bb
|
|
@ -11,6 +11,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/auxvec.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <asm/hwcap.h>
|
||||
|
|
@ -595,6 +597,45 @@ static void lrcpc3_sigill(void)
|
|||
: "=r" (data0), "=r" (data1) : "r" (src) :);
|
||||
}
|
||||
|
||||
static void ignore_signal(int sig, siginfo_t *info, void *context)
|
||||
{
|
||||
ucontext_t *uc = context;
|
||||
|
||||
uc->uc_mcontext.pc += 4;
|
||||
}
|
||||
|
||||
static void ls64_sigill(void)
|
||||
{
|
||||
struct sigaction ign, old;
|
||||
char src[64] __aligned(64) = { 1 };
|
||||
|
||||
/*
|
||||
* LS64 requires target memory to be Device/Non-cacheable (if
|
||||
* FEAT_LS64WB not supported) and the completer supports these
|
||||
* instructions, otherwise we'll receive a SIGBUS. Since we are only
|
||||
* testing the ABI here, so just ignore the SIGBUS and see if we can
|
||||
* execute the instructions without receiving a SIGILL. Restore the
|
||||
* handler of SIGBUS after this test.
|
||||
*/
|
||||
ign.sa_sigaction = ignore_signal;
|
||||
ign.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
sigemptyset(&ign.sa_mask);
|
||||
sigaction(SIGBUS, &ign, &old);
|
||||
|
||||
register void *xn asm ("x8") = src;
|
||||
register u64 xt_1 asm ("x0");
|
||||
|
||||
/* LD64B x0, [x8] */
|
||||
asm volatile(".inst 0xf83fd100" : "=r" (xt_1) : "r" (xn)
|
||||
: "x1", "x2", "x3", "x4", "x5", "x6", "x7");
|
||||
|
||||
/* ST64B x0, [x8] */
|
||||
asm volatile(".inst 0xf83f9100" : : "r" (xt_1), "r" (xn)
|
||||
: "x1", "x2", "x3", "x4", "x5", "x6", "x7");
|
||||
|
||||
sigaction(SIGBUS, &old, NULL);
|
||||
}
|
||||
|
||||
static const struct hwcap_data {
|
||||
const char *name;
|
||||
unsigned long at_hwcap;
|
||||
|
|
@ -1134,6 +1175,14 @@ static const struct hwcap_data {
|
|||
.hwcap_bit = HWCAP3_MTE_STORE_ONLY,
|
||||
.cpuinfo = "mtestoreonly",
|
||||
},
|
||||
{
|
||||
.name = "LS64",
|
||||
.at_hwcap = AT_HWCAP3,
|
||||
.hwcap_bit = HWCAP3_LS64,
|
||||
.cpuinfo = "ls64",
|
||||
.sigill_fn = ls64_sigill,
|
||||
.sigill_reliable = true,
|
||||
},
|
||||
};
|
||||
|
||||
typedef void (*sighandler_fn)(int, siginfo_t *, void *);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user