On Sat, Jun 14, 2025 at 12:14:49AM -0700, Nicolin Chen wrote: I made some small changes:
> /** > * struct tegra241_vintf - Virtual Interface > + * @vsmmu: Embedded arm_vsmmu structure > * @idx: Global index in the CMDQV > * @enabled: Enable status > * @hyp_own: Owned by hypervisor (in-kernel) > * @cmdqv: Parent CMDQV pointer > * @lvcmdqs: List of logical VCMDQ pointers Added: + * @lvcmdq_mutex: Lock to serialize user-allocated lvcmdq for the following change: > @@ -154,19 +172,41 @@ struct tegra241_vintf { > > struct tegra241_cmdqv *cmdqv; > struct tegra241_vcmdq **lvcmdqs; > + struct mutex lvcmdq_mutex; /* user space race */ [...] > +static void > +tegra241_vintf_destroy_lvcmdq_user(struct iommufd_hw_queue *hw_queue) > +{ > + struct tegra241_vcmdq *vcmdq = hw_queue_to_vcmdq(hw_queue); > + > + tegra241_vcmdq_hw_deinit(vcmdq); > + tegra241_vcmdq_unmap_lvcmdq(vcmdq); > + tegra241_vintf_free_lvcmdq(vcmdq->vintf, vcmdq->lidx); > + if (vcmdq->prev) > + iommufd_hw_queue_undepend(vcmdq, vcmdq->prev, core); Added mutex to pair with tegra241_vintf_alloc_lvcmdq_user(): mutex_lock(&vcmdq->vintf->lvcmdq_mutex); ... mutex_unlock(&vcmdq->vintf->lvcmdq_mutex); > + /* > + * Initialize the user-owned VINTF without a LVCMDQ, because it has to > + * wait for the allocation of a user-owned LVCMDQ, for security reason. > + * It is different than the kernel-owned VINTF0, which had pre-assigned > + * and pre-allocated global VCMDQs that would be mapped to the LVCMDQs > + * by the tegra241_vintf_hw_init() call. > + */ > + ret = tegra241_vintf_hw_init(vintf, false); Revised a bit: + /* + * Initialize the user-owned VINTF without a LVCMDQ, as it cannot pre- + * allocate a LVCMDQ until user space wants one, for security reasons. [...] Thanks Nicolin