On Wed, Sep 29 2021 at 11:31, Tony Luck wrote:
> diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
> index a58800973aed..5a3c87fd65de 100644
> --- a/arch/x86/kernel/traps.c
> +++ b/arch/x86/kernel/traps.c
> @@ -528,6 +528,32 @@ static enum kernel_gp_hint get_kernel_gp_address(struct 
> pt_regs *regs,
>  
>  #define GPFSTR "general protection fault"
>  
> +/*
> + * When a user executes the ENQCMD instruction it will #GP
> + * fault if the IA32_PASID MSR has not been set up with a
> + * valid PASID.
> + * So if the process has been allocated a PASID (mm->pasid)
> + * AND the IA32_PASID MSR has not been initialized, try to
> + * fix this #GP by initializing the IA32_PASID MSR.
> + * If the #GP was for some other reason, it will trigger
> + * again, but this routine will return false and the #GP
> + * will be processed.
> + */
> +static void try_fixup_pasid(void)
> +{
> +     if (!cpu_feature_enabled(X86_FEATURE_ENQCMD))
> +             return false;
> +
> +#ifdef CONFIG_IOMMU_SUPPORT
> +     if (current->mm->pasid && !current->pasid_activated) {
> +             current->pasid_activated = 1;
> +             wrmsrl(MSR_IA32_PASID, current->mm->pasid);
> +             return true;
> +     }
> +#endif
> +     return false;
> +}
> +
>  DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
>  {
>       char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
> @@ -536,6 +562,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
>       unsigned long gp_addr;
>       int ret;
>  
> +     if (user_mode(regs) && try_fixup_pasid())
> +             return;
> +
>       cond_local_irq_enable(regs);
>  
>       if (static_cpu_has(X86_FEATURE_UMIP)) {

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

Reply via email to