public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] kvm-s390: infrastructure to kick vcpus out of guest state - v3
@ 2009-05-29 10:58 ehrhardt
  2009-05-29 10:58 ` [PATCH 2/4] kvm-s390: fix interruption caused by signal - v2 ehrhardt
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: ehrhardt @ 2009-05-29 10:58 UTC (permalink / raw)
  To: kvm, avi
  Cc: ehrhardt, borntraeger, cotte, heiko.carstens, schwidefsky,
	mtosatti

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

*updates in v3*
- ensure allocations (might_sleep) are out of atomic context

*updates in v2*
instead of a "kick to level" behaviour the patch now implements a kick to the
lowest level. The check there bails out to upper levels if not all outstanding
vcpu->requests could be handled internally (it could still support an explicit
kick to level if ever needed).

To ensure vcpu's come out of guest context in certain cases this patch adds a
s390 specific way to kick them out of guest context. Currently it kicks them
out to rerun the vcpu_run path in the s390 code, but the mechanism itself is
expandable and with a new flag we could also add e.g. kicks to userspace etc.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 include/asm/kvm_host.h |    5 ++--
 kvm/intercept.c        |   14 +++++++++--
 kvm/kvm-s390.c         |    6 ++++
 kvm/kvm-s390.h         |   17 ++++++++++++++
 kvm/sigp.c             |   59 ++++++++++++++++++++++++++++++++++---------------
 5 files changed, 79 insertions(+), 22 deletions(-)

[diff]
Index: kvm/arch/s390/kvm/intercept.c
===================================================================
--- kvm.orig/arch/s390/kvm/intercept.c
+++ kvm/arch/s390/kvm/intercept.c
@@ -128,7 +128,7 @@ static int handle_noop(struct kvm_vcpu *
 
 static int handle_stop(struct kvm_vcpu *vcpu)
 {
-	int rc;
+	int rc = 0;
 
 	vcpu->stat.exit_stop_request++;
 	atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
@@ -141,12 +141,20 @@ static int handle_stop(struct kvm_vcpu *
 			rc = -ENOTSUPP;
 	}
 
+	if (vcpu->arch.local_int.action_bits & ACTION_VCPUREQUEST_ON_STOP) {
+		vcpu->arch.local_int.action_bits &= ~ACTION_VCPUREQUEST_ON_STOP;
+		if (kvm_s390_handle_vcpu_requests(vcpu, VCPUREQUESTLVL_SIGP)) {
+			rc = SIE_INTERCEPT_CHECKREQUESTS;
+			vcpu->run->exit_reason = KVM_EXIT_INTR;
+		}
+	}
+
 	if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
 		vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
 		VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
 		rc = -ENOTSUPP;
-	} else
-		rc = 0;
+	}
+
 	spin_unlock_bh(&vcpu->arch.local_int.lock);
 	return rc;
 }
Index: kvm/arch/s390/kvm/kvm-s390.c
===================================================================
--- kvm.orig/arch/s390/kvm/kvm-s390.c
+++ kvm/arch/s390/kvm/kvm-s390.c
@@ -487,6 +487,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 
 	vcpu_load(vcpu);
 
+rerun_vcpu:
+	kvm_s390_handle_vcpu_requests(vcpu, VCPUREQUESTLVL_VCPURUN);
+
 	/* verify, that memory has been registered */
 	if (!vcpu->kvm->arch.guest_memsize) {
 		vcpu_put(vcpu);
@@ -519,6 +522,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 		rc = kvm_handle_sie_intercept(vcpu);
 	} while (!signal_pending(current) && !rc);
 
+	if (rc == SIE_INTERCEPT_CHECKREQUESTS)
+		goto rerun_vcpu;
+
 	if (signal_pending(current) && !rc)
 		rc = -EINTR;
 
Index: kvm/arch/s390/kvm/kvm-s390.h
===================================================================
--- kvm.orig/arch/s390/kvm/kvm-s390.h
+++ kvm/arch/s390/kvm/kvm-s390.h
@@ -20,6 +20,8 @@
 
 typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
 
+/* negativ values are error codes, positive values for internal conditions */
+#define SIE_INTERCEPT_CHECKREQUESTS		(1<<0)
 int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
 
 #define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\
@@ -50,6 +52,21 @@ int kvm_s390_inject_vm(struct kvm *kvm,
 int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
 		struct kvm_s390_interrupt *s390int);
 int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
+int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
+
+/* interception levels from which handle vcpu requests can be called */
+#define VCPUREQUESTLVL_SIGP		1
+#define VCPUREQUESTLVL_VCPURUN		2
+static inline unsigned long kvm_s390_handle_vcpu_requests(struct kvm_vcpu *vcpu,
+						   int level)
+{
+	BUG_ON(!level);
+
+	if (!vcpu->requests)
+		return 0;
+
+	return vcpu->requests;
+}
 
 /* implemented in priv.c */
 int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
Index: kvm/arch/s390/include/asm/kvm_host.h
===================================================================
--- kvm.orig/arch/s390/include/asm/kvm_host.h
+++ kvm/arch/s390/include/asm/kvm_host.h
@@ -180,8 +180,9 @@ struct kvm_s390_interrupt_info {
 };
 
 /* for local_interrupt.action_flags */
-#define ACTION_STORE_ON_STOP 1
-#define ACTION_STOP_ON_STOP  2
+#define ACTION_STORE_ON_STOP		(1<<0)
+#define ACTION_STOP_ON_STOP		(1<<1)
+#define ACTION_VCPUREQUEST_ON_STOP	(1<<2)
 
 struct kvm_s390_local_interrupt {
 	spinlock_t lock;
Index: kvm/arch/s390/kvm/sigp.c
===================================================================
--- kvm.orig/arch/s390/kvm/sigp.c
+++ kvm/arch/s390/kvm/sigp.c
@@ -1,7 +1,7 @@
 /*
  * sigp.c - handlinge interprocessor communication
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -9,6 +9,7 @@
  *
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
+ *               Christian Ehrhardt <ehrhardt@de.ibm.com>
  */
 
 #include <linux/kvm.h>
@@ -107,7 +108,22 @@ unlock:
 	return rc;
 }
 
-static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int store)
+static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action,
+				struct kvm_s390_interrupt_info *inti)
+{
+	spin_lock_bh(&li->lock);
+	list_add_tail(&inti->list, &li->list);
+	atomic_set(&li->active, 1);
+	atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
+	li->action_bits |= action;
+	if (waitqueue_active(&li->wq))
+		wake_up_interruptible(&li->wq);
+	spin_unlock_bh(&li->lock);
+
+	return 0; /* order accepted */
+}
+
+static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
 {
 	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
 	struct kvm_s390_local_interrupt *li;
@@ -120,33 +136,42 @@ static int __sigp_stop(struct kvm_vcpu *
 	inti = kzalloc(sizeof(*inti), GFP_KERNEL);
 	if (!inti)
 		return -ENOMEM;
-
 	inti->type = KVM_S390_SIGP_STOP;
 
 	spin_lock(&fi->lock);
 	li = fi->local_int[cpu_addr];
 	if (li == NULL) {
 		rc = 3; /* not operational */
-		kfree(inti);
 		goto unlock;
 	}
-	spin_lock_bh(&li->lock);
-	list_add_tail(&inti->list, &li->list);
-	atomic_set(&li->active, 1);
-	atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
-	if (store)
-		li->action_bits |= ACTION_STORE_ON_STOP;
-	li->action_bits |= ACTION_STOP_ON_STOP;
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
-	spin_unlock_bh(&li->lock);
-	rc = 0; /* order accepted */
+
+	rc = __inject_sigp_stop(li, action, inti);
+
 unlock:
 	spin_unlock(&fi->lock);
+	if (rc)
+		kfree(inti);
 	VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr);
 	return rc;
 }
 
+int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action)
+{
+	struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
+	struct kvm_s390_interrupt_info *inti;
+	int rc;
+
+	inti = kzalloc(sizeof(*inti), GFP_KERNEL);
+	if (!inti)
+		return -ENOMEM;
+	inti->type = KVM_S390_SIGP_STOP;
+
+	rc = __inject_sigp_stop(li, action, inti);
+	if (rc)
+		kfree(inti);
+	return rc;
+}
+
 static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
 {
 	int rc;
@@ -261,11 +286,11 @@ int kvm_s390_handle_sigp(struct kvm_vcpu
 		break;
 	case SIGP_STOP:
 		vcpu->stat.instruction_sigp_stop++;
-		rc = __sigp_stop(vcpu, cpu_addr, 0);
+		rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP);
 		break;
 	case SIGP_STOP_STORE_STATUS:
 		vcpu->stat.instruction_sigp_stop++;
-		rc = __sigp_stop(vcpu, cpu_addr, 1);
+		rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP);
 		break;
 	case SIGP_SET_ARCH:
 		vcpu->stat.instruction_sigp_arch++;

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

* [PATCH 2/4] kvm-s390: fix interruption caused by signal - v2
  2009-05-29 10:58 [PATCH 1/4] kvm-s390: infrastructure to kick vcpus out of guest state - v3 ehrhardt
@ 2009-05-29 10:58 ` ehrhardt
  2009-05-29 10:58 ` [PATCH 3/4] kvm-s390: update vcpu->cpu ehrhardt
  2009-05-29 10:58 ` [PATCH 4/4] kvm-s390: streamline memslot handling - v6 ehrhardt
  2 siblings, 0 replies; 7+ messages in thread
From: ehrhardt @ 2009-05-29 10:58 UTC (permalink / raw)
  To: kvm, avi
  Cc: ehrhardt, borntraeger, cotte, heiko.carstens, schwidefsky,
	mtosatti

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

*updates in v2*
merged a small piece of code from patch 1/1 that belongs here themtically

If signal pending is true we exit without updating kvm_run, userspace
currently just does nothing and jumps to kvm_run again.
Since we did not set an exit_reason we might end up with a random one
(whatever was the last exit). Therefore it was possible to e.g. jump to
the psw position the last real interruption set.
Setting the INTR exit reason ensures that no old psw data is swapped
in on reentry.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 kvm-s390.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

[diff]
Index: kvm/arch/s390/kvm/kvm-s390.c
===================================================================
--- kvm.orig/arch/s390/kvm/kvm-s390.c
+++ kvm/arch/s390/kvm/kvm-s390.c
@@ -509,6 +509,7 @@ rerun_vcpu:
 		vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
 		break;
 	case KVM_EXIT_UNKNOWN:
+	case KVM_EXIT_INTR:
 	case KVM_EXIT_S390_RESET:
 		break;
 	default:
@@ -525,8 +526,10 @@ rerun_vcpu:
 	if (rc == SIE_INTERCEPT_CHECKREQUESTS)
 		goto rerun_vcpu;
 
-	if (signal_pending(current) && !rc)
+	if (signal_pending(current) && !rc) {
+		kvm_run->exit_reason = KVM_EXIT_INTR;
 		rc = -EINTR;
+	}
 
 	if (rc == -ENOTSUPP) {
 		/* intercept cannot be handled in-kernel, prepare kvm-run */

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

* [PATCH 3/4] kvm-s390: update vcpu->cpu
  2009-05-29 10:58 [PATCH 1/4] kvm-s390: infrastructure to kick vcpus out of guest state - v3 ehrhardt
  2009-05-29 10:58 ` [PATCH 2/4] kvm-s390: fix interruption caused by signal - v2 ehrhardt
@ 2009-05-29 10:58 ` ehrhardt
  2009-05-29 10:58 ` [PATCH 4/4] kvm-s390: streamline memslot handling - v6 ehrhardt
  2 siblings, 0 replies; 7+ messages in thread
From: ehrhardt @ 2009-05-29 10:58 UTC (permalink / raw)
  To: kvm, avi
  Cc: ehrhardt, borntraeger, cotte, heiko.carstens, schwidefsky,
	mtosatti

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

kvm on s390 formerly ignored vcpu->cpu.
This patch adds set/unset vcpu->cpu in kvm_arch_vcpu_load/put to allow
further architecture unification e.g. let generic code not find -1 on
currently scheduled vcpus.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 kvm-s390.c |    2 ++
 1 file changed, 2 insertions(+)

[diff]
Index: kvm/arch/s390/kvm/kvm-s390.c
===================================================================
--- kvm.orig/arch/s390/kvm/kvm-s390.c
+++ kvm/arch/s390/kvm/kvm-s390.c
@@ -243,6 +243,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcp
 
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
+	vcpu->cpu = cpu;
 	save_fp_regs(&vcpu->arch.host_fpregs);
 	save_access_regs(vcpu->arch.host_acrs);
 	vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
@@ -252,6 +253,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu 
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	vcpu->cpu = -1;
 	save_fp_regs(&vcpu->arch.guest_fpregs);
 	save_access_regs(vcpu->arch.guest_acrs);
 	restore_fp_regs(&vcpu->arch.host_fpregs);

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

* [PATCH 4/4] kvm-s390: streamline memslot handling - v6
  2009-05-29 10:58 [PATCH 1/4] kvm-s390: infrastructure to kick vcpus out of guest state - v3 ehrhardt
  2009-05-29 10:58 ` [PATCH 2/4] kvm-s390: fix interruption caused by signal - v2 ehrhardt
  2009-05-29 10:58 ` [PATCH 3/4] kvm-s390: update vcpu->cpu ehrhardt
@ 2009-05-29 10:58 ` ehrhardt
  2009-05-31  8:22   ` Avi Kivity
  2 siblings, 1 reply; 7+ messages in thread
From: ehrhardt @ 2009-05-29 10:58 UTC (permalink / raw)
  To: kvm, avi
  Cc: ehrhardt, borntraeger, cotte, heiko.carstens, schwidefsky,
	mtosatti

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

*updates in v6*
- ensure the wait_on_bit waiter is notified
- move the reset of requests to kvm_vcpu_release to drop them early

*updates in v5*
- ensure dropping vcpu all requests while freeing a vcpu

*updates in v4*
- kickout only scheduled vcpus (its superfluous and wait might hang forever on
  not running vcpus)

*updates in v3*
- handling the mmu reload vcpu request can now be handled inside the sigp
  handling avoiding an addtional exit
- kvm_arch_set_memory_region now waits for kicked vcpu's to consume the request
  bit it set to ensure that after the kvm_arch_set_memory_region call all vcpus
  use the updated memory information

*updates in v2*
- added optimization to skip (addtional) kickout of vcpu's that had the request
  already set.

This patch relocates the variables kvm-s390 uses to track guest mem addr/size.
As discussed dropping the variables at struct kvm_arch level allows to use the
common vcpu->request based mechanism to reload guest memory if e.g. changes
via set_memory_region.
The kick mechanism introduced in this series is used to ensure running vcpus
leave guest state to catch the update.


Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 arch/s390/include/asm/kvm_host.h |    4 --
 arch/s390/kvm/gaccess.h          |   23 ++++++++-------
 arch/s390/kvm/intercept.c        |    6 ++--
 arch/s390/kvm/kvm-s390.c         |   57 ++++++++++++++++-----------------------
 arch/s390/kvm/kvm-s390.h         |   36 +++++++++++++++++++++++-
 arch/s390/kvm/sigp.c             |    4 +-
 virt/kvm/kvm_main.c              |    4 ++
 7 files changed, 81 insertions(+), 53 deletions(-)

[diff]
Index: kvm/arch/s390/kvm/gaccess.h
===================================================================
--- kvm.orig/arch/s390/kvm/gaccess.h
+++ kvm/arch/s390/kvm/gaccess.h
@@ -1,7 +1,7 @@
 /*
  * gaccess.h -  access guest memory
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -16,13 +16,14 @@
 #include <linux/compiler.h>
 #include <linux/kvm_host.h>
 #include <asm/uaccess.h>
+#include "kvm-s390.h"
 
 static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu,
 					       unsigned long guestaddr)
 {
 	unsigned long prefix  = vcpu->arch.sie_block->prefix;
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if (guestaddr < 2 * PAGE_SIZE)
 		guestaddr += prefix;
@@ -158,8 +159,8 @@ static inline int copy_to_guest(struct k
 				const void *from, unsigned long n)
 {
 	unsigned long prefix  = vcpu->arch.sie_block->prefix;
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE))
 		goto slowpath;
@@ -209,8 +210,8 @@ static inline int copy_from_guest(struct
 				  unsigned long guestsrc, unsigned long n)
 {
 	unsigned long prefix  = vcpu->arch.sie_block->prefix;
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE))
 		goto slowpath;
@@ -244,8 +245,8 @@ static inline int copy_to_guest_absolute
 					 unsigned long guestdest,
 					 const void *from, unsigned long n)
 {
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if (guestdest + n > memsize)
 		return -EFAULT;
@@ -262,8 +263,8 @@ static inline int copy_from_guest_absolu
 					   unsigned long guestsrc,
 					   unsigned long n)
 {
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if (guestsrc + n > memsize)
 		return -EFAULT;
Index: kvm/arch/s390/kvm/intercept.c
===================================================================
--- kvm.orig/arch/s390/kvm/intercept.c
+++ kvm/arch/s390/kvm/intercept.c
@@ -1,7 +1,7 @@
 /*
  * intercept.c - in-kernel handling for sie intercepts
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -166,9 +166,9 @@ static int handle_validity(struct kvm_vc
 
 	vcpu->stat.exit_validity++;
 	if ((viwhy == 0x37) && (vcpu->arch.sie_block->prefix
-		<= vcpu->kvm->arch.guest_memsize - 2*PAGE_SIZE)){
+		<= kvm_s390_vcpu_get_memsize(vcpu) - 2*PAGE_SIZE)) {
 		rc = fault_in_pages_writeable((char __user *)
-			 vcpu->kvm->arch.guest_origin +
+			 vcpu->arch.sie_block->gmsor +
 			 vcpu->arch.sie_block->prefix,
 			 2*PAGE_SIZE);
 		if (rc)
Index: kvm/arch/s390/kvm/kvm-s390.c
===================================================================
--- kvm.orig/arch/s390/kvm/kvm-s390.c
+++ kvm/arch/s390/kvm/kvm-s390.c
@@ -1,7 +1,7 @@
 /*
  * s390host.c --  hosting zSeries kernel virtual machines
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -10,6 +10,7 @@
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
  *               Heiko Carstens <heiko.carstens@de.ibm.com>
+ *               Christian Ehrhardt <ehrhardt@de.ibm.com>
  */
 
 #include <linux/compiler.h>
@@ -278,16 +279,10 @@ static void kvm_s390_vcpu_initial_reset(
 	vcpu->arch.sie_block->gbea = 1;
 }
 
-/* The current code can have up to 256 pages for virtio */
-#define VIRTIODESCSPACE (256ul * 4096ul)
-
 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
 	atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
-	vcpu->arch.sie_block->gmslm = vcpu->kvm->arch.guest_memsize +
-				      vcpu->kvm->arch.guest_origin +
-				      VIRTIODESCSPACE - 1ul;
-	vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin;
+	set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests);
 	vcpu->arch.sie_block->ecb   = 2;
 	vcpu->arch.sie_block->eca   = 0xC1002001U;
 	hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
@@ -493,8 +488,9 @@ rerun_vcpu:
 	kvm_s390_handle_vcpu_requests(vcpu, VCPUREQUESTLVL_VCPURUN);
 
 	/* verify, that memory has been registered */
-	if (!vcpu->kvm->arch.guest_memsize) {
+	if (!vcpu->arch.sie_block->gmslm) {
 		vcpu_put(vcpu);
+		VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu");
 		return -EINVAL;
 	}
 
@@ -677,6 +673,12 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 	return -EINVAL;
 }
 
+static int wait_bit_schedule(void *word)
+{
+	schedule();
+	return 0;
+}
+
 /* Section: memory related */
 int kvm_arch_set_memory_region(struct kvm *kvm,
 				struct kvm_userspace_memory_region *mem,
@@ -684,6 +686,7 @@ int kvm_arch_set_memory_region(struct kv
 				int user_alloc)
 {
 	int i;
+	struct kvm_vcpu *vcpu;
 
 	/* A few sanity checks. We can have exactly one memory slot which has
 	   to start at guest virtual zero and which has to be located at a
@@ -692,7 +695,7 @@ int kvm_arch_set_memory_region(struct kv
 	   vmas. It is okay to mmap() and munmap() stuff in this slot after
 	   doing this call at any time */
 
-	if (mem->slot || kvm->arch.guest_memsize)
+	if (mem->slot)
 		return -EINVAL;
 
 	if (mem->guest_phys_addr)
@@ -707,36 +710,24 @@ int kvm_arch_set_memory_region(struct kv
 	if (!user_alloc)
 		return -EINVAL;
 
-	/* lock all vcpus */
+	/* request update of sie control block for all available vcpus */
 	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		if (!kvm->vcpus[i])
+		vcpu = kvm->vcpus[i];
+		if (!vcpu)
+			continue;
+
+		if (!test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
 			continue;
-		if (!mutex_trylock(&kvm->vcpus[i]->mutex))
-			goto fail_out;
-	}
 
-	kvm->arch.guest_origin = mem->userspace_addr;
-	kvm->arch.guest_memsize = mem->memory_size;
+		if (vcpu->cpu == -1)
+			continue;
 
-	/* update sie control blocks, and unlock all vcpus */
-	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		if (kvm->vcpus[i]) {
-			kvm->vcpus[i]->arch.sie_block->gmsor =
-				kvm->arch.guest_origin;
-			kvm->vcpus[i]->arch.sie_block->gmslm =
-				kvm->arch.guest_memsize +
-				kvm->arch.guest_origin +
-				VIRTIODESCSPACE - 1ul;
-			mutex_unlock(&kvm->vcpus[i]->mutex);
-		}
+		kvm_s390_inject_sigp_stop(vcpu, ACTION_VCPUREQUEST_ON_STOP);
+		wait_on_bit(&vcpu->requests, KVM_REQ_MMU_RELOAD,
+			    wait_bit_schedule, TASK_UNINTERRUPTIBLE);
 	}
 
 	return 0;
-
-fail_out:
-	for (; i >= 0; i--)
-		mutex_unlock(&kvm->vcpus[i]->mutex);
-	return -EINVAL;
 }
 
 void kvm_arch_flush_shadow(struct kvm *kvm)
Index: kvm/arch/s390/kvm/kvm-s390.h
===================================================================
--- kvm.orig/arch/s390/kvm/kvm-s390.h
+++ kvm/arch/s390/kvm/kvm-s390.h
@@ -1,7 +1,7 @@
 /*
  * kvm_s390.h -  definition for kvm on s390
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -9,6 +9,7 @@
  *
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
+ *               Christian Ehrhardt <ehrhardt@de.ibm.com>
  */
 
 #ifndef ARCH_S390_KVM_S390_H
@@ -18,6 +19,9 @@
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 
+/* The current code can have up to 256 pages for virtio */
+#define VIRTIODESCSPACE (256ul * 4096ul)
+
 typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
 
 /* negativ values are error codes, positive values for internal conditions */
@@ -54,6 +58,29 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu
 int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
 int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
 
+static inline int kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.sie_block->gmslm
+		- vcpu->arch.sie_block->gmsor
+		- VIRTIODESCSPACE + 1ul;
+}
+
+static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
+{
+	struct kvm_memory_slot *mem;
+
+	down_read(&vcpu->kvm->slots_lock);
+	mem = &vcpu->kvm->memslots[0];
+
+	vcpu->arch.sie_block->gmsor = mem->userspace_addr;
+	vcpu->arch.sie_block->gmslm =
+		mem->userspace_addr +
+		(mem->npages << PAGE_SHIFT) +
+		VIRTIODESCSPACE - 1ul;
+
+	up_read(&vcpu->kvm->slots_lock);
+}
+
 /* interception levels from which handle vcpu requests can be called */
 #define VCPUREQUESTLVL_SIGP		1
 #define VCPUREQUESTLVL_VCPURUN		2
@@ -65,6 +92,13 @@ static inline unsigned long kvm_s390_han
 	if (!vcpu->requests)
 		return 0;
 
+	/* requests that can be handled at all levels */
+	if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) {
+		smp_mb__after_clear_bit();
+		wake_up_bit(vcpu->requests, KVM_REQ_MMU_RELOAD);
+		kvm_s390_vcpu_set_mem(vcpu);
+	}
+
 	return vcpu->requests;
 }
 
Index: kvm/arch/s390/include/asm/kvm_host.h
===================================================================
--- kvm.orig/arch/s390/include/asm/kvm_host.h
+++ kvm/arch/s390/include/asm/kvm_host.h
@@ -1,7 +1,7 @@
 /*
  * asm-s390/kvm_host.h - definition for kernel virtual machines on s390
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -226,8 +226,6 @@ struct kvm_vm_stat {
 };
 
 struct kvm_arch{
-	unsigned long guest_origin;
-	unsigned long guest_memsize;
 	struct sca_block *sca;
 	debug_info_t *dbf;
 	struct kvm_s390_float_interrupt float_int;
Index: kvm/arch/s390/kvm/sigp.c
===================================================================
--- kvm.orig/arch/s390/kvm/sigp.c
+++ kvm/arch/s390/kvm/sigp.c
@@ -202,9 +202,9 @@ static int __sigp_set_prefix(struct kvm_
 	/* make sure that the new value is valid memory */
 	address = address & 0x7fffe000u;
 	if ((copy_from_guest(vcpu, &tmp,
-		(u64) (address + vcpu->kvm->arch.guest_origin) , 1)) ||
+		(u64) (address + vcpu->arch.sie_block->gmsor) , 1)) ||
 	   (copy_from_guest(vcpu, &tmp, (u64) (address +
-			vcpu->kvm->arch.guest_origin + PAGE_SIZE), 1))) {
+			vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) {
 		*reg |= SIGP_STAT_INVALID_PARAMETER;
 		return 1; /* invalid parameter */
 	}
Index: kvm/virt/kvm/kvm_main.c
===================================================================
--- kvm.orig/virt/kvm/kvm_main.c
+++ kvm/virt/kvm/kvm_main.c
@@ -1686,6 +1686,10 @@ static int kvm_vcpu_release(struct inode
 {
 	struct kvm_vcpu *vcpu = filp->private_data;
 
+	clear_bit(vcpu->requests, KVM_REQ_MMU_RELOAD);
+	smp_mb__after_clear_bit();
+	wake_up_bit(vcpu->requests, KVM_REQ_MMU_RELOAD);
+
 	kvm_put_kvm(vcpu->kvm);
 	return 0;
 }

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

* Re: [PATCH 4/4] kvm-s390: streamline memslot handling - v6
  2009-05-29 10:58 ` [PATCH 4/4] kvm-s390: streamline memslot handling - v6 ehrhardt
@ 2009-05-31  8:22   ` Avi Kivity
  2009-06-02 12:32     ` Marcelo Tosatti
  0 siblings, 1 reply; 7+ messages in thread
From: Avi Kivity @ 2009-05-31  8:22 UTC (permalink / raw)
  To: ehrhardt; +Cc: kvm, borntraeger, cotte, heiko.carstens, schwidefsky, mtosatti

ehrhardt@linux.vnet.ibm.com wrote:
> From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
>
> *updates in v6*
> - ensure the wait_on_bit waiter is notified
> - move the reset of requests to kvm_vcpu_release to drop them early
>
> *updates in v5*
> - ensure dropping vcpu all requests while freeing a vcpu
>
> *updates in v4*
> - kickout only scheduled vcpus (its superfluous and wait might hang forever on
>   not running vcpus)
>
>   

v3 is already in (and pushed so I can't unapply), so please rebase on 
top of current git.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 4/4] kvm-s390: streamline memslot handling - v6
  2009-05-31  8:22   ` Avi Kivity
@ 2009-06-02 12:32     ` Marcelo Tosatti
  2009-06-02 14:23       ` Christian Ehrhardt
  0 siblings, 1 reply; 7+ messages in thread
From: Marcelo Tosatti @ 2009-06-02 12:32 UTC (permalink / raw)
  To: Avi Kivity; +Cc: ehrhardt, kvm, borntraeger, cotte, heiko.carstens, schwidefsky

On Sun, May 31, 2009 at 11:22:58AM +0300, Avi Kivity wrote:
> ehrhardt@linux.vnet.ibm.com wrote:
>> From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
>>
>> *updates in v6*
>> - ensure the wait_on_bit waiter is notified
>> - move the reset of requests to kvm_vcpu_release to drop them early
>>
>> *updates in v5*
>> - ensure dropping vcpu all requests while freeing a vcpu
>>
>> *updates in v4*
>> - kickout only scheduled vcpus (its superfluous and wait might hang forever on
>>   not running vcpus)
>>
>>   
>
> v3 is already in (and pushed so I can't unapply), so please rebase on  
> top of current git.

Christian, 

Seems a good step toward further unification. Can you please rebase as
requested? 


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

* Re: [PATCH 4/4] kvm-s390: streamline memslot handling - v6
  2009-06-02 12:32     ` Marcelo Tosatti
@ 2009-06-02 14:23       ` Christian Ehrhardt
  0 siblings, 0 replies; 7+ messages in thread
From: Christian Ehrhardt @ 2009-06-02 14:23 UTC (permalink / raw)
  To: Marcelo Tosatti, Avi Kivity
  Cc: kvm, borntraeger, cotte, heiko.carstens, schwidefsky

Marcelo Tosatti wrote:
> On Sun, May 31, 2009 at 11:22:58AM +0300, Avi Kivity wrote:
>   
>> ehrhardt@linux.vnet.ibm.com wrote:
>>     
>>> From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
>>>
>>> *updates in v6*
>>> - ensure the wait_on_bit waiter is notified
>>> - move the reset of requests to kvm_vcpu_release to drop them early
>>>
>>> *updates in v5*
>>> - ensure dropping vcpu all requests while freeing a vcpu
>>>
>>> *updates in v4*
>>> - kickout only scheduled vcpus (its superfluous and wait might hang forever on
>>>   not running vcpus)
>>>
>>>   
>>>       
>> v3 is already in (and pushed so I can't unapply), so please rebase on  
>> top of current git.
>>     
>
> Christian, 
>
> Seems a good step toward further unification. Can you please rebase as
> requested? 
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>   
The missing updates are mostly fixes or code merges due to our 
discussions and should be on the list in a few minutes.

-- 

Grüsse / regards, Christian Ehrhardt
IBM Linux Technology Center, Open Virtualization 


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

end of thread, other threads:[~2009-06-02 14:23 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-29 10:58 [PATCH 1/4] kvm-s390: infrastructure to kick vcpus out of guest state - v3 ehrhardt
2009-05-29 10:58 ` [PATCH 2/4] kvm-s390: fix interruption caused by signal - v2 ehrhardt
2009-05-29 10:58 ` [PATCH 3/4] kvm-s390: update vcpu->cpu ehrhardt
2009-05-29 10:58 ` [PATCH 4/4] kvm-s390: streamline memslot handling - v6 ehrhardt
2009-05-31  8:22   ` Avi Kivity
2009-06-02 12:32     ` Marcelo Tosatti
2009-06-02 14:23       ` Christian Ehrhardt

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