kernel device reset support

Dong, Eddie
2007-10-08T10:17:28Z

[-- Attachment #1: Type: text/plain, Size: 3212 bytes --]

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 <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

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

[-- Attachment #2: reset-k2.patch --]
[-- Type: application/octet-stream, Size: 3038 bytes --]

commit 759adceb0eea137fbd15ec542e6bfc778d393955
Author: root <root@vt32-pae.(none)>
Date: Mon Oct 8 18:12:09 2007 +0800

Add VM reset support in kernel side to
reset the kernel devices and VCPUs.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>

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

[-- Attachment #3: Type: text/plain, Size: 314 bytes --]

-------------------------------------------------------------------------
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/

[-- Attachment #4: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org