Skip to content

Commit ac052d8

Browse files
Shyam Sundar S Kjwrdegoede
authored andcommitted
platform/x86/amd/pmf: Add PMF TEE interface
AMD PMF driver loads the PMF TA (Trusted Application) into the AMD ASP's (AMD Security Processor) TEE (Trusted Execution Environment). PMF Trusted Application is a secured firmware placed under /lib/firmware/amdtee gets loaded only when the TEE environment is initialized. Add the initial code path to build these pipes. 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 ed289b9 commit ac052d8

File tree

5 files changed

+130
-5
lines changed

5 files changed

+130
-5
lines changed

drivers/platform/x86/amd/pmf/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ config AMD_PMF
99
depends on POWER_SUPPLY
1010
depends on AMD_NB
1111
select ACPI_PLATFORM_PROFILE
12+
depends on TEE
1213
help
1314
This driver provides support for the AMD Platform Management Framework.
1415
The goal is to enhance end user experience by making AMD PCs smarter,

drivers/platform/x86/amd/pmf/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66

77
obj-$(CONFIG_AMD_PMF) += amd-pmf.o
88
amd-pmf-objs := core.o acpi.o sps.o \
9-
auto-mode.o cnqf.o
9+
auto-mode.o cnqf.o \
10+
tee-if.o

drivers/platform/x86/amd/pmf/core.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,13 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev)
309309
dev_dbg(dev->dev, "SPS enabled and Platform Profiles registered\n");
310310
}
311311

312-
/* Enable Auto Mode */
313-
if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
312+
if (!amd_pmf_init_smart_pc(dev)) {
313+
dev_dbg(dev->dev, "Smart PC Solution Enabled\n");
314+
} else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
314315
amd_pmf_init_auto_mode(dev);
315316
dev_dbg(dev->dev, "Auto Mode Init done\n");
316317
} else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
317318
is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) {
318-
/* Enable Cool n Quiet Framework (CnQF) */
319319
ret = amd_pmf_init_cnqf(dev);
320320
if (ret)
321321
dev_warn(dev->dev, "CnQF Init failed\n");
@@ -330,7 +330,9 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev *dev)
330330
amd_pmf_deinit_sps(dev);
331331
}
332332

333-
if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
333+
if (!dev->smart_pc_enabled) {
334+
amd_pmf_deinit_smart_pc(dev);
335+
} else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
334336
amd_pmf_deinit_auto_mode(dev);
335337
} else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
336338
is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ struct amd_pmf_dev {
179179
bool cnqf_enabled;
180180
bool cnqf_supported;
181181
struct notifier_block pwr_src_notifier;
182+
/* Smart PC solution builder */
183+
struct tee_context *tee_ctx;
184+
struct tee_shm *fw_shm_pool;
185+
u32 session_id;
186+
void *shbuf;
187+
bool smart_pc_enabled;
182188
};
183189

184190
struct apmf_sps_prop_granular {
@@ -389,6 +395,13 @@ struct apmf_dyn_slider_output {
389395
struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
390396
} __packed;
391397

398+
struct ta_pmf_shared_memory {
399+
int command_id;
400+
int resp_id;
401+
u32 pmf_result;
402+
u32 if_version;
403+
};
404+
392405
/* Core Layer */
393406
int apmf_acpi_init(struct amd_pmf_dev *pmf_dev);
394407
void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev);
@@ -433,4 +446,7 @@ void amd_pmf_deinit_cnqf(struct amd_pmf_dev *dev);
433446
int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t time_lapsed_ms);
434447
extern const struct attribute_group cnqf_feature_attribute_group;
435448

449+
/* Smart PC builder Layer */
450+
int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev);
451+
void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev);
436452
#endif /* PMF_H */
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* AMD Platform Management Framework Driver - TEE Interface
4+
*
5+
* Copyright (c) 2023, Advanced Micro Devices, Inc.
6+
* All Rights Reserved.
7+
*
8+
* Author: Shyam Sundar S K <[email protected]>
9+
*/
10+
11+
#include <linux/tee_drv.h>
12+
#include <linux/uuid.h>
13+
#include "pmf.h"
14+
15+
#define MAX_TEE_PARAM 4
16+
static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
17+
0xb1, 0x2d, 0xc5, 0x29, 0xb1, 0x3d, 0x85, 0x43);
18+
19+
static int amd_pmf_amdtee_ta_match(struct tee_ioctl_version_data *ver, const void *data)
20+
{
21+
return ver->impl_id == TEE_IMPL_ID_AMDTEE;
22+
}
23+
24+
static int amd_pmf_ta_open_session(struct tee_context *ctx, u32 *id)
25+
{
26+
struct tee_ioctl_open_session_arg sess_arg = {};
27+
int rc;
28+
29+
export_uuid(sess_arg.uuid, &amd_pmf_ta_uuid);
30+
sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
31+
sess_arg.num_params = 0;
32+
33+
rc = tee_client_open_session(ctx, &sess_arg, NULL);
34+
if (rc < 0 || sess_arg.ret != 0) {
35+
pr_err("Failed to open TEE session err:%#x, rc:%d\n", sess_arg.ret, rc);
36+
return rc;
37+
}
38+
39+
*id = sess_arg.session;
40+
41+
return rc;
42+
}
43+
44+
static int amd_pmf_tee_init(struct amd_pmf_dev *dev)
45+
{
46+
u32 size;
47+
int ret;
48+
49+
dev->tee_ctx = tee_client_open_context(NULL, amd_pmf_amdtee_ta_match, NULL, NULL);
50+
if (IS_ERR(dev->tee_ctx)) {
51+
dev_err(dev->dev, "Failed to open TEE context\n");
52+
return PTR_ERR(dev->tee_ctx);
53+
}
54+
55+
ret = amd_pmf_ta_open_session(dev->tee_ctx, &dev->session_id);
56+
if (ret) {
57+
dev_err(dev->dev, "Failed to open TA session (%d)\n", ret);
58+
ret = -EINVAL;
59+
goto out_ctx;
60+
}
61+
62+
size = sizeof(struct ta_pmf_shared_memory);
63+
dev->fw_shm_pool = tee_shm_alloc_kernel_buf(dev->tee_ctx, size);
64+
if (IS_ERR(dev->fw_shm_pool)) {
65+
dev_err(dev->dev, "Failed to alloc TEE shared memory\n");
66+
ret = PTR_ERR(dev->fw_shm_pool);
67+
goto out_sess;
68+
}
69+
70+
dev->shbuf = tee_shm_get_va(dev->fw_shm_pool, 0);
71+
if (IS_ERR(dev->shbuf)) {
72+
dev_err(dev->dev, "Failed to get TEE virtual address\n");
73+
ret = PTR_ERR(dev->shbuf);
74+
goto out_shm;
75+
}
76+
dev_dbg(dev->dev, "TEE init done\n");
77+
78+
return 0;
79+
80+
out_shm:
81+
tee_shm_free(dev->fw_shm_pool);
82+
out_sess:
83+
tee_client_close_session(dev->tee_ctx, dev->session_id);
84+
out_ctx:
85+
tee_client_close_context(dev->tee_ctx);
86+
87+
return ret;
88+
}
89+
90+
static void amd_pmf_tee_deinit(struct amd_pmf_dev *dev)
91+
{
92+
tee_shm_free(dev->fw_shm_pool);
93+
tee_client_close_session(dev->tee_ctx, dev->session_id);
94+
tee_client_close_context(dev->tee_ctx);
95+
}
96+
97+
int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
98+
{
99+
return amd_pmf_tee_init(dev);
100+
}
101+
102+
void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev)
103+
{
104+
amd_pmf_tee_deinit(dev);
105+
}

0 commit comments

Comments
 (0)