public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/3] add get/set irqchip ioctls for in kernel PIC live migration support
@ 2007-07-25 10:09 He, Qing
       [not found] ` <37E52D09333DE2469A03574C88DBF40F048EA9-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: He, Qing @ 2007-07-25 10:09 UTC (permalink / raw)
  To: kvm-devel

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

This patch adds two new ioctls to dump and write kernel irqchips for
save/restore and live migration. PIC s/r and l/m is implemented in this
patch.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Qing He <qing.he-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>


drivers/kvm/i8259.c    |    7 ++++
 drivers/kvm/irq.h      |    1 
 drivers/kvm/kvm_main.c |   80
+++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/kvm.h    |   34 ++++++++++++++++++++
 4 files changed, 122 insertions(+)

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 4237e17..17b836d 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -115,6 +115,13 @@ static void pic_update_irq(struct kvm_pic *s)
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0)
 		s->irq_request(s->irq_request_opaque, 1);
+	else
+		s->irq_request(s->irq_request_opaque, 0);
+}
+
+void kvm_pic_update_irq(struct kvm_pic *s)
+{
+	pic_update_irq(s);
 }
 
 void kvm_pic_set_irq(void *opaque, int irq, int level)
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index f126057..700db5e 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -59,6 +59,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int
level);
 int kvm_pic_read_irq(struct kvm_pic *s);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
+void kvm_pic_update_irq(struct kvm_pic *s);
 
 #define IOAPIC_NUM_PINS  24
 #define IOAPIC_VERSION_ID 0x11	/* IOAPIC version */
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index c074b26..a7233f7 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -935,6 +935,53 @@ out:
 	return r;
 }
 
+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip
*chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[0],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[1],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	return r;
+}
+
+static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip
*chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&pic_irqchip(kvm)->pics[0],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&pic_irqchip(kvm)->pics[1],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	kvm_pic_update_irq(pic_irqchip(kvm));
+	return r;
+}
+
 static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	int i;
@@ -2902,6 +2949,39 @@ static long kvm_vm_ioctl(struct file *filp,
 		}
 		break;
 	}
+	case KVM_GET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		if (irqchip_in_kernel(kvm)) {
+			r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+			if (r)
+				goto out;
+			r = -EFAULT;
+			if (copy_to_user(argp, &chip, sizeof chip))
+				goto out;
+			r = 0;
+		}
+		break;
+	}
+	case KVM_SET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		if (irqchip_in_kernel(kvm)) {
+			r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+			if (r)
+				goto out;
+			r = 0;
+		}
+		break;
+	}
 	default:
 		;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 49d8124..1b49a7a 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -45,6 +45,38 @@ struct kvm_irq_level {
 	__u32 level;
 };
 
+/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
+struct kvm_ioctl_pic {
+	__u8 last_irr;	/* edge detection */
+	__u8 irr;		/* interrupt request register */
+	__u8 imr;		/* interrupt mask register */
+	__u8 isr;		/* interrupt service register */
+	__u8 priority_add;	/* highest irq priority */
+	__u8 irq_base;
+	__u8 read_reg_select;
+	__u8 poll;
+	__u8 special_mask;
+	__u8 init_state;
+	__u8 auto_eoi;
+	__u8 rotate_on_auto_eoi;
+	__u8 special_fully_nested_mode;
+	__u8 init4;		/* true if 4 byte init */
+	__u8 elcr;		/* PIIX edge/trigger selection */
+	__u8 elcr_mask;
+};
+
+enum kvm_irqchip_id {
+	KVM_IRQCHIP_PIC_MASTER	 = 0,
+	KVM_IRQCHIP_PIC_SLAVE	 = 1,
+};
+
+struct kvm_irqchip {
+	__u32  chip_id;
+        union {
+		struct kvm_ioctl_pic pic;
+	} chip;
+};
+
 enum kvm_exit_reason {
 	KVM_EXIT_UNKNOWN          = 0,
 	KVM_EXIT_EXCEPTION        = 1,
@@ -298,6 +330,8 @@ struct kvm_signal_mask {
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP	  _IO(KVMIO,  0x60)
 #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)
 
 /*
  * ioctls for vcpu fds

[-- Attachment #2: kvm-live-pic-kernel.patch --]
[-- Type: application/octet-stream, Size: 4396 bytes --]

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 4237e17..17b836d 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -115,6 +115,13 @@ static void pic_update_irq(struct kvm_pic *s)
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0)
 		s->irq_request(s->irq_request_opaque, 1);
+	else
+		s->irq_request(s->irq_request_opaque, 0);
+}
+
+void kvm_pic_update_irq(struct kvm_pic *s)
+{
+	pic_update_irq(s);
 }
 
 void kvm_pic_set_irq(void *opaque, int irq, int level)
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index f126057..700db5e 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -59,6 +59,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int level);
 int kvm_pic_read_irq(struct kvm_pic *s);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
+void kvm_pic_update_irq(struct kvm_pic *s);
 
 #define IOAPIC_NUM_PINS  24
 #define IOAPIC_VERSION_ID 0x11	/* IOAPIC version */
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index c074b26..a7233f7 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -935,6 +935,53 @@ out:
 	return r;
 }
 
+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[0],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[1],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	return r;
+}
+
+static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&pic_irqchip(kvm)->pics[0],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&pic_irqchip(kvm)->pics[1],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	kvm_pic_update_irq(pic_irqchip(kvm));
+	return r;
+}
+
 static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	int i;
@@ -2902,6 +2949,39 @@ static long kvm_vm_ioctl(struct file *filp,
 		}
 		break;
 	}
+	case KVM_GET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		if (irqchip_in_kernel(kvm)) {
+			r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+			if (r)
+				goto out;
+			r = -EFAULT;
+			if (copy_to_user(argp, &chip, sizeof chip))
+				goto out;
+			r = 0;
+		}
+		break;
+	}
+	case KVM_SET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		if (irqchip_in_kernel(kvm)) {
+			r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+			if (r)
+				goto out;
+			r = 0;
+		}
+		break;
+	}
 	default:
 		;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 49d8124..1b49a7a 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -45,6 +45,38 @@ struct kvm_irq_level {
 	__u32 level;
 };
 
+/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
+struct kvm_ioctl_pic {
+	__u8 last_irr;	/* edge detection */
+	__u8 irr;		/* interrupt request register */
+	__u8 imr;		/* interrupt mask register */
+	__u8 isr;		/* interrupt service register */
+	__u8 priority_add;	/* highest irq priority */
+	__u8 irq_base;
+	__u8 read_reg_select;
+	__u8 poll;
+	__u8 special_mask;
+	__u8 init_state;
+	__u8 auto_eoi;
+	__u8 rotate_on_auto_eoi;
+	__u8 special_fully_nested_mode;
+	__u8 init4;		/* true if 4 byte init */
+	__u8 elcr;		/* PIIX edge/trigger selection */
+	__u8 elcr_mask;
+};
+
+enum kvm_irqchip_id {
+	KVM_IRQCHIP_PIC_MASTER	 = 0,
+	KVM_IRQCHIP_PIC_SLAVE	 = 1,
+};
+
+struct kvm_irqchip {
+	__u32  chip_id;
+        union {
+		struct kvm_ioctl_pic pic;
+	} chip;
+};
+
 enum kvm_exit_reason {
 	KVM_EXIT_UNKNOWN          = 0,
 	KVM_EXIT_EXCEPTION        = 1,
@@ -298,6 +330,8 @@ struct kvm_signal_mask {
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP	  _IO(KVMIO,  0x60)
 #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)
 
 /*
  * ioctls for vcpu fds

[-- Attachment #3: Type: text/plain, Size: 315 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
https://lists.sourceforge.net/lists/listinfo/kvm-devel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] add get/set irqchip ioctls for in kernel PIC live migration support
       [not found] ` <37E52D09333DE2469A03574C88DBF40F048EA9-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2007-07-25 11:21   ` Avi Kivity
       [not found]     ` <46A7323C.4010308-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Avi Kivity @ 2007-07-25 11:21 UTC (permalink / raw)
  To: He, Qing; +Cc: kvm-devel

He, Qing wrote:
> This patch adds two new ioctls to dump and write kernel irqchips for
> save/restore and live migration. PIC s/r and l/m is implemented in this
> patch.
>
> Signed-off-by: Yaozu (Eddie) Dong <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Qing He <qing.he-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
>
> @@ -2902,6 +2949,39 @@ static long kvm_vm_ioctl(struct file *filp,
>  		}
>  		break;
>  	}
> +	case KVM_GET_IRQCHIP: {
> +		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
> +		struct kvm_irqchip chip;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&chip, argp, sizeof chip))
> +			goto out;
> +		if (irqchip_in_kernel(kvm)) {
> +			r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
> +			if (r)
> +				goto out;
> +			r = -EFAULT;
> +			if (copy_to_user(argp, &chip, sizeof chip))
> +				goto out;
> +			r = 0;
> +		}
>   

We should return something other than EFAULT if !irqchip_in_kernel(). 
Maybe ENXIO?

> +		break;
> +	}
> +	case KVM_SET_IRQCHIP: {
> +		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
> +		struct kvm_irqchip chip;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&chip, argp, sizeof chip))
> +			goto out;
> +		if (irqchip_in_kernel(kvm)) {
> +			r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
> +			if (r)
> +				goto out;
> +			r = 0;
> +		}
>   

Same here.

> +		break;
> +	}
>  	default:
>  		;
>  	}
> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 49d8124..1b49a7a 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -45,6 +45,38 @@ struct kvm_irq_level {
>  	__u32 level;
>  };
>  
> +
> +struct kvm_irqchip {
> +	__u32  chip_id;
>   
Add 32-bits of padding here in case the union needs to be 64-bit aligned
in the future.

> +        union {
> +		struct kvm_ioctl_pic pic;
>   

Reserve some space here so that other members can be added to the union
without changing the ioctl number.


-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] add get/set irqchip ioctls for in kernel PIC live migration support
       [not found]     ` <46A7323C.4010308-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
@ 2007-07-26  3:15       ` He, Qing
       [not found]         ` <37E52D09333DE2469A03574C88DBF40F048EAE-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  2007-07-26  5:43       ` He, Qing
  1 sibling, 1 reply; 5+ messages in thread
From: He, Qing @ 2007-07-26  3:15 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm-devel

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



>-----Original Message-----
>From: Avi Kivity [mailto:avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org]
>Sent: 2007年7月25日 19:22
>To: He, Qing
>Cc: kvm-devel
>Subject: Re: [kvm-devel] [PATCH 2/3] add get/set irqchip ioctls for in kernel PIC live
>migration support
>
>He, Qing wrote:
>> This patch adds two new ioctls to dump and write kernel irqchips for
>> save/restore and live migration. PIC s/r and l/m is implemented in this
>> patch.
>>
>> Signed-off-by: Yaozu (Eddie) Dong <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>> Signed-off-by: Qing He <qing.he-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>>
>>
>> @@ -2902,6 +2949,39 @@ static long kvm_vm_ioctl(struct file *filp,
>>  		}
>>  		break;
>>  	}
>> +	case KVM_GET_IRQCHIP: {
>> +		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
>> +		struct kvm_irqchip chip;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&chip, argp, sizeof chip))
>> +			goto out;
>> +		if (irqchip_in_kernel(kvm)) {
>> +			r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
>> +			if (r)
>> +				goto out;
>> +			r = -EFAULT;
>> +			if (copy_to_user(argp, &chip, sizeof chip))
>> +				goto out;
>> +			r = 0;
>> +		}
>>
>
>We should return something other than EFAULT if !irqchip_in_kernel().
>Maybe ENXIO?

ENXIO is OK.

>
>> +		break;
>> +	}
>> +	case KVM_SET_IRQCHIP: {
>> +		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
>> +		struct kvm_irqchip chip;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&chip, argp, sizeof chip))
>> +			goto out;
>> +		if (irqchip_in_kernel(kvm)) {
>> +			r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
>> +			if (r)
>> +				goto out;
>> +			r = 0;
>> +		}
>>
>
>Same here.
>
>> +		break;
>> +	}
>>  	default:
>>  		;
>>  	}
>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>> index 49d8124..1b49a7a 100644
>> --- a/include/linux/kvm.h
>> +++ b/include/linux/kvm.h
>> @@ -45,6 +45,38 @@ struct kvm_irq_level {
>>  	__u32 level;
>>  };
>>
>> +
>> +struct kvm_irqchip {
>> +	__u32  chip_id;
>>
>Add 32-bits of padding here in case the union needs to be 64-bit aligned
>in the future.

Yeah, it's my fault. I missed the padding here.

>
>> +        union {
>> +		struct kvm_ioctl_pic pic;
>>
>
>Reserve some space here so that other members can be added to the union
>without changing the ioctl number.

I checked the kvm_ioapic structure, if IOAPIC_NUM_PINS==24, at least 216 bytes is required (within the union). If reserving space is for possible future expansion, how much space do you think is appropriate?

>
>
>--
>Do not meddle in the internals of kernels, for they are subtle and quick to panic.


[-- Attachment #2: Type: text/plain, Size: 315 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 #3: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] add get/set irqchip ioctls for in kernel PIC live migration support
       [not found]         ` <37E52D09333DE2469A03574C88DBF40F048EAE-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2007-07-26  5:09           ` Avi Kivity
  0 siblings, 0 replies; 5+ messages in thread
From: Avi Kivity @ 2007-07-26  5:09 UTC (permalink / raw)
  To: He, Qing; +Cc: kvm-devel

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

He, Qing wrote:
>   
>>> +        union {
>>> +		struct kvm_ioctl_pic pic;
>>>
>>>       
>> Reserve some space here so that other members can be added to the union
>> without changing the ioctl number.
>>     
>
> I checked the kvm_ioapic structure, if IOAPIC_NUM_PINS==24, at least 216 bytes is required (within the union). If reserving space is for possible future expansion, how much space do you think is appropriate?
>
>   

Well, round up and double we get 512.


-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.



[-- Attachment #2: Type: text/plain, Size: 315 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 #3: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] add get/set irqchip ioctls for in kernel PIC live migration support
       [not found]     ` <46A7323C.4010308-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
  2007-07-26  3:15       ` He, Qing
@ 2007-07-26  5:43       ` He, Qing
  1 sibling, 0 replies; 5+ messages in thread
From: He, Qing @ 2007-07-26  5:43 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm-devel

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

Avi,
	This is the updated patch for the kernel part, please check.

Thanks,
Qing


kvm: add get/set irqchip ioctls for in-kernel PIC live migration support

This patch adds two new ioctls to dump and write kernel irqchips for
save/restore and live migration. PIC s/r and l/m is implemented in this
patch.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Qing He <qing.he-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>


---
 drivers/kvm/i8259.c    |    7 ++++
 drivers/kvm/irq.h      |    1 
 drivers/kvm/kvm_main.c |   82
+++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/kvm.h    |   36 +++++++++++++++++++++
 4 files changed, 126 insertions(+)

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 4237e17..17b836d 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -115,6 +115,13 @@ static void pic_update_irq(struct kvm_pic *s)
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0)
 		s->irq_request(s->irq_request_opaque, 1);
+	else
+		s->irq_request(s->irq_request_opaque, 0);
+}
+
+void kvm_pic_update_irq(struct kvm_pic *s)
+{
+	pic_update_irq(s);
 }
 
 void kvm_pic_set_irq(void *opaque, int irq, int level)
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index f126057..700db5e 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -59,6 +59,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int
level);
 int kvm_pic_read_irq(struct kvm_pic *s);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
+void kvm_pic_update_irq(struct kvm_pic *s);
 
 #define IOAPIC_NUM_PINS  24
 #define IOAPIC_VERSION_ID 0x11	/* IOAPIC version */
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index c074b26..468c071 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -935,6 +935,53 @@ out:
 	return r;
 }
 
+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip
*chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[0],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[1],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	return r;
+}
+
+static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip
*chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&pic_irqchip(kvm)->pics[0],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&pic_irqchip(kvm)->pics[1],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	kvm_pic_update_irq(pic_irqchip(kvm));
+	return r;
+}
+
 static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	int i;
@@ -2902,6 +2949,41 @@ static long kvm_vm_ioctl(struct file *filp,
 		}
 		break;
 	}
+	case KVM_GET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = -ENXIO;
+		if (!irqchip_in_kernel(kvm))
+			goto out;
+		r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &chip, sizeof chip))
+			goto out;
+		r = 0;
+		break;
+	}
+	case KVM_SET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = -ENXIO;
+		if (!irqchip_in_kernel(kvm))
+			goto out;
+		r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = 0;
+		break;
+	}
 	default:
 		;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 49d8124..0e81143 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -45,6 +45,40 @@ struct kvm_irq_level {
 	__u32 level;
 };
 
+/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
+struct kvm_ioctl_pic {
+	__u8 last_irr;	/* edge detection */
+	__u8 irr;		/* interrupt request register */
+	__u8 imr;		/* interrupt mask register */
+	__u8 isr;		/* interrupt service register */
+	__u8 priority_add;	/* highest irq priority */
+	__u8 irq_base;
+	__u8 read_reg_select;
+	__u8 poll;
+	__u8 special_mask;
+	__u8 init_state;
+	__u8 auto_eoi;
+	__u8 rotate_on_auto_eoi;
+	__u8 special_fully_nested_mode;
+	__u8 init4;		/* true if 4 byte init */
+	__u8 elcr;		/* PIIX edge/trigger selection */
+	__u8 elcr_mask;
+};
+
+enum kvm_irqchip_id {
+	KVM_IRQCHIP_PIC_MASTER	 = 0,
+	KVM_IRQCHIP_PIC_SLAVE	 = 1,
+};
+
+struct kvm_irqchip {
+	__u32 chip_id;
+	__u32 pad;
+        union {
+		char dummy[512];  /* reserving space */
+		struct kvm_ioctl_pic pic;
+	} chip;
+};
+
 enum kvm_exit_reason {
 	KVM_EXIT_UNKNOWN          = 0,
 	KVM_EXIT_EXCEPTION        = 1,
@@ -298,6 +332,8 @@ struct kvm_signal_mask {
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP	  _IO(KVMIO,  0x60)
 #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)
 
 /*
  * ioctls for vcpu fds

[-- Attachment #2: kvm-live-pic-kernel.patch --]
[-- Type: application/octet-stream, Size: 4725 bytes --]

 drivers/kvm/i8259.c    |    7 ++++
 drivers/kvm/irq.h      |    1 
 drivers/kvm/kvm_main.c |   82 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/kvm.h    |   36 +++++++++++++++++++++
 4 files changed, 126 insertions(+)

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 4237e17..17b836d 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -115,6 +115,13 @@ static void pic_update_irq(struct kvm_pic *s)
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0)
 		s->irq_request(s->irq_request_opaque, 1);
+	else
+		s->irq_request(s->irq_request_opaque, 0);
+}
+
+void kvm_pic_update_irq(struct kvm_pic *s)
+{
+	pic_update_irq(s);
 }
 
 void kvm_pic_set_irq(void *opaque, int irq, int level)
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index f126057..700db5e 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -59,6 +59,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int level);
 int kvm_pic_read_irq(struct kvm_pic *s);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
+void kvm_pic_update_irq(struct kvm_pic *s);
 
 #define IOAPIC_NUM_PINS  24
 #define IOAPIC_VERSION_ID 0x11	/* IOAPIC version */
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index c074b26..468c071 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -935,6 +935,53 @@ out:
 	return r;
 }
 
+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[0],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[1],
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	return r;
+}
+
+static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&pic_irqchip(kvm)->pics[0],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&pic_irqchip(kvm)->pics[1],
+			&chip->chip.pic,
+			sizeof(struct kvm_ioctl_pic));
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	kvm_pic_update_irq(pic_irqchip(kvm));
+	return r;
+}
+
 static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	int i;
@@ -2902,6 +2949,41 @@ static long kvm_vm_ioctl(struct file *filp,
 		}
 		break;
 	}
+	case KVM_GET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = -ENXIO;
+		if (!irqchip_in_kernel(kvm))
+			goto out;
+		r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &chip, sizeof chip))
+			goto out;
+		r = 0;
+		break;
+	}
+	case KVM_SET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = -ENXIO;
+		if (!irqchip_in_kernel(kvm))
+			goto out;
+		r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = 0;
+		break;
+	}
 	default:
 		;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 49d8124..0e81143 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -45,6 +45,40 @@ struct kvm_irq_level {
 	__u32 level;
 };
 
+/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
+struct kvm_ioctl_pic {
+	__u8 last_irr;	/* edge detection */
+	__u8 irr;		/* interrupt request register */
+	__u8 imr;		/* interrupt mask register */
+	__u8 isr;		/* interrupt service register */
+	__u8 priority_add;	/* highest irq priority */
+	__u8 irq_base;
+	__u8 read_reg_select;
+	__u8 poll;
+	__u8 special_mask;
+	__u8 init_state;
+	__u8 auto_eoi;
+	__u8 rotate_on_auto_eoi;
+	__u8 special_fully_nested_mode;
+	__u8 init4;		/* true if 4 byte init */
+	__u8 elcr;		/* PIIX edge/trigger selection */
+	__u8 elcr_mask;
+};
+
+enum kvm_irqchip_id {
+	KVM_IRQCHIP_PIC_MASTER	 = 0,
+	KVM_IRQCHIP_PIC_SLAVE	 = 1,
+};
+
+struct kvm_irqchip {
+	__u32 chip_id;
+	__u32 pad;
+        union {
+		char dummy[512];  /* reserving space */
+		struct kvm_ioctl_pic pic;
+	} chip;
+};
+
 enum kvm_exit_reason {
 	KVM_EXIT_UNKNOWN          = 0,
 	KVM_EXIT_EXCEPTION        = 1,
@@ -298,6 +332,8 @@ struct kvm_signal_mask {
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP	  _IO(KVMIO,  0x60)
 #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)
 
 /*
  * ioctls for vcpu fds

[-- Attachment #3: Type: text/plain, Size: 315 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
https://lists.sourceforge.net/lists/listinfo/kvm-devel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-07-26  5:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-25 10:09 [PATCH 2/3] add get/set irqchip ioctls for in kernel PIC live migration support He, Qing
     [not found] ` <37E52D09333DE2469A03574C88DBF40F048EA9-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-25 11:21   ` Avi Kivity
     [not found]     ` <46A7323C.4010308-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-26  3:15       ` He, Qing
     [not found]         ` <37E52D09333DE2469A03574C88DBF40F048EAE-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-26  5:09           ` Avi Kivity
2007-07-26  5:43       ` He, Qing

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox