mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 21:35:07 +00:00
tools/arch/x86: intel_sdsi: Add support for reading meter certificates
Add option to read and decode On Demand meter certificates. Link: https://github.com/intel/intel-sdsi/blob/master/meter-certificate.rst Signed-off-by: David E. Box <david.e.box@linux.intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20221119002343.1281885-10-david.e.box@linux.intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
429e789c67
commit
7fdc03a737
@ -40,8 +40,10 @@
|
||||
#define GUID_V2 0xF210D9EF
|
||||
#define REGS_SIZE_GUID_V2 80
|
||||
#define STATE_CERT_MAX_SIZE 4096
|
||||
#define METER_CERT_MAX_SIZE 4096
|
||||
#define STATE_MAX_NUM_LICENSES 16
|
||||
#define STATE_MAX_NUM_IN_BUNDLE (uint32_t)8
|
||||
#define METER_MAX_NUM_BUNDLES 8
|
||||
|
||||
#define __round_mask(x, y) ((__typeof__(x))((y) - 1))
|
||||
#define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1)
|
||||
@ -151,6 +153,21 @@ struct bundle_encoding {
|
||||
uint32_t encoding_rsvd[7];
|
||||
};
|
||||
|
||||
struct meter_certificate {
|
||||
uint32_t block_signature;
|
||||
uint32_t counter_unit;
|
||||
uint64_t ppin;
|
||||
uint32_t bundle_length;
|
||||
uint32_t reserved;
|
||||
uint32_t mmrc_encoding;
|
||||
uint32_t mmrc_counter;
|
||||
};
|
||||
|
||||
struct bundle_encoding_counter {
|
||||
uint32_t encoding;
|
||||
uint32_t counter;
|
||||
};
|
||||
|
||||
struct sdsi_dev {
|
||||
struct sdsi_regs regs;
|
||||
struct state_certificate sc;
|
||||
@ -161,6 +178,7 @@ struct sdsi_dev {
|
||||
|
||||
enum command {
|
||||
CMD_SOCKET_INFO,
|
||||
CMD_METER_CERT,
|
||||
CMD_STATE_CERT,
|
||||
CMD_PROV_AKC,
|
||||
CMD_PROV_CAP,
|
||||
@ -308,6 +326,86 @@ static void get_feature(uint32_t encoding, char *feature)
|
||||
feature[0] = name[3];
|
||||
}
|
||||
|
||||
static int sdsi_meter_cert_show(struct sdsi_dev *s)
|
||||
{
|
||||
char buf[METER_CERT_MAX_SIZE] = {0};
|
||||
struct bundle_encoding_counter *bec;
|
||||
struct meter_certificate *mc;
|
||||
uint32_t count = 0;
|
||||
FILE *cert_ptr;
|
||||
int ret, size;
|
||||
|
||||
ret = sdsi_update_registers(s);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!s->regs.en_features.sdsi) {
|
||||
fprintf(stderr, "SDSi feature is present but not enabled.\n");
|
||||
fprintf(stderr, " Unable to read meter certificate\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!s->regs.en_features.metering) {
|
||||
fprintf(stderr, "Metering not supporting on this socket.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = chdir(s->dev_path);
|
||||
if (ret == -1) {
|
||||
perror("chdir");
|
||||
return ret;
|
||||
}
|
||||
|
||||
cert_ptr = fopen("meter_certificate", "r");
|
||||
if (!cert_ptr) {
|
||||
perror("Could not open 'meter_certificate' file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
size = fread(buf, 1, sizeof(buf), cert_ptr);
|
||||
if (!size) {
|
||||
fprintf(stderr, "Could not read 'meter_certificate' file\n");
|
||||
fclose(cert_ptr);
|
||||
return -1;
|
||||
}
|
||||
fclose(cert_ptr);
|
||||
|
||||
mc = (struct meter_certificate *)buf;
|
||||
|
||||
printf("\n");
|
||||
printf("Meter certificate for device %s\n", s->dev_name);
|
||||
printf("\n");
|
||||
printf("Block Signature: 0x%x\n", mc->block_signature);
|
||||
printf("Count Unit: %dms\n", mc->counter_unit);
|
||||
printf("PPIN: 0x%lx\n", mc->ppin);
|
||||
printf("Feature Bundle Length: %d\n", mc->bundle_length);
|
||||
printf("MMRC encoding: %d\n", mc->mmrc_encoding);
|
||||
printf("MMRC counter: %d\n", mc->mmrc_counter);
|
||||
if (mc->bundle_length % 8) {
|
||||
fprintf(stderr, "Invalid bundle length\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mc->bundle_length > METER_MAX_NUM_BUNDLES * 8) {
|
||||
fprintf(stderr, "More than %d bundles: %d\n",
|
||||
METER_MAX_NUM_BUNDLES, mc->bundle_length / 8);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bec = (void *)(mc) + sizeof(mc);
|
||||
|
||||
printf("Number of Feature Counters: %d\n", mc->bundle_length / 8);
|
||||
while (count++ < mc->bundle_length / 8) {
|
||||
char feature[5];
|
||||
|
||||
feature[4] = '\0';
|
||||
get_feature(bec[count].encoding, feature);
|
||||
printf(" %s: %d\n", feature, bec[count].counter);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdsi_state_cert_show(struct sdsi_dev *s)
|
||||
{
|
||||
char buf[STATE_CERT_MAX_SIZE] = {0};
|
||||
@ -627,7 +725,7 @@ static void sdsi_free_dev(struct sdsi_dev *s)
|
||||
|
||||
static void usage(char *prog)
|
||||
{
|
||||
printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-a FILE] [-c FILE]]\n", prog);
|
||||
printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-m] [-a FILE] [-c FILE]]\n", prog);
|
||||
}
|
||||
|
||||
static void show_help(void)
|
||||
@ -637,6 +735,7 @@ static void show_help(void)
|
||||
printf(" %-18s\t%s\n", "-d, --devno DEVNO", "On Demand device number");
|
||||
printf(" %-18s\t%s\n", "-i, --info", "show socket information");
|
||||
printf(" %-18s\t%s\n", "-s, --state", "show state certificate");
|
||||
printf(" %-18s\t%s\n", "-m, --meter", "show meter certificate");
|
||||
printf(" %-18s\t%s\n", "-a, --akc FILE", "provision socket with AKC FILE");
|
||||
printf(" %-18s\t%s\n", "-c, --cap FILE>", "provision socket with CAP FILE");
|
||||
}
|
||||
@ -658,6 +757,7 @@ int main(int argc, char *argv[])
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"info", no_argument, 0, 'i'},
|
||||
{"list", no_argument, 0, 'l'},
|
||||
{"meter", no_argument, 0, 'm'},
|
||||
{"state", no_argument, 0, 's'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
@ -665,7 +765,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
while ((opt = getopt_long_only(argc, argv, "+a:c:d:hils", long_options,
|
||||
while ((opt = getopt_long_only(argc, argv, "+a:c:d:hilms", long_options,
|
||||
&option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
@ -678,6 +778,9 @@ int main(int argc, char *argv[])
|
||||
case 'i':
|
||||
command = CMD_SOCKET_INFO;
|
||||
break;
|
||||
case 'm':
|
||||
command = CMD_METER_CERT;
|
||||
break;
|
||||
case 's':
|
||||
command = CMD_STATE_CERT;
|
||||
break;
|
||||
@ -715,6 +818,9 @@ int main(int argc, char *argv[])
|
||||
case CMD_SOCKET_INFO:
|
||||
ret = sdsi_read_reg(s);
|
||||
break;
|
||||
case CMD_METER_CERT:
|
||||
ret = sdsi_meter_cert_show(s);
|
||||
break;
|
||||
case CMD_STATE_CERT:
|
||||
ret = sdsi_state_cert_show(s);
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user