Skip to content

Commit ae82cef

Browse files
Shyam Sundar S Kjwrdegoede
authored andcommitted
platform/x86/amd/pmf: Add support for PMF-TA interaction
PMF TA (Trusted Application) loads via the TEE environment into the AMD ASP. PMF-TA supports two commands: 1) Init: Initialize the TA with the PMF Smart PC policy binary and start the policy engine. A policy is a combination of inputs and outputs, where; - the inputs are the changing dynamics of the system like the user behaviour, system heuristics etc. - the outputs, which are the actions to be set on the system which lead to better power management and enhanced user experience. PMF driver acts as a central manager in this case to supply the inputs required to the TA (either by getting the information from the other kernel subsystems or from userland) 2) Enact: Enact the output actions from the TA. The action could be applying a new thermal limit to boost/throttle the power limits or change system behavior. Reviewed-by: Mario Limonciello <[email protected]> Signed-off-by: Shyam Sundar S K <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Hans de Goede <[email protected]>
1 parent ac052d8 commit ae82cef

File tree

2 files changed

+106
-1
lines changed

2 files changed

+106
-1
lines changed

drivers/platform/x86/amd/pmf/pmf.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
#define ARG_NONE 0
6060
#define AVG_SAMPLE_SIZE 3
6161

62+
/* TA macros */
63+
#define PMF_TA_IF_VERSION_MAJOR 1
64+
6265
/* AMD PMF BIOS interfaces */
6366
struct apmf_verify_interface {
6467
u16 size;
@@ -184,6 +187,7 @@ struct amd_pmf_dev {
184187
struct tee_shm *fw_shm_pool;
185188
u32 session_id;
186189
void *shbuf;
190+
struct delayed_work pb_work;
187191
bool smart_pc_enabled;
188192
};
189193

@@ -395,6 +399,12 @@ struct apmf_dyn_slider_output {
395399
struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
396400
} __packed;
397401

402+
/* Command ids for TA communication */
403+
enum ta_pmf_command {
404+
TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE,
405+
TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES,
406+
};
407+
398408
struct ta_pmf_shared_memory {
399409
int command_id;
400410
int resp_id;

drivers/platform/x86/amd/pmf/tee-if.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,96 @@
1313
#include "pmf.h"
1414

1515
#define MAX_TEE_PARAM 4
16+
17+
/* Policy binary actions sampling frequency (in ms) */
18+
static int pb_actions_ms = MSEC_PER_SEC;
19+
#ifdef CONFIG_AMD_PMF_DEBUG
20+
module_param(pb_actions_ms, int, 0644);
21+
MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions sampling frequency (default = 1000ms)");
22+
#endif
23+
1624
static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
1725
0xb1, 0x2d, 0xc5, 0x29, 0xb1, 0x3d, 0x85, 0x43);
1826

27+
static void amd_pmf_prepare_args(struct amd_pmf_dev *dev, int cmd,
28+
struct tee_ioctl_invoke_arg *arg,
29+
struct tee_param *param)
30+
{
31+
memset(arg, 0, sizeof(*arg));
32+
memset(param, 0, MAX_TEE_PARAM * sizeof(*param));
33+
34+
arg->func = cmd;
35+
arg->session = dev->session_id;
36+
arg->num_params = MAX_TEE_PARAM;
37+
38+
/* Fill invoke cmd params */
39+
param[0].u.memref.size = sizeof(struct ta_pmf_shared_memory);
40+
param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
41+
param[0].u.memref.shm = dev->fw_shm_pool;
42+
param[0].u.memref.shm_offs = 0;
43+
}
44+
45+
static int amd_pmf_invoke_cmd_enact(struct amd_pmf_dev *dev)
46+
{
47+
struct ta_pmf_shared_memory *ta_sm = NULL;
48+
struct tee_param param[MAX_TEE_PARAM];
49+
struct tee_ioctl_invoke_arg arg;
50+
int ret = 0;
51+
52+
if (!dev->tee_ctx)
53+
return -ENODEV;
54+
55+
ta_sm = dev->shbuf;
56+
memset(ta_sm, 0, sizeof(*ta_sm));
57+
ta_sm->command_id = TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES;
58+
ta_sm->if_version = PMF_TA_IF_VERSION_MAJOR;
59+
60+
amd_pmf_prepare_args(dev, TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES, &arg, param);
61+
62+
ret = tee_client_invoke_func(dev->tee_ctx, &arg, param);
63+
if (ret < 0 || arg.ret != 0) {
64+
dev_err(dev->dev, "TEE enact cmd failed. err: %x, ret:%d\n", arg.ret, ret);
65+
return ret;
66+
}
67+
68+
return 0;
69+
}
70+
71+
static int amd_pmf_invoke_cmd_init(struct amd_pmf_dev *dev)
72+
{
73+
struct ta_pmf_shared_memory *ta_sm = NULL;
74+
struct tee_param param[MAX_TEE_PARAM];
75+
struct tee_ioctl_invoke_arg arg;
76+
int ret = 0;
77+
78+
if (!dev->tee_ctx) {
79+
dev_err(dev->dev, "Failed to get TEE context\n");
80+
return -ENODEV;
81+
}
82+
83+
ta_sm = dev->shbuf;
84+
ta_sm->command_id = TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE;
85+
ta_sm->if_version = PMF_TA_IF_VERSION_MAJOR;
86+
87+
amd_pmf_prepare_args(dev, TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE, &arg, param);
88+
89+
ret = tee_client_invoke_func(dev->tee_ctx, &arg, param);
90+
if (ret < 0 || arg.ret != 0) {
91+
dev_err(dev->dev, "Failed to invoke TEE init cmd. err: %x, ret:%d\n", arg.ret, ret);
92+
return ret;
93+
}
94+
95+
return ta_sm->pmf_result;
96+
}
97+
98+
static void amd_pmf_invoke_cmd(struct work_struct *work)
99+
{
100+
struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, pb_work.work);
101+
102+
amd_pmf_invoke_cmd_enact(dev);
103+
schedule_delayed_work(&dev->pb_work, msecs_to_jiffies(pb_actions_ms));
104+
}
105+
19106
static int amd_pmf_amdtee_ta_match(struct tee_ioctl_version_data *ver, const void *data)
20107
{
21108
return ver->impl_id == TEE_IMPL_ID_AMDTEE;
@@ -96,10 +183,18 @@ static void amd_pmf_tee_deinit(struct amd_pmf_dev *dev)
96183

97184
int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
98185
{
99-
return amd_pmf_tee_init(dev);
186+
int ret;
187+
188+
ret = amd_pmf_tee_init(dev);
189+
if (ret)
190+
return ret;
191+
192+
INIT_DELAYED_WORK(&dev->pb_work, amd_pmf_invoke_cmd);
193+
return 0;
100194
}
101195

102196
void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev)
103197
{
198+
cancel_delayed_work_sync(&dev->pb_work);
104199
amd_pmf_tee_deinit(dev);
105200
}

0 commit comments

Comments
 (0)