Kernel side patch to introduce a new API for kernel device reset and force vcpu mp_state to UNINATIALIZED state if it is reset. thx,eddie
Add VM reset support in kernel side to reset the kernel devices and VCPUs. Signed-off-by: Yaozu (Eddie) Dong <[EMAIL PROTECTED]> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index f60255c..661743a 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -330,6 +330,7 @@ struct kvm_vcpu { unsigned long cr8; u64 pdptrs[4]; /* pae */ u64 shadow_efer; + int force_to_quit; u64 apic_base; struct kvm_lapic *apic; /* kernel irqchip context */ #define VCPU_MP_STATE_RUNNABLE 0 diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 71ed1b3..0958f78 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -2199,6 +2199,8 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) vcpu_load(vcpu); if (unlikely(vcpu->mp_state == VCPU_MP_STATE_UNINITIALIZED)) { + if (irqchip_in_kernel(vcpu->kvm) && vcpu->apic) + kvm_lapic_reset(vcpu); kvm_vcpu_block(vcpu); vcpu_put(vcpu); return -EAGAIN; @@ -3095,6 +3097,41 @@ out: return r; } +void kvm_reset_devices(struct kvm *kvm) +{ + kvm_pic_reset(&pic_irqchip(kvm)->pics[1]); + kvm_pic_reset(&pic_irqchip(kvm)->pics[0]); + pic_irqchip(kvm)->output = 0; + kvm_ioapic_reset(kvm->vioapic); +} + +/* + * Reset VM. + * + */ +int kvm_vm_reset(struct kvm *kvm) +{ + struct kvm_vcpu *vcpu; + int i; + + kvm_reset_devices(kvm); + for (i = 0; i < KVM_MAX_VCPUS; i++) { + vcpu = kvm->vcpus[i]; + if (!vcpu) + continue; + /* active VCPU */ + if (vcpu->vcpu_id) + vcpu->mp_state = VCPU_MP_STATE_UNINITIALIZED; + else { + vcpu->mp_state = VCPU_MP_STATE_RUNNABLE; + kvm_lapic_reset(vcpu); + } + vcpu->force_to_quit = 1; + kvm_vcpu_kick(vcpu); + } + return 0; +} + static long kvm_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -3163,6 +3200,12 @@ static long kvm_vm_ioctl(struct file *filp, else goto out; break; + case KVM_RESET: + r = -EFAULT; + if (!irqchip_in_kernel(kvm)) + goto out; + r = kvm_vm_reset(kvm); + break; case KVM_IRQ_LINE: { struct kvm_irq_level irq_event; diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 3d8e01e..0799aad 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -1860,6 +1860,10 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { ++vcpu->stat.irq_exits; + if (vcpu->force_to_quit) { + vcpu->force_to_quit = 0; + return -EINTR; + } return 1; } diff --git a/include/linux/kvm.h b/include/linux/kvm.h index d62d3b2..2fd731f 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -371,6 +371,7 @@ struct kvm_signal_mask { #define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level) #define KVM_GET_IRQCHIP _IOWR(KVMIO, 0x62, struct kvm_irqchip) #define KVM_SET_IRQCHIP _IOR(KVMIO, 0x63, struct kvm_irqchip) +#define KVM_RESET _IO(KVMIO, 0x64) /* * ioctls for vcpu fds
reset-k2.patch
Description: reset-k2.patch
------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel