Commit 2e424c33 authored by Mario Limonciello's avatar Mario Limonciello Committed by Herbert Xu

crypto: ccp - Add support for displaying PSP firmware versions

As it's not always obvious what PSP bootloader or TEE version are
present in OEM systems, add the ability to get this information from
sysfs for supported platforms.
Acked-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent b5827637
......@@ -85,3 +85,21 @@ Description:
Possible values:
0: Not enforced
1: Enforced
What: /sys/bus/pci/devices/<BDF>/bootloader_version
Date: June 2023
KernelVersion: 6.4
Contact: mario.limonciello@amd.com
Description:
The /sys/bus/pci/devices/<BDF>/bootloader_version
file reports the firmware version of the AMD AGESA
bootloader.
What: /sys/bus/pci/devices/<BDF>/tee_version
Date: June 2023
KernelVersion: 6.4
Contact: mario.limonciello@amd.com
Description:
The /sys/bus/pci/devices/<BDF>/tee_version
file reports the firmware version of the AMD Trusted
Execution Environment (TEE).
......@@ -51,6 +51,7 @@ struct tee_vdata {
const unsigned int cmdbuff_addr_hi_reg;
const unsigned int ring_wptr_reg;
const unsigned int ring_rptr_reg;
const unsigned int info_reg;
};
struct platform_access_vdata {
......@@ -69,6 +70,7 @@ struct psp_vdata {
const unsigned int feature_reg;
const unsigned int inten_reg;
const unsigned int intsts_reg;
const unsigned int bootloader_info_reg;
};
/* Structure to hold SP device data */
......
......@@ -8,6 +8,7 @@
* Author: Gary R Hook <gary.hook@amd.com>
*/
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
......@@ -24,6 +25,12 @@
#include "ccp-dev.h"
#include "psp-dev.h"
/* used for version string AA.BB.CC.DD */
#define AA GENMASK(31, 24)
#define BB GENMASK(23, 16)
#define CC GENMASK(15, 8)
#define DD GENMASK(7, 0)
#define MSIX_VECTORS 2
struct sp_pci {
......@@ -88,8 +95,65 @@ static struct attribute_group psp_security_attr_group = {
.is_visible = psp_security_is_visible,
};
#define version_attribute_show(name, _offset) \
static ssize_t name##_show(struct device *d, struct device_attribute *attr, \
char *buf) \
{ \
struct sp_device *sp = dev_get_drvdata(d); \
struct psp_device *psp = sp->psp_data; \
unsigned int val = ioread32(psp->io_regs + _offset); \
return sysfs_emit(buf, "%02lx.%02lx.%02lx.%02lx\n", \
FIELD_GET(AA, val), \
FIELD_GET(BB, val), \
FIELD_GET(CC, val), \
FIELD_GET(DD, val)); \
}
version_attribute_show(bootloader_version, psp->vdata->bootloader_info_reg)
static DEVICE_ATTR_RO(bootloader_version);
version_attribute_show(tee_version, psp->vdata->tee->info_reg)
static DEVICE_ATTR_RO(tee_version);
static struct attribute *psp_firmware_attrs[] = {
&dev_attr_bootloader_version.attr,
&dev_attr_tee_version.attr,
NULL,
};
static umode_t psp_firmware_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
{
struct device *dev = kobj_to_dev(kobj);
struct sp_device *sp = dev_get_drvdata(dev);
struct psp_device *psp = sp->psp_data;
unsigned int val = 0xffffffff;
if (!psp)
return 0;
if (attr == &dev_attr_bootloader_version.attr &&
psp->vdata->bootloader_info_reg)
val = ioread32(psp->io_regs + psp->vdata->bootloader_info_reg);
if (attr == &dev_attr_tee_version.attr &&
psp->capability & PSP_CAPABILITY_TEE &&
psp->vdata->tee->info_reg)
val = ioread32(psp->io_regs + psp->vdata->tee->info_reg);
/* If platform disallows accessing this register it will be all f's */
if (val != 0xffffffff)
return 0444;
return 0;
}
static struct attribute_group psp_firmware_attr_group = {
.attrs = psp_firmware_attrs,
.is_visible = psp_firmware_is_visible,
};
static const struct attribute_group *psp_groups[] = {
&psp_security_attr_group,
&psp_firmware_attr_group,
NULL,
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment