When a vCPU is interrupted by a signal while running a nested guest, KVM will exit to userspace with L2 state. However, userspace has no way to know whether it sees L1 or L2 state (besides calling KVM_GET_STATS_FD, which does not have a stable ABI). This causes multiple problems: The simplest one is L2 state corruption when userspace marks the sregs as dirty. See this mailing list thread [1] for a complete discussion. Another problem is that if userspace decides to continue by emulating instructions, it will unknowingly emulate with L2 state as if L1 doesn't exist, which can be considered a weird guest escape. Introduce a new flag, KVM_RUN_X86_GUEST_MODE, in the kvm_run data structure, which is set when the vCPU exited while running a nested guest. Also introduce a new capability, KVM_CAP_X86_GUEST_MODE, to advertise the functionality to userspace. [1] https://lore.kernel.org/kvm/20240416123558.212040-1-julian.stecklina@cyberus-technology.de/T/#m280aadcb2e10ae02c191a7dc4ed4b711a74b1f55
Unified · Split
| @@ -6419,6 +6419,9 @@ affect the device's behavior. Current defined flags:: · 6418 unmodified lines | |||
| 6419 | #define KVM_RUN_X86_SMM (1 << 0) | 6419 | #define KVM_RUN_X86_SMM (1 << 0) |
| 6420 | /* x86, set if bus lock detected in VM */ | 6420 | /* x86, set if bus lock detected in VM */ |
| 6421 | #define KVM_RUN_X86_BUS_LOCK (1 << 1) | 6421 | #define KVM_RUN_X86_BUS_LOCK (1 << 1) |
| 6422 | /* x86, set if the VCPU is executing a nested (L2) guest */ | ||
| 6423 | #define KVM_RUN_X86_GUEST_MODE (1 << 2) | ||
| 6424 | |||
| 6422 | /* arm64, set for KVM_EXIT_DEBUG */ | 6425 | /* arm64, set for KVM_EXIT_DEBUG */ |
| 6423 | #define KVM_DEBUG_ARCH_HSR_HIGH_VALID (1 << 0) | 6426 | #define KVM_DEBUG_ARCH_HSR_HIGH_VALID (1 << 0) |
| 6424 | 6427 | ||
| @@ -8089,6 +8092,20 @@ by KVM_CHECK_EXTENSION. · 1664 unmodified lines | |||
| 8089 | Note: Userspace is responsible for correctly configuring CPUID 0x15, a.k.a. the | 8092 | Note: Userspace is responsible for correctly configuring CPUID 0x15, a.k.a. the |
| 8090 | core crystal clock frequency, if a non-zero CPUID 0x15 is exposed to the guest. | 8093 | core crystal clock frequency, if a non-zero CPUID 0x15 is exposed to the guest. |
| 8091 | 8094 | ||
| 8095 | 7.36 KVM_CAP_X86_GUEST_MODE | ||
| 8096 | ------------------------------ | ||
| 8097 | |||
| 8098 | :Architectures: x86 | ||
| 8099 | :Returns: Informational only, -EINVAL on direct KVM_ENABLE_CAP. | ||
| 8100 | |||
| 8101 | The presence of this capability indicates that KVM_RUN will update the | ||
| 8102 | KVM_RUN_X86_GUEST_MODE bit in kvm_run.flags to indicate whether the | ||
| 8103 | vCPU was executing nested guest code when it exited. | ||
| 8104 | |||
| 8105 | KVM exits with the register state of either the L1 or L2 guest | ||
| 8106 | depending on which executed at the time of an exit. Userspace must | ||
| 8107 | take care to differentiate between these cases. | ||
| 8108 | |||
| 8092 | 8. Other capabilities. | 8109 | 8. Other capabilities. |
| 8093 | ====================== | 8110 | ====================== |
| 8094 | 8111 | ||
| @@ -106,6 +106,7 @@ struct kvm_ioapic_state { · 105 unmodified lines | |||
| 106 | 106 | ||
| 107 | #define KVM_RUN_X86_SMM (1 << 0) | 107 | #define KVM_RUN_X86_SMM (1 << 0) |
| 108 | #define KVM_RUN_X86_BUS_LOCK (1 << 1) | 108 | #define KVM_RUN_X86_BUS_LOCK (1 << 1) |
| 109 | #define KVM_RUN_X86_GUEST_MODE (1 << 2) | ||
| 109 | 110 | ||
| 110 | /* for KVM_GET_REGS and KVM_SET_REGS */ | 111 | /* for KVM_GET_REGS and KVM_SET_REGS */ |
| 111 | struct kvm_regs { | 112 | struct kvm_regs { |
| @@ -4704,6 +4704,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 4703 unmodified lines | |||
| 4704 | case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: | 4704 | case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: |
| 4705 | case KVM_CAP_IRQFD_RESAMPLE: | 4705 | case KVM_CAP_IRQFD_RESAMPLE: |
| 4706 | case KVM_CAP_MEMORY_FAULT_INFO: | 4706 | case KVM_CAP_MEMORY_FAULT_INFO: |
| 4707 | case KVM_CAP_X86_GUEST_MODE: | ||
| 4707 | r = 1; | 4708 | r = 1; |
| 4708 | break; | 4709 | break; |
| 4709 | case KVM_CAP_X86_APIC_BUS_CYCLES_NS: | 4710 | case KVM_CAP_X86_APIC_BUS_CYCLES_NS: |
| @@ -10277,6 +10278,8 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu) · 5567 unmodified lines | |||
| 10277 | 10278 | ||
| 10278 | if (is_smm(vcpu)) | 10279 | if (is_smm(vcpu)) |
| 10279 | kvm_run->flags |= KVM_RUN_X86_SMM; | 10280 | kvm_run->flags |= KVM_RUN_X86_SMM; |
| 10281 | if (is_guest_mode(vcpu)) | ||
| 10282 | kvm_run->flags |= KVM_RUN_X86_GUEST_MODE; | ||
| 10280 | } | 10283 | } |
| 10281 | 10284 | ||
| 10282 | static void update_cr8_intercept(struct kvm_vcpu *vcpu) | 10285 | static void update_cr8_intercept(struct kvm_vcpu *vcpu) |
| @@ -918,6 +918,7 @@ struct kvm_enable_cap { · 917 unmodified lines | |||
| 918 | #define KVM_CAP_GUEST_MEMFD 234 | 918 | #define KVM_CAP_GUEST_MEMFD 234 |
| 919 | #define KVM_CAP_VM_TYPES 235 | 919 | #define KVM_CAP_VM_TYPES 235 |
| 920 | #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 236 | 920 | #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 236 |
| 921 | #define KVM_CAP_X86_GUEST_MODE 237 | ||
| 921 | 922 | ||
| 922 | struct kvm_irq_routing_irqchip { | 923 | struct kvm_irq_routing_irqchip { |
| 923 | __u32 irqchip; | 924 | __u32 irqchip; |