On Mon, Jun 15, 2020 at 08:48:54AM -0700, Fenghua Yu wrote: > Hi, Peter, > On Mon, Jun 15, 2020 at 09:56:49AM +0200, Peter Zijlstra wrote: > > On Fri, Jun 12, 2020 at 05:41:33PM -0700, Fenghua Yu wrote: > > > +/* > > > + * Apply some heuristics to see if the #GP fault was caused by a thread > > > + * that hasn't had the IA32_PASID MSR initialized. If it looks like that > > > + * is the problem, try initializing the IA32_PASID MSR. If the heuristic > > > + * guesses incorrectly, take one more #GP fault. > > > > How is that going to help? Aren't we then going to run this same > > heuristic again and again and again? > > The heuristic always initializes the MSR with the per mm PASID IIF the > mm has a valid PASID but the MSR doesn't have one. This heuristic usually > happens only once on the first #GP in a thread. But it doesn't guarantee the PASID is the right one. Suppose both the mm has a PASID and the MSR has a VALID one, but the MSR isn't the mm one. Then we NO-OP. So if the exception was due to us having the wrong PASID, we stuck. > If the next #GP still comes in, the heuristic finds out the MSR already > has a valid PASID and thus will not fixup the MSR any more. The fixup() > returns "false" and lets others to handle the #GP. > > So the heuristic will be executed once (at most) and won't be executed > again and again. So I get that you want to set the PASID on-demand, but I find this all really weird code to make that happen. > > > +bool __fixup_pasid_exception(void) > > > +{ > > > + u64 pasid_msr; > > > + unsigned int pasid; > > > + > > > + /* > > > + * This function is called only when this #GP was triggered from user > > > + * space. So the mm cannot be NULL. > > > + */ > > > + pasid = current->mm->pasid; > > > + /* If the mm doesn't have a valid PASID, then can't help. */ > > > + if (invalid_pasid(pasid)) > > > + return false; > > > + > > > + /* > > > + * Since IRQ is disabled now, the current task still owns the FPU on > > > > That's just weird and confusing. What you want to say is that you rely > > on the exception disabling the interrupt. > > I checked SDM again. You are right. #GP can be interrupted by machine check > or other interrupts. So I cannot assume the current task still owns the FPU. > Instead of directly rdmsr() and wrmsr(), I will add helpers that can access > either the MSR on the processor or the PASID state in the memory. That's not in fact what I meant, but yes, you can take exceptions while !IF just fine. > > > + * this CPU and the PASID MSR can be directly accessed. > > > + * > > > + * If the MSR has a valid PASID, the #GP must be for some other reason. > > > + * > > > + * If rdmsr() is really a performance issue, a TIF_ flag may be > > > + * added to check if the thread has a valid PASID instead of rdmsr(). > > > > I don't understand any of this. Nobody except us writes to this MSR, we > > should bloody well know what's in it. What gives? > > Patch 4 describes how to manage the MSR and patch 7 describes the format > of the MSR (20-bit PASID value and bit 31 is valid bit). > > Are they sufficient to help? Or do you mean something else? I don't get why you need a rdmsr here, or why not having one would require a TIF flag. Is that because this MSR is XSAVE/XRSTOR managed? > > > + */ > > > + rdmsrl(MSR_IA32_PASID, pasid_msr); > > > + if (pasid_msr & MSR_IA32_PASID_VALID) > > > + return false; > > > + > > > + /* Fix up the MSR if the MSR doesn't have a valid PASID. */ > > > + wrmsrl(MSR_IA32_PASID, pasid | MSR_IA32_PASID_VALID); How much more expensive is the wrmsr over the rdmsr? Can't we just unconditionally write the current PASID and call it a day? _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx