cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

check_prctl.c (2354B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (C) 2022 ARM Limited
      3
      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, should
     39 * 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}