1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
4 */
5
6 #include <uapi/linux/iommufd.h>
7
8 #include "arm-smmu-v3.h"
9
arm_smmu_hw_info(struct device * dev,u32 * length,enum iommu_hw_info_type * type)10 void *arm_smmu_hw_info(struct device *dev, u32 *length,
11 enum iommu_hw_info_type *type)
12 {
13 struct arm_smmu_master *master = dev_iommu_priv_get(dev);
14 const struct arm_smmu_impl_ops *impl_ops = master->smmu->impl_ops;
15 struct iommu_hw_info_arm_smmuv3 *info;
16 u32 __iomem *base_idr;
17 unsigned int i;
18
19 if (*type != IOMMU_HW_INFO_TYPE_DEFAULT &&
20 *type != IOMMU_HW_INFO_TYPE_ARM_SMMUV3) {
21 if (!impl_ops || !impl_ops->hw_info)
22 return ERR_PTR(-EOPNOTSUPP);
23 return impl_ops->hw_info(master->smmu, length, type);
24 }
25
26 info = kzalloc_obj(*info);
27 if (!info)
28 return ERR_PTR(-ENOMEM);
29
30 base_idr = master->smmu->base + ARM_SMMU_IDR0;
31 for (i = 0; i <= 5; i++)
32 info->idr[i] = readl_relaxed(base_idr + i);
33 info->iidr = readl_relaxed(master->smmu->base + ARM_SMMU_IIDR);
34 info->aidr = readl_relaxed(master->smmu->base + ARM_SMMU_AIDR);
35
36 if (arm_smmu_erratum_repeat_tlbi_cfgi())
37 info->flags |= IOMMU_HW_INFO_ARM_SMMUV3_ERRATA_REPEAT_TLBI_CFGI;
38
39 *length = sizeof(*info);
40 *type = IOMMU_HW_INFO_TYPE_ARM_SMMUV3;
41
42 return info;
43 }
44
arm_smmu_make_nested_cd_table_ste(struct arm_smmu_ste * target,struct arm_smmu_master * master,struct arm_smmu_nested_domain * nested_domain,bool ats_enabled)45 static void arm_smmu_make_nested_cd_table_ste(
46 struct arm_smmu_ste *target, struct arm_smmu_master *master,
47 struct arm_smmu_nested_domain *nested_domain, bool ats_enabled)
48 {
49 arm_smmu_make_s2_domain_ste(
50 target, master, nested_domain->vsmmu->s2_parent, ats_enabled);
51
52 target->data[0] = cpu_to_le64(STRTAB_STE_0_V |
53 FIELD_PREP(STRTAB_STE_0_CFG,
54 STRTAB_STE_0_CFG_NESTED));
55 target->data[0] |= nested_domain->ste[0] &
56 ~cpu_to_le64(STRTAB_STE_0_CFG);
57 target->data[1] |= nested_domain->ste[1];
58 /* Merge events for DoS mitigations on eventq */
59 target->data[1] |= cpu_to_le64(STRTAB_STE_1_MEV);
60 }
61
62 /*
63 * Create a physical STE from the virtual STE that userspace provided when it
64 * created the nested domain. Using the vSTE userspace can request:
65 * - Non-valid STE
66 * - Abort STE
67 * - Bypass STE (install the S2, no CD table)
68 * - CD table STE (install the S2 and the userspace CD table)
69 */
arm_smmu_make_nested_domain_ste(struct arm_smmu_ste * target,struct arm_smmu_master * master,struct arm_smmu_nested_domain * nested_domain,bool ats_enabled)70 static void arm_smmu_make_nested_domain_ste(
71 struct arm_smmu_ste *target, struct arm_smmu_master *master,
72 struct arm_smmu_nested_domain *nested_domain, bool ats_enabled)
73 {
74 unsigned int cfg =
75 FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0]));
76
77 /*
78 * Userspace can request a non-valid STE through the nesting interface.
79 * We relay that into an abort physical STE with the intention that
80 * C_BAD_STE for this SID can be generated to userspace.
81 */
82 if (!(nested_domain->ste[0] & cpu_to_le64(STRTAB_STE_0_V)))
83 cfg = STRTAB_STE_0_CFG_ABORT;
84
85 switch (cfg) {
86 case STRTAB_STE_0_CFG_S1_TRANS:
87 arm_smmu_make_nested_cd_table_ste(target, master, nested_domain,
88 ats_enabled);
89 break;
90 case STRTAB_STE_0_CFG_BYPASS:
91 arm_smmu_make_s2_domain_ste(target, master,
92 nested_domain->vsmmu->s2_parent,
93 ats_enabled);
94 break;
95 case STRTAB_STE_0_CFG_ABORT:
96 default:
97 arm_smmu_make_abort_ste(target);
98 break;
99 }
100 }
101
arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state * state,struct arm_smmu_nested_domain * nested_domain)102 int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
103 struct arm_smmu_nested_domain *nested_domain)
104 {
105 unsigned int cfg =
106 FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0]));
107 struct arm_smmu_vmaster *vmaster;
108 unsigned long vsid;
109 int ret;
110
111 iommu_group_mutex_assert(state->master->dev);
112
113 ret = iommufd_viommu_get_vdev_id(&nested_domain->vsmmu->core,
114 state->master->dev, &vsid);
115 /*
116 * Attaching to a translate nested domain must allocate a vDEVICE prior,
117 * as CD/ATS invalidations and vevents require a vSID to work properly.
118 * A abort/bypass domain is allowed to attach w/o vmaster for GBPA case.
119 */
120 if (ret) {
121 if (cfg == STRTAB_STE_0_CFG_ABORT ||
122 cfg == STRTAB_STE_0_CFG_BYPASS)
123 return 0;
124 return ret;
125 }
126
127 vmaster = kzalloc_obj(*vmaster);
128 if (!vmaster)
129 return -ENOMEM;
130 vmaster->vsmmu = nested_domain->vsmmu;
131 vmaster->vsid = vsid;
132 state->vmaster = vmaster;
133
134 return 0;
135 }
136
arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state * state)137 void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
138 {
139 struct arm_smmu_master *master = state->master;
140
141 mutex_lock(&master->smmu->streams_mutex);
142 kfree(master->vmaster);
143 master->vmaster = state->vmaster;
144 mutex_unlock(&master->smmu->streams_mutex);
145 }
146
arm_smmu_master_clear_vmaster(struct arm_smmu_master * master)147 void arm_smmu_master_clear_vmaster(struct arm_smmu_master *master)
148 {
149 struct arm_smmu_attach_state state = { .master = master };
150
151 arm_smmu_attach_commit_vmaster(&state);
152 }
153
arm_smmu_attach_dev_nested(struct iommu_domain * domain,struct device * dev,struct iommu_domain * old_domain)154 static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
155 struct device *dev,
156 struct iommu_domain *old_domain)
157 {
158 struct arm_smmu_nested_domain *nested_domain =
159 to_smmu_nested_domain(domain);
160 struct arm_smmu_master *master = dev_iommu_priv_get(dev);
161 struct arm_smmu_attach_state state = {
162 .master = master,
163 .old_domain = old_domain,
164 .ssid = IOMMU_NO_PASID,
165 };
166 struct arm_smmu_ste ste;
167 int ret;
168
169 if (nested_domain->vsmmu->smmu != master->smmu)
170 return -EINVAL;
171 if (arm_smmu_ssids_in_use(&master->cd_table))
172 return -EBUSY;
173
174 mutex_lock(&arm_smmu_asid_lock);
175 /*
176 * The VM has to control the actual ATS state at the PCI device because
177 * we forward the invalidations directly from the VM. If the VM doesn't
178 * think ATS is on it will not generate ATC flushes and the ATC will
179 * become incoherent. Since we can't access the actual virtual PCI ATS
180 * config bit here base this off the EATS value in the STE. If the EATS
181 * is set then the VM must generate ATC flushes.
182 */
183 if (FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0])) ==
184 STRTAB_STE_0_CFG_S1_TRANS)
185 state.disable_ats = !nested_domain->enable_ats;
186 ret = arm_smmu_attach_prepare(&state, domain);
187 if (ret) {
188 mutex_unlock(&arm_smmu_asid_lock);
189 return ret;
190 }
191
192 arm_smmu_make_nested_domain_ste(&ste, master, nested_domain,
193 state.ats_enabled);
194 arm_smmu_install_ste_for_dev(master, &ste);
195 arm_smmu_attach_commit(&state);
196 mutex_unlock(&arm_smmu_asid_lock);
197 return 0;
198 }
199
arm_smmu_domain_nested_free(struct iommu_domain * domain)200 static void arm_smmu_domain_nested_free(struct iommu_domain *domain)
201 {
202 kfree(to_smmu_nested_domain(domain));
203 }
204
205 static const struct iommu_domain_ops arm_smmu_nested_ops = {
206 .attach_dev = arm_smmu_attach_dev_nested,
207 .free = arm_smmu_domain_nested_free,
208 };
209
arm_smmu_validate_vste(struct iommu_hwpt_arm_smmuv3 * arg,bool * enable_ats)210 static int arm_smmu_validate_vste(struct iommu_hwpt_arm_smmuv3 *arg,
211 bool *enable_ats)
212 {
213 unsigned int eats;
214 unsigned int cfg;
215
216 if (!(arg->ste[0] & cpu_to_le64(STRTAB_STE_0_V))) {
217 memset(arg->ste, 0, sizeof(arg->ste));
218 return 0;
219 }
220
221 /* EIO is reserved for invalid STE data. */
222 if ((arg->ste[0] & ~STRTAB_STE_0_NESTING_ALLOWED) ||
223 (arg->ste[1] & ~STRTAB_STE_1_NESTING_ALLOWED))
224 return -EIO;
225
226 cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(arg->ste[0]));
227 if (cfg != STRTAB_STE_0_CFG_ABORT && cfg != STRTAB_STE_0_CFG_BYPASS &&
228 cfg != STRTAB_STE_0_CFG_S1_TRANS)
229 return -EIO;
230
231 /*
232 * Only Full ATS or ATS UR is supported
233 * The EATS field will be set by arm_smmu_make_nested_domain_ste()
234 */
235 eats = FIELD_GET(STRTAB_STE_1_EATS, le64_to_cpu(arg->ste[1]));
236 arg->ste[1] &= ~cpu_to_le64(STRTAB_STE_1_EATS);
237 if (eats != STRTAB_STE_1_EATS_ABT && eats != STRTAB_STE_1_EATS_TRANS)
238 return -EIO;
239
240 if (cfg == STRTAB_STE_0_CFG_S1_TRANS)
241 *enable_ats = (eats == STRTAB_STE_1_EATS_TRANS);
242 return 0;
243 }
244
245 struct iommu_domain *
arm_vsmmu_alloc_domain_nested(struct iommufd_viommu * viommu,u32 flags,const struct iommu_user_data * user_data)246 arm_vsmmu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
247 const struct iommu_user_data *user_data)
248 {
249 struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core);
250 struct arm_smmu_nested_domain *nested_domain;
251 struct iommu_hwpt_arm_smmuv3 arg;
252 bool enable_ats = false;
253 int ret;
254
255 if (flags)
256 return ERR_PTR(-EOPNOTSUPP);
257
258 ret = iommu_copy_struct_from_user(&arg, user_data,
259 IOMMU_HWPT_DATA_ARM_SMMUV3, ste);
260 if (ret)
261 return ERR_PTR(ret);
262
263 ret = arm_smmu_validate_vste(&arg, &enable_ats);
264 if (ret)
265 return ERR_PTR(ret);
266
267 nested_domain = kzalloc_obj(*nested_domain, GFP_KERNEL_ACCOUNT);
268 if (!nested_domain)
269 return ERR_PTR(-ENOMEM);
270
271 nested_domain->domain.type = IOMMU_DOMAIN_NESTED;
272 nested_domain->domain.ops = &arm_smmu_nested_ops;
273 nested_domain->enable_ats = enable_ats;
274 nested_domain->vsmmu = vsmmu;
275 nested_domain->ste[0] = arg.ste[0];
276 nested_domain->ste[1] = arg.ste[1] & ~cpu_to_le64(STRTAB_STE_1_EATS);
277
278 return &nested_domain->domain;
279 }
280
arm_vsmmu_vsid_to_sid(struct arm_vsmmu * vsmmu,u32 vsid,u32 * sid)281 static int arm_vsmmu_vsid_to_sid(struct arm_vsmmu *vsmmu, u32 vsid, u32 *sid)
282 {
283 struct arm_smmu_master *master;
284 struct device *dev;
285 int ret = 0;
286
287 xa_lock(&vsmmu->core.vdevs);
288 dev = iommufd_viommu_find_dev(&vsmmu->core, (unsigned long)vsid);
289 if (!dev) {
290 ret = -EIO;
291 goto unlock;
292 }
293 master = dev_iommu_priv_get(dev);
294
295 /* At this moment, iommufd only supports PCI device that has one SID */
296 if (sid)
297 *sid = master->streams[0].id;
298 unlock:
299 xa_unlock(&vsmmu->core.vdevs);
300 return ret;
301 }
302
arm_vsmmu_vdevice_init(struct iommufd_vdevice * vdev)303 static int arm_vsmmu_vdevice_init(struct iommufd_vdevice *vdev)
304 {
305 struct device *dev = iommufd_vdevice_to_device(vdev);
306 struct arm_smmu_master *master = dev_iommu_priv_get(dev);
307
308 /*
309 * arm_vsmmu_vsid_to_sid() maps a vSID to master->streams[0] alone, so
310 * more streams would leave the rest stale and none reads out of bounds.
311 */
312 if (master->num_streams != 1)
313 return -EOPNOTSUPP;
314 return 0;
315 }
316
317 /* This is basically iommu_viommu_arm_smmuv3_invalidate in u64 for conversion */
318 struct arm_vsmmu_invalidation_cmd {
319 union {
320 struct arm_smmu_cmd cmd;
321 struct iommu_viommu_arm_smmuv3_invalidate ucmd;
322 };
323 };
324
325 /*
326 * Convert, in place, the raw invalidation command into an internal format that
327 * can be passed to arm_smmu_cmdq_issue_cmdlist(). Internally commands are
328 * stored in CPU endian.
329 *
330 * Enforce the VMID or SID on the command.
331 */
arm_vsmmu_convert_user_cmd(struct arm_vsmmu * vsmmu,struct arm_vsmmu_invalidation_cmd * cmd)332 static int arm_vsmmu_convert_user_cmd(struct arm_vsmmu *vsmmu,
333 struct arm_vsmmu_invalidation_cmd *cmd)
334 {
335 /* Commands are le64 stored in u64 */
336 cmd->cmd.data[0] = le64_to_cpu(cmd->ucmd.cmd[0]);
337 cmd->cmd.data[1] = le64_to_cpu(cmd->ucmd.cmd[1]);
338
339 switch (cmd->cmd.data[0] & CMDQ_0_OP) {
340 case CMDQ_OP_TLBI_NSNH_ALL:
341 /* Convert to NH_ALL */
342 cmd->cmd.data[0] = CMDQ_OP_TLBI_NH_ALL |
343 FIELD_PREP(CMDQ_TLBI_0_VMID, vsmmu->vmid);
344 cmd->cmd.data[1] = 0;
345 break;
346 case CMDQ_OP_TLBI_NH_VA:
347 case CMDQ_OP_TLBI_NH_VAA:
348 case CMDQ_OP_TLBI_NH_ALL:
349 case CMDQ_OP_TLBI_NH_ASID:
350 cmd->cmd.data[0] &= ~CMDQ_TLBI_0_VMID;
351 cmd->cmd.data[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, vsmmu->vmid);
352 break;
353 case CMDQ_OP_ATC_INV:
354 case CMDQ_OP_CFGI_CD:
355 case CMDQ_OP_CFGI_CD_ALL: {
356 u32 sid, vsid = FIELD_GET(CMDQ_CFGI_0_SID, cmd->cmd.data[0]);
357
358 if (arm_vsmmu_vsid_to_sid(vsmmu, vsid, &sid))
359 return -EIO;
360 cmd->cmd.data[0] &= ~CMDQ_CFGI_0_SID;
361 cmd->cmd.data[0] |= FIELD_PREP(CMDQ_CFGI_0_SID, sid);
362 break;
363 }
364 default:
365 return -EIO;
366 }
367 return 0;
368 }
369
arm_vsmmu_cache_invalidate(struct iommufd_viommu * viommu,struct iommu_user_data_array * array)370 int arm_vsmmu_cache_invalidate(struct iommufd_viommu *viommu,
371 struct iommu_user_data_array *array)
372 {
373 struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core);
374 struct arm_smmu_device *smmu = vsmmu->smmu;
375 struct arm_vsmmu_invalidation_cmd *last;
376 struct arm_vsmmu_invalidation_cmd *cmds;
377 struct arm_vsmmu_invalidation_cmd *cur;
378 struct arm_vsmmu_invalidation_cmd *end;
379 int ret;
380
381 cmds = kzalloc_objs(*cmds, array->entry_num);
382 if (!cmds)
383 return -ENOMEM;
384 cur = cmds;
385 end = cmds + array->entry_num;
386
387 static_assert(sizeof(*cmds) == 2 * sizeof(u64));
388 ret = iommu_copy_struct_from_full_user_array(
389 cmds, sizeof(*cmds), array,
390 IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3);
391 if (ret)
392 goto out;
393
394 last = cmds;
395 while (cur != end) {
396 ret = arm_vsmmu_convert_user_cmd(vsmmu, cur);
397 if (ret)
398 goto out;
399
400 /* FIXME work in blocks of CMDQ_BATCH_ENTRIES and copy each block? */
401 cur++;
402 if (cur != end && (cur - last) != CMDQ_BATCH_ENTRIES - 1)
403 continue;
404
405 /* FIXME always uses the main cmdq rather than trying to group by type */
406 ret = __arm_smmu_cmdq_issue_cmdlist(smmu, &smmu->cmdq, &last->cmd,
407 cur - last, true);
408 if (ret) {
409 cur--;
410 goto out;
411 }
412 last = cur;
413 }
414 out:
415 array->entry_num = cur - cmds;
416 kfree(cmds);
417 return ret;
418 }
419
420 static const struct iommufd_viommu_ops arm_vsmmu_ops = {
421 .alloc_domain_nested = arm_vsmmu_alloc_domain_nested,
422 .cache_invalidate = arm_vsmmu_cache_invalidate,
423 .vdevice_init = arm_vsmmu_vdevice_init,
424 };
425
arm_smmu_get_viommu_size(struct device * dev,enum iommu_viommu_type viommu_type)426 size_t arm_smmu_get_viommu_size(struct device *dev,
427 enum iommu_viommu_type viommu_type)
428 {
429 struct arm_smmu_master *master = dev_iommu_priv_get(dev);
430 struct arm_smmu_device *smmu = master->smmu;
431
432 if (!(smmu->features & ARM_SMMU_FEAT_NESTING))
433 return 0;
434
435 /*
436 * FORCE_SYNC is not set with FEAT_NESTING. Some study of the exact HW
437 * defect is needed to determine if arm_vsmmu_cache_invalidate() needs
438 * any change to remove this.
439 */
440 if (WARN_ON(smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC))
441 return 0;
442
443 /*
444 * Must support some way to prevent the VM from bypassing the cache
445 * because VFIO currently does not do any cache maintenance. canwbs
446 * indicates the device is fully coherent and no cache maintenance is
447 * ever required, even for PCI No-Snoop. S2FWB means the S1 can't make
448 * things non-coherent using the memattr, but No-Snoop behavior is not
449 * effected.
450 */
451 if (!arm_smmu_master_canwbs(master) &&
452 !(smmu->features & ARM_SMMU_FEAT_S2FWB))
453 return 0;
454
455 if (viommu_type == IOMMU_VIOMMU_TYPE_ARM_SMMUV3)
456 return VIOMMU_STRUCT_SIZE(struct arm_vsmmu, core);
457
458 if (!smmu->impl_ops || !smmu->impl_ops->get_viommu_size)
459 return 0;
460 return smmu->impl_ops->get_viommu_size(viommu_type);
461 }
462
arm_vsmmu_init(struct iommufd_viommu * viommu,struct iommu_domain * parent_domain,const struct iommu_user_data * user_data)463 int arm_vsmmu_init(struct iommufd_viommu *viommu,
464 struct iommu_domain *parent_domain,
465 const struct iommu_user_data *user_data)
466 {
467 struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core);
468 struct arm_smmu_device *smmu =
469 container_of(viommu->iommu_dev, struct arm_smmu_device, iommu);
470 struct arm_smmu_domain *s2_parent = to_smmu_domain(parent_domain);
471
472 if (s2_parent->smmu != smmu)
473 return -EINVAL;
474
475 vsmmu->smmu = smmu;
476 vsmmu->s2_parent = s2_parent;
477 /* FIXME Move VMID allocation from the S2 domain allocation to here */
478 vsmmu->vmid = s2_parent->s2_cfg.vmid;
479
480 if (viommu->type == IOMMU_VIOMMU_TYPE_ARM_SMMUV3) {
481 viommu->ops = &arm_vsmmu_ops;
482 return 0;
483 }
484
485 return smmu->impl_ops->vsmmu_init(vsmmu, user_data);
486 }
487
arm_vmaster_report_event(struct arm_smmu_vmaster * vmaster,u64 * evt)488 int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
489 {
490 struct iommu_vevent_arm_smmuv3 vevt;
491 int i;
492
493 lockdep_assert_held(&vmaster->vsmmu->smmu->streams_mutex);
494
495 vevt.evt[0] = cpu_to_le64((evt[0] & ~EVTQ_0_SID) |
496 FIELD_PREP(EVTQ_0_SID, vmaster->vsid));
497 for (i = 1; i < EVTQ_ENT_DWORDS; i++)
498 vevt.evt[i] = cpu_to_le64(evt[i]);
499
500 return iommufd_viommu_report_event(&vmaster->vsmmu->core,
501 IOMMU_VEVENTQ_TYPE_ARM_SMMUV3, &vevt,
502 sizeof(vevt));
503 }
504
505 MODULE_IMPORT_NS("IOMMUFD");
506