> >+                    else if (is_nm_fault(intr_info) &&
> >+                             vcpu->arch.guest_fpu.fpstate->xfd)
> 
> does this necessarily mean the #NM is caused by XFD?

Then the event data should be 0.  Or I missed something obvious? I.e.,
it can be easily differentiated and we should just explicitly set it
to 0.

> 
> >+                            event_data = vcpu->arch.guest_fpu.xfd_err;
> >+
> >+                    vmcs_write64(INJECTED_EVENT_DATA, event_data);
> >+            }
> >+    }
> >+
> >     vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
> >
> >     vmx_clear_hlt(vcpu);
> >@@ -7226,7 +7247,8 @@ static void vmx_recover_nmi_blocking(struct
> >vcpu_vmx *vmx)  static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu,
> >                                   u32 idt_vectoring_info,
> >                                   int instr_len_field,
> >-                                  int error_code_field)
> >+                                  int error_code_field,
> >+                                  int event_data_field)
> 
> event_data_field is used to indicate whether this is a "cancel". I may think 
> it is
> better to simply use a boolean e.g., bool cancel.

I'm fine with the idea if no objections.

> 
> 
> > {
> >     u8 vector;
> >     int type;
> >@@ -7260,6 +7282,37 @@ static void __vmx_complete_interrupts(struct
> kvm_vcpu *vcpu,
> >             vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field);
> >             fallthrough;
> >     case INTR_TYPE_HARD_EXCEPTION:
> >+            if (kvm_is_fred_enabled(vcpu) && event_data_field) {
> >+                    /*
> >+                     * Save original-event data for being used as injected-
> event data.
> >+                     */
> 
> Looks we also expect CPU will update CR2/DR6/XFD_ERR. this hunk looks to me
> just a paranoid check to ensure the cpu works as expected. if that's the 
> case, I
> suggest documenting it a bit in the comment.

These checks are not intended for hw, they make sure nVMX FRED is correctly
implemented and catch regressions.

And yes, in the early stage, I prefer to be paranoid.

> 
> >+                    u64 event_data = vmcs_read64(event_data_field);
> >+
> >+                    switch (vector) {
> >+                    case DB_VECTOR:
> >+                            get_debugreg(vcpu->arch.dr6, 6);
> >+                            WARN_ON(vcpu->arch.dr6 != (event_data ^
> DR6_RESERVED));
> >+                            vcpu->arch.dr6 = event_data ^ DR6_RESERVED;
> >+                            break;
> >+                    case NM_VECTOR:
> >+                            if (vcpu->arch.guest_fpu.fpstate->xfd) {
> >+                                    rdmsrl(MSR_IA32_XFD_ERR, vcpu-
> >arch.guest_fpu.xfd_err);
> >+                                    WARN_ON(vcpu-
> >arch.guest_fpu.xfd_err != event_data);
> >+                                    vcpu->arch.guest_fpu.xfd_err =
> event_data;
> >+                            } else {
> >+                                    WARN_ON(event_data != 0);
> >+                            }
> >+                            break;
> >+                    case PF_VECTOR:
> >+                            WARN_ON(vcpu->arch.cr2 != event_data);
> >+                            vcpu->arch.cr2 = event_data;
> >+                            break;
> >+                    default:
> >+                            WARN_ON(event_data != 0);
> 
> I am not sure if this WARN_ON() can be triggeded by nested VMX. It is 
> legitimate
> for L1 VMM to inject any event w/ an event_data.
> 
> FRED spec says:
> 
> Section 5.2.1 specifies the event data that FRED event delivery of certain 
> events
> saves on the stack. When FRED event delivery is used for an event injected by 
> VM
> entry, the event data saved is the value of the injected-event-data field in 
> the
> VMCS. This value is used instead of what is specified in Section 5.2.1 and is 
> done
> for __ALL__ injected events using FRED event delivery

5.2.1 Saving Information on the Regular Stack also says:
- For any other event, the event data are not currently defined and will
  be zero until they are.

Or you mean something else?

Reply via email to