提交 63623fd4 编写于 作者: L Linus Torvalds

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini:
 "Bugfixes, including the fix for CVE-2020-2732 and a few issues found
  by 'make W=1'"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: s390: rstify new ioctls in api.rst
  KVM: nVMX: Check IO instruction VM-exit conditions
  KVM: nVMX: Refactor IO bitmap checks into helper function
  KVM: nVMX: Don't emulate instructions in guest mode
  KVM: nVMX: Emulate MTF when performing instruction emulation
  KVM: fix error handling in svm_hardware_setup
  KVM: SVM: Fix potential memory leak in svm_cpu_init()
  KVM: apic: avoid calculating pending eoi from an uninitialized val
  KVM: nVMX: clear PIN_BASED_POSTED_INTR from nested pinbased_ctls only when apicv is globally disabled
  KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1
  kvm: x86: svm: Fix NULL pointer dereference when AVIC not enabled
  KVM: VMX: Add VMX_FEATURE_USR_WAIT_PAUSE
  KVM: nVMX: Hold KVM's srcu lock when syncing vmcs12->shadow
  KVM: x86: don't notify userspace IOAPIC on edge-triggered interrupt EOI
  kvm/emulate: fix a -Werror=cast-function-type
  KVM: x86: fix incorrect comparison in trace event
  KVM: nVMX: Fix some obsolete comments and grammar error
  KVM: x86: fix missing prototypes
  KVM: x86: enable -Werror
...@@ -4611,35 +4611,38 @@ unpins the VPA pages and releases all the device pages that are used to ...@@ -4611,35 +4611,38 @@ unpins the VPA pages and releases all the device pages that are used to
track the secure pages by hypervisor. track the secure pages by hypervisor.
4.122 KVM_S390_NORMAL_RESET 4.122 KVM_S390_NORMAL_RESET
---------------------------
Capability: KVM_CAP_S390_VCPU_RESETS :Capability: KVM_CAP_S390_VCPU_RESETS
Architectures: s390 :Architectures: s390
Type: vcpu ioctl :Type: vcpu ioctl
Parameters: none :Parameters: none
Returns: 0 :Returns: 0
This ioctl resets VCPU registers and control structures according to This ioctl resets VCPU registers and control structures according to
the cpu reset definition in the POP (Principles Of Operation). the cpu reset definition in the POP (Principles Of Operation).
4.123 KVM_S390_INITIAL_RESET 4.123 KVM_S390_INITIAL_RESET
----------------------------
Capability: none :Capability: none
Architectures: s390 :Architectures: s390
Type: vcpu ioctl :Type: vcpu ioctl
Parameters: none :Parameters: none
Returns: 0 :Returns: 0
This ioctl resets VCPU registers and control structures according to This ioctl resets VCPU registers and control structures according to
the initial cpu reset definition in the POP. However, the cpu is not the initial cpu reset definition in the POP. However, the cpu is not
put into ESA mode. This reset is a superset of the normal reset. put into ESA mode. This reset is a superset of the normal reset.
4.124 KVM_S390_CLEAR_RESET 4.124 KVM_S390_CLEAR_RESET
--------------------------
Capability: KVM_CAP_S390_VCPU_RESETS :Capability: KVM_CAP_S390_VCPU_RESETS
Architectures: s390 :Architectures: s390
Type: vcpu ioctl :Type: vcpu ioctl
Parameters: none :Parameters: none
Returns: 0 :Returns: 0
This ioctl resets VCPU registers and control structures according to This ioctl resets VCPU registers and control structures according to
the clear cpu reset definition in the POP. However, the cpu is not put the clear cpu reset definition in the POP. However, the cpu is not put
......
...@@ -292,6 +292,14 @@ enum x86emul_mode { ...@@ -292,6 +292,14 @@ enum x86emul_mode {
#define X86EMUL_SMM_MASK (1 << 6) #define X86EMUL_SMM_MASK (1 << 6)
#define X86EMUL_SMM_INSIDE_NMI_MASK (1 << 7) #define X86EMUL_SMM_INSIDE_NMI_MASK (1 << 7)
/*
* fastop functions are declared as taking a never-defined fastop parameter,
* so they can't be called from C directly.
*/
struct fastop;
typedef void (*fastop_t)(struct fastop *);
struct x86_emulate_ctxt { struct x86_emulate_ctxt {
const struct x86_emulate_ops *ops; const struct x86_emulate_ops *ops;
...@@ -324,7 +332,10 @@ struct x86_emulate_ctxt { ...@@ -324,7 +332,10 @@ struct x86_emulate_ctxt {
struct operand src; struct operand src;
struct operand src2; struct operand src2;
struct operand dst; struct operand dst;
int (*execute)(struct x86_emulate_ctxt *ctxt); union {
int (*execute)(struct x86_emulate_ctxt *ctxt);
fastop_t fop;
};
int (*check_perm)(struct x86_emulate_ctxt *ctxt); int (*check_perm)(struct x86_emulate_ctxt *ctxt);
/* /*
* The following six fields are cleared together, * The following six fields are cleared together,
......
...@@ -1122,6 +1122,7 @@ struct kvm_x86_ops { ...@@ -1122,6 +1122,7 @@ struct kvm_x86_ops {
int (*handle_exit)(struct kvm_vcpu *vcpu, int (*handle_exit)(struct kvm_vcpu *vcpu,
enum exit_fastpath_completion exit_fastpath); enum exit_fastpath_completion exit_fastpath);
int (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); int (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
void (*update_emulated_instruction)(struct kvm_vcpu *vcpu);
void (*set_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask); void (*set_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu); u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu);
void (*patch_hypercall)(struct kvm_vcpu *vcpu, void (*patch_hypercall)(struct kvm_vcpu *vcpu,
...@@ -1146,7 +1147,7 @@ struct kvm_x86_ops { ...@@ -1146,7 +1147,7 @@ struct kvm_x86_ops {
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu); void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa); void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); int (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu); int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr); int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr);
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
#define SECONDARY_EXEC_MODE_BASED_EPT_EXEC VMCS_CONTROL_BIT(MODE_BASED_EPT_EXEC) #define SECONDARY_EXEC_MODE_BASED_EPT_EXEC VMCS_CONTROL_BIT(MODE_BASED_EPT_EXEC)
#define SECONDARY_EXEC_PT_USE_GPA VMCS_CONTROL_BIT(PT_USE_GPA) #define SECONDARY_EXEC_PT_USE_GPA VMCS_CONTROL_BIT(PT_USE_GPA)
#define SECONDARY_EXEC_TSC_SCALING VMCS_CONTROL_BIT(TSC_SCALING) #define SECONDARY_EXEC_TSC_SCALING VMCS_CONTROL_BIT(TSC_SCALING)
#define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE 0x04000000 #define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE VMCS_CONTROL_BIT(USR_WAIT_PAUSE)
#define PIN_BASED_EXT_INTR_MASK VMCS_CONTROL_BIT(INTR_EXITING) #define PIN_BASED_EXT_INTR_MASK VMCS_CONTROL_BIT(INTR_EXITING)
#define PIN_BASED_NMI_EXITING VMCS_CONTROL_BIT(NMI_EXITING) #define PIN_BASED_NMI_EXITING VMCS_CONTROL_BIT(NMI_EXITING)
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#define VMX_FEATURE_MODE_BASED_EPT_EXEC ( 2*32+ 22) /* "ept_mode_based_exec" Enable separate EPT EXEC bits for supervisor vs. user */ #define VMX_FEATURE_MODE_BASED_EPT_EXEC ( 2*32+ 22) /* "ept_mode_based_exec" Enable separate EPT EXEC bits for supervisor vs. user */
#define VMX_FEATURE_PT_USE_GPA ( 2*32+ 24) /* "" Processor Trace logs GPAs */ #define VMX_FEATURE_PT_USE_GPA ( 2*32+ 24) /* "" Processor Trace logs GPAs */
#define VMX_FEATURE_TSC_SCALING ( 2*32+ 25) /* Scale hardware TSC when read in guest */ #define VMX_FEATURE_TSC_SCALING ( 2*32+ 25) /* Scale hardware TSC when read in guest */
#define VMX_FEATURE_USR_WAIT_PAUSE ( 2*32+ 26) /* Enable TPAUSE, UMONITOR, UMWAIT in guest */
#define VMX_FEATURE_ENCLV_EXITING ( 2*32+ 28) /* "" VM-Exit on ENCLV (leaf dependent) */ #define VMX_FEATURE_ENCLV_EXITING ( 2*32+ 28) /* "" VM-Exit on ENCLV (leaf dependent) */
#endif /* _ASM_X86_VMXFEATURES_H */ #endif /* _ASM_X86_VMXFEATURES_H */
...@@ -390,6 +390,7 @@ struct kvm_sync_regs { ...@@ -390,6 +390,7 @@ struct kvm_sync_regs {
#define KVM_STATE_NESTED_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_GUEST_MODE 0x00000001
#define KVM_STATE_NESTED_RUN_PENDING 0x00000002 #define KVM_STATE_NESTED_RUN_PENDING 0x00000002
#define KVM_STATE_NESTED_EVMCS 0x00000004 #define KVM_STATE_NESTED_EVMCS 0x00000004
#define KVM_STATE_NESTED_MTF_PENDING 0x00000008
#define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001
#define KVM_STATE_NESTED_SMM_VMXON 0x00000002 #define KVM_STATE_NESTED_SMM_VMXON 0x00000002
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
ccflags-y += -Iarch/x86/kvm ccflags-y += -Iarch/x86/kvm
ccflags-y += -Werror
KVM := ../../../virt/kvm KVM := ../../../virt/kvm
......
...@@ -191,25 +191,6 @@ ...@@ -191,25 +191,6 @@
#define NR_FASTOP (ilog2(sizeof(ulong)) + 1) #define NR_FASTOP (ilog2(sizeof(ulong)) + 1)
#define FASTOP_SIZE 8 #define FASTOP_SIZE 8
/*
* fastop functions have a special calling convention:
*
* dst: rax (in/out)
* src: rdx (in/out)
* src2: rcx (in)
* flags: rflags (in/out)
* ex: rsi (in:fastop pointer, out:zero if exception)
*
* Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for
* different operand sizes can be reached by calculation, rather than a jump
* table (which would be bigger than the code).
*
* fastop functions are declared as taking a never-defined fastop parameter,
* so they can't be called from C directly.
*/
struct fastop;
struct opcode { struct opcode {
u64 flags : 56; u64 flags : 56;
u64 intercept : 8; u64 intercept : 8;
...@@ -311,8 +292,19 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) ...@@ -311,8 +292,19 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
#define ON64(x) #define ON64(x)
#endif #endif
typedef void (*fastop_t)(struct fastop *); /*
* fastop functions have a special calling convention:
*
* dst: rax (in/out)
* src: rdx (in/out)
* src2: rcx (in)
* flags: rflags (in/out)
* ex: rsi (in:fastop pointer, out:zero if exception)
*
* Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for
* different operand sizes can be reached by calculation, rather than a jump
* table (which would be bigger than the code).
*/
static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop); static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop);
#define __FOP_FUNC(name) \ #define __FOP_FUNC(name) \
...@@ -5683,7 +5675,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -5683,7 +5675,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
if (ctxt->execute) { if (ctxt->execute) {
if (ctxt->d & Fastop) if (ctxt->d & Fastop)
rc = fastop(ctxt, (fastop_t)ctxt->execute); rc = fastop(ctxt, ctxt->fop);
else else
rc = ctxt->execute(ctxt); rc = ctxt->execute(ctxt);
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
......
...@@ -417,7 +417,7 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, ...@@ -417,7 +417,7 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
kvm_set_msi_irq(vcpu->kvm, entry, &irq); kvm_set_msi_irq(vcpu->kvm, entry, &irq);
if (irq.level && if (irq.trig_mode &&
kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT, kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
irq.dest_id, irq.dest_mode)) irq.dest_id, irq.dest_mode))
__set_bit(irq.vector, ioapic_handled_vectors); __set_bit(irq.vector, ioapic_handled_vectors);
......
...@@ -627,9 +627,11 @@ static inline bool pv_eoi_enabled(struct kvm_vcpu *vcpu) ...@@ -627,9 +627,11 @@ static inline bool pv_eoi_enabled(struct kvm_vcpu *vcpu)
static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu)
{ {
u8 val; u8 val;
if (pv_eoi_get_user(vcpu, &val) < 0) if (pv_eoi_get_user(vcpu, &val) < 0) {
printk(KERN_WARNING "Can't read EOI MSR value: 0x%llx\n", printk(KERN_WARNING "Can't read EOI MSR value: 0x%llx\n",
(unsigned long long)vcpu->arch.pv_eoi.msr_val); (unsigned long long)vcpu->arch.pv_eoi.msr_val);
return false;
}
return val & 0x1; return val & 0x1;
} }
...@@ -1046,11 +1048,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, ...@@ -1046,11 +1048,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
apic->regs + APIC_TMR); apic->regs + APIC_TMR);
} }
if (vcpu->arch.apicv_active) if (kvm_x86_ops->deliver_posted_interrupt(vcpu, vector)) {
kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
else {
kvm_lapic_set_irr(vector, apic); kvm_lapic_set_irr(vector, apic);
kvm_make_request(KVM_REQ_EVENT, vcpu); kvm_make_request(KVM_REQ_EVENT, vcpu);
kvm_vcpu_kick(vcpu); kvm_vcpu_kick(vcpu);
} }
......
...@@ -339,7 +339,7 @@ TRACE_EVENT( ...@@ -339,7 +339,7 @@ TRACE_EVENT(
/* These depend on page entry type, so compute them now. */ /* These depend on page entry type, so compute them now. */
__field(bool, r) __field(bool, r)
__field(bool, x) __field(bool, x)
__field(u8, u) __field(signed char, u)
), ),
TP_fast_assign( TP_fast_assign(
......
...@@ -1005,33 +1005,32 @@ static void svm_cpu_uninit(int cpu) ...@@ -1005,33 +1005,32 @@ static void svm_cpu_uninit(int cpu)
static int svm_cpu_init(int cpu) static int svm_cpu_init(int cpu)
{ {
struct svm_cpu_data *sd; struct svm_cpu_data *sd;
int r;
sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL); sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL);
if (!sd) if (!sd)
return -ENOMEM; return -ENOMEM;
sd->cpu = cpu; sd->cpu = cpu;
r = -ENOMEM;
sd->save_area = alloc_page(GFP_KERNEL); sd->save_area = alloc_page(GFP_KERNEL);
if (!sd->save_area) if (!sd->save_area)
goto err_1; goto free_cpu_data;
if (svm_sev_enabled()) { if (svm_sev_enabled()) {
r = -ENOMEM;
sd->sev_vmcbs = kmalloc_array(max_sev_asid + 1, sd->sev_vmcbs = kmalloc_array(max_sev_asid + 1,
sizeof(void *), sizeof(void *),
GFP_KERNEL); GFP_KERNEL);
if (!sd->sev_vmcbs) if (!sd->sev_vmcbs)
goto err_1; goto free_save_area;
} }
per_cpu(svm_data, cpu) = sd; per_cpu(svm_data, cpu) = sd;
return 0; return 0;
err_1: free_save_area:
__free_page(sd->save_area);
free_cpu_data:
kfree(sd); kfree(sd);
return r; return -ENOMEM;
} }
...@@ -1350,6 +1349,24 @@ static __init void svm_adjust_mmio_mask(void) ...@@ -1350,6 +1349,24 @@ static __init void svm_adjust_mmio_mask(void)
kvm_mmu_set_mmio_spte_mask(mask, mask, PT_WRITABLE_MASK | PT_USER_MASK); kvm_mmu_set_mmio_spte_mask(mask, mask, PT_WRITABLE_MASK | PT_USER_MASK);
} }
static void svm_hardware_teardown(void)
{
int cpu;
if (svm_sev_enabled()) {
bitmap_free(sev_asid_bitmap);
bitmap_free(sev_reclaim_asid_bitmap);
sev_flush_asids();
}
for_each_possible_cpu(cpu)
svm_cpu_uninit(cpu);
__free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER);
iopm_base = 0;
}
static __init int svm_hardware_setup(void) static __init int svm_hardware_setup(void)
{ {
int cpu; int cpu;
...@@ -1463,29 +1480,10 @@ static __init int svm_hardware_setup(void) ...@@ -1463,29 +1480,10 @@ static __init int svm_hardware_setup(void)
return 0; return 0;
err: err:
__free_pages(iopm_pages, IOPM_ALLOC_ORDER); svm_hardware_teardown();
iopm_base = 0;
return r; return r;
} }
static __exit void svm_hardware_unsetup(void)
{
int cpu;
if (svm_sev_enabled()) {
bitmap_free(sev_asid_bitmap);
bitmap_free(sev_reclaim_asid_bitmap);
sev_flush_asids();
}
for_each_possible_cpu(cpu)
svm_cpu_uninit(cpu);
__free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER);
iopm_base = 0;
}
static void init_seg(struct vmcb_seg *seg) static void init_seg(struct vmcb_seg *seg)
{ {
seg->selector = 0; seg->selector = 0;
...@@ -5232,6 +5230,9 @@ static void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) ...@@ -5232,6 +5230,9 @@ static void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
struct vmcb *vmcb = svm->vmcb; struct vmcb *vmcb = svm->vmcb;
bool activated = kvm_vcpu_apicv_active(vcpu); bool activated = kvm_vcpu_apicv_active(vcpu);
if (!avic)
return;
if (activated) { if (activated) {
/** /**
* During AVIC temporary deactivation, guest could update * During AVIC temporary deactivation, guest could update
...@@ -5255,8 +5256,11 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) ...@@ -5255,8 +5256,11 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
return; return;
} }
static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec) static int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
{ {
if (!vcpu->arch.apicv_active)
return -1;
kvm_lapic_set_irr(vec, vcpu->arch.apic); kvm_lapic_set_irr(vec, vcpu->arch.apic);
smp_mb__after_atomic(); smp_mb__after_atomic();
...@@ -5268,6 +5272,8 @@ static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec) ...@@ -5268,6 +5272,8 @@ static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
put_cpu(); put_cpu();
} else } else
kvm_vcpu_wake_up(vcpu); kvm_vcpu_wake_up(vcpu);
return 0;
} }
static bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu) static bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
...@@ -7378,7 +7384,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { ...@@ -7378,7 +7384,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
.cpu_has_kvm_support = has_svm, .cpu_has_kvm_support = has_svm,
.disabled_by_bios = is_disabled, .disabled_by_bios = is_disabled,
.hardware_setup = svm_hardware_setup, .hardware_setup = svm_hardware_setup,
.hardware_unsetup = svm_hardware_unsetup, .hardware_unsetup = svm_hardware_teardown,
.check_processor_compatibility = svm_check_processor_compat, .check_processor_compatibility = svm_check_processor_compat,
.hardware_enable = svm_hardware_enable, .hardware_enable = svm_hardware_enable,
.hardware_disable = svm_hardware_disable, .hardware_disable = svm_hardware_disable,
...@@ -7433,6 +7439,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { ...@@ -7433,6 +7439,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
.run = svm_vcpu_run, .run = svm_vcpu_run,
.handle_exit = handle_exit, .handle_exit = handle_exit,
.skip_emulated_instruction = skip_emulated_instruction, .skip_emulated_instruction = skip_emulated_instruction,
.update_emulated_instruction = NULL,
.set_interrupt_shadow = svm_set_interrupt_shadow, .set_interrupt_shadow = svm_set_interrupt_shadow,
.get_interrupt_shadow = svm_get_interrupt_shadow, .get_interrupt_shadow = svm_get_interrupt_shadow,
.patch_hypercall = svm_patch_hypercall, .patch_hypercall = svm_patch_hypercall,
......
...@@ -12,6 +12,7 @@ extern bool __read_mostly enable_ept; ...@@ -12,6 +12,7 @@ extern bool __read_mostly enable_ept;
extern bool __read_mostly enable_unrestricted_guest; extern bool __read_mostly enable_unrestricted_guest;
extern bool __read_mostly enable_ept_ad_bits; extern bool __read_mostly enable_ept_ad_bits;
extern bool __read_mostly enable_pml; extern bool __read_mostly enable_pml;
extern bool __read_mostly enable_apicv;
extern int __read_mostly pt_mode; extern int __read_mostly pt_mode;
#define PT_MODE_SYSTEM 0 #define PT_MODE_SYSTEM 0
......
...@@ -3161,10 +3161,10 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, ...@@ -3161,10 +3161,10 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
* or KVM_SET_NESTED_STATE). Otherwise it's called from vmlaunch/vmresume. * or KVM_SET_NESTED_STATE). Otherwise it's called from vmlaunch/vmresume.
* *
* Returns: * Returns:
* NVMX_ENTRY_SUCCESS: Entered VMX non-root mode * NVMX_VMENTRY_SUCCESS: Entered VMX non-root mode
* NVMX_ENTRY_VMFAIL: Consistency check VMFail * NVMX_VMENTRY_VMFAIL: Consistency check VMFail
* NVMX_ENTRY_VMEXIT: Consistency check VMExit * NVMX_VMENTRY_VMEXIT: Consistency check VMExit
* NVMX_ENTRY_KVM_INTERNAL_ERROR: KVM internal error * NVMX_VMENTRY_KVM_INTERNAL_ERROR: KVM internal error
*/ */
enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu,
bool from_vmentry) bool from_vmentry)
...@@ -3609,8 +3609,15 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr) ...@@ -3609,8 +3609,15 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
unsigned long exit_qual; unsigned long exit_qual;
bool block_nested_events = bool block_nested_events =
vmx->nested.nested_run_pending || kvm_event_needs_reinjection(vcpu); vmx->nested.nested_run_pending || kvm_event_needs_reinjection(vcpu);
bool mtf_pending = vmx->nested.mtf_pending;
struct kvm_lapic *apic = vcpu->arch.apic; struct kvm_lapic *apic = vcpu->arch.apic;
/*
* Clear the MTF state. If a higher priority VM-exit is delivered first,
* this state is discarded.
*/
vmx->nested.mtf_pending = false;
if (lapic_in_kernel(vcpu) && if (lapic_in_kernel(vcpu) &&
test_bit(KVM_APIC_INIT, &apic->pending_events)) { test_bit(KVM_APIC_INIT, &apic->pending_events)) {
if (block_nested_events) if (block_nested_events)
...@@ -3621,8 +3628,28 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr) ...@@ -3621,8 +3628,28 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
return 0; return 0;
} }
/*
* Process any exceptions that are not debug traps before MTF.
*/
if (vcpu->arch.exception.pending &&
!vmx_pending_dbg_trap(vcpu) &&
nested_vmx_check_exception(vcpu, &exit_qual)) {
if (block_nested_events)
return -EBUSY;
nested_vmx_inject_exception_vmexit(vcpu, exit_qual);
return 0;
}
if (mtf_pending) {
if (block_nested_events)
return -EBUSY;
nested_vmx_update_pending_dbg(vcpu);
nested_vmx_vmexit(vcpu, EXIT_REASON_MONITOR_TRAP_FLAG, 0, 0);
return 0;
}
if (vcpu->arch.exception.pending && if (vcpu->arch.exception.pending &&
nested_vmx_check_exception(vcpu, &exit_qual)) { nested_vmx_check_exception(vcpu, &exit_qual)) {
if (block_nested_events) if (block_nested_events)
return -EBUSY; return -EBUSY;
nested_vmx_inject_exception_vmexit(vcpu, exit_qual); nested_vmx_inject_exception_vmexit(vcpu, exit_qual);
...@@ -5285,24 +5312,17 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu) ...@@ -5285,24 +5312,17 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu)
return 1; return 1;
} }
/*
static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, * Return true if an IO instruction with the specified port and size should cause
struct vmcs12 *vmcs12) * a VM-exit into L1.
*/
bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port,
int size)
{ {
unsigned long exit_qualification; struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
gpa_t bitmap, last_bitmap; gpa_t bitmap, last_bitmap;
unsigned int port;
int size;
u8 b; u8 b;
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING);
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
port = exit_qualification >> 16;
size = (exit_qualification & 7) + 1;
last_bitmap = (gpa_t)-1; last_bitmap = (gpa_t)-1;
b = -1; b = -1;
...@@ -5329,8 +5349,26 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, ...@@ -5329,8 +5349,26 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
return false; return false;
} }
static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
struct vmcs12 *vmcs12)
{
unsigned long exit_qualification;
unsigned short port;
int size;
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING);
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
port = exit_qualification >> 16;
size = (exit_qualification & 7) + 1;
return nested_vmx_check_io_bitmaps(vcpu, port, size);
}
/* /*
* Return 1 if we should exit from L2 to L1 to handle an MSR access access, * Return 1 if we should exit from L2 to L1 to handle an MSR access,
* rather than handle it ourselves in L0. I.e., check whether L1 expressed * rather than handle it ourselves in L0. I.e., check whether L1 expressed
* disinterest in the current event (read or write a specific MSR) by using an * disinterest in the current event (read or write a specific MSR) by using an
* MSR bitmap. This may be the case even when L0 doesn't use MSR bitmaps. * MSR bitmap. This may be the case even when L0 doesn't use MSR bitmaps.
...@@ -5712,6 +5750,9 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, ...@@ -5712,6 +5750,9 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu,
if (vmx->nested.nested_run_pending) if (vmx->nested.nested_run_pending)
kvm_state.flags |= KVM_STATE_NESTED_RUN_PENDING; kvm_state.flags |= KVM_STATE_NESTED_RUN_PENDING;
if (vmx->nested.mtf_pending)
kvm_state.flags |= KVM_STATE_NESTED_MTF_PENDING;
} }
} }
...@@ -5892,6 +5933,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, ...@@ -5892,6 +5933,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
vmx->nested.nested_run_pending = vmx->nested.nested_run_pending =
!!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING); !!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING);
vmx->nested.mtf_pending =
!!(kvm_state->flags & KVM_STATE_NESTED_MTF_PENDING);
ret = -EINVAL; ret = -EINVAL;
if (nested_cpu_has_shadow_vmcs(vmcs12) && if (nested_cpu_has_shadow_vmcs(vmcs12) &&
vmcs12->vmcs_link_pointer != -1ull) { vmcs12->vmcs_link_pointer != -1ull) {
...@@ -5949,8 +5993,7 @@ void nested_vmx_set_vmcs_shadowing_bitmap(void) ...@@ -5949,8 +5993,7 @@ void nested_vmx_set_vmcs_shadowing_bitmap(void)
* bit in the high half is on if the corresponding bit in the control field * bit in the high half is on if the corresponding bit in the control field
* may be on. See also vmx_control_verify(). * may be on. See also vmx_control_verify().
*/ */
void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps, void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
bool apicv)
{ {
/* /*
* Note that as a general rule, the high half of the MSRs (bits in * Note that as a general rule, the high half of the MSRs (bits in
...@@ -5977,7 +6020,7 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps, ...@@ -5977,7 +6020,7 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps,
PIN_BASED_EXT_INTR_MASK | PIN_BASED_EXT_INTR_MASK |
PIN_BASED_NMI_EXITING | PIN_BASED_NMI_EXITING |
PIN_BASED_VIRTUAL_NMIS | PIN_BASED_VIRTUAL_NMIS |
(apicv ? PIN_BASED_POSTED_INTR : 0); (enable_apicv ? PIN_BASED_POSTED_INTR : 0);
msrs->pinbased_ctls_high |= msrs->pinbased_ctls_high |=
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
PIN_BASED_VMX_PREEMPTION_TIMER; PIN_BASED_VMX_PREEMPTION_TIMER;
......
...@@ -17,8 +17,7 @@ enum nvmx_vmentry_status { ...@@ -17,8 +17,7 @@ enum nvmx_vmentry_status {
}; };
void vmx_leave_nested(struct kvm_vcpu *vcpu); void vmx_leave_nested(struct kvm_vcpu *vcpu);
void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps, void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps);
bool apicv);
void nested_vmx_hardware_unsetup(void); void nested_vmx_hardware_unsetup(void);
__init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)); __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *));
void nested_vmx_set_vmcs_shadowing_bitmap(void); void nested_vmx_set_vmcs_shadowing_bitmap(void);
...@@ -34,6 +33,8 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata); ...@@ -34,6 +33,8 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata);
int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification, int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification,
u32 vmx_instruction_info, bool wr, int len, gva_t *ret); u32 vmx_instruction_info, bool wr, int len, gva_t *ret);
void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu); void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu);
bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port,
int size);
static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu) static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
{ {
...@@ -175,6 +176,11 @@ static inline bool nested_cpu_has_virtual_nmis(struct vmcs12 *vmcs12) ...@@ -175,6 +176,11 @@ static inline bool nested_cpu_has_virtual_nmis(struct vmcs12 *vmcs12)
return vmcs12->pin_based_vm_exec_control & PIN_BASED_VIRTUAL_NMIS; return vmcs12->pin_based_vm_exec_control & PIN_BASED_VIRTUAL_NMIS;
} }
static inline int nested_cpu_has_mtf(struct vmcs12 *vmcs12)
{
return nested_cpu_has(vmcs12, CPU_BASED_MONITOR_TRAP_FLAG);
}
static inline int nested_cpu_has_ept(struct vmcs12 *vmcs12) static inline int nested_cpu_has_ept(struct vmcs12 *vmcs12)
{ {
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT); return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT);
......
...@@ -95,7 +95,7 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO); ...@@ -95,7 +95,7 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO);
static bool __read_mostly fasteoi = 1; static bool __read_mostly fasteoi = 1;
module_param(fasteoi, bool, S_IRUGO); module_param(fasteoi, bool, S_IRUGO);
static bool __read_mostly enable_apicv = 1; bool __read_mostly enable_apicv = 1;
module_param(enable_apicv, bool, S_IRUGO); module_param(enable_apicv, bool, S_IRUGO);
/* /*
...@@ -1175,6 +1175,10 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) ...@@ -1175,6 +1175,10 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
vmx->guest_msrs[i].mask); vmx->guest_msrs[i].mask);
} }
if (vmx->nested.need_vmcs12_to_shadow_sync)
nested_sync_vmcs12_to_shadow(vcpu);
if (vmx->guest_state_loaded) if (vmx->guest_state_loaded)
return; return;
...@@ -1599,6 +1603,40 @@ static int skip_emulated_instruction(struct kvm_vcpu *vcpu) ...@@ -1599,6 +1603,40 @@ static int skip_emulated_instruction(struct kvm_vcpu *vcpu)
return 1; return 1;
} }
/*
* Recognizes a pending MTF VM-exit and records the nested state for later
* delivery.
*/
static void vmx_update_emulated_instruction(struct kvm_vcpu *vcpu)
{
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
struct vcpu_vmx *vmx = to_vmx(vcpu);
if (!is_guest_mode(vcpu))
return;
/*
* Per the SDM, MTF takes priority over debug-trap exceptions besides
* T-bit traps. As instruction emulation is completed (i.e. at the
* instruction boundary), any #DB exception pending delivery must be a
* debug-trap. Record the pending MTF state to be delivered in
* vmx_check_nested_events().
*/
if (nested_cpu_has_mtf(vmcs12) &&
(!vcpu->arch.exception.pending ||
vcpu->arch.exception.nr == DB_VECTOR))
vmx->nested.mtf_pending = true;
else
vmx->nested.mtf_pending = false;
}
static int vmx_skip_emulated_instruction(struct kvm_vcpu *vcpu)
{
vmx_update_emulated_instruction(vcpu);
return skip_emulated_instruction(vcpu);
}
static void vmx_clear_hlt(struct kvm_vcpu *vcpu) static void vmx_clear_hlt(struct kvm_vcpu *vcpu)
{ {
/* /*
...@@ -3818,24 +3856,29 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, ...@@ -3818,24 +3856,29 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
* 2. If target vcpu isn't running(root mode), kick it to pick up the * 2. If target vcpu isn't running(root mode), kick it to pick up the
* interrupt from PIR in next vmentry. * interrupt from PIR in next vmentry.
*/ */
static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector) static int vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
{ {
struct vcpu_vmx *vmx = to_vmx(vcpu); struct vcpu_vmx *vmx = to_vmx(vcpu);
int r; int r;
r = vmx_deliver_nested_posted_interrupt(vcpu, vector); r = vmx_deliver_nested_posted_interrupt(vcpu, vector);
if (!r) if (!r)
return; return 0;
if (!vcpu->arch.apicv_active)
return -1;
if (pi_test_and_set_pir(vector, &vmx->pi_desc)) if (pi_test_and_set_pir(vector, &vmx->pi_desc))
return; return 0;
/* If a previous notification has sent the IPI, nothing to do. */ /* If a previous notification has sent the IPI, nothing to do. */
if (pi_test_and_set_on(&vmx->pi_desc)) if (pi_test_and_set_on(&vmx->pi_desc))
return; return 0;
if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false)) if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
kvm_vcpu_kick(vcpu); kvm_vcpu_kick(vcpu);
return 0;
} }
/* /*
...@@ -6482,8 +6525,11 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) ...@@ -6482,8 +6525,11 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmcs_write32(PLE_WINDOW, vmx->ple_window); vmcs_write32(PLE_WINDOW, vmx->ple_window);
} }
if (vmx->nested.need_vmcs12_to_shadow_sync) /*
nested_sync_vmcs12_to_shadow(vcpu); * We did this in prepare_switch_to_guest, because it needs to
* be within srcu_read_lock.
*/
WARN_ON_ONCE(vmx->nested.need_vmcs12_to_shadow_sync);
if (kvm_register_is_dirty(vcpu, VCPU_REGS_RSP)) if (kvm_register_is_dirty(vcpu, VCPU_REGS_RSP))
vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]); vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
...@@ -6757,8 +6803,7 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) ...@@ -6757,8 +6803,7 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
if (nested) if (nested)
nested_vmx_setup_ctls_msrs(&vmx->nested.msrs, nested_vmx_setup_ctls_msrs(&vmx->nested.msrs,
vmx_capability.ept, vmx_capability.ept);
kvm_vcpu_apicv_active(vcpu));
else else
memset(&vmx->nested.msrs, 0, sizeof(vmx->nested.msrs)); memset(&vmx->nested.msrs, 0, sizeof(vmx->nested.msrs));
...@@ -6839,8 +6884,7 @@ static int __init vmx_check_processor_compat(void) ...@@ -6839,8 +6884,7 @@ static int __init vmx_check_processor_compat(void)
if (setup_vmcs_config(&vmcs_conf, &vmx_cap) < 0) if (setup_vmcs_config(&vmcs_conf, &vmx_cap) < 0)
return -EIO; return -EIO;
if (nested) if (nested)
nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, vmx_cap.ept, nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, vmx_cap.ept);
enable_apicv);
if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) { if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) {
printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n", printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n",
smp_processor_id()); smp_processor_id());
...@@ -7101,6 +7145,39 @@ static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu) ...@@ -7101,6 +7145,39 @@ static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu)
to_vmx(vcpu)->req_immediate_exit = true; to_vmx(vcpu)->req_immediate_exit = true;
} }
static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info)
{
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
unsigned short port;
bool intercept;
int size;
if (info->intercept == x86_intercept_in ||
info->intercept == x86_intercept_ins) {
port = info->src_val;
size = info->dst_bytes;
} else {
port = info->dst_val;
size = info->src_bytes;
}
/*
* If the 'use IO bitmaps' VM-execution control is 0, IO instruction
* VM-exits depend on the 'unconditional IO exiting' VM-execution
* control.
*
* Otherwise, IO instruction VM-exits are controlled by the IO bitmaps.
*/
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
intercept = nested_cpu_has(vmcs12,
CPU_BASED_UNCOND_IO_EXITING);
else
intercept = nested_vmx_check_io_bitmaps(vcpu, port, size);
return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE;
}
static int vmx_check_intercept(struct kvm_vcpu *vcpu, static int vmx_check_intercept(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info, struct x86_instruction_info *info,
enum x86_intercept_stage stage) enum x86_intercept_stage stage)
...@@ -7108,19 +7185,31 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, ...@@ -7108,19 +7185,31 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
struct vmcs12 *vmcs12 = get_vmcs12(vcpu); struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
switch (info->intercept) {
/* /*
* RDPID causes #UD if disabled through secondary execution controls. * RDPID causes #UD if disabled through secondary execution controls.
* Because it is marked as EmulateOnUD, we need to intercept it here. * Because it is marked as EmulateOnUD, we need to intercept it here.
*/ */
if (info->intercept == x86_intercept_rdtscp && case x86_intercept_rdtscp:
!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) {
ctxt->exception.vector = UD_VECTOR; ctxt->exception.vector = UD_VECTOR;
ctxt->exception.error_code_valid = false; ctxt->exception.error_code_valid = false;
return X86EMUL_PROPAGATE_FAULT; return X86EMUL_PROPAGATE_FAULT;
} }
break;
case x86_intercept_in:
case x86_intercept_ins:
case x86_intercept_out:
case x86_intercept_outs:
return vmx_check_intercept_io(vcpu, info);
/* TODO: check more intercepts... */ /* TODO: check more intercepts... */
return X86EMUL_CONTINUE; default:
break;
}
return X86EMUL_UNHANDLEABLE;
} }
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
...@@ -7702,7 +7791,7 @@ static __init int hardware_setup(void) ...@@ -7702,7 +7791,7 @@ static __init int hardware_setup(void)
if (nested) { if (nested) {
nested_vmx_setup_ctls_msrs(&vmcs_config.nested, nested_vmx_setup_ctls_msrs(&vmcs_config.nested,
vmx_capability.ept, enable_apicv); vmx_capability.ept);
r = nested_vmx_hardware_setup(kvm_vmx_exit_handlers); r = nested_vmx_hardware_setup(kvm_vmx_exit_handlers);
if (r) if (r)
...@@ -7786,7 +7875,8 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = { ...@@ -7786,7 +7875,8 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
.run = vmx_vcpu_run, .run = vmx_vcpu_run,
.handle_exit = vmx_handle_exit, .handle_exit = vmx_handle_exit,
.skip_emulated_instruction = skip_emulated_instruction, .skip_emulated_instruction = vmx_skip_emulated_instruction,
.update_emulated_instruction = vmx_update_emulated_instruction,
.set_interrupt_shadow = vmx_set_interrupt_shadow, .set_interrupt_shadow = vmx_set_interrupt_shadow,
.get_interrupt_shadow = vmx_get_interrupt_shadow, .get_interrupt_shadow = vmx_get_interrupt_shadow,
.patch_hypercall = vmx_patch_hypercall, .patch_hypercall = vmx_patch_hypercall,
......
...@@ -150,6 +150,9 @@ struct nested_vmx { ...@@ -150,6 +150,9 @@ struct nested_vmx {
/* L2 must run next, and mustn't decide to exit to L1. */ /* L2 must run next, and mustn't decide to exit to L1. */
bool nested_run_pending; bool nested_run_pending;
/* Pending MTF VM-exit into L1. */
bool mtf_pending;
struct loaded_vmcs vmcs02; struct loaded_vmcs vmcs02;
/* /*
......
...@@ -6891,6 +6891,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, ...@@ -6891,6 +6891,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
kvm_rip_write(vcpu, ctxt->eip); kvm_rip_write(vcpu, ctxt->eip);
if (r && ctxt->tf) if (r && ctxt->tf)
r = kvm_vcpu_do_singlestep(vcpu); r = kvm_vcpu_do_singlestep(vcpu);
if (kvm_x86_ops->update_emulated_instruction)
kvm_x86_ops->update_emulated_instruction(vcpu);
__kvm_set_rflags(vcpu, ctxt->eflags); __kvm_set_rflags(vcpu, ctxt->eflags);
} }
......
...@@ -889,6 +889,8 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu); ...@@ -889,6 +889,8 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu); bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu);
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu);
bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu); bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu);
int kvm_arch_post_init_vm(struct kvm *kvm);
void kvm_arch_pre_destroy_vm(struct kvm *kvm);
#ifndef __KVM_HAVE_ARCH_VM_ALLOC #ifndef __KVM_HAVE_ARCH_VM_ALLOC
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册