mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
cpacfstats: dynamically load PAI and CPUMF counter
Up until now cpacfstats assumes that on the running hardware either all PAI and CPUMF are available or non at all. Which counters are supported may be hardware dependent and can vary in the future. With this commit cpacfstats dynamically loads the counters from sysfs entries in (/sys/devices/pai_crypto/events/) and (/sys/devices/cpum_cf/events/) respectively. Additionally cpacfstats has a new way of determining which PAI counters are meant for kernel usage. Signed-off-by: Finn Callies <fcallies@linux.ibm.com> Reviewed-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
93d3c44a1a
commit
c0fc21efb3
@@ -21,10 +21,11 @@ ALL_CPPFLAGS += -DVERSION=$(VERSION)
|
||||
|
||||
all: check_dep cpacfstats cpacfstatsd
|
||||
|
||||
cpacfstatsd: cpacfstatsd.o stats_sock.o perf_crypto.o
|
||||
cpacfstatsd: cpacfstatsd.o stats_sock.o perf_crypto.o cpacfstats_common.o \
|
||||
$(rootdir)/libutil/libutil.a
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -ludev -lpthread -o $@
|
||||
|
||||
cpacfstats: cpacfstats.o stats_sock.o
|
||||
cpacfstats: cpacfstats.o stats_sock.o cpacfstats_common.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
|
||||
@@ -55,168 +55,6 @@ static const char *const counter_str[] = {
|
||||
[PAI_KERNEL] = "pai_kernel"
|
||||
};
|
||||
|
||||
/* Strings for the pai counter details. Note that this is 0-based
|
||||
* while PoP is 1-based.
|
||||
*/
|
||||
static const char *const pai_str[] = {
|
||||
[ 0] = "KM DES",
|
||||
[ 1] = "KM 2key TDES",
|
||||
[ 2] = "KM TDES",
|
||||
[ 3] = "KM DES protected key",
|
||||
[ 4] = "KM 2key TDES protected key",
|
||||
[ 5] = "KM TDES protected key",
|
||||
[ 6] = "KM AES 128bit",
|
||||
[ 7] = "KM AES 192bit",
|
||||
[ 8] = "KM AES 256bit",
|
||||
[ 9] = "KM AES 128bit protected key",
|
||||
[ 10] = "KM AES 192bit protected key",
|
||||
[ 11] = "KM AES 256bit protected key",
|
||||
[ 12] = "KM AES-XTS 128bit",
|
||||
[ 13] = "KM AES-XTS 256bit",
|
||||
[ 14] = "KM AES-XTS 128bit protected key",
|
||||
[ 15] = "KM AES-XTS 256bit protected key",
|
||||
[ 16] = "KMC DES",
|
||||
[ 17] = "KMC 2key TDES",
|
||||
[ 18] = "KMC TDES",
|
||||
[ 19] = "KMC DES protected key",
|
||||
[ 20] = "KMC 2key TDES protected key",
|
||||
[ 21] = "KMC TDES protected key",
|
||||
[ 22] = "KMC AES 128bit",
|
||||
[ 23] = "KMC AES 192bit",
|
||||
[ 24] = "KMC AES 256bit",
|
||||
[ 25] = "KMC AES 128bit protected key",
|
||||
[ 26] = "KMC AES 192bit protected key",
|
||||
[ 27] = "KMC AES 256bit protected key",
|
||||
[ 28] = "KMC PRNG",
|
||||
[ 29] = "KMA AES 128bit",
|
||||
[ 30] = "KMA AES 192bit",
|
||||
[ 31] = "KMA AES 256bit",
|
||||
[ 32] = "KMA AES 128bit protected key",
|
||||
[ 33] = "KMA AES 192bit protected key",
|
||||
[ 34] = "KMA AES 256bit protected key",
|
||||
[ 35] = "KMF DES",
|
||||
[ 36] = "KMF 2key TDES",
|
||||
[ 37] = "KMF TDES",
|
||||
[ 38] = "KMF DES protected key",
|
||||
[ 39] = "KMF 2key TDES protected key",
|
||||
[ 40] = "KMF TDES protected key",
|
||||
[ 41] = "KMF AES 128bit",
|
||||
[ 42] = "KMF AES 192bit",
|
||||
[ 43] = "KMF AES 256bit",
|
||||
[ 44] = "KMF AES 128bit protected key",
|
||||
[ 45] = "KMF AES 192bit protected key",
|
||||
[ 46] = "KMF AES 256bit protected key",
|
||||
[ 47] = "KMCTR DES",
|
||||
[ 48] = "KMCTR 2key TDES",
|
||||
[ 49] = "KMCTR TDES",
|
||||
[ 50] = "KMCTR DES protected key",
|
||||
[ 51] = "KMCTR 2key TDES protected key",
|
||||
[ 52] = "KMCTR TDES protected key",
|
||||
[ 53] = "KMCTR AES 128bit",
|
||||
[ 54] = "KMCTR AES 192bit",
|
||||
[ 55] = "KMCTR AES 256bit",
|
||||
[ 56] = "KMCTR AES 128bit protected key",
|
||||
[ 57] = "KMCTR AES 192bit protected key",
|
||||
[ 58] = "KMCTR AES 256bit protected key",
|
||||
[ 59] = "KMO DES",
|
||||
[ 60] = "KMO 2key TDES",
|
||||
[ 61] = "KMO TDES",
|
||||
[ 62] = "KMO DES protected key",
|
||||
[ 63] = "KMO 2key TDES protected key",
|
||||
[ 64] = "KMO TDES protected key",
|
||||
[ 65] = "KMO AES 128bit",
|
||||
[ 66] = "KMO AES 192bit",
|
||||
[ 67] = "KMO AES 256bit",
|
||||
[ 68] = "KMO AES 128bit protected key",
|
||||
[ 69] = "KMO AES 192bit protected key",
|
||||
[ 70] = "KMO AES 256bit protected key",
|
||||
[ 71] = "KIMD SHA1",
|
||||
[ 72] = "KIMD SHA256",
|
||||
[ 73] = "KIMD SHA512",
|
||||
[ 74] = "KIMD SHA3-224",
|
||||
[ 75] = "KIMD SHA3-256",
|
||||
[ 76] = "KIMD SHA3-384",
|
||||
[ 77] = "KIMD SHA3-512",
|
||||
[ 78] = "KIMD SHAKE 128",
|
||||
[ 79] = "KIMD SHAKE 256",
|
||||
[ 80] = "KIMD GHASH",
|
||||
[ 81] = "KLMD SHA1",
|
||||
[ 82] = "KLMD SHA256",
|
||||
[ 83] = "KLMD SHA512",
|
||||
[ 84] = "KLMD SHA3-224",
|
||||
[ 85] = "KLMD SHA3-256",
|
||||
[ 86] = "KLMD SHA3-384",
|
||||
[ 87] = "KLMD SHA3-512",
|
||||
[ 88] = "KLMD SHAKE 128",
|
||||
[ 89] = "KLMD SHAKE 256",
|
||||
[ 90] = "KMAC DES",
|
||||
[ 91] = "KMAC 2key TDES",
|
||||
[ 92] = "KMAC TDES",
|
||||
[ 93] = "KMAC DES protected key",
|
||||
[ 94] = "KMAC 2key TDES protected key",
|
||||
[ 95] = "KMAC TDES protected key",
|
||||
[ 96] = "KMAC AES 128bit",
|
||||
[ 97] = "KMAC AES 192bit",
|
||||
[ 98] = "KMAC AES 256bit",
|
||||
[ 99] = "KMAC AES 128bit protected key",
|
||||
[100] = "KMAC AES 192bit protected key",
|
||||
[101] = "KMAC AES 256bit protected key",
|
||||
[102] = "PCC Last Block CMAC DES",
|
||||
[103] = "PCC Last Block CMAC 2key TDES",
|
||||
[104] = "PCC Last Block CMAC TDES",
|
||||
[105] = "PCC Last Block CMAC DES protected key",
|
||||
[106] = "PCC Last Block CMAC 2key TDES protected key",
|
||||
[107] = "PCC Last Block CMAC TDES protected key",
|
||||
[108] = "PCC Last Block CMAC AES 128bit",
|
||||
[109] = "PCC Last Block CMAC AES 192bit",
|
||||
[110] = "PCC Last Block CMAC AES 256bit",
|
||||
[111] = "PCC Last Block CMAC AES 128bit protected key",
|
||||
[112] = "PCC Last Block CMAC AES 192bit protected key",
|
||||
[113] = "PCC Last Block CMAC AES 256bit protected key",
|
||||
[114] = "PCC XTS Parameter AES 128bit",
|
||||
[115] = "PCC XTS Parameter AES 256bit",
|
||||
[116] = "PCC XTS Parameter AES 128bit protected key",
|
||||
[117] = "PCC XTS Parameter AES 256bit protected key",
|
||||
[118] = "PCC Scalar Mult P256",
|
||||
[119] = "PCC Scalar Mult P384",
|
||||
[120] = "PCC Scalar Mult P521",
|
||||
[121] = "PCC Scalar Mult Ed25519",
|
||||
[122] = "PCC Scalar Mult Ed448",
|
||||
[123] = "PCC Scalar Mult X25519",
|
||||
[124] = "PCC Scalar Mult X448",
|
||||
[125] = "PRNO SHA512 DRNG",
|
||||
[126] = "PRNO TRNG Query Ratio",
|
||||
[127] = "PRNO TRNG",
|
||||
[128] = "KDSA ECDSA Verify P256",
|
||||
[129] = "KDSA ECDSA Verify P384",
|
||||
[130] = "KDSA ECDSA Verify P521",
|
||||
[131] = "KDSA ECDSA Sign P256",
|
||||
[132] = "KDSA ECDSA Sign P384",
|
||||
[133] = "KDSA ECDSA Sign P521",
|
||||
[134] = "KDSA ECDSA Sign P256 protected key",
|
||||
[135] = "KDSA ECDSA Sign P384 protected key",
|
||||
[136] = "KDSA ECDSA Sign P521 protected key",
|
||||
[137] = "KDSA EdDSA Verify Ed25519",
|
||||
[138] = "KDSA EdDSA Verify Ed448",
|
||||
[139] = "KDSA EdDSA Sign Ed25519",
|
||||
[140] = "KDSA EdDSA Sign Ed448",
|
||||
[141] = "KDSA EdDSA Sign Ed25519 protected key",
|
||||
[142] = "KDSA EdDSA Sign Ed448 protected key",
|
||||
[143] = "PCKMO DES",
|
||||
[144] = "PCKMO 2key TDES",
|
||||
[145] = "PCKMO TDES",
|
||||
[146] = "PCKMO AES 128bit",
|
||||
[147] = "PCKMO AES 192bit",
|
||||
[148] = "PCKMO AES 256bit",
|
||||
[149] = "PCKMO ECC P256",
|
||||
[150] = "PCKMO ECC P384",
|
||||
[151] = "PCKMO ECC P521",
|
||||
[152] = "PCKMO ECC Ed25519",
|
||||
[153] = "PCKMO ECC Ed448",
|
||||
[154] = "Reserved 1",
|
||||
[155] = "Reserved 2"
|
||||
};
|
||||
|
||||
|
||||
static int paiprintnonzero;
|
||||
|
||||
@@ -275,7 +113,8 @@ static void json_print_virtual_counter_answer(int s, int ctr,
|
||||
int state, uint64_t value)
|
||||
{
|
||||
int paictr = 0, paistate = 0, ec;
|
||||
uint64_t i, paivalue = 0, maxnum;
|
||||
uint64_t i, paivalue = 0;
|
||||
unsigned int maxnum;
|
||||
const char *space;
|
||||
|
||||
switch (ctr) {
|
||||
@@ -288,11 +127,11 @@ static void json_print_virtual_counter_answer(int s, int ctr,
|
||||
printf("\"value\":%d}", !!value);
|
||||
return;
|
||||
case PAI_USER:
|
||||
maxnum = NUM_PAI_USER;
|
||||
maxnum = get_num_user_space_ctrs();
|
||||
space = "user";
|
||||
break;
|
||||
case PAI_KERNEL:
|
||||
maxnum = NUM_PAI_KERNEL;
|
||||
maxnum = MAX_NUM_PAI;
|
||||
space = "kernel";
|
||||
break;
|
||||
default:
|
||||
@@ -304,7 +143,7 @@ static void json_print_virtual_counter_answer(int s, int ctr,
|
||||
return;
|
||||
if (value > maxnum) {
|
||||
eprint("Incompatible versions detected!\n");
|
||||
eprint("Expected %"PRIu64" counter space for %s, but got %"PRIu64"\n",
|
||||
eprint("Expected %lu counter space for %s, but got %lu\n",
|
||||
maxnum, space, value);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -315,18 +154,18 @@ static void json_print_virtual_counter_answer(int s, int ctr,
|
||||
/* No more data for this virtual event after error. */
|
||||
return;
|
||||
}
|
||||
if (paictr > NUM_PAI_KERNEL) {
|
||||
if (paictr > MAX_NUM_PAI) {
|
||||
eprint("Pai counter number too big: %d\n", paictr);
|
||||
} else {
|
||||
printjsonsep();
|
||||
printf("{\"counter\":\"%s\",\"space\":\"%s\",\"counterid\":%d,",
|
||||
pai_str[paictr], space, paictr + 1);
|
||||
get_ctr_name(paictr), space, paictr + 1);
|
||||
if (paistate < 0) {
|
||||
printf("\"error\":%d}", paistate);
|
||||
/* Protocol does not send further counters. */
|
||||
return;
|
||||
}
|
||||
printf("\"value\":%"PRIu64"}", paivalue);
|
||||
printf("\"value\":%lu}", paivalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,7 +180,8 @@ static void print_virtual_counter_answer(int s,
|
||||
[UNSUPPORTED] = "unsupported"
|
||||
};
|
||||
int paictr = 0, paistate = 0, ec;
|
||||
uint64_t i, paivalue = 0, maxnum;
|
||||
uint64_t i, paivalue = 0;
|
||||
unsigned int maxnum;
|
||||
const char *ctrstr;
|
||||
|
||||
switch (ctr) {
|
||||
@@ -350,11 +190,11 @@ static void print_virtual_counter_answer(int s,
|
||||
printf(" hotplug detected\n");
|
||||
return;
|
||||
case PAI_USER:
|
||||
maxnum = NUM_PAI_USER;
|
||||
maxnum = get_num_user_space_ctrs();
|
||||
ctrstr = "pai_user";
|
||||
break;
|
||||
case PAI_KERNEL:
|
||||
maxnum = NUM_PAI_KERNEL;
|
||||
maxnum = MAX_NUM_PAI;
|
||||
ctrstr = "pai_kernel";
|
||||
break;
|
||||
default:
|
||||
@@ -372,7 +212,7 @@ static void print_virtual_counter_answer(int s,
|
||||
return;
|
||||
if (value > maxnum) {
|
||||
eprint("Incompatible versions detected!\n");
|
||||
eprint("Expected %"PRIu64" counters for %s, but got %"PRIu64"\n",
|
||||
eprint("Expected %lu counters for %s, but got %lu\n",
|
||||
maxnum, ctrstr, value);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -383,10 +223,10 @@ static void print_virtual_counter_answer(int s,
|
||||
/* No more data for this virtual event after error. */
|
||||
return;
|
||||
}
|
||||
if (paictr > NUM_PAI_KERNEL)
|
||||
if (paictr > MAX_NUM_PAI)
|
||||
eprint("Pai counter number too big: %d\n", paictr);
|
||||
else if (!paiprintnonzero || paivalue > 0)
|
||||
printf(" %-45s: %"PRIu64"\n", pai_str[paictr], paivalue);
|
||||
printf(" %-45s: %lu\n", get_ctr_name(paictr), paivalue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +242,7 @@ static void print_answer(int s, int ctr, int state, uint64_t value)
|
||||
else if (state == UNSUPPORTED)
|
||||
printf(" %s counter: unsupported\n", counter_str[ctr]);
|
||||
else
|
||||
printf(" %s counter: %"PRIu64"\n", counter_str[ctr], value);
|
||||
printf(" %s counter: %lu\n", counter_str[ctr], value);
|
||||
}
|
||||
|
||||
|
||||
@@ -417,7 +257,7 @@ static void json_print_answer(int s, int ctr, int state, uint64_t value)
|
||||
} else if (state == ENABLED) {
|
||||
printjsonsep();
|
||||
printf("{\"counter\":\"%s\",", counter_str[ctr]);
|
||||
printf("\"value\":%"PRIu64"}", value);
|
||||
printf("\"value\":%lu}", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,22 @@
|
||||
#define DEFAULT_RECV_TIMEOUT (30 * 1000)
|
||||
|
||||
/*
|
||||
* Number of PAI counters for user space. This excludes PCKMO since
|
||||
* this instruction is privileged.
|
||||
* Number of PAI counters. Contains all counters regardless of kernel or user
|
||||
* space
|
||||
*/
|
||||
#define NUM_PAI_USER 143
|
||||
/* Number of PAI counters for kernel space. Contains all counters. */
|
||||
#define NUM_PAI_KERNEL 156
|
||||
#define MAX_NUM_PAI 156
|
||||
|
||||
/*
|
||||
* This is the sysfs directory from which cpacfstatsd daemon application loads
|
||||
* the available PAI counters
|
||||
*/
|
||||
#define SYSFS_PAI_COUNTER "/sys/bus/event_source/devices/pai_crypto/events/"
|
||||
|
||||
/*
|
||||
* Note that this is the first kernel only counter in the 1-based list of the
|
||||
* architecture and NOT from the 0-based list in the cpacfstats code!
|
||||
*/
|
||||
#define FIRST_KERNEL_ONLY_COUNTER 144
|
||||
|
||||
int eprint(const char *format, ...);
|
||||
|
||||
@@ -67,6 +77,12 @@ enum state_e {
|
||||
UNSUPPORTED
|
||||
};
|
||||
|
||||
enum counter_type {
|
||||
SUPPRESS_COUNTER = 0,
|
||||
KERNEL_AND_USER_COUNTER,
|
||||
KERNEL_ONLY_COUNTER,
|
||||
};
|
||||
|
||||
/*
|
||||
* query send from client to daemon
|
||||
* Consist of:
|
||||
@@ -122,15 +138,23 @@ int recv_msg(int sfd, struct msg *m, int timeout);
|
||||
|
||||
/* perf_crypto.c */
|
||||
|
||||
int perf_init(void);
|
||||
int perf_init(unsigned int *supported_counters);
|
||||
void perf_stop(void);
|
||||
void perf_close(void);
|
||||
int perf_enable_ctr(enum ctr_e ctr);
|
||||
int perf_disable_ctr(enum ctr_e ctr);
|
||||
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value);
|
||||
int perf_read_ctr(enum ctr_e ctr, uint64_t *value);
|
||||
int perf_enable_ctr(enum ctr_e ctr, unsigned int *supported_counters);
|
||||
int perf_disable_ctr(enum ctr_e ctr, unsigned int *supported_counters);
|
||||
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value, unsigned int
|
||||
*supported_counters);
|
||||
int perf_read_ctr(enum ctr_e ctr, uint64_t *value, unsigned int
|
||||
*supported_counters);
|
||||
int perf_ecc_supported(void);
|
||||
int perf_ctr_state(enum ctr_e ctr);
|
||||
int perf_read_pai_ctr(unsigned int ctrnum, int user, uint64_t *value);
|
||||
|
||||
/* cpacfstats_common.c */
|
||||
|
||||
enum counter_type is_user_space(unsigned int ctr);
|
||||
const char *get_ctr_name(unsigned int ctr);
|
||||
unsigned int get_num_user_space_ctrs(void);
|
||||
|
||||
#endif
|
||||
|
||||
233
cpacfstats/cpacfstats_common.c
Normal file
233
cpacfstats/cpacfstats_common.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* cpacfstats_common.c - shared code by daemon and client
|
||||
*
|
||||
* Copyright IBM Corp. 2024
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "cpacfstats.h"
|
||||
|
||||
struct pai_counter {
|
||||
const char *str;
|
||||
const unsigned int counter_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings for the pai counter details.
|
||||
* Integer indicating if kernel space is needed (0 for user, KERNEL_ONLY_COUNTER for kernel)
|
||||
* Note that this is 0-based while PoP is 1-based.
|
||||
*
|
||||
* When adding new items to this list add the counter number in the pai_idx
|
||||
* list in cpacfstatsd.c and increase the number of total counters in
|
||||
* cpacfstats.h.
|
||||
*/
|
||||
const struct pai_counter pai[] = {
|
||||
[ 0] = {"KM DES", KERNEL_AND_USER_COUNTER},
|
||||
[ 1] = {"KM 2key TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 2] = {"KM TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 3] = {"KM DES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 4] = {"KM 2key TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 5] = {"KM TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 6] = {"KM AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 7] = {"KM AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 8] = {"KM AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 9] = {"KM AES 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 10] = {"KM AES 192bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 11] = {"KM AES 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 12] = {"KM AES-XTS 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 13] = {"KM AES-XTS 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 14] = {"KM AES-XTS 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 15] = {"KM AES-XTS 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 16] = {"KMC DES", KERNEL_AND_USER_COUNTER},
|
||||
[ 17] = {"KMC 2key TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 18] = {"KMC TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 19] = {"KMC DES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 20] = {"KMC 2key TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 21] = {"KMC TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 22] = {"KMC AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 23] = {"KMC AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 24] = {"KMC AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 25] = {"KMC AES 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 26] = {"KMC AES 192bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 27] = {"KMC AES 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 28] = {"KMC PRNG", KERNEL_AND_USER_COUNTER},
|
||||
[ 29] = {"KMA AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 30] = {"KMA AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 31] = {"KMA AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 32] = {"KMA AES 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 33] = {"KMA AES 192bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 34] = {"KMA AES 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 35] = {"KMF DES", KERNEL_AND_USER_COUNTER},
|
||||
[ 36] = {"KMF 2key TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 37] = {"KMF TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 38] = {"KMF DES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 39] = {"KMF 2key TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 40] = {"KMF TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 41] = {"KMF AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 42] = {"KMF AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 43] = {"KMF AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 44] = {"KMF AES 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 45] = {"KMF AES 192bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 46] = {"KMF AES 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 47] = {"KMCTR DES", KERNEL_AND_USER_COUNTER},
|
||||
[ 48] = {"KMCTR 2key TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 49] = {"KMCTR TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 50] = {"KMCTR DES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 51] = {"KMCTR 2key TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 52] = {"KMCTR TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 53] = {"KMCTR AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 54] = {"KMCTR AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 55] = {"KMCTR AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 56] = {"KMCTR AES 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 57] = {"KMCTR AES 192bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 58] = {"KMCTR AES 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 59] = {"KMO DES", KERNEL_AND_USER_COUNTER},
|
||||
[ 60] = {"KMO 2key TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 61] = {"KMO TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 62] = {"KMO DES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 63] = {"KMO 2key TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 64] = {"KMO TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 65] = {"KMO AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 66] = {"KMO AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 67] = {"KMO AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 68] = {"KMO AES 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 69] = {"KMO AES 192bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 70] = {"KMO AES 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 71] = {"KIMD SHA1", KERNEL_AND_USER_COUNTER},
|
||||
[ 72] = {"KIMD SHA256", KERNEL_AND_USER_COUNTER},
|
||||
[ 73] = {"KIMD SHA512", KERNEL_AND_USER_COUNTER},
|
||||
[ 74] = {"KIMD SHA3-224", KERNEL_AND_USER_COUNTER},
|
||||
[ 75] = {"KIMD SHA3-256", KERNEL_AND_USER_COUNTER},
|
||||
[ 76] = {"KIMD SHA3-384", KERNEL_AND_USER_COUNTER},
|
||||
[ 77] = {"KIMD SHA3-512", KERNEL_AND_USER_COUNTER},
|
||||
[ 78] = {"KIMD SHAKE 128", KERNEL_AND_USER_COUNTER},
|
||||
[ 79] = {"KIMD SHAKE 256", KERNEL_AND_USER_COUNTER},
|
||||
[ 80] = {"KIMD GHASH", KERNEL_AND_USER_COUNTER},
|
||||
[ 81] = {"KLMD SHA1", KERNEL_AND_USER_COUNTER},
|
||||
[ 82] = {"KLMD SHA256", KERNEL_AND_USER_COUNTER},
|
||||
[ 83] = {"KLMD SHA512", KERNEL_AND_USER_COUNTER},
|
||||
[ 84] = {"KLMD SHA3-224", KERNEL_AND_USER_COUNTER},
|
||||
[ 85] = {"KLMD SHA3-256", KERNEL_AND_USER_COUNTER},
|
||||
[ 86] = {"KLMD SHA3-384", KERNEL_AND_USER_COUNTER},
|
||||
[ 87] = {"KLMD SHA3-512", KERNEL_AND_USER_COUNTER},
|
||||
[ 88] = {"KLMD SHAKE 128", KERNEL_AND_USER_COUNTER},
|
||||
[ 89] = {"KLMD SHAKE 256", KERNEL_AND_USER_COUNTER},
|
||||
[ 90] = {"KMAC DES", KERNEL_AND_USER_COUNTER},
|
||||
[ 91] = {"KMAC 2key TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 92] = {"KMAC TDES", KERNEL_AND_USER_COUNTER},
|
||||
[ 93] = {"KMAC DES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 94] = {"KMAC 2key TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 95] = {"KMAC TDES protected key", KERNEL_AND_USER_COUNTER},
|
||||
[ 96] = {"KMAC AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 97] = {"KMAC AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 98] = {"KMAC AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[ 99] = {"KMAC AES 128bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[100] = {"KMAC AES 192bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[101] = {"KMAC AES 256bit protected key", KERNEL_AND_USER_COUNTER},
|
||||
[102] = {"PCC Last Block CMAC DES", KERNEL_AND_USER_COUNTER},
|
||||
[103] = {"PCC Last Block CMAC 2key TDES", KERNEL_AND_USER_COUNTER},
|
||||
[104] = {"PCC Last Block CMAC TDES", KERNEL_AND_USER_COUNTER},
|
||||
[105] = {"PCC Last Block CMAC DES protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[106] = {"PCC Last Block CMAC 2key TDES protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[107] = {"PCC Last Block CMAC TDES protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[108] = {"PCC Last Block CMAC AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[109] = {"PCC Last Block CMAC AES 192bit", KERNEL_AND_USER_COUNTER},
|
||||
[110] = {"PCC Last Block CMAC AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[111] = {"PCC Last Block CMAC AES 128bit protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[112] = {"PCC Last Block CMAC AES 192bit protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[113] = {"PCC Last Block CMAC AES 256bit protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[114] = {"PCC XTS Parameter AES 128bit", KERNEL_AND_USER_COUNTER},
|
||||
[115] = {"PCC XTS Parameter AES 256bit", KERNEL_AND_USER_COUNTER},
|
||||
[116] = {"PCC XTS Parameter AES 128bit protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[117] = {"PCC XTS Parameter AES 256bit protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[118] = {"PCC Scalar Mult P256", KERNEL_AND_USER_COUNTER},
|
||||
[119] = {"PCC Scalar Mult P384", KERNEL_AND_USER_COUNTER},
|
||||
[120] = {"PCC Scalar Mult P521", KERNEL_AND_USER_COUNTER},
|
||||
[121] = {"PCC Scalar Mult Ed25519", KERNEL_AND_USER_COUNTER},
|
||||
[122] = {"PCC Scalar Mult Ed448", KERNEL_AND_USER_COUNTER},
|
||||
[123] = {"PCC Scalar Mult X25519", KERNEL_AND_USER_COUNTER},
|
||||
[124] = {"PCC Scalar Mult X448", KERNEL_AND_USER_COUNTER},
|
||||
[125] = {"PRNO SHA512 DRNG", KERNEL_AND_USER_COUNTER},
|
||||
[126] = {"PRNO TRNG Query Ratio", KERNEL_AND_USER_COUNTER},
|
||||
[127] = {"PRNO TRNG", KERNEL_AND_USER_COUNTER},
|
||||
[128] = {"KDSA ECDSA Verify P256", KERNEL_AND_USER_COUNTER},
|
||||
[129] = {"KDSA ECDSA Verify P384", KERNEL_AND_USER_COUNTER},
|
||||
[130] = {"KDSA ECDSA Verify P521", KERNEL_AND_USER_COUNTER},
|
||||
[131] = {"KDSA ECDSA Sign P256", KERNEL_AND_USER_COUNTER},
|
||||
[132] = {"KDSA ECDSA Sign P384", KERNEL_AND_USER_COUNTER},
|
||||
[133] = {"KDSA ECDSA Sign P521", KERNEL_AND_USER_COUNTER},
|
||||
[134] = {"KDSA ECDSA Sign P256 protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[135] = {"KDSA ECDSA Sign P384 protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[136] = {"KDSA ECDSA Sign P521 protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[137] = {"KDSA EdDSA Verify Ed25519", KERNEL_AND_USER_COUNTER},
|
||||
[138] = {"KDSA EdDSA Verify Ed448", KERNEL_AND_USER_COUNTER},
|
||||
[139] = {"KDSA EdDSA Sign Ed25519", KERNEL_AND_USER_COUNTER},
|
||||
[140] = {"KDSA EdDSA Sign Ed448", KERNEL_AND_USER_COUNTER},
|
||||
[141] = {"KDSA EdDSA Sign Ed25519 protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[142] = {"KDSA EdDSA Sign Ed448 protected key",
|
||||
KERNEL_AND_USER_COUNTER},
|
||||
[143] = {"PCKMO DES", KERNEL_ONLY_COUNTER},
|
||||
[144] = {"PCKMO 2key TDES", KERNEL_ONLY_COUNTER},
|
||||
[145] = {"PCKMO TDES", KERNEL_ONLY_COUNTER},
|
||||
[146] = {"PCKMO AES 128bit", KERNEL_ONLY_COUNTER},
|
||||
[147] = {"PCKMO AES 192bit", KERNEL_ONLY_COUNTER},
|
||||
[148] = {"PCKMO AES 256bit", KERNEL_ONLY_COUNTER},
|
||||
[149] = {"PCKMO ECC P256", KERNEL_ONLY_COUNTER},
|
||||
[150] = {"PCKMO ECC P384", KERNEL_ONLY_COUNTER},
|
||||
[151] = {"PCKMO ECC P521", KERNEL_ONLY_COUNTER},
|
||||
[152] = {"PCKMO ECC Ed25519", KERNEL_ONLY_COUNTER},
|
||||
[153] = {"PCKMO ECC Ed448", KERNEL_ONLY_COUNTER},
|
||||
[154] = {"Reserved 1", KERNEL_ONLY_COUNTER},
|
||||
[155] = {"Reserved 2", KERNEL_ONLY_COUNTER}
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns counter_type of pai_counter struct
|
||||
*
|
||||
* SUPPRESS_COUNTER
|
||||
* KERNEL_AND_USER_COUNTER
|
||||
* KERNEL_ONLY_COUNTER
|
||||
*/
|
||||
enum counter_type is_user_space(unsigned int ctr)
|
||||
{
|
||||
if (ctr >= MAX_NUM_PAI)
|
||||
return SUPPRESS_COUNTER;
|
||||
return pai[ctr].counter_type;
|
||||
}
|
||||
|
||||
const char *get_ctr_name(unsigned int ctr)
|
||||
{
|
||||
if (ctr >= MAX_NUM_PAI)
|
||||
return NULL;
|
||||
return pai[ctr].str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns number of PAI counters for which no kernel space is needed
|
||||
*/
|
||||
unsigned int get_num_user_space_ctrs(void)
|
||||
{
|
||||
unsigned int counter = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < MAX_NUM_PAI; i++) {
|
||||
if (is_user_space(i) == KERNEL_AND_USER_COUNTER)
|
||||
counter++;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
@@ -24,12 +24,52 @@
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "cpacfstats.h"
|
||||
|
||||
static volatile int stopsig;
|
||||
|
||||
/*
|
||||
* This list contains the counter numbers sorted by instruction
|
||||
*/
|
||||
static const unsigned int pai_idx[] = {
|
||||
// KM
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
// KMC
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
// KMA
|
||||
29, 30, 31, 32, 33, 34,
|
||||
// KMF
|
||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
|
||||
// KMCTR
|
||||
47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
|
||||
// KMO
|
||||
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
|
||||
// KIMD
|
||||
71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
|
||||
// KLMD
|
||||
81, 82, 83, 84, 85, 86, 87, 88, 89,
|
||||
// KMAC
|
||||
90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
|
||||
// PCC
|
||||
102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
|
||||
114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
|
||||
// PRNO
|
||||
125, 126, 127,
|
||||
// KDSA
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
|
||||
140, 141, 142,
|
||||
// PCKMO
|
||||
143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
|
||||
// Reserved
|
||||
154, 155
|
||||
};
|
||||
|
||||
static const char *const name = "cpacfstatsd";
|
||||
|
||||
static const char *const usage =
|
||||
@@ -93,34 +133,35 @@ static int send_answer(int s, int ctr, int state, uint64_t value)
|
||||
* Note that the PAI counters are 0-based, not 1 based as in PoP!
|
||||
* Sending ends with the first error.
|
||||
*/
|
||||
static int do_send_pai(int s, int user)
|
||||
static int do_send_pai(int s, int user, unsigned int *counter)
|
||||
{
|
||||
int ctr, state, i, maxctr, rc = 0;
|
||||
int ctr, state, i, rc = 0;
|
||||
unsigned int current_ctr;
|
||||
uint64_t value;
|
||||
|
||||
if (user) {
|
||||
ctr = PAI_USER;
|
||||
maxctr = NUM_PAI_USER;
|
||||
} else {
|
||||
ctr = PAI_KERNEL;
|
||||
maxctr = NUM_PAI_KERNEL;
|
||||
}
|
||||
ctr = user ? PAI_USER : PAI_KERNEL;
|
||||
|
||||
state = perf_ctr_state(ctr);
|
||||
if (state != ENABLED)
|
||||
return rc;
|
||||
for (i = 0; i < maxctr; ++i) {
|
||||
rc = perf_read_pai_ctr(i, user, &value);
|
||||
for (i = 0; i < MAX_NUM_PAI; ++i) {
|
||||
current_ctr = pai_idx[i];
|
||||
if ((user && is_user_space(current_ctr) != KERNEL_AND_USER_COUNTER) ||
|
||||
(!user && is_user_space(current_ctr) == SUPPRESS_COUNTER) ||
|
||||
counter[current_ctr] != 1)
|
||||
continue;
|
||||
rc = perf_read_pai_ctr(current_ctr, user, &value);
|
||||
if (rc != 0) {
|
||||
send_answer(s, i, rc, 0);
|
||||
send_answer(s, current_ctr, rc, 0);
|
||||
break;
|
||||
}
|
||||
send_answer(s, i, state, value);
|
||||
send_answer(s, current_ctr, state, value);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int do_enable(int s, enum ctr_e ctr)
|
||||
static int do_enable(int s, enum ctr_e ctr, unsigned int *supported_counters)
|
||||
{
|
||||
uint64_t value = 0;
|
||||
int i, rc = 0;
|
||||
@@ -132,7 +173,7 @@ static int do_enable(int s, enum ctr_e ctr)
|
||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||
state = perf_ctr_state(i);
|
||||
if (state == DISABLED) {
|
||||
rc = perf_enable_ctr(i);
|
||||
rc = perf_enable_ctr(i, supported_counters);
|
||||
if (rc != 0) {
|
||||
send_answer(s, i, rc, 0);
|
||||
break;
|
||||
@@ -140,7 +181,7 @@ static int do_enable(int s, enum ctr_e ctr)
|
||||
state = ENABLED;
|
||||
}
|
||||
if (state != UNSUPPORTED) {
|
||||
rc = perf_read_ctr(i, &value);
|
||||
rc = perf_read_ctr(i, &value, supported_counters);
|
||||
if (rc != 0) {
|
||||
send_answer(s, i, rc, 0);
|
||||
break;
|
||||
@@ -148,20 +189,20 @@ static int do_enable(int s, enum ctr_e ctr)
|
||||
}
|
||||
send_answer(s, i, state, value);
|
||||
if (i == PAI_USER)
|
||||
rc = do_send_pai(s, 1);
|
||||
rc = do_send_pai(s, 1, supported_counters);
|
||||
if (i == PAI_KERNEL)
|
||||
rc = do_send_pai(s, 0);
|
||||
rc = do_send_pai(s, 0, supported_counters);
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value, NULL);
|
||||
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int do_disable(int s, enum ctr_e ctr)
|
||||
static int do_disable(int s, enum ctr_e ctr, unsigned int *supported_counters)
|
||||
{
|
||||
int i, rc = 0;
|
||||
uint64_t value;
|
||||
@@ -171,7 +212,7 @@ static int do_disable(int s, enum ctr_e ctr)
|
||||
continue;
|
||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||
if (perf_ctr_state(i) == ENABLED) {
|
||||
rc = perf_disable_ctr(i);
|
||||
rc = perf_disable_ctr(i, supported_counters);
|
||||
if (rc != 0) {
|
||||
send_answer(s, i, rc, 0);
|
||||
break;
|
||||
@@ -181,14 +222,14 @@ static int do_disable(int s, enum ctr_e ctr)
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value, NULL);
|
||||
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int do_reset(int s, enum ctr_e ctr)
|
||||
static int do_reset(int s, enum ctr_e ctr, unsigned int *supported_counters)
|
||||
{
|
||||
int i, rc = 0, state;
|
||||
uint64_t value;
|
||||
@@ -199,7 +240,7 @@ static int do_reset(int s, enum ctr_e ctr)
|
||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||
state = perf_ctr_state(i);
|
||||
if (state == ENABLED) {
|
||||
rc = perf_reset_ctr(i, &value);
|
||||
rc = perf_reset_ctr(i, &value, supported_counters);
|
||||
if (rc != 0) {
|
||||
send_answer(s, i, rc, 0);
|
||||
break;
|
||||
@@ -207,20 +248,20 @@ static int do_reset(int s, enum ctr_e ctr)
|
||||
}
|
||||
send_answer(s, i, state, value);
|
||||
if (i == PAI_USER)
|
||||
rc = do_send_pai(s, 1);
|
||||
rc = do_send_pai(s, 1, supported_counters);
|
||||
if (i == PAI_KERNEL)
|
||||
rc = do_send_pai(s, 0);
|
||||
rc = do_send_pai(s, 0, supported_counters);
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value, NULL);
|
||||
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int do_print(int s, enum ctr_e ctr)
|
||||
static int do_print(int s, enum ctr_e ctr, unsigned int *supported_counters)
|
||||
{
|
||||
int i, rc = 0, state;
|
||||
uint64_t value = 0;
|
||||
@@ -231,7 +272,7 @@ static int do_print(int s, enum ctr_e ctr)
|
||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||
state = perf_ctr_state(i);
|
||||
if (state == ENABLED) {
|
||||
rc = perf_read_ctr(i, &value);
|
||||
rc = perf_read_ctr(i, &value, supported_counters);
|
||||
if (rc != 0) {
|
||||
send_answer(s, i, rc, 0);
|
||||
break;
|
||||
@@ -239,13 +280,13 @@ static int do_print(int s, enum ctr_e ctr)
|
||||
}
|
||||
send_answer(s, i, state, value);
|
||||
if (i == PAI_USER)
|
||||
rc = do_send_pai(s, 1);
|
||||
rc = do_send_pai(s, 1, supported_counters);
|
||||
if (i == PAI_KERNEL)
|
||||
rc = do_send_pai(s, 0);
|
||||
rc = do_send_pai(s, 0, supported_counters);
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||
rc = perf_read_ctr(HOTPLUG_DETECTED, &value, NULL);
|
||||
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||
}
|
||||
return rc;
|
||||
@@ -436,9 +477,44 @@ int eprint(const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns -1 on error
|
||||
* returns X where X is the found counters in dir
|
||||
*
|
||||
* the supplied array supported_counters[] is filled in this function with the
|
||||
* available PAI counters found in SYSFS_PAI_COUNTER
|
||||
*/
|
||||
static void supported_functions(unsigned int supported_counters[])
|
||||
{
|
||||
const char *dir = SYSFS_PAI_COUNTER;
|
||||
struct dirent *dp = NULL;
|
||||
char filepath[PATH_MAX];
|
||||
unsigned int num;
|
||||
DIR *dfd = NULL;
|
||||
|
||||
dfd = opendir(dir);
|
||||
if (dfd == NULL)
|
||||
return;
|
||||
|
||||
while ((dp = readdir(dfd)) != NULL) {
|
||||
if ((strcmp(dp->d_name, ".") != 0) &&
|
||||
(strcmp(dp->d_name, "..") != 0)) {
|
||||
snprintf(filepath, sizeof(filepath), "%s%s", dir, dp->d_name);
|
||||
if (util_file_read_va(filepath, "event=0x10%x", &num) != 1)
|
||||
continue;
|
||||
if (num > 0 && num <= MAX_NUM_PAI)
|
||||
supported_counters[num - 1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dfd);
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, sfd, foreground = 0, startup_pipe = -1, initialized = 0;
|
||||
unsigned int supported_counters[MAX_NUM_PAI] = { 0 };
|
||||
struct sigaction act;
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -485,7 +561,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (perf_init() != 0) {
|
||||
supported_functions(supported_counters);
|
||||
|
||||
if (perf_init(supported_counters) != 0) {
|
||||
eprint("Couldn't initialize perf lib\n");
|
||||
goto error;
|
||||
}
|
||||
@@ -548,13 +626,13 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (cmd == ENABLE)
|
||||
rc = do_enable(s, ctr);
|
||||
rc = do_enable(s, ctr, supported_counters);
|
||||
else if (cmd == DISABLE)
|
||||
rc = do_disable(s, ctr);
|
||||
rc = do_disable(s, ctr, supported_counters);
|
||||
else if (cmd == RESET)
|
||||
rc = do_reset(s, ctr);
|
||||
rc = do_reset(s, ctr, supported_counters);
|
||||
else if (cmd == PRINT)
|
||||
rc = do_print(s, ctr);
|
||||
rc = do_print(s, ctr, supported_counters);
|
||||
else {
|
||||
eprint("Received unknown command %d, ignoring\n",
|
||||
(int) cmd);
|
||||
|
||||
@@ -52,8 +52,8 @@ static struct pmf_data {
|
||||
|
||||
struct percpucounter {
|
||||
int ctr_fds[ALL_COUNTER];
|
||||
int pai_user[NUM_PAI_USER];
|
||||
int pai_kernel[NUM_PAI_KERNEL];
|
||||
int pai_user[MAX_NUM_PAI];
|
||||
int pai_kernel[MAX_NUM_PAI];
|
||||
unsigned int cpunum;
|
||||
struct percpucounter *next;
|
||||
};
|
||||
@@ -84,10 +84,10 @@ static struct percpucounter *allocpercpucounter(unsigned int cpunum)
|
||||
|
||||
for (i = 0; i < ALL_COUNTER; ++i)
|
||||
ppc->ctr_fds[i] = -1;
|
||||
for (i = 0; i < NUM_PAI_USER; ++i)
|
||||
for (i = 0; i < MAX_NUM_PAI; ++i) {
|
||||
ppc->pai_user[i] = -1;
|
||||
for (i = 0; i < NUM_PAI_KERNEL; ++i)
|
||||
ppc->pai_kernel[i] = -1;
|
||||
}
|
||||
ppc->cpunum = cpunum;
|
||||
ppc->next = NULL;
|
||||
}
|
||||
@@ -100,10 +100,10 @@ static void freepercpucounter(struct percpucounter *pcpu)
|
||||
|
||||
for (i = 0; i < ALL_COUNTER; ++i)
|
||||
(void)close(pcpu->ctr_fds[i]);
|
||||
for (i = 0; i < NUM_PAI_USER; ++i)
|
||||
for (i = 0; i < MAX_NUM_PAI; ++i) {
|
||||
(void)close(pcpu->pai_user[i]);
|
||||
for (i = 0; i < NUM_PAI_KERNEL; ++i)
|
||||
(void)close(pcpu->pai_kernel[i]);
|
||||
}
|
||||
free(pcpu);
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ static int perf_event_encode(int *pmutype, int *eventid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int activatecpu(unsigned int cpu)
|
||||
static int activatecpu(unsigned int cpu, unsigned int *supported_counters)
|
||||
{
|
||||
struct perf_event_attr pfm_event;
|
||||
struct percpucounter *ppc;
|
||||
@@ -273,7 +273,10 @@ static int activatecpu(unsigned int cpu)
|
||||
(ctr_state[PAI_USER] == UNSUPPORTED) ==
|
||||
(ctr_state[PAI_KERNEL] == UNSUPPORTED) */
|
||||
if (ctr_state[PAI_USER] != UNSUPPORTED) {
|
||||
for (i = 1; i <= NUM_PAI_USER; ++i) {
|
||||
for (i = 1; i <= MAX_NUM_PAI; ++i) {
|
||||
if (is_user_space(i - 1) != KERNEL_AND_USER_COUNTER ||
|
||||
supported_counters[i - 1] != 1)
|
||||
continue;
|
||||
memset(&pfm_event, 0, sizeof(pfm_event));
|
||||
pfm_event.size = sizeof(pfm_event);
|
||||
pfm_event.type = paipmutype;
|
||||
@@ -307,7 +310,14 @@ static int activatecpu(unsigned int cpu)
|
||||
ppc->pai_kernel[i - 1] = fd;
|
||||
}
|
||||
}
|
||||
for (; i <= NUM_PAI_KERNEL; ++i) {
|
||||
/*
|
||||
* i can start at the index of the first PAI counter
|
||||
* for which kernel space is needed
|
||||
*/
|
||||
for (i = FIRST_KERNEL_ONLY_COUNTER; i <= MAX_NUM_PAI; ++i) {
|
||||
if (is_user_space(i - 1) == SUPPRESS_COUNTER ||
|
||||
supported_counters[i - 1] != 1)
|
||||
continue;
|
||||
memset(&pfm_event, 0, sizeof(pfm_event));
|
||||
pfm_event.size = sizeof(pfm_event);
|
||||
pfm_event.type = paipmutype;
|
||||
@@ -348,10 +358,10 @@ static void deactivatecpu(unsigned int cpunum)
|
||||
if (pcpu != NULL) {
|
||||
for (i = 0; i < ALL_COUNTER; ++i)
|
||||
(void)close(pcpu->ctr_fds[i]);
|
||||
for (i = 0; i < NUM_PAI_USER; ++i)
|
||||
for (i = 0; i < MAX_NUM_PAI; ++i) {
|
||||
(void)close(pcpu->pai_user[i]);
|
||||
for (i = 0; i < NUM_PAI_KERNEL; ++i)
|
||||
(void)close(pcpu->pai_kernel[i]);
|
||||
}
|
||||
free(pcpu);
|
||||
if (enabledcounter)
|
||||
hotplugdetected = 1;
|
||||
@@ -359,7 +369,7 @@ static void deactivatecpu(unsigned int cpunum)
|
||||
pthread_mutex_unlock(&rootmux);
|
||||
}
|
||||
|
||||
static int addallcpus(void)
|
||||
static int addallcpus(unsigned int *supported_counters)
|
||||
{
|
||||
unsigned int start, end;
|
||||
int scanned, rc = 0;
|
||||
@@ -379,7 +389,7 @@ static int addallcpus(void)
|
||||
if (scanned == 1)
|
||||
end = start;
|
||||
for (; start <= end; ++start) {
|
||||
if (activatecpu(start)) {
|
||||
if (activatecpu(start, supported_counters)) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -409,7 +419,7 @@ static int perf_load_counter_data(void)
|
||||
return res;
|
||||
}
|
||||
|
||||
static void *hotplughandler(void *UNUSED(unused))
|
||||
static void *hotplughandler(void *supported_counters)
|
||||
{
|
||||
struct udev *hotplug;
|
||||
struct udev_monitor *monitor;
|
||||
@@ -452,7 +462,7 @@ static void *hotplughandler(void *UNUSED(unused))
|
||||
path = udev_device_get_devpath(dev);
|
||||
if (sscanf(path, "/devices/system/cpu/cpu%u", &cpunum) != 1)
|
||||
continue;
|
||||
if (on && activatecpu(cpunum))
|
||||
if (on && activatecpu(cpunum, (unsigned int *) supported_counters))
|
||||
eprint("Failed to attach to hotplugged CPU %u\n", cpunum);
|
||||
if (off)
|
||||
deactivatecpu(cpunum);
|
||||
@@ -462,11 +472,18 @@ static void *hotplughandler(void *UNUSED(unused))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int perf_init(void)
|
||||
int perf_init(unsigned int *supported_counters)
|
||||
{
|
||||
int ecc_supported, i, num;
|
||||
static const char *cpum_cf[] = {
|
||||
"DEA_FUNCTIONS",
|
||||
"AES_FUNCTIONS",
|
||||
"SHA_FUNCTIONS",
|
||||
"PRNG_FUNCTIONS",
|
||||
"ECC_FUNCTION_COUNT"
|
||||
};
|
||||
unsigned long maxfd;
|
||||
struct rlimit rlim;
|
||||
int i, num;
|
||||
FILE *f;
|
||||
|
||||
/* initialize performance monitoring library */
|
||||
@@ -478,16 +495,18 @@ int perf_init(void)
|
||||
/* We currently support all cpumf counters plus two virtual
|
||||
* counters for PAI. */
|
||||
num = ALL_COUNTER + 2;
|
||||
/* Check if ECC is supported on current hardware */
|
||||
ecc_supported = perf_counter_supported("cpum_cf", "ECC_FUNCTION_COUNT");
|
||||
|
||||
if (!cpumf_authorized()) {
|
||||
for (i = 0; i < ALL_COUNTER; ++i)
|
||||
ctr_state[i] = UNSUPPORTED;
|
||||
num -= ALL_COUNTER;
|
||||
} else if (!ecc_supported) {
|
||||
ctr_state[ECC_FUNCTIONS] = UNSUPPORTED;
|
||||
--num;
|
||||
} else {
|
||||
for (i = 0; i < ALL_COUNTER; i++) {
|
||||
if (!perf_counter_supported("cpum_cf", cpum_cf[i])) {
|
||||
ctr_state[i] = UNSUPPORTED;
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!perf_counter_supported("pai_crypto", "CRYPTO_ALL")) {
|
||||
@@ -523,11 +542,12 @@ int perf_init(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pthread_create(&hotplugthread, NULL, hotplughandler, NULL)) {
|
||||
if (pthread_create(&hotplugthread, NULL, hotplughandler,
|
||||
supported_counters)) {
|
||||
eprint("Failed to start hotplug handler thread\n");
|
||||
return -1;
|
||||
}
|
||||
return addallcpus();
|
||||
return addallcpus(supported_counters);
|
||||
}
|
||||
|
||||
|
||||
@@ -552,11 +572,14 @@ void perf_close(void)
|
||||
}
|
||||
|
||||
|
||||
static int enable_array(int *arr, int size)
|
||||
static int enable_array(int *arr, int user, unsigned int *supported_counters)
|
||||
{
|
||||
int i, ec, rc = 0;
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
for (i = 0; i < MAX_NUM_PAI; ++i) {
|
||||
if ((user && is_user_space(i) != KERNEL_AND_USER_COUNTER) ||
|
||||
supported_counters[i] != 1 || is_user_space(i) == SUPPRESS_COUNTER)
|
||||
continue;
|
||||
ec = ioctl(arr[i], PERF_EVENT_IOC_ENABLE, 0);
|
||||
if (ec < 0) {
|
||||
eprint("Ioctl(PERF_EVENT_IOC_ENABLE) failed with errno=%d [%s]\n",
|
||||
@@ -568,14 +591,14 @@ static int enable_array(int *arr, int size)
|
||||
}
|
||||
|
||||
|
||||
int perf_enable_ctr(enum ctr_e ctr)
|
||||
int perf_enable_ctr(enum ctr_e ctr, unsigned int *supported_counters)
|
||||
{
|
||||
struct percpucounter *pcpu;
|
||||
int ec, rc = 0;
|
||||
|
||||
if (ctr == ALL_COUNTER) {
|
||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
||||
rc = perf_enable_ctr(ctr);
|
||||
rc = perf_enable_ctr(ctr, supported_counters);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
@@ -593,7 +616,7 @@ int perf_enable_ctr(enum ctr_e ctr)
|
||||
endforeachcpu();
|
||||
} else if (ctr == PAI_USER) {
|
||||
foreachcpu(pcpu) {
|
||||
ec = enable_array(pcpu->pai_user, NUM_PAI_USER);
|
||||
ec = enable_array(pcpu->pai_user, 1, supported_counters);
|
||||
if (ec < 0)
|
||||
rc = -1;
|
||||
}
|
||||
@@ -602,7 +625,7 @@ int perf_enable_ctr(enum ctr_e ctr)
|
||||
endforeachcpu();
|
||||
} else if (ctr == PAI_KERNEL) {
|
||||
foreachcpu(pcpu) {
|
||||
ec = enable_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
|
||||
ec = enable_array(pcpu->pai_kernel, 0, supported_counters);
|
||||
if (ec < 0)
|
||||
rc = -1;
|
||||
}
|
||||
@@ -617,11 +640,14 @@ int perf_enable_ctr(enum ctr_e ctr)
|
||||
}
|
||||
|
||||
|
||||
static int disable_array(int *arr, int size)
|
||||
static int disable_array(int *arr, int user, unsigned int *supported_counters)
|
||||
{
|
||||
int i, ec, rc = 0;
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
for (i = 0; i < MAX_NUM_PAI; ++i) {
|
||||
if ((user && is_user_space(i) != KERNEL_AND_USER_COUNTER) ||
|
||||
supported_counters[i] != 1 || is_user_space(i) == SUPPRESS_COUNTER)
|
||||
continue;
|
||||
ec = ioctl(arr[i], PERF_EVENT_IOC_DISABLE, 0);
|
||||
if (ec < 0) {
|
||||
eprint("Ioctl(PERF_EVENT_IOC_DISABLE) failed with errno=%d [%s]\n",
|
||||
@@ -633,14 +659,14 @@ static int disable_array(int *arr, int size)
|
||||
}
|
||||
|
||||
|
||||
int perf_disable_ctr(enum ctr_e ctr)
|
||||
int perf_disable_ctr(enum ctr_e ctr, unsigned int *supported_counters)
|
||||
{
|
||||
struct percpucounter *pcpu;
|
||||
int ec, rc = 0;
|
||||
|
||||
if (ctr == ALL_COUNTER) {
|
||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
||||
rc = perf_disable_ctr(ctr);
|
||||
rc = perf_disable_ctr(ctr, supported_counters);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
@@ -660,7 +686,7 @@ int perf_disable_ctr(enum ctr_e ctr)
|
||||
endforeachcpu();
|
||||
} else if (ctr == PAI_USER) {
|
||||
foreachcpu(pcpu) {
|
||||
ec = disable_array(pcpu->pai_user, NUM_PAI_USER);
|
||||
ec = disable_array(pcpu->pai_user, 1, supported_counters);
|
||||
if (ec < 0)
|
||||
rc = -1;
|
||||
}
|
||||
@@ -671,7 +697,7 @@ int perf_disable_ctr(enum ctr_e ctr)
|
||||
endforeachcpu();
|
||||
} else if (ctr == PAI_KERNEL) {
|
||||
foreachcpu(pcpu) {
|
||||
ec = disable_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
|
||||
ec = disable_array(pcpu->pai_kernel, 0, supported_counters);
|
||||
if (ec < 0)
|
||||
rc = -1;
|
||||
}
|
||||
@@ -688,11 +714,14 @@ int perf_disable_ctr(enum ctr_e ctr)
|
||||
}
|
||||
|
||||
|
||||
static int reset_array(int *arr, int size)
|
||||
static int reset_array(int *arr, int user, unsigned int *supported_counters)
|
||||
{
|
||||
int ec, rc = 0, i;
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
for (i = 0; i < MAX_NUM_PAI; ++i) {
|
||||
if ((user && is_user_space(i) != KERNEL_AND_USER_COUNTER) ||
|
||||
supported_counters[i] != 1 || is_user_space(i) == SUPPRESS_COUNTER)
|
||||
continue;
|
||||
ec = ioctl(arr[i], PERF_EVENT_IOC_RESET, 0);
|
||||
if (ec < 0) {
|
||||
eprint("Ioctl(PERF_EVENT_IOC_RESET) failed with errno=%d [%s]\n",
|
||||
@@ -704,14 +733,15 @@ static int reset_array(int *arr, int size)
|
||||
}
|
||||
|
||||
|
||||
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value)
|
||||
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value, unsigned int
|
||||
*supported_counters)
|
||||
{
|
||||
struct percpucounter *pcpu;
|
||||
int ec, rc = 0;
|
||||
|
||||
if (ctr == ALL_COUNTER) {
|
||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
||||
rc = perf_reset_ctr(ctr, value);
|
||||
rc = perf_reset_ctr(ctr, value, supported_counters);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
@@ -727,14 +757,14 @@ int perf_reset_ctr(enum ctr_e ctr, uint64_t *value)
|
||||
endforeachcpu();
|
||||
} else if (ctr == PAI_USER) {
|
||||
foreachcpu(pcpu) {
|
||||
ec = reset_array(pcpu->pai_user, NUM_PAI_USER);
|
||||
ec = reset_array(pcpu->pai_user, 1, supported_counters);
|
||||
if (ec < 0)
|
||||
rc = -1;
|
||||
}
|
||||
endforeachcpu();
|
||||
} else if (ctr == PAI_KERNEL) {
|
||||
foreachcpu(pcpu) {
|
||||
ec = reset_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
|
||||
ec = reset_array(pcpu->pai_kernel, 0, supported_counters);
|
||||
if (ec < 0)
|
||||
rc = -1;
|
||||
}
|
||||
@@ -743,12 +773,13 @@ int perf_reset_ctr(enum ctr_e ctr, uint64_t *value)
|
||||
rc = -1;
|
||||
}
|
||||
if (rc == 0)
|
||||
rc = perf_read_ctr(ctr, value);
|
||||
rc = perf_read_ctr(ctr, value, supported_counters);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int perf_read_ctr(enum ctr_e ctr, uint64_t *value)
|
||||
int perf_read_ctr(enum ctr_e ctr, uint64_t *value, unsigned int
|
||||
*supported_counters)
|
||||
{
|
||||
struct percpucounter *pcpu;
|
||||
int ec, rc = 0;
|
||||
@@ -761,11 +792,26 @@ int perf_read_ctr(enum ctr_e ctr, uint64_t *value)
|
||||
return 0;
|
||||
}
|
||||
if (ctr == PAI_USER) {
|
||||
*value = NUM_PAI_USER;
|
||||
int c = 0;
|
||||
|
||||
for (int i = 0; i < MAX_NUM_PAI; i++) {
|
||||
if (is_user_space(i) == KERNEL_AND_USER_COUNTER &&
|
||||
supported_counters[i] == 1)
|
||||
c++;
|
||||
}
|
||||
|
||||
*value = c;
|
||||
return 0;
|
||||
}
|
||||
if (ctr == PAI_KERNEL) {
|
||||
*value = NUM_PAI_KERNEL;
|
||||
int c = 0;
|
||||
|
||||
for (int i = 0; i < MAX_NUM_PAI; i++) {
|
||||
if (supported_counters[i] == 1)
|
||||
c++;
|
||||
}
|
||||
|
||||
*value = c;
|
||||
return 0;
|
||||
}
|
||||
if (ctr >= ALL_COUNTER)
|
||||
@@ -802,14 +848,15 @@ int perf_ctr_state(enum ctr_e ctr) {
|
||||
int perf_read_pai_ctr(unsigned int ctrnum, int user, uint64_t *value)
|
||||
{
|
||||
struct percpucounter *pcpu;
|
||||
unsigned int maxctr;
|
||||
int *arr, ec, rc = 0;
|
||||
uint64_t val;
|
||||
|
||||
*value = 0;
|
||||
maxctr = user ? NUM_PAI_USER : NUM_PAI_KERNEL;
|
||||
if (ctrnum >= maxctr)
|
||||
|
||||
if (is_user_space(ctrnum) == SUPPRESS_COUNTER ||
|
||||
(user && is_user_space(ctrnum) == KERNEL_ONLY_COUNTER))
|
||||
return -1;
|
||||
|
||||
foreachcpu(pcpu) {
|
||||
arr = user ? pcpu->pai_user : pcpu->pai_kernel;
|
||||
ec = read(arr[ctrnum], &val, sizeof(val));
|
||||
|
||||
Reference in New Issue
Block a user