public inbox for linux-s390@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] KVM: s390: Patches for kvm-next.
@ 2013-06-12 11:54 Cornelia Huck
  2013-06-12 11:54 ` [PATCH 1/6] KVM: s390: Provide function for setting the guest storage key Cornelia Huck
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Cornelia Huck @ 2013-06-12 11:54 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: Christian Borntraeger, Heiko Carstens, Martin Schwidefsky, KVM,
	linux-s390

Hi,

here are some patches that have accumulated in our kvm/s390 patch queue.

There's now support for large pages in the guest, and perf samples can
be sorted between kvm host or guest. Other than that, some cleanup and
a bugfix.

Please apply.

Christian Borntraeger (3):
  KVM: s390: Provide function for setting the guest storage key
  KVM: s390: guest large pages
  KVM: s390: Use common waitqueue

Heinz Graalfs (1):
  KVM: s390,perf: Detect if perf samples belong to KVM host or guest

Michael Mueller (1):
  KVM: s390: code cleanup to use common vcpu slab cache

Thomas Huth (1):
  KVM: s390: Fix epsw instruction decoding

 arch/s390/include/asm/kvm_host.h   |  8 +++-
 arch/s390/include/asm/perf_event.h | 10 +++++
 arch/s390/include/asm/pgalloc.h    |  3 ++
 arch/s390/kernel/entry64.S         |  1 +
 arch/s390/kernel/perf_event.c      | 52 ++++++++++++++++++++++
 arch/s390/kernel/s390_ksyms.c      |  1 +
 arch/s390/kvm/interrupt.c          | 18 ++++----
 arch/s390/kvm/kvm-s390.c           | 15 ++++---
 arch/s390/kvm/kvm-s390.h           |  6 +++
 arch/s390/kvm/priv.c               | 89 ++++++++++++++++++++++++++++++++++++--
 arch/s390/kvm/sigp.c               | 16 +++----
 arch/s390/mm/pgtable.c             | 48 ++++++++++++++++++++
 12 files changed, 238 insertions(+), 29 deletions(-)

-- 
1.8.1.6

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

* [PATCH 1/6] KVM: s390: Provide function for setting the guest storage key
  2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
@ 2013-06-12 11:54 ` Cornelia Huck
  2013-06-12 11:54 ` [PATCH 2/6] KVM: s390: guest large pages Cornelia Huck
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Cornelia Huck @ 2013-06-12 11:54 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: Christian Borntraeger, Heiko Carstens, Martin Schwidefsky, KVM,
	linux-s390

From: Christian Borntraeger <borntraeger@de.ibm.com>

From time to time we need to set the guest storage key. Lets
provide a helper function that handles the changes with all the
right locking and checking.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 arch/s390/include/asm/pgalloc.h |  3 +++
 arch/s390/mm/pgtable.c          | 48 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 590c321..e1408dd 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -22,6 +22,9 @@ unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
 void page_table_free(struct mm_struct *, unsigned long *);
 void page_table_free_rcu(struct mmu_gather *, unsigned long *);
 
+int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
+			  unsigned long key, bool nq);
+
 static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
 	typedef struct { char _[n]; } addrtype;
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 1e0c438..44b1450 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -771,6 +771,54 @@ static inline void page_table_free_pgste(unsigned long *table)
 	__free_page(page);
 }
 
+int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
+			  unsigned long key, bool nq)
+{
+	spinlock_t *ptl;
+	pgste_t old, new;
+	pte_t *ptep;
+
+	down_read(&mm->mmap_sem);
+	ptep = get_locked_pte(current->mm, addr, &ptl);
+	if (unlikely(!ptep)) {
+		up_read(&mm->mmap_sem);
+		return -EFAULT;
+	}
+
+	new = old = pgste_get_lock(ptep);
+	pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT |
+			    PGSTE_ACC_BITS | PGSTE_FP_BIT);
+	pgste_val(new) |= (key & (_PAGE_CHANGED | _PAGE_REFERENCED)) << 48;
+	pgste_val(new) |= (key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
+	if (!(pte_val(*ptep) & _PAGE_INVALID)) {
+		unsigned long address, bits;
+		unsigned char skey;
+
+		address = pte_val(*ptep) & PAGE_MASK;
+		skey = page_get_storage_key(address);
+		bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
+		/* Set storage key ACC and FP */
+		page_set_storage_key(address,
+				(key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)),
+				!nq);
+
+		/* Merge host changed & referenced into pgste  */
+		pgste_val(new) |= bits << 52;
+		/* Transfer skey changed & referenced bit to kvm user bits */
+		pgste_val(new) |= bits << 45;	/* PGSTE_UR_BIT & PGSTE_UC_BIT */
+	}
+	/* changing the guest storage key is considered a change of the page */
+	if ((pgste_val(new) ^ pgste_val(old)) &
+	    (PGSTE_ACC_BITS | PGSTE_FP_BIT | PGSTE_GR_BIT | PGSTE_GC_BIT))
+		pgste_val(new) |= PGSTE_UC_BIT;
+
+	pgste_set_unlock(ptep, new);
+	pte_unmap_unlock(*ptep, ptl);
+	up_read(&mm->mmap_sem);
+	return 0;
+}
+EXPORT_SYMBOL(set_guest_storage_key);
+
 #else /* CONFIG_PGSTE */
 
 static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm,
-- 
1.8.1.6

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

* [PATCH 2/6] KVM: s390: guest large pages
  2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
  2013-06-12 11:54 ` [PATCH 1/6] KVM: s390: Provide function for setting the guest storage key Cornelia Huck
@ 2013-06-12 11:54 ` Cornelia Huck
  2013-06-12 11:54 ` [PATCH 3/6] KVM: s390: code cleanup to use common vcpu slab cache Cornelia Huck
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Cornelia Huck @ 2013-06-12 11:54 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: Christian Borntraeger, Heiko Carstens, Martin Schwidefsky, KVM,
	linux-s390

From: Christian Borntraeger <borntraeger@de.ibm.com>

This patch enables kvm to give large pages to the guest. The heavy
lifting is done by the hardware, the host only has to take care
of the PFMF instruction, which is also part of EDAT-1.

We also support the non-quiescing key setting facility if the host
supports it, to behave similar to the interpretation of sske.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 arch/s390/include/asm/kvm_host.h |  5 ++-
 arch/s390/kvm/kvm-s390.c         |  7 +++-
 arch/s390/kvm/kvm-s390.h         |  6 +++
 arch/s390/kvm/priv.c             | 86 +++++++++++++++++++++++++++++++++++++++-
 4 files changed, 99 insertions(+), 5 deletions(-)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 9a809f9..43207dd 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -62,6 +62,7 @@ struct sca_block {
 #define CPUSTAT_MCDS       0x00000100
 #define CPUSTAT_SM         0x00000080
 #define CPUSTAT_G          0x00000008
+#define CPUSTAT_GED        0x00000004
 #define CPUSTAT_J          0x00000002
 #define CPUSTAT_P          0x00000001
 
@@ -96,7 +97,8 @@ struct kvm_s390_sie_block {
 	__u32	scaoh;			/* 0x005c */
 	__u8	reserved60;		/* 0x0060 */
 	__u8	ecb;			/* 0x0061 */
-	__u8	reserved62[2];		/* 0x0062 */
+	__u8    ecb2;                   /* 0x0062 */
+	__u8    reserved63[1];          /* 0x0063 */
 	__u32	scaol;			/* 0x0064 */
 	__u8	reserved68[4];		/* 0x0068 */
 	__u32	todpr;			/* 0x006c */
@@ -136,6 +138,7 @@ struct kvm_vcpu_stat {
 	u32 deliver_program_int;
 	u32 deliver_io_int;
 	u32 exit_wait_state;
+	u32 instruction_pfmf;
 	u32 instruction_stidp;
 	u32 instruction_spx;
 	u32 instruction_stpx;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 93444c4..e56caec 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -59,6 +59,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
 	{ "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
 	{ "exit_wait_state", VCPU_STAT(exit_wait_state) },
+	{ "instruction_pfmf", VCPU_STAT(instruction_pfmf) },
 	{ "instruction_stidp", VCPU_STAT(instruction_stidp) },
 	{ "instruction_spx", VCPU_STAT(instruction_spx) },
 	{ "instruction_stpx", VCPU_STAT(instruction_stpx) },
@@ -381,8 +382,10 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
 	atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
 						    CPUSTAT_SM |
-						    CPUSTAT_STOPPED);
+						    CPUSTAT_STOPPED |
+						    CPUSTAT_GED);
 	vcpu->arch.sie_block->ecb   = 6;
+	vcpu->arch.sie_block->ecb2  = 8;
 	vcpu->arch.sie_block->eca   = 0xC1002001U;
 	vcpu->arch.sie_block->fac   = (int) (long) facilities;
 	hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
@@ -1125,7 +1128,7 @@ static int __init kvm_s390_init(void)
 		return -ENOMEM;
 	}
 	memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
-	facilities[0] &= 0xff00fff3f47c0000ULL;
+	facilities[0] &= 0xff82fff3f47c0000ULL;
 	facilities[1] &= 0x001c000000000000ULL;
 	return 0;
 }
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 269b523..15795b8 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -86,6 +86,12 @@ static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu,
 	*address2 = (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2;
 }
 
+static inline void kvm_s390_get_regs_rre(struct kvm_vcpu *vcpu, int *r1, int *r2)
+{
+	*r1 = (vcpu->arch.sie_block->ipb & 0x00f00000) >> 20;
+	*r2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16;
+}
+
 static inline u64 kvm_s390_get_base_disp_rsy(struct kvm_vcpu *vcpu)
 {
 	u32 base2 = vcpu->arch.sie_block->ipb >> 28;
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index ecc58a6..bda9c9b 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -1,7 +1,7 @@
 /*
  * handling privileged instructions
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008, 2013
  *
  * 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)
@@ -20,6 +20,9 @@
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
 #include <asm/sysinfo.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
 #include <asm/ptrace.h>
 #include <asm/compat.h>
 #include "gaccess.h"
@@ -212,7 +215,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
 
 	vcpu->stat.instruction_stfl++;
 	/* only pass the facility bits, which we can handle */
-	facility_list = S390_lowcore.stfl_fac_list & 0xff00fff3;
+	facility_list = S390_lowcore.stfl_fac_list & 0xff82fff3;
 
 	rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
 			   &facility_list, sizeof(facility_list));
@@ -468,9 +471,88 @@ static int handle_epsw(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+#define PFMF_RESERVED   0xfffc0101UL
+#define PFMF_SK         0x00020000UL
+#define PFMF_CF         0x00010000UL
+#define PFMF_UI         0x00008000UL
+#define PFMF_FSC        0x00007000UL
+#define PFMF_NQ         0x00000800UL
+#define PFMF_MR         0x00000400UL
+#define PFMF_MC         0x00000200UL
+#define PFMF_KEY        0x000000feUL
+
+static int handle_pfmf(struct kvm_vcpu *vcpu)
+{
+	int reg1, reg2;
+	unsigned long start, end;
+
+	vcpu->stat.instruction_pfmf++;
+
+	kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
+
+	if (!MACHINE_HAS_PFMF)
+		return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
+
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OPERATION);
+
+	if (vcpu->run->s.regs.gprs[reg1] & PFMF_RESERVED)
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	/* Only provide non-quiescing support if the host supports it */
+	if (vcpu->run->s.regs.gprs[reg1] & PFMF_NQ &&
+	    S390_lowcore.stfl_fac_list & 0x00020000)
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	/* No support for conditional-SSKE */
+	if (vcpu->run->s.regs.gprs[reg1] & (PFMF_MR | PFMF_MC))
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	start = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK;
+	switch (vcpu->run->s.regs.gprs[reg1] & PFMF_FSC) {
+	case 0x00000000:
+		end = (start + (1UL << 12)) & ~((1UL << 12) - 1);
+		break;
+	case 0x00001000:
+		end = (start + (1UL << 20)) & ~((1UL << 20) - 1);
+		break;
+	/* We dont support EDAT2
+	case 0x00002000:
+		end = (start + (1UL << 31)) & ~((1UL << 31) - 1);
+		break;*/
+	default:
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+	}
+	while (start < end) {
+		unsigned long useraddr;
+
+		useraddr = gmap_translate(start, vcpu->arch.gmap);
+		if (IS_ERR((void *)useraddr))
+			return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+
+		if (vcpu->run->s.regs.gprs[reg1] & PFMF_CF) {
+			if (clear_user((void __user *)useraddr, PAGE_SIZE))
+				return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+		}
+
+		if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) {
+			if (set_guest_storage_key(current->mm, useraddr,
+					vcpu->run->s.regs.gprs[reg1] & PFMF_KEY,
+					vcpu->run->s.regs.gprs[reg1] & PFMF_NQ))
+				return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+		}
+
+		start += PAGE_SIZE;
+	}
+	if (vcpu->run->s.regs.gprs[reg1] & PFMF_FSC)
+		vcpu->run->s.regs.gprs[reg2] = end;
+	return 0;
+}
+
 static const intercept_handler_t b9_handlers[256] = {
 	[0x8d] = handle_epsw,
 	[0x9c] = handle_io_inst,
+	[0xaf] = handle_pfmf,
 };
 
 int kvm_s390_handle_b9(struct kvm_vcpu *vcpu)
-- 
1.8.1.6

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

* [PATCH 3/6] KVM: s390: code cleanup to use common vcpu slab cache
  2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
  2013-06-12 11:54 ` [PATCH 1/6] KVM: s390: Provide function for setting the guest storage key Cornelia Huck
  2013-06-12 11:54 ` [PATCH 2/6] KVM: s390: guest large pages Cornelia Huck
@ 2013-06-12 11:54 ` Cornelia Huck
  2013-06-12 11:54 ` [PATCH 4/6] KVM: s390: Use common waitqueue Cornelia Huck
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Cornelia Huck @ 2013-06-12 11:54 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: Christian Borntraeger, Heiko Carstens, Martin Schwidefsky, KVM,
	linux-s390, Michael Mueller

From: Michael Mueller <mimu@linux.vnet.ibm.com>

cleanup of arch specific code to use common code provided vcpu slab cache
instead of kzalloc() provided memory

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 arch/s390/kvm/kvm-s390.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index e56caec..757e1c6 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -278,7 +278,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 
 	free_page((unsigned long)(vcpu->arch.sie_block));
 	kvm_vcpu_uninit(vcpu);
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);
 }
 
 static void kvm_free_vcpus(struct kvm *kvm)
@@ -408,7 +408,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
 
 	rc = -ENOMEM;
 
-	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
+	vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
 	if (!vcpu)
 		goto out;
 
@@ -453,7 +453,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
 out_free_sie_block:
 	free_page((unsigned long)(vcpu->arch.sie_block));
 out_free_cpu:
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);
 out:
 	return ERR_PTR(rc);
 }
-- 
1.8.1.6

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

* [PATCH 4/6] KVM: s390: Use common waitqueue
  2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
                   ` (2 preceding siblings ...)
  2013-06-12 11:54 ` [PATCH 3/6] KVM: s390: code cleanup to use common vcpu slab cache Cornelia Huck
@ 2013-06-12 11:54 ` Cornelia Huck
  2013-06-12 11:54 ` [PATCH 5/6] KVM: s390,perf: Detect if perf samples belong to KVM host or guest Cornelia Huck
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Cornelia Huck @ 2013-06-12 11:54 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: Christian Borntraeger, Heiko Carstens, Martin Schwidefsky, KVM,
	linux-s390

From: Christian Borntraeger <borntraeger@de.ibm.com>

Lets use the common waitqueue for kvm cpus on s390. By itself it is
just a cleanup, but it should also improve the accuracy of diag 0x44
which is implemented via kvm_vcpu_on_spin. kvm_vcpu_on_spin has
an explicit check for waiting on the waitqueue to optimize the
yielding.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 arch/s390/include/asm/kvm_host.h |  2 +-
 arch/s390/kvm/interrupt.c        | 18 +++++++++---------
 arch/s390/kvm/kvm-s390.c         |  2 +-
 arch/s390/kvm/sigp.c             | 16 ++++++++--------
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 43207dd..d3ffd7e 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -228,7 +228,7 @@ struct kvm_s390_local_interrupt {
 	atomic_t active;
 	struct kvm_s390_float_interrupt *float_int;
 	int timer_due; /* event indicator for waitqueue below */
-	wait_queue_head_t wq;
+	wait_queue_head_t *wq;
 	atomic_t *cpuflags;
 	unsigned int action_bits;
 };
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 5c94817..7f35cb3 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -438,7 +438,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
 no_timer:
 	spin_lock(&vcpu->arch.local_int.float_int->lock);
 	spin_lock_bh(&vcpu->arch.local_int.lock);
-	add_wait_queue(&vcpu->arch.local_int.wq, &wait);
+	add_wait_queue(&vcpu->wq, &wait);
 	while (list_empty(&vcpu->arch.local_int.list) &&
 		list_empty(&vcpu->arch.local_int.float_int->list) &&
 		(!vcpu->arch.local_int.timer_due) &&
@@ -452,7 +452,7 @@ no_timer:
 	}
 	__unset_cpu_idle(vcpu);
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&vcpu->arch.local_int.wq, &wait);
+	remove_wait_queue(&vcpu->wq, &wait);
 	spin_unlock_bh(&vcpu->arch.local_int.lock);
 	spin_unlock(&vcpu->arch.local_int.float_int->lock);
 	hrtimer_try_to_cancel(&vcpu->arch.ckc_timer);
@@ -465,8 +465,8 @@ void kvm_s390_tasklet(unsigned long parm)
 
 	spin_lock(&vcpu->arch.local_int.lock);
 	vcpu->arch.local_int.timer_due = 1;
-	if (waitqueue_active(&vcpu->arch.local_int.wq))
-		wake_up_interruptible(&vcpu->arch.local_int.wq);
+	if (waitqueue_active(&vcpu->wq))
+		wake_up_interruptible(&vcpu->wq);
 	spin_unlock(&vcpu->arch.local_int.lock);
 }
 
@@ -613,7 +613,7 @@ int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code)
 	spin_lock_bh(&li->lock);
 	list_add(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
-	BUG_ON(waitqueue_active(&li->wq));
+	BUG_ON(waitqueue_active(li->wq));
 	spin_unlock_bh(&li->lock);
 	return 0;
 }
@@ -746,8 +746,8 @@ int kvm_s390_inject_vm(struct kvm *kvm,
 	li = fi->local_int[sigcpu];
 	spin_lock_bh(&li->lock);
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	spin_unlock_bh(&li->lock);
 	spin_unlock(&fi->lock);
 	mutex_unlock(&kvm->lock);
@@ -832,8 +832,8 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
 	if (inti->type == KVM_S390_SIGP_STOP)
 		li->action_bits |= ACTION_STOP_ON_STOP;
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&vcpu->arch.local_int.wq);
+	if (waitqueue_active(&vcpu->wq))
+		wake_up_interruptible(&vcpu->wq);
 	spin_unlock_bh(&li->lock);
 	mutex_unlock(&vcpu->kvm->lock);
 	return 0;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 757e1c6..22e8ace 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -438,7 +438,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
 	vcpu->arch.local_int.float_int = &kvm->arch.float_int;
 	spin_lock(&kvm->arch.float_int.lock);
 	kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
-	init_waitqueue_head(&vcpu->arch.local_int.wq);
+	vcpu->arch.local_int.wq = &vcpu->wq;
 	vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
 	spin_unlock(&kvm->arch.float_int.lock);
 
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 1c48ab2..033c864 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -79,8 +79,8 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr)
 	list_add_tail(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	spin_unlock_bh(&li->lock);
 	rc = SIGP_CC_ORDER_CODE_ACCEPTED;
 	VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr);
@@ -117,8 +117,8 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr)
 	list_add_tail(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	spin_unlock_bh(&li->lock);
 	rc = SIGP_CC_ORDER_CODE_ACCEPTED;
 	VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", cpu_addr);
@@ -145,8 +145,8 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
 	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);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 out:
 	spin_unlock_bh(&li->lock);
 
@@ -250,8 +250,8 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
 
 	list_add_tail(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	rc = SIGP_CC_ORDER_CODE_ACCEPTED;
 
 	VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", cpu_addr, address);
-- 
1.8.1.6

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

* [PATCH 5/6] KVM: s390,perf: Detect if perf samples belong to KVM host or guest
  2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
                   ` (3 preceding siblings ...)
  2013-06-12 11:54 ` [PATCH 4/6] KVM: s390: Use common waitqueue Cornelia Huck
@ 2013-06-12 11:54 ` Cornelia Huck
  2013-06-12 11:54 ` [PATCH 6/6] KVM: s390: Fix epsw instruction decoding Cornelia Huck
  2013-06-17 15:14 ` [PATCH 0/6] KVM: s390: Patches for kvm-next Paolo Bonzini
  6 siblings, 0 replies; 8+ messages in thread
From: Cornelia Huck @ 2013-06-12 11:54 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: Christian Borntraeger, Heiko Carstens, Martin Schwidefsky, KVM,
	linux-s390, Heinz Graalfs

From: Heinz Graalfs <graalfs@linux.vnet.ibm.com>

This patch is based on an original patch of David Hildenbrand.

The perf core implementation calls architecture specific code in order
to ask for specific information for a particular sample:

perf_instruction_pointer()
When perf core code asks for the instruction pointer, architecture
specific code must detect if a KVM guest was running when the sample
was taken. A sample can be associated with a  KVM guest when the PSW
supervisor state bit is set and the PSW instruction pointer part
contains the address of 'sie_exit'.
A KVM guest's instruction pointer information is then retrieved via
gpsw entry pointed to by the sie control-block.

perf_misc_flags()
perf code code calls this function in order to associate the kernel
vs. user state infomation with a particular sample. Architecture
specific code must also first detectif a KVM guest was running
at the time the sample was taken.

Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 arch/s390/include/asm/kvm_host.h   |  1 +
 arch/s390/include/asm/perf_event.h | 10 ++++++++
 arch/s390/kernel/entry64.S         |  1 +
 arch/s390/kernel/perf_event.c      | 52 ++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/s390_ksyms.c      |  1 +
 5 files changed, 65 insertions(+)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index d3ffd7e..4339069 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -275,4 +275,5 @@ struct kvm_arch{
 };
 
 extern int sie64a(struct kvm_s390_sie_block *, u64 *);
+extern char sie_exit;
 #endif
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h
index 5f0173a..1141fb3 100644
--- a/arch/s390/include/asm/perf_event.h
+++ b/arch/s390/include/asm/perf_event.h
@@ -14,3 +14,13 @@
 /* Per-CPU flags for PMU states */
 #define PMU_F_RESERVED			0x1000
 #define PMU_F_ENABLED			0x2000
+
+#ifdef CONFIG_64BIT
+
+/* Perf callbacks */
+struct pt_regs;
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+#define perf_misc_flags(regs) perf_misc_flags(regs)
+
+#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 51d99ac..b094ced 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -964,6 +964,7 @@ sie_done:
 # See also HANDLE_SIE_INTERCEPT
 rewind_pad:
 	nop	0
+	.globl sie_exit
 sie_exit:
 	lg	%r14,__SF_EMPTY+8(%r15)		# load guest register save area
 	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c
index f58f37f..a6fc037 100644
--- a/arch/s390/kernel/perf_event.c
+++ b/arch/s390/kernel/perf_event.c
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/perf_event.h>
+#include <linux/kvm_host.h>
 #include <linux/percpu.h>
 #include <linux/export.h>
 #include <asm/irq.h>
@@ -39,6 +40,57 @@ int perf_num_counters(void)
 }
 EXPORT_SYMBOL(perf_num_counters);
 
+static struct kvm_s390_sie_block *sie_block(struct pt_regs *regs)
+{
+	struct stack_frame *stack = (struct stack_frame *) regs->gprs[15];
+
+	if (!stack)
+		return NULL;
+
+	return (struct kvm_s390_sie_block *) stack->empty1[0];
+}
+
+static bool is_in_guest(struct pt_regs *regs)
+{
+	unsigned long ip = instruction_pointer(regs);
+
+	if (user_mode(regs))
+		return false;
+
+	return ip == (unsigned long) &sie_exit;
+}
+
+static unsigned long guest_is_user_mode(struct pt_regs *regs)
+{
+	return sie_block(regs)->gpsw.mask & PSW_MASK_PSTATE;
+}
+
+static unsigned long instruction_pointer_guest(struct pt_regs *regs)
+{
+	return sie_block(regs)->gpsw.addr & PSW_ADDR_INSN;
+}
+
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+	return is_in_guest(regs) ? instruction_pointer_guest(regs)
+				 : instruction_pointer(regs);
+}
+
+static unsigned long perf_misc_guest_flags(struct pt_regs *regs)
+{
+	return guest_is_user_mode(regs) ? PERF_RECORD_MISC_GUEST_USER
+					: PERF_RECORD_MISC_GUEST_KERNEL;
+}
+
+unsigned long perf_misc_flags(struct pt_regs *regs)
+{
+	if (is_in_guest(regs))
+		return perf_misc_guest_flags(regs);
+
+	return user_mode(regs) ? PERF_RECORD_MISC_USER
+			       : PERF_RECORD_MISC_KERNEL;
+}
+
 void perf_event_print_debug(void)
 {
 	struct cpumf_ctr_info cf_info;
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 9bdbcef..3bac589 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -7,6 +7,7 @@ EXPORT_SYMBOL(_mcount);
 #endif
 #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
 EXPORT_SYMBOL(sie64a);
+EXPORT_SYMBOL(sie_exit);
 #endif
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
-- 
1.8.1.6

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

* [PATCH 6/6] KVM: s390: Fix epsw instruction decoding
  2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
                   ` (4 preceding siblings ...)
  2013-06-12 11:54 ` [PATCH 5/6] KVM: s390,perf: Detect if perf samples belong to KVM host or guest Cornelia Huck
@ 2013-06-12 11:54 ` Cornelia Huck
  2013-06-17 15:14 ` [PATCH 0/6] KVM: s390: Patches for kvm-next Paolo Bonzini
  6 siblings, 0 replies; 8+ messages in thread
From: Cornelia Huck @ 2013-06-12 11:54 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: Christian Borntraeger, Heiko Carstens, Martin Schwidefsky, KVM,
	linux-s390, Thomas Huth

From: Thomas Huth <thuth@linux.vnet.ibm.com>

The handle_epsw() function calculated the first register in the wrong way,
so that it always used r0 by mistake. Now the code uses the common helper
function for decoding the registers of rre functions instead to avoid such
mistakes.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 arch/s390/kvm/priv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index bda9c9b..a0c63d7 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -457,8 +457,7 @@ static int handle_epsw(struct kvm_vcpu *vcpu)
 {
 	int reg1, reg2;
 
-	reg1 = (vcpu->arch.sie_block->ipb & 0x00f00000) >> 24;
-	reg2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16;
+	kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
 
 	/* This basically extracts the mask half of the psw. */
 	vcpu->run->s.regs.gprs[reg1] &= 0xffffffff00000000;
-- 
1.8.1.6

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

* Re: [PATCH 0/6] KVM: s390: Patches for kvm-next.
  2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
                   ` (5 preceding siblings ...)
  2013-06-12 11:54 ` [PATCH 6/6] KVM: s390: Fix epsw instruction decoding Cornelia Huck
@ 2013-06-17 15:14 ` Paolo Bonzini
  6 siblings, 0 replies; 8+ messages in thread
From: Paolo Bonzini @ 2013-06-17 15:14 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Gleb Natapov, Christian Borntraeger, Heiko Carstens,
	Martin Schwidefsky, KVM, linux-s390

Il 12/06/2013 13:54, Cornelia Huck ha scritto:
> Hi,
> 
> here are some patches that have accumulated in our kvm/s390 patch queue.
> 
> There's now support for large pages in the guest, and perf samples can
> be sorted between kvm host or guest. Other than that, some cleanup and
> a bugfix.
> 
> Please apply.
> 
> Christian Borntraeger (3):
>   KVM: s390: Provide function for setting the guest storage key
>   KVM: s390: guest large pages
>   KVM: s390: Use common waitqueue
> 
> Heinz Graalfs (1):
>   KVM: s390,perf: Detect if perf samples belong to KVM host or guest
> 
> Michael Mueller (1):
>   KVM: s390: code cleanup to use common vcpu slab cache
> 
> Thomas Huth (1):
>   KVM: s390: Fix epsw instruction decoding
> 
>  arch/s390/include/asm/kvm_host.h   |  8 +++-
>  arch/s390/include/asm/perf_event.h | 10 +++++
>  arch/s390/include/asm/pgalloc.h    |  3 ++
>  arch/s390/kernel/entry64.S         |  1 +
>  arch/s390/kernel/perf_event.c      | 52 ++++++++++++++++++++++
>  arch/s390/kernel/s390_ksyms.c      |  1 +
>  arch/s390/kvm/interrupt.c          | 18 ++++----
>  arch/s390/kvm/kvm-s390.c           | 15 ++++---
>  arch/s390/kvm/kvm-s390.h           |  6 +++
>  arch/s390/kvm/priv.c               | 89 ++++++++++++++++++++++++++++++++++++--
>  arch/s390/kvm/sigp.c               | 16 +++----
>  arch/s390/mm/pgtable.c             | 48 ++++++++++++++++++++
>  12 files changed, 238 insertions(+), 29 deletions(-)
> 

Applied, thanks.

Paolo

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

end of thread, other threads:[~2013-06-17 15:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-12 11:54 [PATCH 0/6] KVM: s390: Patches for kvm-next Cornelia Huck
2013-06-12 11:54 ` [PATCH 1/6] KVM: s390: Provide function for setting the guest storage key Cornelia Huck
2013-06-12 11:54 ` [PATCH 2/6] KVM: s390: guest large pages Cornelia Huck
2013-06-12 11:54 ` [PATCH 3/6] KVM: s390: code cleanup to use common vcpu slab cache Cornelia Huck
2013-06-12 11:54 ` [PATCH 4/6] KVM: s390: Use common waitqueue Cornelia Huck
2013-06-12 11:54 ` [PATCH 5/6] KVM: s390,perf: Detect if perf samples belong to KVM host or guest Cornelia Huck
2013-06-12 11:54 ` [PATCH 6/6] KVM: s390: Fix epsw instruction decoding Cornelia Huck
2013-06-17 15:14 ` [PATCH 0/6] KVM: s390: Patches for kvm-next Paolo Bonzini

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