brintos

brintos / linux-shallow public Read only

0
0
Text · 2.3 KiB · f139a33 Raw
120 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) 2022 ARM Limited3 4#include <stdbool.h>5#include <stdio.h>6#include <string.h>7 8#include <sys/auxv.h>9#include <sys/prctl.h>10 11#include <asm/hwcap.h>12 13#include "kselftest.h"14 15static int set_tagged_addr_ctrl(int val)16{17	int ret;18 19	ret = prctl(PR_SET_TAGGED_ADDR_CTRL, val, 0, 0, 0);20	if (ret < 0)21		ksft_print_msg("PR_SET_TAGGED_ADDR_CTRL: failed %d %d (%s)\n",22			       ret, errno, strerror(errno));23	return ret;24}25 26static int get_tagged_addr_ctrl(void)27{28	int ret;29 30	ret = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);31	if (ret < 0)32		ksft_print_msg("PR_GET_TAGGED_ADDR_CTRL failed: %d %d (%s)\n",33			       ret, errno, strerror(errno));34	return ret;35}36 37/*38 * Read the current mode without having done any configuration, should39 * run first.40 */41void check_basic_read(void)42{43	int ret;44 45	ret = get_tagged_addr_ctrl();46	if (ret < 0) {47		ksft_test_result_fail("check_basic_read\n");48		return;49	}50 51	if (ret & PR_MTE_TCF_SYNC)52		ksft_print_msg("SYNC enabled\n");53	if (ret & PR_MTE_TCF_ASYNC)54		ksft_print_msg("ASYNC enabled\n");55 56	/* Any configuration is valid */57	ksft_test_result_pass("check_basic_read\n");58}59 60/*61 * Attempt to set a specified combination of modes.62 */63void set_mode_test(const char *name, int hwcap2, int mask)64{65	int ret;66 67	if ((getauxval(AT_HWCAP2) & hwcap2) != hwcap2) {68		ksft_test_result_skip("%s\n", name);69		return;70	}71 72	ret = set_tagged_addr_ctrl(mask);73	if (ret < 0) {74		ksft_test_result_fail("%s\n", name);75		return;76	}77 78	ret = get_tagged_addr_ctrl();79	if (ret < 0) {80		ksft_test_result_fail("%s\n", name);81		return;82	}83 84	if ((ret & PR_MTE_TCF_MASK) == mask) {85		ksft_test_result_pass("%s\n", name);86	} else {87		ksft_print_msg("Got %x, expected %x\n",88			       (ret & PR_MTE_TCF_MASK), mask);89		ksft_test_result_fail("%s\n", name);90	}91}92 93struct mte_mode {94	int mask;95	int hwcap2;96	const char *name;97} mte_modes[] = {98	{ PR_MTE_TCF_NONE,  0,          "NONE"  },99	{ PR_MTE_TCF_SYNC,  HWCAP2_MTE, "SYNC"  },100	{ PR_MTE_TCF_ASYNC, HWCAP2_MTE, "ASYNC" },101	{ PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC,  HWCAP2_MTE, "SYNC+ASYNC"  },102};103 104int main(void)105{106	int i;107 108	ksft_print_header();109	ksft_set_plan(5);110 111	check_basic_read();112	for (i = 0; i < ARRAY_SIZE(mte_modes); i++)113		set_mode_test(mte_modes[i].name, mte_modes[i].hwcap2,114			      mte_modes[i].mask);115 116	ksft_print_cnts();117 118	return 0;119}120