Re: [PATCH v2 16/40] arm64: mm: Pin down ASIDs for sharing mm with devices

2018-05-17 Thread Jean-Philippe Brucker
On 15/05/18 15:16, Catalin Marinas wrote:
> Hi Jean-Philippe,
> 
> On Fri, May 11, 2018 at 08:06:17PM +0100, Jean-Philippe Brucker wrote:
>> +unsigned long mm_context_get(struct mm_struct *mm)
>> +{
>> +unsigned long flags;
>> +u64 asid;
>> +
>> +raw_spin_lock_irqsave(_asid_lock, flags);
>> +
>> +asid = atomic64_read(>context.id);
>> +
>> +if (mm->context.pinned) {
>> +mm->context.pinned++;
>> +asid &= ~ASID_MASK;
>> +goto out_unlock;
>> +}
>> +
>> +if (nr_pinned_asids >= max_pinned_asids) {
>> +asid = 0;
>> +goto out_unlock;
>> +}
>> +
>> +if (!asid_gen_match(asid)) {
>> +/*
>> + * We went through one or more rollover since that ASID was
>> + * used. Ensure that it is still valid, or generate a new one.
>> + * The cpu argument isn't used by new_context.
>> + */
>> +asid = new_context(mm, 0);
>> +atomic64_set(>context.id, asid);
>> +}
>> +
>> +asid &= ~ASID_MASK;
>> +
>> +nr_pinned_asids++;
>> +__set_bit(asid2idx(asid), pinned_asid_map);
>> +mm->context.pinned++;
>> +
>> +out_unlock:
>> +raw_spin_unlock_irqrestore(_asid_lock, flags);
>> +
>> +return asid;
>> +}
> 
> With CONFIG_UNMAP_KERNEL_AT_EL0 (a.k.a. KPTI), the hardware ASID has bit
> 0 set automatically when entering user space (and cleared when getting
> back to the kernel). If the returned asid value here is going to be used
> as is in the calling code, you should probably set bit 0 when KPTI is
> enabled.
> 

Oh right, I'll change this

Thanks,
Jean
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 16/40] arm64: mm: Pin down ASIDs for sharing mm with devices

2018-05-15 Thread Catalin Marinas
Hi Jean-Philippe,

On Fri, May 11, 2018 at 08:06:17PM +0100, Jean-Philippe Brucker wrote:
> +unsigned long mm_context_get(struct mm_struct *mm)
> +{
> + unsigned long flags;
> + u64 asid;
> +
> + raw_spin_lock_irqsave(_asid_lock, flags);
> +
> + asid = atomic64_read(>context.id);
> +
> + if (mm->context.pinned) {
> + mm->context.pinned++;
> + asid &= ~ASID_MASK;
> + goto out_unlock;
> + }
> +
> + if (nr_pinned_asids >= max_pinned_asids) {
> + asid = 0;
> + goto out_unlock;
> + }
> +
> + if (!asid_gen_match(asid)) {
> + /*
> +  * We went through one or more rollover since that ASID was
> +  * used. Ensure that it is still valid, or generate a new one.
> +  * The cpu argument isn't used by new_context.
> +  */
> + asid = new_context(mm, 0);
> + atomic64_set(>context.id, asid);
> + }
> +
> + asid &= ~ASID_MASK;
> +
> + nr_pinned_asids++;
> + __set_bit(asid2idx(asid), pinned_asid_map);
> + mm->context.pinned++;
> +
> +out_unlock:
> + raw_spin_unlock_irqrestore(_asid_lock, flags);
> +
> + return asid;
> +}

With CONFIG_UNMAP_KERNEL_AT_EL0 (a.k.a. KPTI), the hardware ASID has bit
0 set automatically when entering user space (and cleared when getting
back to the kernel). If the returned asid value here is going to be used
as is in the calling code, you should probably set bit 0 when KPTI is
enabled.

-- 
Catalin
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu