Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1543507 > unrolled thread

[PATCH v2 0/6] KVM: x86: minor irqchip improvements (API change)

Started byRadim Krčmář <rkrcmar@redhat.com>
First post2016-12-16 16:20 +0100
Last post2017-01-03 13:20 +0100
Articles 16 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/6] KVM: x86: minor irqchip improvements (API change) Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:20 +0100
    [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip() Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:20 +0100
      Re: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and  pic_irqchip() Paolo Bonzini <pbonzini@redhat.com> - 2016-12-16 16:30 +0100
        Re: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and  pic_irqchip() Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:50 +0100
      Re: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and  pic_irqchip() David Hildenbrand <david@redhat.com> - 2017-01-03 14:00 +0100
    [PATCH v2 4/6] KVM: x86: refactor pic setup in kvm_set_routing_entry Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:20 +0100
      Re: [PATCH v2 4/6] KVM: x86: refactor pic setup in  kvm_set_routing_entry David Hildenbrand <david@redhat.com> - 2017-01-03 14:10 +0100
    [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic setup Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:20 +0100
      Re: [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic  setup David Hildenbrand <david@redhat.com> - 2017-01-03 14:10 +0100
        Re: [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic  setup Paolo Bonzini <pbonzini@redhat.com> - 2017-01-03 17:20 +0100
    [PATCH v2 5/6] KVM: x86: prevent setup of invalid routes Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:20 +0100
      Re: [PATCH v2 5/6] KVM: x86: prevent setup of invalid routes David Hildenbrand <david@redhat.com> - 2017-01-03 14:10 +0100
    [PATCH v2 6/6] KVM: x86: simplify conditions with split/kernel irqchip Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:20 +0100
      Re: [PATCH v2 6/6] KVM: x86: simplify conditions with split/kernel  irqchip David Hildenbrand <david@redhat.com> - 2017-01-03 16:20 +0100
    [PATCH v2 1/6] KVM: x86: don't allow kernel irqchip with split irqchip Radim Krčmář <rkrcmar@redhat.com> - 2016-12-16 16:20 +0100
      Re: [PATCH v2 1/6] KVM: x86: don't allow kernel irqchip with split  irqchip David Hildenbrand <david@redhat.com> - 2017-01-03 13:20 +0100

#1543507 — [PATCH v2 0/6] KVM: x86: minor irqchip improvements (API change)

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:20 +0100
Subject[PATCH v2 0/6] KVM: x86: minor irqchip improvements (API change)
Message-ID<sP2sF-5nI-3@gated-at.bofh.it>
v2:
  Uses enum kvm_irqchip_mode to encode state and renames irqchip_kvm to
  irqchip_kernel, which might be easily confused with irqchip_in_kernel.

v1: https://www.spinics.net/lists/kernel/msg2391115.html
> There are two API changes:
> 1) [1/6] forbids KVM_CREATE_IRQCHIP after KVM_CAP_SPLIT_IRQCHIP
> 2) [5/6] makes KVM_SET_GSI_ROUTING reject pic and ioapic routes in split
>    irqchip mode, because they make no sense and are currently "working" only
>    because of a hacky NULL check.
> 
> [1-4/6] are needed for [5/6]; [6/6] is just a cherry.


Radim Krčmář (6):
  KVM: x86: don't allow kernel irqchip with split irqchip
  KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()
  KVM: x86: make pic setup code look like ioapic setup
  KVM: x86: refactor pic setup in kvm_set_routing_entry
  KVM: x86: prevent setup of invalid routes
  KVM: x86: simplify conditions with split/kernel irqchip

 arch/x86/include/asm/kvm_host.h |  8 +++++++-
 arch/x86/kvm/i8259.c            | 16 +++++++++++-----
 arch/x86/kvm/irq.h              | 19 ++++++++++---------
 arch/x86/kvm/irq_comm.c         | 29 ++++++++++-------------------
 arch/x86/kvm/x86.c              | 41 +++++++++++++++++++++--------------------
 5 files changed, 59 insertions(+), 54 deletions(-)

-- 
2.11.0

[toc] | [next] | [standalone]


#1543513 — [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:20 +0100
Subject[PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()
Message-ID<sP2sG-5nI-25@gated-at.bofh.it>
In reply to#1543507
irqchip_in_kernel() tried to save a bit by reusing pic_irqchip(), but it
just complicated the code.
Add a separate state for the irqchip mode.

Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 v2: change two bools into one enum and rename everything [Paolo]
---
 arch/x86/include/asm/kvm_host.h |  8 +++++++-
 arch/x86/kvm/irq.h              | 15 ++++++++-------
 arch/x86/kvm/x86.c              |  5 +++--
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 7892530cbacf..d3acd295446d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -715,6 +715,12 @@ struct kvm_hv {
 	HV_REFERENCE_TSC_PAGE tsc_ref;
 };
 
+enum kvm_irqchip_mode {
+	KVM_IRQCHIP_NONE,
+	KVM_IRQCHIP_KERNEL,       /* created with KVM_CREATE_IRQCHIP */
+	KVM_IRQCHIP_SPLIT,        /* created with KVM_CAP_SPLIT_IRQCHIP */
+};
+
 struct kvm_arch {
 	unsigned int n_used_mmu_pages;
 	unsigned int n_requested_mmu_pages;
@@ -787,7 +793,7 @@ struct kvm_arch {
 
 	u64 disabled_quirks;
 
-	bool irqchip_split;
+	enum kvm_irqchip_mode irqchip_mode;
 	u8 nr_reserved_ioapic_pins;
 
 	bool disabled_lapic_found;
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 035731eb3897..79cfc945125c 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -93,18 +93,19 @@ static inline int pic_in_kernel(struct kvm *kvm)
 
 static inline int irqchip_split(struct kvm *kvm)
 {
-	return kvm->arch.irqchip_split;
+	return kvm->arch.irqchip_mode == KVM_IRQCHIP_SPLIT;
+}
+
+static inline int irqchip_kernel(struct kvm *kvm)
+{
+	return kvm->arch.irqchip_mode == KVM_IRQCHIP_KERNEL;
 }
 
 static inline int irqchip_in_kernel(struct kvm *kvm)
 {
-	struct kvm_pic *vpic = pic_irqchip(kvm);
-	bool ret;
+	bool ret = irqchip_kernel(kvm) || irqchip_split(kvm);
 
-	ret = (vpic != NULL);
-	ret |= irqchip_split(kvm);
-
-	/* Read vpic before kvm->irq_routing.  */
+	/* Matches with wmb after initializing kvm->irq_routing. */
 	smp_rmb();
 	return ret;
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e670591337af..a8dbfb4129c5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3872,7 +3872,7 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 			goto split_irqchip_unlock;
 		/* Pairs with irqchip_in_kernel. */
 		smp_wmb();
-		kvm->arch.irqchip_split = true;
+		kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
 		kvm->arch.nr_reserved_ioapic_pins = cap->args[0];
 		r = 0;
 split_irqchip_unlock:
@@ -3966,8 +3966,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
 			mutex_unlock(&kvm->slots_lock);
 			goto create_irqchip_unlock;
 		}
-		/* Write kvm->irq_routing before kvm->arch.vpic.  */
+		/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
 		smp_wmb();
+		kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
 		kvm->arch.vpic = vpic;
 	create_irqchip_unlock:
 		mutex_unlock(&kvm->lock);
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1543525 — Re: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()

FromPaolo Bonzini <pbonzini@redhat.com>
Date2016-12-16 16:30 +0100
SubjectRe: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()
Message-ID<sP2Cl-5qY-29@gated-at.bofh.it>
In reply to#1543513

On 16/12/2016 16:10, Radim Krčmář wrote:
> +	bool ret = irqchip_kernel(kvm) || irqchip_split(kvm);

        bool ret = (kvm->arch.irqchip_mode != KVM_IRQCHIP_NONE);

:)

Paolo

>  
> -	ret = (vpic != NULL);
> -	ret |= irqchip_split(kvm);
> -
> -	/* Read vpic before kvm->irq_routing.  */
> +	/* Matches with wmb after initializing kvm->irq_routing. */
>  	smp_rmb();

[toc] | [prev] | [next] | [standalone]


#1543530 — Re: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:50 +0100
SubjectRe: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()
Message-ID<sP2VH-5xB-3@gated-at.bofh.it>
In reply to#1543525
2016-12-16 16:25+0100, Paolo Bonzini:
> On 16/12/2016 16:10, Radim Krčmář wrote:
>> +	bool ret = irqchip_kernel(kvm) || irqchip_split(kvm);
> 
>         bool ret = (kvm->arch.irqchip_mode != KVM_IRQCHIP_NONE);
> 
> :)

(That imposes an assumption that we will only add in-kernel irqchips!
 Are we willing to sell our souls for faster code? :])

I'll use that line without parentheses, thanks.

[toc] | [prev] | [next] | [standalone]


#1549765 — Re: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()

FromDavid Hildenbrand <david@redhat.com>
Date2017-01-03 14:00 +0100
SubjectRe: [PATCH v2 2/6] KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()
Message-ID<sVwR3-6u9-3@gated-at.bofh.it>
In reply to#1543513
Am 16.12.2016 um 16:10 schrieb Radim Krčmář:
> irqchip_in_kernel() tried to save a bit by reusing pic_irqchip(), but it
> just complicated the code.
> Add a separate state for the irqchip mode.
>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  v2: change two bools into one enum and rename everything [Paolo]
> ---
>  arch/x86/include/asm/kvm_host.h |  8 +++++++-
>  arch/x86/kvm/irq.h              | 15 ++++++++-------
>  arch/x86/kvm/x86.c              |  5 +++--
>  3 files changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 7892530cbacf..d3acd295446d 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -715,6 +715,12 @@ struct kvm_hv {
>  	HV_REFERENCE_TSC_PAGE tsc_ref;
>  };
>
> +enum kvm_irqchip_mode {
> +	KVM_IRQCHIP_NONE,
> +	KVM_IRQCHIP_KERNEL,       /* created with KVM_CREATE_IRQCHIP */
> +	KVM_IRQCHIP_SPLIT,        /* created with KVM_CAP_SPLIT_IRQCHIP */

Was wondering if FULL/SPLIT would be a better naming. However I also
find irqchip_kernel() vs irqchip_in_kernel() slightly confusing.

Anyhow, with the suggestion of Paolo included,

Reviewed-by: David Hildenbrand <david@redhat.com>

> +};


-- 

David

[toc] | [prev] | [next] | [standalone]


#1543516 — [PATCH v2 4/6] KVM: x86: refactor pic setup in kvm_set_routing_entry

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:20 +0100
Subject[PATCH v2 4/6] KVM: x86: refactor pic setup in kvm_set_routing_entry
Message-ID<sP2sG-5nI-43@gated-at.bofh.it>
In reply to#1543507
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 v2: r-b Paolo
---
 arch/x86/kvm/irq_comm.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 6c0191615f23..1dfeb185a1e3 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -297,15 +297,13 @@ int kvm_set_routing_entry(struct kvm *kvm,
 	case KVM_IRQ_ROUTING_IRQCHIP:
 		delta = 0;
 		switch (ue->u.irqchip.irqchip) {
+		case KVM_IRQCHIP_PIC_SLAVE:
+			delta = 8;
+			/* fall through */
 		case KVM_IRQCHIP_PIC_MASTER:
 			e->set = kvm_set_pic_irq;
 			max_pin = PIC_NUM_PINS;
 			break;
-		case KVM_IRQCHIP_PIC_SLAVE:
-			e->set = kvm_set_pic_irq;
-			max_pin = PIC_NUM_PINS;
-			delta = 8;
-			break;
 		case KVM_IRQCHIP_IOAPIC:
 			max_pin = KVM_IOAPIC_NUM_PINS;
 			e->set = kvm_set_ioapic_irq;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1549767 — Re: [PATCH v2 4/6] KVM: x86: refactor pic setup in kvm_set_routing_entry

FromDavid Hildenbrand <david@redhat.com>
Date2017-01-03 14:10 +0100
SubjectRe: [PATCH v2 4/6] KVM: x86: refactor pic setup in kvm_set_routing_entry
Message-ID<sVx0J-6NW-15@gated-at.bofh.it>
In reply to#1543516
Am 16.12.2016 um 16:10 schrieb Radim Krčmář:
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  v2: r-b Paolo
> ---
>  arch/x86/kvm/irq_comm.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
> index 6c0191615f23..1dfeb185a1e3 100644
> --- a/arch/x86/kvm/irq_comm.c
> +++ b/arch/x86/kvm/irq_comm.c
> @@ -297,15 +297,13 @@ int kvm_set_routing_entry(struct kvm *kvm,
>  	case KVM_IRQ_ROUTING_IRQCHIP:
>  		delta = 0;
>  		switch (ue->u.irqchip.irqchip) {
> +		case KVM_IRQCHIP_PIC_SLAVE:
> +			delta = 8;
> +			/* fall through */
>  		case KVM_IRQCHIP_PIC_MASTER:
>  			e->set = kvm_set_pic_irq;
>  			max_pin = PIC_NUM_PINS;
>  			break;
> -		case KVM_IRQCHIP_PIC_SLAVE:
> -			e->set = kvm_set_pic_irq;
> -			max_pin = PIC_NUM_PINS;
> -			delta = 8;
> -			break;
>  		case KVM_IRQCHIP_IOAPIC:
>  			max_pin = KVM_IOAPIC_NUM_PINS;
>  			e->set = kvm_set_ioapic_irq;
>

Had the exact same thing in mind when reading that piece of code.

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

David

[toc] | [prev] | [next] | [standalone]


#1543517 — [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic setup

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:20 +0100
Subject[PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic setup
Message-ID<sP2sG-5nI-33@gated-at.bofh.it>
In reply to#1543507
We don't treat kvm->arch.vpic specially anymore, so the setup can look
like ioapic.  This gets a bit more information out of return values.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 v2: r-b Paolo
---
 arch/x86/kvm/i8259.c | 16 +++++++++++-----
 arch/x86/kvm/irq.h   |  4 ++--
 arch/x86/kvm/x86.c   | 30 +++++++++++++++---------------
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 7cc2360f1848..73ea24d4f119 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -598,14 +598,14 @@ static const struct kvm_io_device_ops picdev_eclr_ops = {
 	.write    = picdev_eclr_write,
 };
 
-struct kvm_pic *kvm_create_pic(struct kvm *kvm)
+int kvm_pic_init(struct kvm *kvm)
 {
 	struct kvm_pic *s;
 	int ret;
 
 	s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
 	if (!s)
-		return NULL;
+		return -ENOMEM;
 	spin_lock_init(&s->lock);
 	s->kvm = kvm;
 	s->pics[0].elcr_mask = 0xf8;
@@ -635,7 +635,9 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
 
 	mutex_unlock(&kvm->slots_lock);
 
-	return s;
+	kvm->arch.vpic = s;
+
+	return 0;
 
 fail_unreg_1:
 	kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_slave);
@@ -648,13 +650,17 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
 
 	kfree(s);
 
-	return NULL;
+	return ret;
 }
 
-void kvm_destroy_pic(struct kvm_pic *vpic)
+void kvm_pic_destroy(struct kvm *kvm)
 {
+	struct kvm_pic *vpic = kvm->arch.vpic;
+
 	kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_master);
 	kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_slave);
 	kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_eclr);
+
+	kvm->arch.vpic = NULL;
 	kfree(vpic);
 }
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 79cfc945125c..13248d4d306c 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -73,8 +73,8 @@ struct kvm_pic {
 	unsigned long irq_states[PIC_NUM_PINS];
 };
 
-struct kvm_pic *kvm_create_pic(struct kvm *kvm);
-void kvm_destroy_pic(struct kvm_pic *vpic);
+int kvm_pic_init(struct kvm *kvm);
+void kvm_pic_destroy(struct kvm *kvm);
 int kvm_pic_read_irq(struct kvm *kvm);
 void kvm_pic_update_irq(struct kvm_pic *s);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a8dbfb4129c5..2fa004029b37 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3935,33 +3935,34 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		r = kvm_vm_ioctl_get_nr_mmu_pages(kvm);
 		break;
 	case KVM_CREATE_IRQCHIP: {
-		struct kvm_pic *vpic;
-
 		mutex_lock(&kvm->lock);
+
 		r = -EEXIST;
 		if (irqchip_in_kernel(kvm))
 			goto create_irqchip_unlock;
+
 		r = -EINVAL;
 		if (kvm->created_vcpus)
 			goto create_irqchip_unlock;
-		r = -ENOMEM;
-		vpic = kvm_create_pic(kvm);
-		if (vpic) {
-			r = kvm_ioapic_init(kvm);
-			if (r) {
-				mutex_lock(&kvm->slots_lock);
-				kvm_destroy_pic(vpic);
-				mutex_unlock(&kvm->slots_lock);
-				goto create_irqchip_unlock;
-			}
-		} else
+
+		r = kvm_pic_init(kvm);
+		if (r)
 			goto create_irqchip_unlock;
+
+		r = kvm_ioapic_init(kvm);
+		if (r) {
+			mutex_lock(&kvm->slots_lock);
+			kvm_pic_destroy(kvm);
+			mutex_unlock(&kvm->slots_lock);
+			goto create_irqchip_unlock;
+		}
+
 		r = kvm_setup_default_irq_routing(kvm);
 		if (r) {
 			mutex_lock(&kvm->slots_lock);
 			mutex_lock(&kvm->irq_lock);
 			kvm_ioapic_destroy(kvm);
-			kvm_destroy_pic(vpic);
+			kvm_pic_destroy(kvm);
 			mutex_unlock(&kvm->irq_lock);
 			mutex_unlock(&kvm->slots_lock);
 			goto create_irqchip_unlock;
@@ -3969,7 +3970,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
 		smp_wmb();
 		kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
-		kvm->arch.vpic = vpic;
 	create_irqchip_unlock:
 		mutex_unlock(&kvm->lock);
 		break;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1549768 — Re: [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic setup

FromDavid Hildenbrand <david@redhat.com>
Date2017-01-03 14:10 +0100
SubjectRe: [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic setup
Message-ID<sVx0J-6NW-13@gated-at.bofh.it>
In reply to#1543517
Am 16.12.2016 um 16:10 schrieb Radim Krčmář:
> We don't treat kvm->arch.vpic specially anymore, so the setup can look
> like ioapic.  This gets a bit more information out of return values.
>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  v2: r-b Paolo
> ---
>  arch/x86/kvm/i8259.c | 16 +++++++++++-----
>  arch/x86/kvm/irq.h   |  4 ++--
>  arch/x86/kvm/x86.c   | 30 +++++++++++++++---------------
>  3 files changed, 28 insertions(+), 22 deletions(-)
>
> diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
> index 7cc2360f1848..73ea24d4f119 100644
> --- a/arch/x86/kvm/i8259.c
> +++ b/arch/x86/kvm/i8259.c
> @@ -598,14 +598,14 @@ static const struct kvm_io_device_ops picdev_eclr_ops = {
>  	.write    = picdev_eclr_write,
>  };
>
> -struct kvm_pic *kvm_create_pic(struct kvm *kvm)
> +int kvm_pic_init(struct kvm *kvm)
>  {
>  	struct kvm_pic *s;
>  	int ret;
>
>  	s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
>  	if (!s)
> -		return NULL;
> +		return -ENOMEM;
>  	spin_lock_init(&s->lock);
>  	s->kvm = kvm;
>  	s->pics[0].elcr_mask = 0xf8;
> @@ -635,7 +635,9 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
>
>  	mutex_unlock(&kvm->slots_lock);
>
> -	return s;
> +	kvm->arch.vpic = s;
> +
> +	return 0;
>
>  fail_unreg_1:
>  	kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_slave);
> @@ -648,13 +650,17 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
>
>  	kfree(s);
>
> -	return NULL;
> +	return ret;
>  }
>
> -void kvm_destroy_pic(struct kvm_pic *vpic)
> +void kvm_pic_destroy(struct kvm *kvm)
>  {
> +	struct kvm_pic *vpic = kvm->arch.vpic;
> +
>  	kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_master);
>  	kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_slave);
>  	kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_eclr);
> +
> +	kvm->arch.vpic = NULL;
>  	kfree(vpic);
>  }
> diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
> index 79cfc945125c..13248d4d306c 100644
> --- a/arch/x86/kvm/irq.h
> +++ b/arch/x86/kvm/irq.h
> @@ -73,8 +73,8 @@ struct kvm_pic {
>  	unsigned long irq_states[PIC_NUM_PINS];
>  };
>
> -struct kvm_pic *kvm_create_pic(struct kvm *kvm);
> -void kvm_destroy_pic(struct kvm_pic *vpic);
> +int kvm_pic_init(struct kvm *kvm);
> +void kvm_pic_destroy(struct kvm *kvm);
>  int kvm_pic_read_irq(struct kvm *kvm);
>  void kvm_pic_update_irq(struct kvm_pic *s);
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index a8dbfb4129c5..2fa004029b37 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3935,33 +3935,34 @@ long kvm_arch_vm_ioctl(struct file *filp,
>  		r = kvm_vm_ioctl_get_nr_mmu_pages(kvm);
>  		break;
>  	case KVM_CREATE_IRQCHIP: {
> -		struct kvm_pic *vpic;
> -
>  		mutex_lock(&kvm->lock);
> +
>  		r = -EEXIST;
>  		if (irqchip_in_kernel(kvm))
>  			goto create_irqchip_unlock;
> +
>  		r = -EINVAL;
>  		if (kvm->created_vcpus)
>  			goto create_irqchip_unlock;
> -		r = -ENOMEM;
> -		vpic = kvm_create_pic(kvm);
> -		if (vpic) {
> -			r = kvm_ioapic_init(kvm);
> -			if (r) {
> -				mutex_lock(&kvm->slots_lock);
> -				kvm_destroy_pic(vpic);
> -				mutex_unlock(&kvm->slots_lock);
> -				goto create_irqchip_unlock;
> -			}
> -		} else
> +
> +		r = kvm_pic_init(kvm);
> +		if (r)
>  			goto create_irqchip_unlock;
> +
> +		r = kvm_ioapic_init(kvm);
> +		if (r) {
> +			mutex_lock(&kvm->slots_lock);
> +			kvm_pic_destroy(kvm);
> +			mutex_unlock(&kvm->slots_lock);
> +			goto create_irqchip_unlock;
> +		}
> +
>  		r = kvm_setup_default_irq_routing(kvm);
>  		if (r) {
>  			mutex_lock(&kvm->slots_lock);
>  			mutex_lock(&kvm->irq_lock);
>  			kvm_ioapic_destroy(kvm);
> -			kvm_destroy_pic(vpic);
> +			kvm_pic_destroy(kvm);
>  			mutex_unlock(&kvm->irq_lock);
>  			mutex_unlock(&kvm->slots_lock);
>  			goto create_irqchip_unlock;
> @@ -3969,7 +3970,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
>  		/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
>  		smp_wmb();
>  		kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
> -		kvm->arch.vpic = vpic;

This originally saved us from a race condition as far as I can
reconstruct from the commit history. Think the problem was
vpic being set but routes not being set up yet.

commit 71ba994c94a81c37185ef2fb5190844286ba9aca
Author: Paolo Bonzini <pbonzini@redhat.com>
Date:   Wed Jul 29 12:31:15 2015 +0200

     KVM: x86: clean/fix memory barriers in irqchip_in_kernel

     The memory barriers are trying to protect against concurrent RCU-based
     interrupt injection, but the IRQ routing table is not valid at the time
     kvm->arch.vpic is written.  Fix this by writing kvm->arch.vpic last.
     kvm_destroy_pic then need not set kvm->arch.vpic to NULL; modify it
     to take a struct kvm_pic* and reuse it if the IOAPIC creation fails.

     Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

I assume that this is now fixed via the irqchip_mode, as it is stored
last? If so, I really like this patch :)

>  	create_irqchip_unlock:
>  		mutex_unlock(&kvm->lock);
>  		break;
>


-- 

David

[toc] | [prev] | [next] | [standalone]


#1549922 — Re: [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic setup

FromPaolo Bonzini <pbonzini@redhat.com>
Date2017-01-03 17:20 +0100
SubjectRe: [PATCH v2 3/6] KVM: x86: make pic setup code look like ioapic setup
Message-ID<sVzYB-pP-13@gated-at.bofh.it>
In reply to#1549768

On 03/01/2017 14:04, David Hildenbrand wrote:
> Am 16.12.2016 um 16:10 schrieb Radim Krčmář:
>> We don't treat kvm->arch.vpic specially anymore, so the setup can look
>> like ioapic.  This gets a bit more information out of return values.
>
> This originally saved us from a race condition as far as I can
> reconstruct from the commit history. Think the problem was
> vpic being set but routes not being set up yet.
> 
> commit 71ba994c94a81c37185ef2fb5190844286ba9aca
> Author: Paolo Bonzini <pbonzini@redhat.com>
> Date:   Wed Jul 29 12:31:15 2015 +0200
> 
>     KVM: x86: clean/fix memory barriers in irqchip_in_kernel
> 
>     The memory barriers are trying to protect against concurrent RCU-based
>     interrupt injection, but the IRQ routing table is not valid at the time
>     kvm->arch.vpic is written.  Fix this by writing kvm->arch.vpic last.
>     kvm_destroy_pic then need not set kvm->arch.vpic to NULL; modify it
>     to take a struct kvm_pic* and reuse it if the IOAPIC creation fails.
> 
>     Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> I assume that this is now fixed via the irqchip_mode, as it is stored
> last? If so, I really like this patch :)

Yes, the previous patch referred to that when it said
"irqchip_in_kernel() tried to save a bit by reusing pic_irqchip()", and
what this commit message means by "not trteating kvm->arch.vpic
specially anymore".

Paolo

[toc] | [prev] | [next] | [standalone]


#1543518 — [PATCH v2 5/6] KVM: x86: prevent setup of invalid routes

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:20 +0100
Subject[PATCH v2 5/6] KVM: x86: prevent setup of invalid routes
Message-ID<sP2sG-5nI-41@gated-at.bofh.it>
In reply to#1543507
The check in kvm_set_pic_irq() and kvm_set_ioapic_irq() was just a
temporary measure until the code improved enough for us to do this.

This changes APIC in a case when KVM_SET_GSI_ROUTING is called to set up pic
and ioapic routes before KVM_CREATE_IRQCHIP.  Those rules would get overwritten
by KVM_CREATE_IRQCHIP at best, so it is pointless to allow it.  Userspaces
hopefully noticed that things don't work if they do that and don't do that.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 v2: r-b Paolo
---
 arch/x86/kvm/irq_comm.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 1dfeb185a1e3..2639b8d3dce2 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -41,15 +41,6 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
 			   bool line_status)
 {
 	struct kvm_pic *pic = pic_irqchip(kvm);
-
-	/*
-	 * XXX: rejecting pic routes when pic isn't in use would be better,
-	 * but the default routing table is installed while kvm->arch.vpic is
-	 * NULL and KVM_CREATE_IRQCHIP can race with KVM_IRQ_LINE.
-	 */
-	if (!pic)
-		return -1;
-
 	return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level);
 }
 
@@ -58,10 +49,6 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
 			      bool line_status)
 {
 	struct kvm_ioapic *ioapic = kvm->arch.vioapic;
-
-	if (!ioapic)
-		return -1;
-
 	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level,
 				line_status);
 }
@@ -301,10 +288,16 @@ int kvm_set_routing_entry(struct kvm *kvm,
 			delta = 8;
 			/* fall through */
 		case KVM_IRQCHIP_PIC_MASTER:
+			if (!pic_in_kernel(kvm))
+				goto out;
+
 			e->set = kvm_set_pic_irq;
 			max_pin = PIC_NUM_PINS;
 			break;
 		case KVM_IRQCHIP_IOAPIC:
+			if (!ioapic_in_kernel(kvm))
+				goto out;
+
 			max_pin = KVM_IOAPIC_NUM_PINS;
 			e->set = kvm_set_ioapic_irq;
 			break;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1549770 — Re: [PATCH v2 5/6] KVM: x86: prevent setup of invalid routes

FromDavid Hildenbrand <david@redhat.com>
Date2017-01-03 14:10 +0100
SubjectRe: [PATCH v2 5/6] KVM: x86: prevent setup of invalid routes
Message-ID<sVx0K-6NW-35@gated-at.bofh.it>
In reply to#1543518
Am 16.12.2016 um 16:10 schrieb Radim Krčmář:
> The check in kvm_set_pic_irq() and kvm_set_ioapic_irq() was just a
> temporary measure until the code improved enough for us to do this.
>
> This changes APIC in a case when KVM_SET_GSI_ROUTING is called to set up pic
> and ioapic routes before KVM_CREATE_IRQCHIP.  Those rules would get overwritten
> by KVM_CREATE_IRQCHIP at best, so it is pointless to allow it.  Userspaces
> hopefully noticed that things don't work if they do that and don't do that.
>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  v2: r-b Paolo
> ---
>  arch/x86/kvm/irq_comm.c | 19 ++++++-------------
>  1 file changed, 6 insertions(+), 13 deletions(-)
>
> diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
> index 1dfeb185a1e3..2639b8d3dce2 100644
> --- a/arch/x86/kvm/irq_comm.c
> +++ b/arch/x86/kvm/irq_comm.c
> @@ -41,15 +41,6 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
>  			   bool line_status)
>  {
>  	struct kvm_pic *pic = pic_irqchip(kvm);
> -
> -	/*
> -	 * XXX: rejecting pic routes when pic isn't in use would be better,
> -	 * but the default routing table is installed while kvm->arch.vpic is
> -	 * NULL and KVM_CREATE_IRQCHIP can race with KVM_IRQ_LINE.
> -	 */
> -	if (!pic)
> -		return -1;
> -
>  	return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level);
>  }
>
> @@ -58,10 +49,6 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
>  			      bool line_status)
>  {
>  	struct kvm_ioapic *ioapic = kvm->arch.vioapic;
> -
> -	if (!ioapic)
> -		return -1;
> -
>  	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level,
>  				line_status);
>  }
> @@ -301,10 +288,16 @@ int kvm_set_routing_entry(struct kvm *kvm,
>  			delta = 8;
>  			/* fall through */
>  		case KVM_IRQCHIP_PIC_MASTER:
> +			if (!pic_in_kernel(kvm))
> +				goto out;
> +
>  			e->set = kvm_set_pic_irq;
>  			max_pin = PIC_NUM_PINS;
>  			break;
>  		case KVM_IRQCHIP_IOAPIC:
> +			if (!ioapic_in_kernel(kvm))
> +				goto out;
> +
>  			max_pin = KVM_IOAPIC_NUM_PINS;
>  			e->set = kvm_set_ioapic_irq;
>  			break;
>

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

David

[toc] | [prev] | [next] | [standalone]


#1543519 — [PATCH v2 6/6] KVM: x86: simplify conditions with split/kernel irqchip

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:20 +0100
Subject[PATCH v2 6/6] KVM: x86: simplify conditions with split/kernel irqchip
Message-ID<sP2sG-5nI-39@gated-at.bofh.it>
In reply to#1543507
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 v2: r-b Paolo, irqchip_kvm -> irqchip_kernel due to earlier changes
---
 arch/x86/kvm/irq_comm.c | 2 +-
 arch/x86/kvm/x86.c      | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 2639b8d3dce2..b96d3893f121 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -400,7 +400,7 @@ int kvm_setup_empty_irq_routing(struct kvm *kvm)
 
 void kvm_arch_post_irq_routing_update(struct kvm *kvm)
 {
-	if (ioapic_in_kernel(kvm) || !irqchip_in_kernel(kvm))
+	if (!irqchip_split(kvm))
 		return;
 	kvm_make_scan_ioapic_request(kvm);
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2fa004029b37..0801db551b4c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4005,7 +4005,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		}
 
 		r = -ENXIO;
-		if (!irqchip_in_kernel(kvm) || irqchip_split(kvm))
+		if (!irqchip_kernel(kvm))
 			goto get_irqchip_out;
 		r = kvm_vm_ioctl_get_irqchip(kvm, chip);
 		if (r)
@@ -4029,7 +4029,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		}
 
 		r = -ENXIO;
-		if (!irqchip_in_kernel(kvm) || irqchip_split(kvm))
+		if (!irqchip_kernel(kvm))
 			goto set_irqchip_out;
 		r = kvm_vm_ioctl_set_irqchip(kvm, chip);
 		if (r)
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1549868 — Re: [PATCH v2 6/6] KVM: x86: simplify conditions with split/kernel irqchip

FromDavid Hildenbrand <david@redhat.com>
Date2017-01-03 16:20 +0100
SubjectRe: [PATCH v2 6/6] KVM: x86: simplify conditions with split/kernel irqchip
Message-ID<sVz2y-8cw-45@gated-at.bofh.it>
In reply to#1543519
Am 16.12.2016 um 16:10 schrieb Radim Krčmář:
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  v2: r-b Paolo, irqchip_kvm -> irqchip_kernel due to earlier changes

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

David

[toc] | [prev] | [next] | [standalone]


#1543521 — [PATCH v2 1/6] KVM: x86: don't allow kernel irqchip with split irqchip

FromRadim Krčmář <rkrcmar@redhat.com>
Date2016-12-16 16:20 +0100
Subject[PATCH v2 1/6] KVM: x86: don't allow kernel irqchip with split irqchip
Message-ID<sP2sG-5nI-37@gated-at.bofh.it>
In reply to#1543507
Split irqchip cannot be created after creating the kernel irqchip, but
we forgot to restrict the other way.  This is an API change.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 v2: r-b Paolo
---
 arch/x86/kvm/x86.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1f0d2383f5ee..e670591337af 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3939,7 +3939,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
 
 		mutex_lock(&kvm->lock);
 		r = -EEXIST;
-		if (kvm->arch.vpic)
+		if (irqchip_in_kernel(kvm))
 			goto create_irqchip_unlock;
 		r = -EINVAL;
 		if (kvm->created_vcpus)
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1549733 — Re: [PATCH v2 1/6] KVM: x86: don't allow kernel irqchip with split irqchip

FromDavid Hildenbrand <david@redhat.com>
Date2017-01-03 13:20 +0100
SubjectRe: [PATCH v2 1/6] KVM: x86: don't allow kernel irqchip with split irqchip
Message-ID<sVwel-60K-1@gated-at.bofh.it>
In reply to#1543521
Am 16.12.2016 um 16:10 schrieb Radim Krčmář:
> Split irqchip cannot be created after creating the kernel irqchip, but
> we forgot to restrict the other way.  This is an API change.
>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  v2: r-b Paolo
> ---
>  arch/x86/kvm/x86.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 1f0d2383f5ee..e670591337af 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3939,7 +3939,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
>
>  		mutex_lock(&kvm->lock);
>  		r = -EEXIST;
> -		if (kvm->arch.vpic)
> +		if (irqchip_in_kernel(kvm))
>  			goto create_irqchip_unlock;
>  		r = -EINVAL;
>  		if (kvm->created_vcpus)
>

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

David

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web