On March 17, 2023 2:55:44 AM PDT, andrew.cooper3@xxxxxxxxxx wrote: >On 17/03/2023 9:39 am, Lai Jiangshan wrote: >>> +#ifdef CONFIG_X86_FRED >>> +static bool ex_handler_eretu(const struct exception_table_entry *fixup, >>> + struct pt_regs *regs, unsigned long error_code) >>> +{ >>> + struct pt_regs *uregs = (struct pt_regs *)(regs->sp - offsetof(struct pt_regs, ip)); >>> + unsigned short ss = uregs->ss; >>> + unsigned short cs = uregs->cs; >>> + >>> + fred_info(uregs)->edata = fred_event_data(regs); >>> + uregs->ssx = regs->ssx; >>> + uregs->ss = ss; >>> + uregs->csx = regs->csx; >>> + uregs->current_stack_level = 0; >>> + uregs->cs = cs; >> Hello >> >> If the ERETU instruction had tried to return from NMI to ring3 and just faulted, >> is NMI still blocked? >> >> We know that IRET unconditionally enables NMI, but I can't find any clue in the >> FRED's manual. >> >> In the pseudocode of ERETU in the manual, it seems that NMI is only enabled when >> ERETU succeeds with bit28 in csx set. If so, this code will fail to reenable >> NMI if bit28 is not explicitly re-set in csx. > >IRET clearing NMI blocking is the source of an immense amount of grief, >and ultimately the reason why Linux and others can't use supervisor >shadow stacks at the moment. > >Changing this property, so NMIs only get unblocked on successful >execution of an ERET{S,U}, was a key demand of the FRED spec. > >i.e. until you have successfully ERET*'d, you're still logically in the >NMI handler and NMIs need to remain blocked even when handling the #GP >from a bad ERET. > >~Andrew This is correct.