|
13 | 13 | #include "pmf.h" |
14 | 14 |
|
15 | 15 | #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 | + |
16 | 24 | static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d, |
17 | 25 | 0xb1, 0x2d, 0xc5, 0x29, 0xb1, 0x3d, 0x85, 0x43); |
18 | 26 |
|
| 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 | + |
19 | 106 | static int amd_pmf_amdtee_ta_match(struct tee_ioctl_version_data *ver, const void *data) |
20 | 107 | { |
21 | 108 | return ver->impl_id == TEE_IMPL_ID_AMDTEE; |
@@ -96,10 +183,18 @@ static void amd_pmf_tee_deinit(struct amd_pmf_dev *dev) |
96 | 183 |
|
97 | 184 | int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev) |
98 | 185 | { |
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; |
100 | 194 | } |
101 | 195 |
|
102 | 196 | void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev) |
103 | 197 | { |
| 198 | + cancel_delayed_work_sync(&dev->pb_work); |
104 | 199 | amd_pmf_tee_deinit(dev); |
105 | 200 | } |
0 commit comments