All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] booke: Added ONE_REG interface for IAC/DAC debug registers
@ 2012-08-03  7:20 ` Bharat Bhushan
  0 siblings, 0 replies; 31+ messages in thread
From: Bharat Bhushan @ 2012-08-03  7:08 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

From: Bharat Bhushan <bharat.bhushan@freescale.com>

IAC/DAC are defined as 32 bit while they are 64 bit wide. So ONE_REG
interface is added to set/get them.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm.h      |   12 ++++++
 arch/powerpc/include/asm/kvm_host.h |   24 +++++++++++-
 arch/powerpc/kvm/booke.c            |   66 +++++++++++++++++++++++++++++++++-
 arch/powerpc/kvm/booke_emulate.c    |    8 ++--
 4 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 1bea4d8..3c14202 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -221,6 +221,12 @@ struct kvm_sregs {
 
 			__u32 dbsr;	/* KVM_SREGS_E_UPDATE_DBSR */
 			__u32 dbcr[3];
+			/*
+			 * iac/dac registers are 64bit wide, while this API
+			 * interface provides only lower 32 bits on 64 bit
+			 * processors. ONE_REG interface is added for 64bit
+			 * iac/dac registers.
+			 */
 			__u32 iac[4];
 			__u32 dac[2];
 			__u32 dvc[2];
@@ -326,5 +332,11 @@ struct kvm_book3e_206_tlb_params {
 };
 
 #define KVM_REG_PPC_HIOR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
+#define KVM_REG_PPC_IAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
+#define KVM_REG_PPC_IAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
+#define KVM_REG_PPC_IAC3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
+#define KVM_REG_PPC_IAC4	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
+#define KVM_REG_PPC_DAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
+#define KVM_REG_PPC_DAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
 
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 873ec11..dcee499 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -344,6 +344,27 @@ struct kvmppc_slb {
 	bool class	: 1;
 };
 
+# ifdef CONFIG_PPC_FSL_BOOK3E
+#define KVMPPC_BOOKE_IAC_NUM	2
+#define KVMPPC_BOOKE_DAC_NUM	2
+# else
+#define KVMPPC_BOOKE_IAC_NUM	4
+#define KVMPPC_BOOKE_DAC_NUM	2
+# endif
+#define KVMPPC_BOOKE_MAX_IAC	4
+#define KVMPPC_BOOKE_MAX_DAC	2
+
+struct kvmppc_booke_debug_reg {
+	u32 dbcr0;
+	u32 dbcr1;
+	u32 dbcr2;
+#ifdef CONFIG_KVM_E500MC
+	u32 dbcr4;
+#endif
+	u64 iac[KVMPPC_BOOKE_MAX_IAC];
+	u64 dac[KVMPPC_BOOKE_MAX_DAC];
+};
+
 struct kvm_vcpu_arch {
 	ulong host_stack;
 	u32 host_pid;
@@ -438,9 +459,8 @@ struct kvm_vcpu_arch {
 
 	u32 ccr0;
 	u32 ccr1;
-	u32 dbcr0;
-	u32 dbcr1;
 	u32 dbsr;
+	struct kvmppc_booke_debug_reg dbg_reg;
 
 	u64 mmcr[3];
 	u32 pmc[8];
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 68ed863..aebbb8b 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1379,12 +1379,74 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	return -EINVAL;
+	int r = -EINVAL;
+
+	switch(reg->id) {
+	case KVM_REG_PPC_IAC1:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[0], sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC2:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[1], sizeof(u64));
+		break;
+#ifndef CONFIG_PPC_FSL_BOOK3E
+	case KVM_REG_PPC_IAC3:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[2], sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC4:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[3], sizeof(u64));
+		break;
+#endif
+	case KVM_REG_PPC_DAC1:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.dac[0], sizeof(u64));
+		break;
+	case KVM_REG_PPC_DAC2:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.dac[1], sizeof(u64));
+		break;
+	default:
+		break;
+	}
+	return r;
 }
 
 int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	return -EINVAL;
+	int r = -EINVAL;
+
+	switch(reg->id) {
+	case KVM_REG_PPC_IAC1:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[0],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC2:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[1],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC3:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[2],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC4:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[3],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_DAC1:
+		r = copy_from_user(&vcpu->arch.dbg_reg.dac[0],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_DAC2:
+		r = copy_from_user(&vcpu->arch.dbg_reg.dac[1],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	default:
+		break;
+	}
+	return r;
 }
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index 5a66ade..cc99a0b 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -133,10 +133,10 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
 		vcpu->arch.csrr1 = spr_val;
 		break;
 	case SPRN_DBCR0:
-		vcpu->arch.dbcr0 = spr_val;
+		vcpu->arch.dbg_reg.dbcr0 = spr_val;
 		break;
 	case SPRN_DBCR1:
-		vcpu->arch.dbcr1 = spr_val;
+		vcpu->arch.dbg_reg.dbcr1 = spr_val;
 		break;
 	case SPRN_DBSR:
 		vcpu->arch.dbsr &= ~spr_val;
@@ -266,10 +266,10 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 		*spr_val = vcpu->arch.csrr1;
 		break;
 	case SPRN_DBCR0:
-		*spr_val = vcpu->arch.dbcr0;
+		*spr_val = vcpu->arch.dbg_reg.dbcr0;
 		break;
 	case SPRN_DBCR1:
-		*spr_val = vcpu->arch.dbcr1;
+		*spr_val = vcpu->arch.dbg_reg.dbcr1;
 		break;
 	case SPRN_DBSR:
 		*spr_val = vcpu->arch.dbsr;
-- 
1.7.0.4

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

* [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
  2012-08-03  7:20 ` Bharat Bhushan
@ 2012-08-03  7:20   ` Bharat Bhushan
  -1 siblings, 0 replies; 31+ messages in thread
From: Bharat Bhushan @ 2012-08-03  7:08 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
all handlers are considered to be the same size. This will not be
the case if we want to use different macros for different handlers.

This patch improves the kvmppc_booke_handler so that it can
support different macros for different handlers.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[bharat.bhushan@freescale.com: Substantial changes]
Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_ppc.h  |    2 -
 arch/powerpc/kvm/booke.c            |    9 ++++---
 arch/powerpc/kvm/booke.h            |    1 +
 arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
 arch/powerpc/kvm/e500.c             |   13 +++++++----
 5 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 1438a5e..deb55bd 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -47,8 +47,6 @@ enum emulation_result {
 
 extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
 extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
-extern char kvmppc_handlers_start[];
-extern unsigned long kvmppc_handler_len;
 extern void kvmppc_handler_highmem(void);
 
 extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index aebbb8b..1338233 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void)
 {
 #ifndef CONFIG_KVM_BOOKE_HV
 	unsigned long ivor[16];
+	unsigned long *handler = kvmppc_booke_handler_addr;
 	unsigned long max_ivor = 0;
 	int i;
 
@@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
 
 	for (i = 0; i < 16; i++) {
 		if (ivor[i] > max_ivor)
-			max_ivor = ivor[i];
+			max_ivor = i;
 
 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
-		       kvmppc_handlers_start + i * kvmppc_handler_len,
-		       kvmppc_handler_len);
+		       (void *)handler[i], handler[i + 1] - handler[i]);
 	}
 	flush_icache_range(kvmppc_booke_handlers,
-	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+	                   kvmppc_booke_handlers + ivor[max_ivor] +
+                               handler[max_ivor + 1] - handler[max_ivor]);
 #endif /* !BOOKE_HV */
 	return 0;
 }
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index ba61974..de9e526 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -65,6 +65,7 @@
 			  (1 << BOOKE_IRQPRIO_CRITICAL))
 
 extern unsigned long kvmppc_booke_handlers;
+extern unsigned long kvmppc_booke_handler_addr[];
 
 void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
 void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index bb46b32..3539805 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
 	bctr
 .endm
 
+.macro KVM_HANDLER_ADDR ivor_nr
+	.long	kvmppc_handler_\ivor_nr
+.endm
+
+.macro KVM_HANDLER_END
+	.long	kvmppc_handlers_end
+.endm
+
 _GLOBAL(kvmppc_handlers_start)
 KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
@@ -93,9 +101,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
-
-_GLOBAL(kvmppc_handler_len)
-	.long kvmppc_handler_1 - kvmppc_handler_0
+_GLOBAL(kvmppc_handlers_end)
 
 /* Registers:
  *  SPRG_SCRATCH0: guest r4
@@ -463,6 +469,31 @@ lightweight_exit:
 	lwz	r4, VCPU_GPR(R4)(r4)
 	rfi
 
+	.data
+	.align	4
+	.globl	kvmppc_booke_handler_addr
+kvmppc_booke_handler_addr:
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
+KVM_HANDLER_END /*Always keep this in end*/
+
 #ifdef CONFIG_SPE
 _GLOBAL(kvmppc_save_guest_spe)
 	cmpi	0,r3,0
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index b479ed7..cb7a5e7 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void)
 {
 	int r, i;
 	unsigned long ivor[3];
+	unsigned long *handler = kvmppc_booke_handler_addr;
 	unsigned long max_ivor = 0;
 
 	r = kvmppc_core_check_processor_compat();
 	if (r)
 		return r;
 
+	handler += 16;
+
 	r = kvmppc_booke_init();
 	if (r)
 		return r;
@@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
 	ivor[1] = mfspr(SPRN_IVOR33);
 	ivor[2] = mfspr(SPRN_IVOR34);
 	for (i = 0; i < 3; i++) {
-		if (ivor[i] > max_ivor)
-			max_ivor = ivor[i];
+		if (ivor[i] > ivor[max_ivor])
+			max_ivor = i;
 
 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
-		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
-		       kvmppc_handler_len);
+		       (void *)handler[i], handler[i + 1] - handler[i]);
 	}
 	flush_icache_range(kvmppc_booke_handlers,
-			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+	                   kvmppc_booke_handlers + ivor[max_ivor] +
+	                       handler[max_ivor + 1] - handler[max_ivor]);
 
 	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
 }
-- 
1.7.0.4

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

* [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-03  7:20 ` Bharat Bhushan
@ 2012-08-03  7:20   ` Bharat Bhushan
  -1 siblings, 0 replies; 31+ messages in thread
From: Bharat Bhushan @ 2012-08-03  7:08 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

Installed debug handler will be used for guest debug support and
debug facility emulation features (patches for these features
will follow this patch).

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[bharat.bhushan@freescale.com: Substantial changes]
Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/kernel/asm-offsets.c   |    1 +
 arch/powerpc/kvm/booke_interrupts.S |   45 +++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index dcee499..bd78523 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -494,6 +494,7 @@ struct kvm_vcpu_arch {
 	u32 tlbcfg[4];
 	u32 mmucfg;
 	u32 epr;
+	u32 crit_save;
 #endif
 	gpa_t paddr_accessed;
 	gva_t vaddr_accessed;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 85b05c4..92f149b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -563,6 +563,7 @@ int main(void)
 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
+	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
 #endif /* CONFIG_PPC_BOOK3S */
 #endif /* CONFIG_KVM */
 
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index 3539805..890673c 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
 	bctr
 .endm
 
+.macro KVM_DBG_HANDLER ivor_nr scratch srr0
+_GLOBAL(kvmppc_handler_\ivor_nr)
+	mtspr   \scratch, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	stw	r3, VCPU_CRIT_SAVE(r4)
+	mfcr	r3
+	mfspr	r4, SPRN_CSRR1
+	andi.	r4, r4, MSR_PR
+	bne	1f
+	/* debug interrupt happened in enter/exit path */
+	mfspr   r4, SPRN_CSRR1
+	rlwinm  r4, r4, 0, ~MSR_DE
+	mtspr   SPRN_CSRR1, r4
+	lis	r4, 0xffff
+	ori	r4, r4, 0xffff
+	mtspr	SPRN_DBSR, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	mtcr	r3
+	lwz     r3, VCPU_CRIT_SAVE(r4)
+	mfspr   r4, \scratch
+	rfci
+1:	/* debug interrupt happened in guest */
+	mfspr   r4, \scratch
+	mtcr	r3
+	mr	r3, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	stw	r3, VCPU_GPR(R4)(r4)
+	stw	r5, VCPU_GPR(R5)(r4)
+	stw	r6, VCPU_GPR(R6)(r4)
+	lwz     r3, VCPU_CRIT_SAVE(r4)
+	mfspr	r5, \srr0
+	stw	r3, VCPU_GPR(R3)(r4)
+	stw	r5, VCPU_PC(r4)
+	mfctr	r5
+	lis	r6, kvmppc_resume_host@h
+	stw	r5, VCPU_CTR(r4)
+	li	r5, \ivor_nr
+	ori	r6, r6, kvmppc_resume_host@l
+	mtctr	r6
+	bctr
+.endm
+
 .macro KVM_HANDLER_ADDR ivor_nr
 	.long	kvmppc_handler_\ivor_nr
 .endm
-- 
1.7.0.4

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

* [PATCH 1/3] booke: Added ONE_REG interface for IAC/DAC debug registers
@ 2012-08-03  7:20 ` Bharat Bhushan
  0 siblings, 0 replies; 31+ messages in thread
From: Bharat Bhushan @ 2012-08-03  7:20 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

From: Bharat Bhushan <bharat.bhushan@freescale.com>

IAC/DAC are defined as 32 bit while they are 64 bit wide. So ONE_REG
interface is added to set/get them.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm.h      |   12 ++++++
 arch/powerpc/include/asm/kvm_host.h |   24 +++++++++++-
 arch/powerpc/kvm/booke.c            |   66 +++++++++++++++++++++++++++++++++-
 arch/powerpc/kvm/booke_emulate.c    |    8 ++--
 4 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 1bea4d8..3c14202 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -221,6 +221,12 @@ struct kvm_sregs {
 
 			__u32 dbsr;	/* KVM_SREGS_E_UPDATE_DBSR */
 			__u32 dbcr[3];
+			/*
+			 * iac/dac registers are 64bit wide, while this API
+			 * interface provides only lower 32 bits on 64 bit
+			 * processors. ONE_REG interface is added for 64bit
+			 * iac/dac registers.
+			 */
 			__u32 iac[4];
 			__u32 dac[2];
 			__u32 dvc[2];
@@ -326,5 +332,11 @@ struct kvm_book3e_206_tlb_params {
 };
 
 #define KVM_REG_PPC_HIOR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
+#define KVM_REG_PPC_IAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
+#define KVM_REG_PPC_IAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
+#define KVM_REG_PPC_IAC3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
+#define KVM_REG_PPC_IAC4	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
+#define KVM_REG_PPC_DAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
+#define KVM_REG_PPC_DAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
 
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 873ec11..dcee499 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -344,6 +344,27 @@ struct kvmppc_slb {
 	bool class	: 1;
 };
 
+# ifdef CONFIG_PPC_FSL_BOOK3E
+#define KVMPPC_BOOKE_IAC_NUM	2
+#define KVMPPC_BOOKE_DAC_NUM	2
+# else
+#define KVMPPC_BOOKE_IAC_NUM	4
+#define KVMPPC_BOOKE_DAC_NUM	2
+# endif
+#define KVMPPC_BOOKE_MAX_IAC	4
+#define KVMPPC_BOOKE_MAX_DAC	2
+
+struct kvmppc_booke_debug_reg {
+	u32 dbcr0;
+	u32 dbcr1;
+	u32 dbcr2;
+#ifdef CONFIG_KVM_E500MC
+	u32 dbcr4;
+#endif
+	u64 iac[KVMPPC_BOOKE_MAX_IAC];
+	u64 dac[KVMPPC_BOOKE_MAX_DAC];
+};
+
 struct kvm_vcpu_arch {
 	ulong host_stack;
 	u32 host_pid;
@@ -438,9 +459,8 @@ struct kvm_vcpu_arch {
 
 	u32 ccr0;
 	u32 ccr1;
-	u32 dbcr0;
-	u32 dbcr1;
 	u32 dbsr;
+	struct kvmppc_booke_debug_reg dbg_reg;
 
 	u64 mmcr[3];
 	u32 pmc[8];
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 68ed863..aebbb8b 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1379,12 +1379,74 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	return -EINVAL;
+	int r = -EINVAL;
+
+	switch(reg->id) {
+	case KVM_REG_PPC_IAC1:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[0], sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC2:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[1], sizeof(u64));
+		break;
+#ifndef CONFIG_PPC_FSL_BOOK3E
+	case KVM_REG_PPC_IAC3:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[2], sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC4:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.iac[3], sizeof(u64));
+		break;
+#endif
+	case KVM_REG_PPC_DAC1:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.dac[0], sizeof(u64));
+		break;
+	case KVM_REG_PPC_DAC2:
+		r = copy_to_user((u64 __user *)(long)reg->addr,
+				 &vcpu->arch.dbg_reg.dac[1], sizeof(u64));
+		break;
+	default:
+		break;
+	}
+	return r;
 }
 
 int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	return -EINVAL;
+	int r = -EINVAL;
+
+	switch(reg->id) {
+	case KVM_REG_PPC_IAC1:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[0],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC2:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[1],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC3:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[2],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_IAC4:
+		r = copy_from_user(&vcpu->arch.dbg_reg.iac[3],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_DAC1:
+		r = copy_from_user(&vcpu->arch.dbg_reg.dac[0],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	case KVM_REG_PPC_DAC2:
+		r = copy_from_user(&vcpu->arch.dbg_reg.dac[1],
+			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		break;
+	default:
+		break;
+	}
+	return r;
 }
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index 5a66ade..cc99a0b 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -133,10 +133,10 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
 		vcpu->arch.csrr1 = spr_val;
 		break;
 	case SPRN_DBCR0:
-		vcpu->arch.dbcr0 = spr_val;
+		vcpu->arch.dbg_reg.dbcr0 = spr_val;
 		break;
 	case SPRN_DBCR1:
-		vcpu->arch.dbcr1 = spr_val;
+		vcpu->arch.dbg_reg.dbcr1 = spr_val;
 		break;
 	case SPRN_DBSR:
 		vcpu->arch.dbsr &= ~spr_val;
@@ -266,10 +266,10 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 		*spr_val = vcpu->arch.csrr1;
 		break;
 	case SPRN_DBCR0:
-		*spr_val = vcpu->arch.dbcr0;
+		*spr_val = vcpu->arch.dbg_reg.dbcr0;
 		break;
 	case SPRN_DBCR1:
-		*spr_val = vcpu->arch.dbcr1;
+		*spr_val = vcpu->arch.dbg_reg.dbcr1;
 		break;
 	case SPRN_DBSR:
 		*spr_val = vcpu->arch.dbsr;
-- 
1.7.0.4



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

* [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
@ 2012-08-03  7:20   ` Bharat Bhushan
  0 siblings, 0 replies; 31+ messages in thread
From: Bharat Bhushan @ 2012-08-03  7:20 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
all handlers are considered to be the same size. This will not be
the case if we want to use different macros for different handlers.

This patch improves the kvmppc_booke_handler so that it can
support different macros for different handlers.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[bharat.bhushan@freescale.com: Substantial changes]
Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_ppc.h  |    2 -
 arch/powerpc/kvm/booke.c            |    9 ++++---
 arch/powerpc/kvm/booke.h            |    1 +
 arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
 arch/powerpc/kvm/e500.c             |   13 +++++++----
 5 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 1438a5e..deb55bd 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -47,8 +47,6 @@ enum emulation_result {
 
 extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
 extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
-extern char kvmppc_handlers_start[];
-extern unsigned long kvmppc_handler_len;
 extern void kvmppc_handler_highmem(void);
 
 extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index aebbb8b..1338233 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void)
 {
 #ifndef CONFIG_KVM_BOOKE_HV
 	unsigned long ivor[16];
+	unsigned long *handler = kvmppc_booke_handler_addr;
 	unsigned long max_ivor = 0;
 	int i;
 
@@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
 
 	for (i = 0; i < 16; i++) {
 		if (ivor[i] > max_ivor)
-			max_ivor = ivor[i];
+			max_ivor = i;
 
 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
-		       kvmppc_handlers_start + i * kvmppc_handler_len,
-		       kvmppc_handler_len);
+		       (void *)handler[i], handler[i + 1] - handler[i]);
 	}
 	flush_icache_range(kvmppc_booke_handlers,
-	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+	                   kvmppc_booke_handlers + ivor[max_ivor] +
+                               handler[max_ivor + 1] - handler[max_ivor]);
 #endif /* !BOOKE_HV */
 	return 0;
 }
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index ba61974..de9e526 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -65,6 +65,7 @@
 			  (1 << BOOKE_IRQPRIO_CRITICAL))
 
 extern unsigned long kvmppc_booke_handlers;
+extern unsigned long kvmppc_booke_handler_addr[];
 
 void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
 void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index bb46b32..3539805 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
 	bctr
 .endm
 
+.macro KVM_HANDLER_ADDR ivor_nr
+	.long	kvmppc_handler_\ivor_nr
+.endm
+
+.macro KVM_HANDLER_END
+	.long	kvmppc_handlers_end
+.endm
+
 _GLOBAL(kvmppc_handlers_start)
 KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
@@ -93,9 +101,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
-
-_GLOBAL(kvmppc_handler_len)
-	.long kvmppc_handler_1 - kvmppc_handler_0
+_GLOBAL(kvmppc_handlers_end)
 
 /* Registers:
  *  SPRG_SCRATCH0: guest r4
@@ -463,6 +469,31 @@ lightweight_exit:
 	lwz	r4, VCPU_GPR(R4)(r4)
 	rfi
 
+	.data
+	.align	4
+	.globl	kvmppc_booke_handler_addr
+kvmppc_booke_handler_addr:
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
+KVM_HANDLER_END /*Always keep this in end*/
+
 #ifdef CONFIG_SPE
 _GLOBAL(kvmppc_save_guest_spe)
 	cmpi	0,r3,0
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index b479ed7..cb7a5e7 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void)
 {
 	int r, i;
 	unsigned long ivor[3];
+	unsigned long *handler = kvmppc_booke_handler_addr;
 	unsigned long max_ivor = 0;
 
 	r = kvmppc_core_check_processor_compat();
 	if (r)
 		return r;
 
+	handler += 16;
+
 	r = kvmppc_booke_init();
 	if (r)
 		return r;
@@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
 	ivor[1] = mfspr(SPRN_IVOR33);
 	ivor[2] = mfspr(SPRN_IVOR34);
 	for (i = 0; i < 3; i++) {
-		if (ivor[i] > max_ivor)
-			max_ivor = ivor[i];
+		if (ivor[i] > ivor[max_ivor])
+			max_ivor = i;
 
 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
-		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
-		       kvmppc_handler_len);
+		       (void *)handler[i], handler[i + 1] - handler[i]);
 	}
 	flush_icache_range(kvmppc_booke_handlers,
-			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+	                   kvmppc_booke_handlers + ivor[max_ivor] +
+	                       handler[max_ivor + 1] - handler[max_ivor]);
 
 	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
 }
-- 
1.7.0.4



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

* [PATCH 3/3] KVM: PPC: booke: Added debug handler
@ 2012-08-03  7:20   ` Bharat Bhushan
  0 siblings, 0 replies; 31+ messages in thread
From: Bharat Bhushan @ 2012-08-03  7:20 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

Installed debug handler will be used for guest debug support and
debug facility emulation features (patches for these features
will follow this patch).

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[bharat.bhushan@freescale.com: Substantial changes]
Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/kernel/asm-offsets.c   |    1 +
 arch/powerpc/kvm/booke_interrupts.S |   45 +++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index dcee499..bd78523 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -494,6 +494,7 @@ struct kvm_vcpu_arch {
 	u32 tlbcfg[4];
 	u32 mmucfg;
 	u32 epr;
+	u32 crit_save;
 #endif
 	gpa_t paddr_accessed;
 	gva_t vaddr_accessed;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 85b05c4..92f149b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -563,6 +563,7 @@ int main(void)
 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
+	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
 #endif /* CONFIG_PPC_BOOK3S */
 #endif /* CONFIG_KVM */
 
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index 3539805..890673c 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
 	bctr
 .endm
 
+.macro KVM_DBG_HANDLER ivor_nr scratch srr0
+_GLOBAL(kvmppc_handler_\ivor_nr)
+	mtspr   \scratch, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	stw	r3, VCPU_CRIT_SAVE(r4)
+	mfcr	r3
+	mfspr	r4, SPRN_CSRR1
+	andi.	r4, r4, MSR_PR
+	bne	1f
+	/* debug interrupt happened in enter/exit path */
+	mfspr   r4, SPRN_CSRR1
+	rlwinm  r4, r4, 0, ~MSR_DE
+	mtspr   SPRN_CSRR1, r4
+	lis	r4, 0xffff
+	ori	r4, r4, 0xffff
+	mtspr	SPRN_DBSR, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	mtcr	r3
+	lwz     r3, VCPU_CRIT_SAVE(r4)
+	mfspr   r4, \scratch
+	rfci
+1:	/* debug interrupt happened in guest */
+	mfspr   r4, \scratch
+	mtcr	r3
+	mr	r3, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	stw	r3, VCPU_GPR(R4)(r4)
+	stw	r5, VCPU_GPR(R5)(r4)
+	stw	r6, VCPU_GPR(R6)(r4)
+	lwz     r3, VCPU_CRIT_SAVE(r4)
+	mfspr	r5, \srr0
+	stw	r3, VCPU_GPR(R3)(r4)
+	stw	r5, VCPU_PC(r4)
+	mfctr	r5
+	lis	r6, kvmppc_resume_host@h
+	stw	r5, VCPU_CTR(r4)
+	li	r5, \ivor_nr
+	ori	r6, r6, kvmppc_resume_host@l
+	mtctr	r6
+	bctr
+.endm
+
 .macro KVM_HANDLER_ADDR ivor_nr
 	.long	kvmppc_handler_\ivor_nr
 .endm
-- 
1.7.0.4



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

* Re: [PATCH 1/3] booke: Added ONE_REG interface for IAC/DAC debug registers
  2012-08-03  7:20 ` Bharat Bhushan
@ 2012-08-07 10:30   ` Alexander Graf
  -1 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-07 10:30 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 03.08.2012, at 09:08, Bharat Bhushan wrote:

> From: Bharat Bhushan <bharat.bhushan@freescale.com>
> 
> IAC/DAC are defined as 32 bit while they are 64 bit wide. So ONE_REG
> interface is added to set/get them.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm.h      |   12 ++++++
> arch/powerpc/include/asm/kvm_host.h |   24 +++++++++++-
> arch/powerpc/kvm/booke.c            |   66 +++++++++++++++++++++++++++++++++-
> arch/powerpc/kvm/booke_emulate.c    |    8 ++--
> 4 files changed, 102 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
> index 1bea4d8..3c14202 100644
> --- a/arch/powerpc/include/asm/kvm.h
> +++ b/arch/powerpc/include/asm/kvm.h
> @@ -221,6 +221,12 @@ struct kvm_sregs {
> 
> 			__u32 dbsr;	/* KVM_SREGS_E_UPDATE_DBSR */
> 			__u32 dbcr[3];
> +			/*
> +			 * iac/dac registers are 64bit wide, while this API
> +			 * interface provides only lower 32 bits on 64 bit
> +			 * processors. ONE_REG interface is added for 64bit
> +			 * iac/dac registers.
> +			 */
> 			__u32 iac[4];
> 			__u32 dac[2];
> 			__u32 dvc[2];
> @@ -326,5 +332,11 @@ struct kvm_book3e_206_tlb_params {
> };
> 
> #define KVM_REG_PPC_HIOR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
> +#define KVM_REG_PPC_IAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
> +#define KVM_REG_PPC_IAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
> +#define KVM_REG_PPC_IAC3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
> +#define KVM_REG_PPC_IAC4	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
> +#define KVM_REG_PPC_DAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
> +#define KVM_REG_PPC_DAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
> 
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index 873ec11..dcee499 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -344,6 +344,27 @@ struct kvmppc_slb {
> 	bool class	: 1;
> };
> 
> +# ifdef CONFIG_PPC_FSL_BOOK3E
> +#define KVMPPC_BOOKE_IAC_NUM	2
> +#define KVMPPC_BOOKE_DAC_NUM	2
> +# else
> +#define KVMPPC_BOOKE_IAC_NUM	4
> +#define KVMPPC_BOOKE_DAC_NUM	2
> +# endif
> +#define KVMPPC_BOOKE_MAX_IAC	4
> +#define KVMPPC_BOOKE_MAX_DAC	2
> +
> +struct kvmppc_booke_debug_reg {
> +	u32 dbcr0;
> +	u32 dbcr1;
> +	u32 dbcr2;
> +#ifdef CONFIG_KVM_E500MC
> +	u32 dbcr4;
> +#endif
> +	u64 iac[KVMPPC_BOOKE_MAX_IAC];
> +	u64 dac[KVMPPC_BOOKE_MAX_DAC];
> +};
> +
> struct kvm_vcpu_arch {
> 	ulong host_stack;
> 	u32 host_pid;
> @@ -438,9 +459,8 @@ struct kvm_vcpu_arch {
> 
> 	u32 ccr0;
> 	u32 ccr1;
> -	u32 dbcr0;
> -	u32 dbcr1;
> 	u32 dbsr;
> +	struct kvmppc_booke_debug_reg dbg_reg;

Please put an #ifdef CONFIG_BOOKE around the above block.

> 
> 	u64 mmcr[3];
> 	u32 pmc[8];
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 68ed863..aebbb8b 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1379,12 +1379,74 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
> 
> int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	return -EINVAL;
> +	int r = -EINVAL;
> +
> +	switch(reg->id) {
> +	case KVM_REG_PPC_IAC1:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[0], sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC2:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[1], sizeof(u64));
> +		break;
> +#ifndef CONFIG_PPC_FSL_BOOK3E

No need for the #ifdef. Also, please do something like

case KVM_REG_PPC_IAC1:
case KVM_REG_PPC_IAC2:
case KVM_REG_PPC_IAC3:
case KVM_REG_PPC_IAC4: {
	int iac = reg->id - KVM_REG_PPC_IAC1;
	r = copy_to_user(..., ...iac[iac], ...);
	break;
}

Alex

> +	case KVM_REG_PPC_IAC3:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[2], sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC4:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[3], sizeof(u64));
> +		break;
> +#endif
> +	case KVM_REG_PPC_DAC1:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.dac[0], sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_DAC2:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.dac[1], sizeof(u64));
> +		break;
> +	default:
> +		break;
> +	}
> +	return r;
> }
> 
> int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	return -EINVAL;
> +	int r = -EINVAL;
> +
> +	switch(reg->id) {
> +	case KVM_REG_PPC_IAC1:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[0],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC2:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[1],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC3:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[2],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC4:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[3],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_DAC1:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.dac[0],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_DAC2:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.dac[1],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	default:
> +		break;
> +	}
> +	return r;
> }
> 
> int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
> diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
> index 5a66ade..cc99a0b 100644
> --- a/arch/powerpc/kvm/booke_emulate.c
> +++ b/arch/powerpc/kvm/booke_emulate.c
> @@ -133,10 +133,10 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
> 		vcpu->arch.csrr1 = spr_val;
> 		break;
> 	case SPRN_DBCR0:
> -		vcpu->arch.dbcr0 = spr_val;
> +		vcpu->arch.dbg_reg.dbcr0 = spr_val;
> 		break;
> 	case SPRN_DBCR1:
> -		vcpu->arch.dbcr1 = spr_val;
> +		vcpu->arch.dbg_reg.dbcr1 = spr_val;
> 		break;
> 	case SPRN_DBSR:
> 		vcpu->arch.dbsr &= ~spr_val;
> @@ -266,10 +266,10 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
> 		*spr_val = vcpu->arch.csrr1;
> 		break;
> 	case SPRN_DBCR0:
> -		*spr_val = vcpu->arch.dbcr0;
> +		*spr_val = vcpu->arch.dbg_reg.dbcr0;
> 		break;
> 	case SPRN_DBCR1:
> -		*spr_val = vcpu->arch.dbcr1;
> +		*spr_val = vcpu->arch.dbg_reg.dbcr1;
> 		break;
> 	case SPRN_DBSR:
> 		*spr_val = vcpu->arch.dbsr;
> -- 
> 1.7.0.4
> 
> 

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

* Re: [PATCH 1/3] booke: Added ONE_REG interface for IAC/DAC debug registers
@ 2012-08-07 10:30   ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-07 10:30 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 03.08.2012, at 09:08, Bharat Bhushan wrote:

> From: Bharat Bhushan <bharat.bhushan@freescale.com>
> 
> IAC/DAC are defined as 32 bit while they are 64 bit wide. So ONE_REG
> interface is added to set/get them.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm.h      |   12 ++++++
> arch/powerpc/include/asm/kvm_host.h |   24 +++++++++++-
> arch/powerpc/kvm/booke.c            |   66 +++++++++++++++++++++++++++++++++-
> arch/powerpc/kvm/booke_emulate.c    |    8 ++--
> 4 files changed, 102 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
> index 1bea4d8..3c14202 100644
> --- a/arch/powerpc/include/asm/kvm.h
> +++ b/arch/powerpc/include/asm/kvm.h
> @@ -221,6 +221,12 @@ struct kvm_sregs {
> 
> 			__u32 dbsr;	/* KVM_SREGS_E_UPDATE_DBSR */
> 			__u32 dbcr[3];
> +			/*
> +			 * iac/dac registers are 64bit wide, while this API
> +			 * interface provides only lower 32 bits on 64 bit
> +			 * processors. ONE_REG interface is added for 64bit
> +			 * iac/dac registers.
> +			 */
> 			__u32 iac[4];
> 			__u32 dac[2];
> 			__u32 dvc[2];
> @@ -326,5 +332,11 @@ struct kvm_book3e_206_tlb_params {
> };
> 
> #define KVM_REG_PPC_HIOR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
> +#define KVM_REG_PPC_IAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
> +#define KVM_REG_PPC_IAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
> +#define KVM_REG_PPC_IAC3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
> +#define KVM_REG_PPC_IAC4	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
> +#define KVM_REG_PPC_DAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
> +#define KVM_REG_PPC_DAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
> 
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index 873ec11..dcee499 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -344,6 +344,27 @@ struct kvmppc_slb {
> 	bool class	: 1;
> };
> 
> +# ifdef CONFIG_PPC_FSL_BOOK3E
> +#define KVMPPC_BOOKE_IAC_NUM	2
> +#define KVMPPC_BOOKE_DAC_NUM	2
> +# else
> +#define KVMPPC_BOOKE_IAC_NUM	4
> +#define KVMPPC_BOOKE_DAC_NUM	2
> +# endif
> +#define KVMPPC_BOOKE_MAX_IAC	4
> +#define KVMPPC_BOOKE_MAX_DAC	2
> +
> +struct kvmppc_booke_debug_reg {
> +	u32 dbcr0;
> +	u32 dbcr1;
> +	u32 dbcr2;
> +#ifdef CONFIG_KVM_E500MC
> +	u32 dbcr4;
> +#endif
> +	u64 iac[KVMPPC_BOOKE_MAX_IAC];
> +	u64 dac[KVMPPC_BOOKE_MAX_DAC];
> +};
> +
> struct kvm_vcpu_arch {
> 	ulong host_stack;
> 	u32 host_pid;
> @@ -438,9 +459,8 @@ struct kvm_vcpu_arch {
> 
> 	u32 ccr0;
> 	u32 ccr1;
> -	u32 dbcr0;
> -	u32 dbcr1;
> 	u32 dbsr;
> +	struct kvmppc_booke_debug_reg dbg_reg;

Please put an #ifdef CONFIG_BOOKE around the above block.

> 
> 	u64 mmcr[3];
> 	u32 pmc[8];
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 68ed863..aebbb8b 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1379,12 +1379,74 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
> 
> int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	return -EINVAL;
> +	int r = -EINVAL;
> +
> +	switch(reg->id) {
> +	case KVM_REG_PPC_IAC1:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[0], sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC2:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[1], sizeof(u64));
> +		break;
> +#ifndef CONFIG_PPC_FSL_BOOK3E

No need for the #ifdef. Also, please do something like

case KVM_REG_PPC_IAC1:
case KVM_REG_PPC_IAC2:
case KVM_REG_PPC_IAC3:
case KVM_REG_PPC_IAC4: {
	int iac = reg->id - KVM_REG_PPC_IAC1;
	r = copy_to_user(..., ...iac[iac], ...);
	break;
}

Alex

> +	case KVM_REG_PPC_IAC3:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[2], sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC4:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.iac[3], sizeof(u64));
> +		break;
> +#endif
> +	case KVM_REG_PPC_DAC1:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.dac[0], sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_DAC2:
> +		r = copy_to_user((u64 __user *)(long)reg->addr,
> +				 &vcpu->arch.dbg_reg.dac[1], sizeof(u64));
> +		break;
> +	default:
> +		break;
> +	}
> +	return r;
> }
> 
> int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	return -EINVAL;
> +	int r = -EINVAL;
> +
> +	switch(reg->id) {
> +	case KVM_REG_PPC_IAC1:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[0],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC2:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[1],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC3:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[2],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_IAC4:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.iac[3],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_DAC1:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.dac[0],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	case KVM_REG_PPC_DAC2:
> +		r = copy_from_user(&vcpu->arch.dbg_reg.dac[1],
> +			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		break;
> +	default:
> +		break;
> +	}
> +	return r;
> }
> 
> int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
> diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
> index 5a66ade..cc99a0b 100644
> --- a/arch/powerpc/kvm/booke_emulate.c
> +++ b/arch/powerpc/kvm/booke_emulate.c
> @@ -133,10 +133,10 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
> 		vcpu->arch.csrr1 = spr_val;
> 		break;
> 	case SPRN_DBCR0:
> -		vcpu->arch.dbcr0 = spr_val;
> +		vcpu->arch.dbg_reg.dbcr0 = spr_val;
> 		break;
> 	case SPRN_DBCR1:
> -		vcpu->arch.dbcr1 = spr_val;
> +		vcpu->arch.dbg_reg.dbcr1 = spr_val;
> 		break;
> 	case SPRN_DBSR:
> 		vcpu->arch.dbsr &= ~spr_val;
> @@ -266,10 +266,10 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
> 		*spr_val = vcpu->arch.csrr1;
> 		break;
> 	case SPRN_DBCR0:
> -		*spr_val = vcpu->arch.dbcr0;
> +		*spr_val = vcpu->arch.dbg_reg.dbcr0;
> 		break;
> 	case SPRN_DBCR1:
> -		*spr_val = vcpu->arch.dbcr1;
> +		*spr_val = vcpu->arch.dbg_reg.dbcr1;
> 		break;
> 	case SPRN_DBSR:
> 		*spr_val = vcpu->arch.dbsr;
> -- 
> 1.7.0.4
> 
> 


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

* Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
  2012-08-03  7:20   ` Bharat Bhushan
@ 2012-08-07 10:46     ` Alexander Graf
  -1 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-07 10:46 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 03.08.2012, at 09:08, Bharat Bhushan wrote:

> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
> all handlers are considered to be the same size. This will not be
> the case if we want to use different macros for different handlers.
> 
> This patch improves the kvmppc_booke_handler so that it can
> support different macros for different handlers.
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> [bharat.bhushan@freescale.com: Substantial changes]
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
> arch/powerpc/kvm/booke.c            |    9 ++++---
> arch/powerpc/kvm/booke.h            |    1 +
> arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
> arch/powerpc/kvm/e500.c             |   13 +++++++----
> 5 files changed, 48 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> index 1438a5e..deb55bd 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -47,8 +47,6 @@ enum emulation_result {
> 
> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
> extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
> -extern char kvmppc_handlers_start[];
> -extern unsigned long kvmppc_handler_len;
> extern void kvmppc_handler_highmem(void);
> 
> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index aebbb8b..1338233 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void)
> {
> #ifndef CONFIG_KVM_BOOKE_HV
> 	unsigned long ivor[16];
> +	unsigned long *handler = kvmppc_booke_handler_addr;
> 	unsigned long max_ivor = 0;
> 	int i;
> 
> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
> 
> 	for (i = 0; i < 16; i++) {
> 		if (ivor[i] > max_ivor)
> -			max_ivor = ivor[i];
> +			max_ivor = i;
> 
> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
> -		       kvmppc_handler_len);
> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> 	}
> 	flush_icache_range(kvmppc_booke_handlers,
> -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> +                               handler[max_ivor + 1] - handler[max_ivor]);
> #endif /* !BOOKE_HV */
> 	return 0;
> }
> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> index ba61974..de9e526 100644
> --- a/arch/powerpc/kvm/booke.h
> +++ b/arch/powerpc/kvm/booke.h
> @@ -65,6 +65,7 @@
> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
> 
> extern unsigned long kvmppc_booke_handlers;
> +extern unsigned long kvmppc_booke_handler_addr[];
> 
> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
> void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
> index bb46b32..3539805 100644
> --- a/arch/powerpc/kvm/booke_interrupts.S
> +++ b/arch/powerpc/kvm/booke_interrupts.S
> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> 	bctr
> .endm
> 
> +.macro KVM_HANDLER_ADDR ivor_nr
> +	.long	kvmppc_handler_\ivor_nr
> +.endm
> +
> +.macro KVM_HANDLER_END
> +	.long	kvmppc_handlers_end
> +.endm
> +
> _GLOBAL(kvmppc_handlers_start)
> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
> @@ -93,9 +101,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> -
> -_GLOBAL(kvmppc_handler_len)
> -	.long kvmppc_handler_1 - kvmppc_handler_0
> +_GLOBAL(kvmppc_handlers_end)
> 
> /* Registers:
>  *  SPRG_SCRATCH0: guest r4
> @@ -463,6 +469,31 @@ lightweight_exit:
> 	lwz	r4, VCPU_GPR(R4)(r4)
> 	rfi
> 
> +	.data
> +	.align	4
> +	.globl	kvmppc_booke_handler_addr
> +kvmppc_booke_handler_addr:
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
> +KVM_HANDLER_END /*Always keep this in end*/
> +
> #ifdef CONFIG_SPE
> _GLOBAL(kvmppc_save_guest_spe)
> 	cmpi	0,r3,0
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index b479ed7..cb7a5e7 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void)
> {
> 	int r, i;
> 	unsigned long ivor[3];
> +	unsigned long *handler = kvmppc_booke_handler_addr;

/* Process remaining handlers above the generic first 16 */
unsigned long *handler = &kvmppc_booke_handler_addr[16];

> 	unsigned long max_ivor = 0;
> 
> 	r = kvmppc_core_check_processor_compat();
> 	if (r)
> 		return r;
> 
> +	handler += 16;
> +
> 	r = kvmppc_booke_init();
> 	if (r)
> 		return r;
> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
> 	ivor[1] = mfspr(SPRN_IVOR33);
> 	ivor[2] = mfspr(SPRN_IVOR34);
> 	for (i = 0; i < 3; i++) {
> -		if (ivor[i] > max_ivor)
> -			max_ivor = ivor[i];
> +		if (ivor[i] > ivor[max_ivor])
> +			max_ivor = i;
> 
> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
> -		       kvmppc_handler_len);
> +		       (void *)handler[i], handler[i + 1] - handler[i]);

handler_len = handler[i + 1] - handler[i];
handler_end = max(handler_end, handler[i] + handler_len);

> 	}
> 	flush_icache_range(kvmppc_booke_handlers,
> -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> +	                       handler[max_ivor + 1] - handler[max_ivor]);

handler_end


Alex


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

* Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
@ 2012-08-07 10:46     ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-07 10:46 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 03.08.2012, at 09:08, Bharat Bhushan wrote:

> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
> all handlers are considered to be the same size. This will not be
> the case if we want to use different macros for different handlers.
> 
> This patch improves the kvmppc_booke_handler so that it can
> support different macros for different handlers.
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> [bharat.bhushan@freescale.com: Substantial changes]
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
> arch/powerpc/kvm/booke.c            |    9 ++++---
> arch/powerpc/kvm/booke.h            |    1 +
> arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
> arch/powerpc/kvm/e500.c             |   13 +++++++----
> 5 files changed, 48 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> index 1438a5e..deb55bd 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -47,8 +47,6 @@ enum emulation_result {
> 
> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
> extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
> -extern char kvmppc_handlers_start[];
> -extern unsigned long kvmppc_handler_len;
> extern void kvmppc_handler_highmem(void);
> 
> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index aebbb8b..1338233 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void)
> {
> #ifndef CONFIG_KVM_BOOKE_HV
> 	unsigned long ivor[16];
> +	unsigned long *handler = kvmppc_booke_handler_addr;
> 	unsigned long max_ivor = 0;
> 	int i;
> 
> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
> 
> 	for (i = 0; i < 16; i++) {
> 		if (ivor[i] > max_ivor)
> -			max_ivor = ivor[i];
> +			max_ivor = i;
> 
> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
> -		       kvmppc_handler_len);
> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> 	}
> 	flush_icache_range(kvmppc_booke_handlers,
> -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> +                               handler[max_ivor + 1] - handler[max_ivor]);
> #endif /* !BOOKE_HV */
> 	return 0;
> }
> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> index ba61974..de9e526 100644
> --- a/arch/powerpc/kvm/booke.h
> +++ b/arch/powerpc/kvm/booke.h
> @@ -65,6 +65,7 @@
> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
> 
> extern unsigned long kvmppc_booke_handlers;
> +extern unsigned long kvmppc_booke_handler_addr[];
> 
> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
> void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
> index bb46b32..3539805 100644
> --- a/arch/powerpc/kvm/booke_interrupts.S
> +++ b/arch/powerpc/kvm/booke_interrupts.S
> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> 	bctr
> .endm
> 
> +.macro KVM_HANDLER_ADDR ivor_nr
> +	.long	kvmppc_handler_\ivor_nr
> +.endm
> +
> +.macro KVM_HANDLER_END
> +	.long	kvmppc_handlers_end
> +.endm
> +
> _GLOBAL(kvmppc_handlers_start)
> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
> @@ -93,9 +101,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> -
> -_GLOBAL(kvmppc_handler_len)
> -	.long kvmppc_handler_1 - kvmppc_handler_0
> +_GLOBAL(kvmppc_handlers_end)
> 
> /* Registers:
>  *  SPRG_SCRATCH0: guest r4
> @@ -463,6 +469,31 @@ lightweight_exit:
> 	lwz	r4, VCPU_GPR(R4)(r4)
> 	rfi
> 
> +	.data
> +	.align	4
> +	.globl	kvmppc_booke_handler_addr
> +kvmppc_booke_handler_addr:
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
> +KVM_HANDLER_END /*Always keep this in end*/
> +
> #ifdef CONFIG_SPE
> _GLOBAL(kvmppc_save_guest_spe)
> 	cmpi	0,r3,0
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index b479ed7..cb7a5e7 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void)
> {
> 	int r, i;
> 	unsigned long ivor[3];
> +	unsigned long *handler = kvmppc_booke_handler_addr;

/* Process remaining handlers above the generic first 16 */
unsigned long *handler = &kvmppc_booke_handler_addr[16];

> 	unsigned long max_ivor = 0;
> 
> 	r = kvmppc_core_check_processor_compat();
> 	if (r)
> 		return r;
> 
> +	handler += 16;
> +
> 	r = kvmppc_booke_init();
> 	if (r)
> 		return r;
> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
> 	ivor[1] = mfspr(SPRN_IVOR33);
> 	ivor[2] = mfspr(SPRN_IVOR34);
> 	for (i = 0; i < 3; i++) {
> -		if (ivor[i] > max_ivor)
> -			max_ivor = ivor[i];
> +		if (ivor[i] > ivor[max_ivor])
> +			max_ivor = i;
> 
> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
> -		       kvmppc_handler_len);
> +		       (void *)handler[i], handler[i + 1] - handler[i]);

handler_len = handler[i + 1] - handler[i];
handler_end = max(handler_end, handler[i] + handler_len);

> 	}
> 	flush_icache_range(kvmppc_booke_handlers,
> -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> +	                       handler[max_ivor + 1] - handler[max_ivor]);

handler_end


Alex


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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-03  7:20   ` Bharat Bhushan
@ 2012-08-07 10:47     ` Alexander Graf
  -1 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-07 10:47 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 03.08.2012, at 09:08, Bharat Bhushan wrote:

> Installed debug handler will be used for guest debug support and
> debug facility emulation features (patches for these features
> will follow this patch).
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> [bharat.bhushan@freescale.com: Substantial changes]
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm_host.h |    1 +
> arch/powerpc/kernel/asm-offsets.c   |    1 +
> arch/powerpc/kvm/booke_interrupts.S |   45 +++++++++++++++++++++++++++++++++++
> 3 files changed, 47 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index dcee499..bd78523 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -494,6 +494,7 @@ struct kvm_vcpu_arch {
> 	u32 tlbcfg[4];
> 	u32 mmucfg;
> 	u32 epr;
> +	u32 crit_save;
> #endif
> 	gpa_t paddr_accessed;
> 	gva_t vaddr_accessed;
> diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
> index 85b05c4..92f149b 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -563,6 +563,7 @@ int main(void)
> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> #endif /* CONFIG_PPC_BOOK3S */
> #endif /* CONFIG_KVM */
> 
> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
> index 3539805..890673c 100644
> --- a/arch/powerpc/kvm/booke_interrupts.S
> +++ b/arch/powerpc/kvm/booke_interrupts.S
> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> 	bctr
> .endm
> 
> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0

This is a lot of asm code. Any chance to share a good share of it with the generic handler?


Alex

> +_GLOBAL(kvmppc_handler_\ivor_nr)
> +	mtspr   \scratch, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	stw	r3, VCPU_CRIT_SAVE(r4)
> +	mfcr	r3
> +	mfspr	r4, SPRN_CSRR1
> +	andi.	r4, r4, MSR_PR
> +	bne	1f
> +	/* debug interrupt happened in enter/exit path */
> +	mfspr   r4, SPRN_CSRR1
> +	rlwinm  r4, r4, 0, ~MSR_DE
> +	mtspr   SPRN_CSRR1, r4
> +	lis	r4, 0xffff
> +	ori	r4, r4, 0xffff
> +	mtspr	SPRN_DBSR, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	mtcr	r3
> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> +	mfspr   r4, \scratch
> +	rfci
> +1:	/* debug interrupt happened in guest */
> +	mfspr   r4, \scratch
> +	mtcr	r3
> +	mr	r3, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	stw	r3, VCPU_GPR(R4)(r4)
> +	stw	r5, VCPU_GPR(R5)(r4)
> +	stw	r6, VCPU_GPR(R6)(r4)
> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> +	mfspr	r5, \srr0
> +	stw	r3, VCPU_GPR(R3)(r4)
> +	stw	r5, VCPU_PC(r4)
> +	mfctr	r5
> +	lis	r6, kvmppc_resume_host@h
> +	stw	r5, VCPU_CTR(r4)
> +	li	r5, \ivor_nr
> +	ori	r6, r6, kvmppc_resume_host@l
> +	mtctr	r6
> +	bctr
> +.endm
> +
> .macro KVM_HANDLER_ADDR ivor_nr
> 	.long	kvmppc_handler_\ivor_nr
> .endm
> -- 
> 1.7.0.4
> 
> 

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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
@ 2012-08-07 10:47     ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-07 10:47 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 03.08.2012, at 09:08, Bharat Bhushan wrote:

> Installed debug handler will be used for guest debug support and
> debug facility emulation features (patches for these features
> will follow this patch).
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> [bharat.bhushan@freescale.com: Substantial changes]
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm_host.h |    1 +
> arch/powerpc/kernel/asm-offsets.c   |    1 +
> arch/powerpc/kvm/booke_interrupts.S |   45 +++++++++++++++++++++++++++++++++++
> 3 files changed, 47 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index dcee499..bd78523 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -494,6 +494,7 @@ struct kvm_vcpu_arch {
> 	u32 tlbcfg[4];
> 	u32 mmucfg;
> 	u32 epr;
> +	u32 crit_save;
> #endif
> 	gpa_t paddr_accessed;
> 	gva_t vaddr_accessed;
> diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
> index 85b05c4..92f149b 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -563,6 +563,7 @@ int main(void)
> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> #endif /* CONFIG_PPC_BOOK3S */
> #endif /* CONFIG_KVM */
> 
> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
> index 3539805..890673c 100644
> --- a/arch/powerpc/kvm/booke_interrupts.S
> +++ b/arch/powerpc/kvm/booke_interrupts.S
> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> 	bctr
> .endm
> 
> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0

This is a lot of asm code. Any chance to share a good share of it with the generic handler?


Alex

> +_GLOBAL(kvmppc_handler_\ivor_nr)
> +	mtspr   \scratch, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	stw	r3, VCPU_CRIT_SAVE(r4)
> +	mfcr	r3
> +	mfspr	r4, SPRN_CSRR1
> +	andi.	r4, r4, MSR_PR
> +	bne	1f
> +	/* debug interrupt happened in enter/exit path */
> +	mfspr   r4, SPRN_CSRR1
> +	rlwinm  r4, r4, 0, ~MSR_DE
> +	mtspr   SPRN_CSRR1, r4
> +	lis	r4, 0xffff
> +	ori	r4, r4, 0xffff
> +	mtspr	SPRN_DBSR, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	mtcr	r3
> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> +	mfspr   r4, \scratch
> +	rfci
> +1:	/* debug interrupt happened in guest */
> +	mfspr   r4, \scratch
> +	mtcr	r3
> +	mr	r3, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	stw	r3, VCPU_GPR(R4)(r4)
> +	stw	r5, VCPU_GPR(R5)(r4)
> +	stw	r6, VCPU_GPR(R6)(r4)
> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> +	mfspr	r5, \srr0
> +	stw	r3, VCPU_GPR(R3)(r4)
> +	stw	r5, VCPU_PC(r4)
> +	mfctr	r5
> +	lis	r6, kvmppc_resume_host@h
> +	stw	r5, VCPU_CTR(r4)
> +	li	r5, \ivor_nr
> +	ori	r6, r6, kvmppc_resume_host@l
> +	mtctr	r6
> +	bctr
> +.endm
> +
> .macro KVM_HANDLER_ADDR ivor_nr
> 	.long	kvmppc_handler_\ivor_nr
> .endm
> -- 
> 1.7.0.4
> 
> 


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

* RE: [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-07 10:47     ` Alexander Graf
@ 2012-08-07 16:02       ` Bhushan Bharat-R65777
  -1 siblings, 0 replies; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-07 16:02 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Tuesday, August 07, 2012 4:18 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
> 
> 
> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
> 
> > Installed debug handler will be used for guest debug support and debug
> > facility emulation features (patches for these features will follow
> > this patch).
> >
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > [bharat.bhushan@freescale.com: Substantial changes]
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > arch/powerpc/include/asm/kvm_host.h |    1 +
> > arch/powerpc/kernel/asm-offsets.c   |    1 +
> > arch/powerpc/kvm/booke_interrupts.S |   45 +++++++++++++++++++++++++++++++++++
> > 3 files changed, 47 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/kvm_host.h
> > b/arch/powerpc/include/asm/kvm_host.h
> > index dcee499..bd78523 100644
> > --- a/arch/powerpc/include/asm/kvm_host.h
> > +++ b/arch/powerpc/include/asm/kvm_host.h
> > @@ -494,6 +494,7 @@ struct kvm_vcpu_arch {
> > 	u32 tlbcfg[4];
> > 	u32 mmucfg;
> > 	u32 epr;
> > +	u32 crit_save;
> > #endif
> > 	gpa_t paddr_accessed;
> > 	gva_t vaddr_accessed;
> > diff --git a/arch/powerpc/kernel/asm-offsets.c
> > b/arch/powerpc/kernel/asm-offsets.c
> > index 85b05c4..92f149b 100644
> > --- a/arch/powerpc/kernel/asm-offsets.c
> > +++ b/arch/powerpc/kernel/asm-offsets.c
> > @@ -563,6 +563,7 @@ int main(void)
> > 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> > 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> > 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> > +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> > #endif /* CONFIG_PPC_BOOK3S */
> > #endif /* CONFIG_KVM */
> >
> > diff --git a/arch/powerpc/kvm/booke_interrupts.S
> > b/arch/powerpc/kvm/booke_interrupts.S
> > index 3539805..890673c 100644
> > --- a/arch/powerpc/kvm/booke_interrupts.S
> > +++ b/arch/powerpc/kvm/booke_interrupts.S
> > @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> > 	bctr
> > .endm
> >
> > +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> 
> This is a lot of asm code. Any chance to share a good share of it with the
> generic handler?

Yes it is a lot of code but I am finding it difficult.

Thanks
-Bharat

> 
> 
> Alex
> 
> > +_GLOBAL(kvmppc_handler_\ivor_nr)
> > +	mtspr   \scratch, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	stw	r3, VCPU_CRIT_SAVE(r4)
> > +	mfcr	r3
> > +	mfspr	r4, SPRN_CSRR1
> > +	andi.	r4, r4, MSR_PR
> > +	bne	1f
> > +	/* debug interrupt happened in enter/exit path */
> > +	mfspr   r4, SPRN_CSRR1
> > +	rlwinm  r4, r4, 0, ~MSR_DE
> > +	mtspr   SPRN_CSRR1, r4
> > +	lis	r4, 0xffff
> > +	ori	r4, r4, 0xffff
> > +	mtspr	SPRN_DBSR, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	mtcr	r3
> > +	lwz     r3, VCPU_CRIT_SAVE(r4)
> > +	mfspr   r4, \scratch
> > +	rfci
> > +1:	/* debug interrupt happened in guest */
> > +	mfspr   r4, \scratch
> > +	mtcr	r3
> > +	mr	r3, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	stw	r3, VCPU_GPR(R4)(r4)
> > +	stw	r5, VCPU_GPR(R5)(r4)
> > +	stw	r6, VCPU_GPR(R6)(r4)
> > +	lwz     r3, VCPU_CRIT_SAVE(r4)
> > +	mfspr	r5, \srr0
> > +	stw	r3, VCPU_GPR(R3)(r4)
> > +	stw	r5, VCPU_PC(r4)
> > +	mfctr	r5
> > +	lis	r6, kvmppc_resume_host@h
> > +	stw	r5, VCPU_CTR(r4)
> > +	li	r5, \ivor_nr
> > +	ori	r6, r6, kvmppc_resume_host@l
> > +	mtctr	r6
> > +	bctr
> > +.endm
> > +
> > .macro KVM_HANDLER_ADDR ivor_nr
> > 	.long	kvmppc_handler_\ivor_nr
> > .endm
> > --
> > 1.7.0.4
> >
> >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body
> of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH 3/3] KVM: PPC: booke: Added debug handler
@ 2012-08-07 16:02       ` Bhushan Bharat-R65777
  0 siblings, 0 replies; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-07 16:02 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Tuesday, August 07, 2012 4:18 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
> 
> 
> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
> 
> > Installed debug handler will be used for guest debug support and debug
> > facility emulation features (patches for these features will follow
> > this patch).
> >
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > [bharat.bhushan@freescale.com: Substantial changes]
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > arch/powerpc/include/asm/kvm_host.h |    1 +
> > arch/powerpc/kernel/asm-offsets.c   |    1 +
> > arch/powerpc/kvm/booke_interrupts.S |   45 +++++++++++++++++++++++++++++++++++
> > 3 files changed, 47 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/kvm_host.h
> > b/arch/powerpc/include/asm/kvm_host.h
> > index dcee499..bd78523 100644
> > --- a/arch/powerpc/include/asm/kvm_host.h
> > +++ b/arch/powerpc/include/asm/kvm_host.h
> > @@ -494,6 +494,7 @@ struct kvm_vcpu_arch {
> > 	u32 tlbcfg[4];
> > 	u32 mmucfg;
> > 	u32 epr;
> > +	u32 crit_save;
> > #endif
> > 	gpa_t paddr_accessed;
> > 	gva_t vaddr_accessed;
> > diff --git a/arch/powerpc/kernel/asm-offsets.c
> > b/arch/powerpc/kernel/asm-offsets.c
> > index 85b05c4..92f149b 100644
> > --- a/arch/powerpc/kernel/asm-offsets.c
> > +++ b/arch/powerpc/kernel/asm-offsets.c
> > @@ -563,6 +563,7 @@ int main(void)
> > 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> > 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> > 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> > +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> > #endif /* CONFIG_PPC_BOOK3S */
> > #endif /* CONFIG_KVM */
> >
> > diff --git a/arch/powerpc/kvm/booke_interrupts.S
> > b/arch/powerpc/kvm/booke_interrupts.S
> > index 3539805..890673c 100644
> > --- a/arch/powerpc/kvm/booke_interrupts.S
> > +++ b/arch/powerpc/kvm/booke_interrupts.S
> > @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> > 	bctr
> > .endm
> >
> > +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> 
> This is a lot of asm code. Any chance to share a good share of it with the
> generic handler?

Yes it is a lot of code but I am finding it difficult.

Thanks
-Bharat

> 
> 
> Alex
> 
> > +_GLOBAL(kvmppc_handler_\ivor_nr)
> > +	mtspr   \scratch, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	stw	r3, VCPU_CRIT_SAVE(r4)
> > +	mfcr	r3
> > +	mfspr	r4, SPRN_CSRR1
> > +	andi.	r4, r4, MSR_PR
> > +	bne	1f
> > +	/* debug interrupt happened in enter/exit path */
> > +	mfspr   r4, SPRN_CSRR1
> > +	rlwinm  r4, r4, 0, ~MSR_DE
> > +	mtspr   SPRN_CSRR1, r4
> > +	lis	r4, 0xffff
> > +	ori	r4, r4, 0xffff
> > +	mtspr	SPRN_DBSR, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	mtcr	r3
> > +	lwz     r3, VCPU_CRIT_SAVE(r4)
> > +	mfspr   r4, \scratch
> > +	rfci
> > +1:	/* debug interrupt happened in guest */
> > +	mfspr   r4, \scratch
> > +	mtcr	r3
> > +	mr	r3, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	stw	r3, VCPU_GPR(R4)(r4)
> > +	stw	r5, VCPU_GPR(R5)(r4)
> > +	stw	r6, VCPU_GPR(R6)(r4)
> > +	lwz     r3, VCPU_CRIT_SAVE(r4)
> > +	mfspr	r5, \srr0
> > +	stw	r3, VCPU_GPR(R3)(r4)
> > +	stw	r5, VCPU_PC(r4)
> > +	mfctr	r5
> > +	lis	r6, kvmppc_resume_host@h
> > +	stw	r5, VCPU_CTR(r4)
> > +	li	r5, \ivor_nr
> > +	ori	r6, r6, kvmppc_resume_host@l
> > +	mtctr	r6
> > +	bctr
> > +.endm
> > +
> > .macro KVM_HANDLER_ADDR ivor_nr
> > 	.long	kvmppc_handler_\ivor_nr
> > .endm
> > --
> > 1.7.0.4
> >
> >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body
> of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html



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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-07 10:47     ` Alexander Graf
@ 2012-08-07 20:44       ` Scott Wood
  -1 siblings, 0 replies; 31+ messages in thread
From: Scott Wood @ 2012-08-07 20:44 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Bharat Bhushan, kvm-ppc, kvm, Bharat Bhushan

On 08/07/2012 05:47 AM, Alexander Graf wrote:
>> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
>> index 3539805..890673c 100644
>> --- a/arch/powerpc/kvm/booke_interrupts.S
>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>> 	bctr
>> .endm
>>
>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> 
> This is a lot of asm code. Any chance to share a good share of it with the generic handler?

That entire file could use an update to lok more like
bookehv_interrupts.S and its use of asm macros.

-Scott



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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
@ 2012-08-07 20:44       ` Scott Wood
  0 siblings, 0 replies; 31+ messages in thread
From: Scott Wood @ 2012-08-07 20:44 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Bharat Bhushan, kvm-ppc, kvm, Bharat Bhushan

On 08/07/2012 05:47 AM, Alexander Graf wrote:
>> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
>> index 3539805..890673c 100644
>> --- a/arch/powerpc/kvm/booke_interrupts.S
>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>> 	bctr
>> .endm
>>
>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> 
> This is a lot of asm code. Any chance to share a good share of it with the generic handler?

That entire file could use an update to lok more like
bookehv_interrupts.S and its use of asm macros.

-Scott



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

* RE: [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-07 20:44       ` Scott Wood
@ 2012-08-08  1:02         ` Bhushan Bharat-R65777
  -1 siblings, 0 replies; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-08  1:02 UTC (permalink / raw)
  To: Wood Scott-B07421, Alexander Graf; +Cc: kvm-ppc, kvm



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Wednesday, August 08, 2012 2:15 AM
> To: Alexander Graf
> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> Bharat-R65777
> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
> 
> On 08/07/2012 05:47 AM, Alexander Graf wrote:
> >> diff --git a/arch/powerpc/kvm/booke_interrupts.S
> >> b/arch/powerpc/kvm/booke_interrupts.S
> >> index 3539805..890673c 100644
> >> --- a/arch/powerpc/kvm/booke_interrupts.S
> >> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >> 	bctr
> >> .endm
> >>
> >> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >
> > This is a lot of asm code. Any chance to share a good share of it with the
> generic handler?
> 
> That entire file could use an update to lok more like bookehv_interrupts.S and
> its use of asm macros.

In booke there is assumption that size of KVM IVORs will not me more than host IVORs size so that only IVPR is changed. 

I tried to give it that shape of bookehv_interrupts.S  and found that size of some IVORs become more than host IVORs.

Thanks
-Bharat

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

* RE: [PATCH 3/3] KVM: PPC: booke: Added debug handler
@ 2012-08-08  1:02         ` Bhushan Bharat-R65777
  0 siblings, 0 replies; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-08  1:02 UTC (permalink / raw)
  To: Wood Scott-B07421, Alexander Graf; +Cc: kvm-ppc, kvm

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogV29vZCBTY290dC1CMDc0
MjENCj4gU2VudDogV2VkbmVzZGF5LCBBdWd1c3QgMDgsIDIwMTIgMjoxNSBBTQ0KPiBUbzogQWxl
eGFuZGVyIEdyYWYNCj4gQ2M6IEJodXNoYW4gQmhhcmF0LVI2NTc3Nzsga3ZtLXBwY0B2Z2VyLmtl
cm5lbC5vcmc7IGt2bUB2Z2VyLmtlcm5lbC5vcmc7IEJodXNoYW4NCj4gQmhhcmF0LVI2NTc3Nw0K
PiBTdWJqZWN0OiBSZTogW1BBVENIIDMvM10gS1ZNOiBQUEM6IGJvb2tlOiBBZGRlZCBkZWJ1ZyBo
YW5kbGVyDQo+IA0KPiBPbiAwOC8wNy8yMDEyIDA1OjQ3IEFNLCBBbGV4YW5kZXIgR3JhZiB3cm90
ZToNCj4gPj4gZGlmZiAtLWdpdCBhL2FyY2gvcG93ZXJwYy9rdm0vYm9va2VfaW50ZXJydXB0cy5T
DQo+ID4+IGIvYXJjaC9wb3dlcnBjL2t2bS9ib29rZV9pbnRlcnJ1cHRzLlMNCj4gPj4gaW5kZXgg
MzUzOTgwNS4uODkwNjczYyAxMDA2NDQNCj4gPj4gLS0tIGEvYXJjaC9wb3dlcnBjL2t2bS9ib29r
ZV9pbnRlcnJ1cHRzLlMNCj4gPj4gKysrIGIvYXJjaC9wb3dlcnBjL2t2bS9ib29rZV9pbnRlcnJ1
cHRzLlMNCj4gPj4gQEAgLTczLDYgKzczLDUxIEBAIF9HTE9CQUwoa3ZtcHBjX2hhbmRsZXJfXGl2
b3JfbnIpDQo+ID4+IAliY3RyDQo+ID4+IC5lbmRtDQo+ID4+DQo+ID4+ICsubWFjcm8gS1ZNX0RC
R19IQU5ETEVSIGl2b3JfbnIgc2NyYXRjaCBzcnIwDQo+ID4NCj4gPiBUaGlzIGlzIGEgbG90IG9m
IGFzbSBjb2RlLiBBbnkgY2hhbmNlIHRvIHNoYXJlIGEgZ29vZCBzaGFyZSBvZiBpdCB3aXRoIHRo
ZQ0KPiBnZW5lcmljIGhhbmRsZXI/DQo+IA0KPiBUaGF0IGVudGlyZSBmaWxlIGNvdWxkIHVzZSBh
biB1cGRhdGUgdG8gbG9rIG1vcmUgbGlrZSBib29rZWh2X2ludGVycnVwdHMuUyBhbmQNCj4gaXRz
IHVzZSBvZiBhc20gbWFjcm9zLg0KDQpJbiBib29rZSB0aGVyZSBpcyBhc3N1bXB0aW9uIHRoYXQg
c2l6ZSBvZiBLVk0gSVZPUnMgd2lsbCBub3QgbWUgbW9yZSB0aGFuIGhvc3QgSVZPUnMgc2l6ZSBz
byB0aGF0IG9ubHkgSVZQUiBpcyBjaGFuZ2VkLiANCg0KSSB0cmllZCB0byBnaXZlIGl0IHRoYXQg
c2hhcGUgb2YgYm9va2Vodl9pbnRlcnJ1cHRzLlMgIGFuZCBmb3VuZCB0aGF0IHNpemUgb2Ygc29t
ZSBJVk9ScyBiZWNvbWUgbW9yZSB0aGFuIGhvc3QgSVZPUnMuDQoNClRoYW5rcw0KLUJoYXJhdA0K


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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-08  1:02         ` Bhushan Bharat-R65777
@ 2012-08-08 11:10           ` Alexander Graf
  -1 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-08 11:10 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: Wood Scott-B07421, kvm-ppc, kvm


On 08.08.2012, at 03:02, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Wood Scott-B07421
>> Sent: Wednesday, August 08, 2012 2:15 AM
>> To: Alexander Graf
>> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>> Bharat-R65777
>> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
>> 
>> On 08/07/2012 05:47 AM, Alexander Graf wrote:
>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>> index 3539805..890673c 100644
>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>> 	bctr
>>>> .endm
>>>> 
>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>> 
>>> This is a lot of asm code. Any chance to share a good share of it with the
>> generic handler?
>> 
>> That entire file could use an update to lok more like bookehv_interrupts.S and
>> its use of asm macros.
> 
> In booke there is assumption that size of KVM IVORs will not me more than host IVORs size so that only IVPR is changed. 
> 
> I tried to give it that shape of bookehv_interrupts.S  and found that size of some IVORs become more than host IVORs.

We can always jump off to another (more generic?) function and only have a small stub in the IVOR referenced code.


Alex


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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
@ 2012-08-08 11:10           ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-08 11:10 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: Wood Scott-B07421, kvm-ppc, kvm


On 08.08.2012, at 03:02, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Wood Scott-B07421
>> Sent: Wednesday, August 08, 2012 2:15 AM
>> To: Alexander Graf
>> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>> Bharat-R65777
>> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
>> 
>> On 08/07/2012 05:47 AM, Alexander Graf wrote:
>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>> index 3539805..890673c 100644
>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>> 	bctr
>>>> .endm
>>>> 
>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>> 
>>> This is a lot of asm code. Any chance to share a good share of it with the
>> generic handler?
>> 
>> That entire file could use an update to lok more like bookehv_interrupts.S and
>> its use of asm macros.
> 
> In booke there is assumption that size of KVM IVORs will not me more than host IVORs size so that only IVPR is changed. 
> 
> I tried to give it that shape of bookehv_interrupts.S  and found that size of some IVORs become more than host IVORs.

We can always jump off to another (more generic?) function and only have a small stub in the IVOR referenced code.


Alex


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

* RE: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
  2012-08-07 10:46     ` Alexander Graf
  (?)
@ 2012-08-10  6:38     ` Bhushan Bharat-R65777
  2012-08-10  9:19         ` Alexander Graf
  -1 siblings, 1 reply; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-10  6:38 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Tuesday, August 07, 2012 4:16 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
> 
> 
> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
> 
> > Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
> > all handlers are considered to be the same size. This will not be
> > the case if we want to use different macros for different handlers.
> >
> > This patch improves the kvmppc_booke_handler so that it can
> > support different macros for different handlers.
> >
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > [bharat.bhushan@freescale.com: Substantial changes]
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > arch/powerpc/include/asm/kvm_ppc.h  |    2 -
> > arch/powerpc/kvm/booke.c            |    9 ++++---
> > arch/powerpc/kvm/booke.h            |    1 +
> > arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
> > arch/powerpc/kvm/e500.c             |   13 +++++++----
> > 5 files changed, 48 insertions(+), 14 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/kvm_ppc.h
> b/arch/powerpc/include/asm/kvm_ppc.h
> > index 1438a5e..deb55bd 100644
> > --- a/arch/powerpc/include/asm/kvm_ppc.h
> > +++ b/arch/powerpc/include/asm/kvm_ppc.h
> > @@ -47,8 +47,6 @@ enum emulation_result {
> >
> > extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
> > extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
> > -extern char kvmppc_handlers_start[];
> > -extern unsigned long kvmppc_handler_len;
> > extern void kvmppc_handler_highmem(void);
> >
> > extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> > index aebbb8b..1338233 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void)
> > {
> > #ifndef CONFIG_KVM_BOOKE_HV
> > 	unsigned long ivor[16];
> > +	unsigned long *handler = kvmppc_booke_handler_addr;
> > 	unsigned long max_ivor = 0;
> > 	int i;
> >
> > @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
> >
> > 	for (i = 0; i < 16; i++) {
> > 		if (ivor[i] > max_ivor)
> > -			max_ivor = ivor[i];
> > +			max_ivor = i;
> >
> > 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> > -		       kvmppc_handlers_start + i * kvmppc_handler_len,
> > -		       kvmppc_handler_len);
> > +		       (void *)handler[i], handler[i + 1] - handler[i]);
> > 	}
> > 	flush_icache_range(kvmppc_booke_handlers,
> > -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> > +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> > +                               handler[max_ivor + 1] - handler[max_ivor]);
> > #endif /* !BOOKE_HV */
> > 	return 0;
> > }
> > diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> > index ba61974..de9e526 100644
> > --- a/arch/powerpc/kvm/booke.h
> > +++ b/arch/powerpc/kvm/booke.h
> > @@ -65,6 +65,7 @@
> > 			  (1 << BOOKE_IRQPRIO_CRITICAL))
> >
> > extern unsigned long kvmppc_booke_handlers;
> > +extern unsigned long kvmppc_booke_handler_addr[];
> >
> > void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
> > void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
> > diff --git a/arch/powerpc/kvm/booke_interrupts.S
> b/arch/powerpc/kvm/booke_interrupts.S
> > index bb46b32..3539805 100644
> > --- a/arch/powerpc/kvm/booke_interrupts.S
> > +++ b/arch/powerpc/kvm/booke_interrupts.S
> > @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> > 	bctr
> > .endm
> >
> > +.macro KVM_HANDLER_ADDR ivor_nr
> > +	.long	kvmppc_handler_\ivor_nr
> > +.endm
> > +
> > +.macro KVM_HANDLER_END
> > +	.long	kvmppc_handlers_end
> > +.endm
> > +
> > _GLOBAL(kvmppc_handlers_start)
> > KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> > KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
> > @@ -93,9 +101,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
> SPRN_CSRR0
> > KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> > KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> > KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> > -
> > -_GLOBAL(kvmppc_handler_len)
> > -	.long kvmppc_handler_1 - kvmppc_handler_0
> > +_GLOBAL(kvmppc_handlers_end)
> >
> > /* Registers:
> >  *  SPRG_SCRATCH0: guest r4
> > @@ -463,6 +469,31 @@ lightweight_exit:
> > 	lwz	r4, VCPU_GPR(R4)(r4)
> > 	rfi
> >
> > +	.data
> > +	.align	4
> > +	.globl	kvmppc_booke_handler_addr
> > +kvmppc_booke_handler_addr:
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
> > +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
> > +KVM_HANDLER_END /*Always keep this in end*/
> > +
> > #ifdef CONFIG_SPE
> > _GLOBAL(kvmppc_save_guest_spe)
> > 	cmpi	0,r3,0
> > diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> > index b479ed7..cb7a5e7 100644
> > --- a/arch/powerpc/kvm/e500.c
> > +++ b/arch/powerpc/kvm/e500.c
> > @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void)
> > {
> > 	int r, i;
> > 	unsigned long ivor[3];
> > +	unsigned long *handler = kvmppc_booke_handler_addr;
> 
> /* Process remaining handlers above the generic first 16 */
> unsigned long *handler = &kvmppc_booke_handler_addr[16];
> 
> > 	unsigned long max_ivor = 0;
> >
> > 	r = kvmppc_core_check_processor_compat();
> > 	if (r)
> > 		return r;
> >
> > +	handler += 16;
> > +
> > 	r = kvmppc_booke_init();
> > 	if (r)
> > 		return r;
> > @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
> > 	ivor[1] = mfspr(SPRN_IVOR33);
> > 	ivor[2] = mfspr(SPRN_IVOR34);
> > 	for (i = 0; i < 3; i++) {
> > -		if (ivor[i] > max_ivor)
> > -			max_ivor = ivor[i];
> > +		if (ivor[i] > ivor[max_ivor])
> > +			max_ivor = i;
> >
> > 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> > -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
> > -		       kvmppc_handler_len);
> > +		       (void *)handler[i], handler[i + 1] - handler[i]);
> 
> handler_len = handler[i + 1] - handler[i];
> handler_end = max(handler_end, handler[i] + handler_len);

Ok .

> 
> > 	}
> > 	flush_icache_range(kvmppc_booke_handlers,
> > -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> > +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> > +	                       handler[max_ivor + 1] - handler[max_ivor]);
> 
> handler_end

I do not get how this logic will work and simple. Can you please explain ?

The end address here is calculated by IVOR offset (same as host ivor offset) where KVM handler[last] is copied in kvmppc_booke_handlers and length by handler[last + 1] - handler[last];

Thanks
-Bharat

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

* RE: [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-08 11:10           ` Alexander Graf
  (?)
@ 2012-08-10  6:55           ` Bhushan Bharat-R65777
  2012-08-10  9:21               ` Alexander Graf
  -1 siblings, 1 reply; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-10  6:55 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Wood Scott-B07421, kvm-ppc, kvm



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Wednesday, August 08, 2012 4:41 PM
> To: Bhushan Bharat-R65777
> Cc: Wood Scott-B07421; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
> 
> 
> On 08.08.2012, at 03:02, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: Wood Scott-B07421
> >> Sent: Wednesday, August 08, 2012 2:15 AM
> >> To: Alexander Graf
> >> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org;
> >> kvm@vger.kernel.org; Bhushan
> >> Bharat-R65777
> >> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
> >>
> >> On 08/07/2012 05:47 AM, Alexander Graf wrote:
> >>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
> >>>> b/arch/powerpc/kvm/booke_interrupts.S
> >>>> index 3539805..890673c 100644
> >>>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>>> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>> 	bctr
> >>>> .endm
> >>>>
> >>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>
> >>> This is a lot of asm code. Any chance to share a good share of it
> >>> with the
> >> generic handler?
> >>
> >> That entire file could use an update to lok more like
> >> bookehv_interrupts.S and its use of asm macros.
> >
> > In booke there is assumption that size of KVM IVORs will not me more than host
> IVORs size so that only IVPR is changed.
> >
> > I tried to give it that shape of bookehv_interrupts.S  and found that size of
> some IVORs become more than host IVORs.
> 
> We can always jump off to another (more generic?) function and only have a small
> stub in the IVOR referenced code.

What extra KVM_DBG_HANDLER have from KVM_HANDLER is the handing of debug single step (which is similar to host).
So do you want a jump in assembly for handling the debug single step? Or you really think of moving something from the KVM_HANDLER to more generic?

Thanks
-Bharat

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

* Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
  2012-08-10  6:38     ` Bhushan Bharat-R65777
@ 2012-08-10  9:19         ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-10  9:19 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc, kvm


On 10.08.2012, at 08:38, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Tuesday, August 07, 2012 4:16 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
>> 
>> 
>> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
>> 
>>> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
>>> all handlers are considered to be the same size. This will not be
>>> the case if we want to use different macros for different handlers.
>>> 
>>> This patch improves the kvmppc_booke_handler so that it can
>>> support different macros for different handlers.
>>> 
>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>> [bharat.bhushan@freescale.com: Substantial changes]
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
>>> arch/powerpc/kvm/booke.c            |    9 ++++---
>>> arch/powerpc/kvm/booke.h            |    1 +
>>> arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
>>> arch/powerpc/kvm/e500.c             |   13 +++++++----
>>> 5 files changed, 48 insertions(+), 14 deletions(-)
>>> 
>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>> b/arch/powerpc/include/asm/kvm_ppc.h
>>> index 1438a5e..deb55bd 100644
>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>> @@ -47,8 +47,6 @@ enum emulation_result {
>>> 
>>> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
>>> extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
>>> -extern char kvmppc_handlers_start[];
>>> -extern unsigned long kvmppc_handler_len;
>>> extern void kvmppc_handler_highmem(void);
>>> 
>>> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>>> index aebbb8b..1338233 100644
>>> --- a/arch/powerpc/kvm/booke.c
>>> +++ b/arch/powerpc/kvm/booke.c
>>> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void)
>>> {
>>> #ifndef CONFIG_KVM_BOOKE_HV
>>> 	unsigned long ivor[16];
>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>>> 	unsigned long max_ivor = 0;
>>> 	int i;
>>> 
>>> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
>>> 
>>> 	for (i = 0; i < 16; i++) {
>>> 		if (ivor[i] > max_ivor)
>>> -			max_ivor = ivor[i];
>>> +			max_ivor = i;
>>> 
>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
>>> -		       kvmppc_handler_len);
>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>>> 	}
>>> 	flush_icache_range(kvmppc_booke_handlers,
>>> -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>> +                               handler[max_ivor + 1] - handler[max_ivor]);
>>> #endif /* !BOOKE_HV */
>>> 	return 0;
>>> }
>>> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
>>> index ba61974..de9e526 100644
>>> --- a/arch/powerpc/kvm/booke.h
>>> +++ b/arch/powerpc/kvm/booke.h
>>> @@ -65,6 +65,7 @@
>>> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
>>> 
>>> extern unsigned long kvmppc_booke_handlers;
>>> +extern unsigned long kvmppc_booke_handler_addr[];
>>> 
>>> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
>>> void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>> b/arch/powerpc/kvm/booke_interrupts.S
>>> index bb46b32..3539805 100644
>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>> 	bctr
>>> .endm
>>> 
>>> +.macro KVM_HANDLER_ADDR ivor_nr
>>> +	.long	kvmppc_handler_\ivor_nr
>>> +.endm
>>> +
>>> +.macro KVM_HANDLER_END
>>> +	.long	kvmppc_handlers_end
>>> +.endm
>>> +
>>> _GLOBAL(kvmppc_handlers_start)
>>> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
>>> @@ -93,9 +101,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
>> SPRN_CSRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>> -
>>> -_GLOBAL(kvmppc_handler_len)
>>> -	.long kvmppc_handler_1 - kvmppc_handler_0
>>> +_GLOBAL(kvmppc_handlers_end)
>>> 
>>> /* Registers:
>>> *  SPRG_SCRATCH0: guest r4
>>> @@ -463,6 +469,31 @@ lightweight_exit:
>>> 	lwz	r4, VCPU_GPR(R4)(r4)
>>> 	rfi
>>> 
>>> +	.data
>>> +	.align	4
>>> +	.globl	kvmppc_booke_handler_addr
>>> +kvmppc_booke_handler_addr:
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
>>> +KVM_HANDLER_END /*Always keep this in end*/
>>> +
>>> #ifdef CONFIG_SPE
>>> _GLOBAL(kvmppc_save_guest_spe)
>>> 	cmpi	0,r3,0
>>> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
>>> index b479ed7..cb7a5e7 100644
>>> --- a/arch/powerpc/kvm/e500.c
>>> +++ b/arch/powerpc/kvm/e500.c
>>> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void)
>>> {
>>> 	int r, i;
>>> 	unsigned long ivor[3];
>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>> 
>> /* Process remaining handlers above the generic first 16 */
>> unsigned long *handler = &kvmppc_booke_handler_addr[16];
>> 
>>> 	unsigned long max_ivor = 0;
>>> 
>>> 	r = kvmppc_core_check_processor_compat();
>>> 	if (r)
>>> 		return r;
>>> 
>>> +	handler += 16;
>>> +
>>> 	r = kvmppc_booke_init();
>>> 	if (r)
>>> 		return r;
>>> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
>>> 	ivor[1] = mfspr(SPRN_IVOR33);
>>> 	ivor[2] = mfspr(SPRN_IVOR34);
>>> 	for (i = 0; i < 3; i++) {
>>> -		if (ivor[i] > max_ivor)
>>> -			max_ivor = ivor[i];
>>> +		if (ivor[i] > ivor[max_ivor])
>>> +			max_ivor = i;
>>> 
>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>> -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
>>> -		       kvmppc_handler_len);
>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>> 
>> handler_len = handler[i + 1] - handler[i];
>> handler_end = max(handler_end, handler[i] + handler_len);
> 
> Ok .
> 
>> 
>>> 	}
>>> 	flush_icache_range(kvmppc_booke_handlers,
>>> -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>> +	                       handler[max_ivor + 1] - handler[max_ivor]);
>> 
>> handler_end
> 
> I do not get how this logic will work and simple. Can you please explain ?
> 
> The end address here is calculated by IVOR offset (same as host ivor offset) where KVM handler[last] is copied in kvmppc_booke_handlers and length by handler[last + 1] - handler[last];

Hrm. You want to flush from [ kvmppc_booke_handlers ; kvmppc_booke_handlers + handlers_len ].

handlers_len = handler[0] - handler_end;


Alex

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

* Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
@ 2012-08-10  9:19         ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-10  9:19 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc, kvm


On 10.08.2012, at 08:38, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Tuesday, August 07, 2012 4:16 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
>> 
>> 
>> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
>> 
>>> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
>>> all handlers are considered to be the same size. This will not be
>>> the case if we want to use different macros for different handlers.
>>> 
>>> This patch improves the kvmppc_booke_handler so that it can
>>> support different macros for different handlers.
>>> 
>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>> [bharat.bhushan@freescale.com: Substantial changes]
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
>>> arch/powerpc/kvm/booke.c            |    9 ++++---
>>> arch/powerpc/kvm/booke.h            |    1 +
>>> arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
>>> arch/powerpc/kvm/e500.c             |   13 +++++++----
>>> 5 files changed, 48 insertions(+), 14 deletions(-)
>>> 
>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>> b/arch/powerpc/include/asm/kvm_ppc.h
>>> index 1438a5e..deb55bd 100644
>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>> @@ -47,8 +47,6 @@ enum emulation_result {
>>> 
>>> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
>>> extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
>>> -extern char kvmppc_handlers_start[];
>>> -extern unsigned long kvmppc_handler_len;
>>> extern void kvmppc_handler_highmem(void);
>>> 
>>> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>>> index aebbb8b..1338233 100644
>>> --- a/arch/powerpc/kvm/booke.c
>>> +++ b/arch/powerpc/kvm/booke.c
>>> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void)
>>> {
>>> #ifndef CONFIG_KVM_BOOKE_HV
>>> 	unsigned long ivor[16];
>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>>> 	unsigned long max_ivor = 0;
>>> 	int i;
>>> 
>>> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
>>> 
>>> 	for (i = 0; i < 16; i++) {
>>> 		if (ivor[i] > max_ivor)
>>> -			max_ivor = ivor[i];
>>> +			max_ivor = i;
>>> 
>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
>>> -		       kvmppc_handler_len);
>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>>> 	}
>>> 	flush_icache_range(kvmppc_booke_handlers,
>>> -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>> +                               handler[max_ivor + 1] - handler[max_ivor]);
>>> #endif /* !BOOKE_HV */
>>> 	return 0;
>>> }
>>> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
>>> index ba61974..de9e526 100644
>>> --- a/arch/powerpc/kvm/booke.h
>>> +++ b/arch/powerpc/kvm/booke.h
>>> @@ -65,6 +65,7 @@
>>> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
>>> 
>>> extern unsigned long kvmppc_booke_handlers;
>>> +extern unsigned long kvmppc_booke_handler_addr[];
>>> 
>>> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
>>> void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>> b/arch/powerpc/kvm/booke_interrupts.S
>>> index bb46b32..3539805 100644
>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>> 	bctr
>>> .endm
>>> 
>>> +.macro KVM_HANDLER_ADDR ivor_nr
>>> +	.long	kvmppc_handler_\ivor_nr
>>> +.endm
>>> +
>>> +.macro KVM_HANDLER_END
>>> +	.long	kvmppc_handlers_end
>>> +.endm
>>> +
>>> _GLOBAL(kvmppc_handlers_start)
>>> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
>>> @@ -93,9 +101,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
>> SPRN_CSRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>> -
>>> -_GLOBAL(kvmppc_handler_len)
>>> -	.long kvmppc_handler_1 - kvmppc_handler_0
>>> +_GLOBAL(kvmppc_handlers_end)
>>> 
>>> /* Registers:
>>> *  SPRG_SCRATCH0: guest r4
>>> @@ -463,6 +469,31 @@ lightweight_exit:
>>> 	lwz	r4, VCPU_GPR(R4)(r4)
>>> 	rfi
>>> 
>>> +	.data
>>> +	.align	4
>>> +	.globl	kvmppc_booke_handler_addr
>>> +kvmppc_booke_handler_addr:
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
>>> +KVM_HANDLER_END /*Always keep this in end*/
>>> +
>>> #ifdef CONFIG_SPE
>>> _GLOBAL(kvmppc_save_guest_spe)
>>> 	cmpi	0,r3,0
>>> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
>>> index b479ed7..cb7a5e7 100644
>>> --- a/arch/powerpc/kvm/e500.c
>>> +++ b/arch/powerpc/kvm/e500.c
>>> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void)
>>> {
>>> 	int r, i;
>>> 	unsigned long ivor[3];
>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>> 
>> /* Process remaining handlers above the generic first 16 */
>> unsigned long *handler = &kvmppc_booke_handler_addr[16];
>> 
>>> 	unsigned long max_ivor = 0;
>>> 
>>> 	r = kvmppc_core_check_processor_compat();
>>> 	if (r)
>>> 		return r;
>>> 
>>> +	handler += 16;
>>> +
>>> 	r = kvmppc_booke_init();
>>> 	if (r)
>>> 		return r;
>>> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
>>> 	ivor[1] = mfspr(SPRN_IVOR33);
>>> 	ivor[2] = mfspr(SPRN_IVOR34);
>>> 	for (i = 0; i < 3; i++) {
>>> -		if (ivor[i] > max_ivor)
>>> -			max_ivor = ivor[i];
>>> +		if (ivor[i] > ivor[max_ivor])
>>> +			max_ivor = i;
>>> 
>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>> -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
>>> -		       kvmppc_handler_len);
>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>> 
>> handler_len = handler[i + 1] - handler[i];
>> handler_end = max(handler_end, handler[i] + handler_len);
> 
> Ok .
> 
>> 
>>> 	}
>>> 	flush_icache_range(kvmppc_booke_handlers,
>>> -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>> +	                       handler[max_ivor + 1] - handler[max_ivor]);
>> 
>> handler_end
> 
> I do not get how this logic will work and simple. Can you please explain ?
> 
> The end address here is calculated by IVOR offset (same as host ivor offset) where KVM handler[last] is copied in kvmppc_booke_handlers and length by handler[last + 1] - handler[last];

Hrm. You want to flush from [ kvmppc_booke_handlers ; kvmppc_booke_handlers + handlers_len ].

handlers_len = handler[0] - handler_end;


Alex


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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
  2012-08-10  6:55           ` Bhushan Bharat-R65777
@ 2012-08-10  9:21               ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-10  9:21 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: Wood Scott-B07421, kvm-ppc, kvm


On 10.08.2012, at 08:55, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Wednesday, August 08, 2012 4:41 PM
>> To: Bhushan Bharat-R65777
>> Cc: Wood Scott-B07421; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
>> 
>> 
>> On 08.08.2012, at 03:02, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Wood Scott-B07421
>>>> Sent: Wednesday, August 08, 2012 2:15 AM
>>>> To: Alexander Graf
>>>> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org;
>>>> kvm@vger.kernel.org; Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
>>>> 
>>>> On 08/07/2012 05:47 AM, Alexander Graf wrote:
>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>>> index 3539805..890673c 100644
>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>>> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>> 	bctr
>>>>>> .endm
>>>>>> 
>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>> 
>>>>> This is a lot of asm code. Any chance to share a good share of it
>>>>> with the
>>>> generic handler?
>>>> 
>>>> That entire file could use an update to lok more like
>>>> bookehv_interrupts.S and its use of asm macros.
>>> 
>>> In booke there is assumption that size of KVM IVORs will not me more than host
>> IVORs size so that only IVPR is changed.
>>> 
>>> I tried to give it that shape of bookehv_interrupts.S  and found that size of
>> some IVORs become more than host IVORs.
>> 
>> We can always jump off to another (more generic?) function and only have a small
>> stub in the IVOR referenced code.
> 
> What extra KVM_DBG_HANDLER have from KVM_HANDLER is the handing of debug single step (which is similar to host).
> So do you want a jump in assembly for handling the debug single step? Or you really think of moving something from the KVM_HANDLER to more generic?

I'm thinking of "if we don't have enough space in block A, create another block B that has more space to handle things again" :). I'll leave the implementation details to you :D


Alex


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

* Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
@ 2012-08-10  9:21               ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-10  9:21 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: Wood Scott-B07421, kvm-ppc, kvm


On 10.08.2012, at 08:55, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Wednesday, August 08, 2012 4:41 PM
>> To: Bhushan Bharat-R65777
>> Cc: Wood Scott-B07421; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
>> 
>> 
>> On 08.08.2012, at 03:02, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Wood Scott-B07421
>>>> Sent: Wednesday, August 08, 2012 2:15 AM
>>>> To: Alexander Graf
>>>> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org;
>>>> kvm@vger.kernel.org; Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 3/3] KVM: PPC: booke: Added debug handler
>>>> 
>>>> On 08/07/2012 05:47 AM, Alexander Graf wrote:
>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>>> index 3539805..890673c 100644
>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>>> @@ -73,6 +73,51 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>> 	bctr
>>>>>> .endm
>>>>>> 
>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>> 
>>>>> This is a lot of asm code. Any chance to share a good share of it
>>>>> with the
>>>> generic handler?
>>>> 
>>>> That entire file could use an update to lok more like
>>>> bookehv_interrupts.S and its use of asm macros.
>>> 
>>> In booke there is assumption that size of KVM IVORs will not me more than host
>> IVORs size so that only IVPR is changed.
>>> 
>>> I tried to give it that shape of bookehv_interrupts.S  and found that size of
>> some IVORs become more than host IVORs.
>> 
>> We can always jump off to another (more generic?) function and only have a small
>> stub in the IVOR referenced code.
> 
> What extra KVM_DBG_HANDLER have from KVM_HANDLER is the handing of debug single step (which is similar to host).
> So do you want a jump in assembly for handling the debug single step? Or you really think of moving something from the KVM_HANDLER to more generic?

I'm thinking of "if we don't have enough space in block A, create another block B that has more space to handle things again" :). I'll leave the implementation details to you :D


Alex


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

* RE: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
  2012-08-10  9:19         ` Alexander Graf
  (?)
@ 2012-08-10 10:41         ` Bhushan Bharat-R65777
  2012-08-10 10:57             ` Alexander Graf
  -1 siblings, 1 reply; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-10 10:41 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm



> -----Original Message-----
> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of
> Alexander Graf
> Sent: Friday, August 10, 2012 2:49 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
> 
> 
> On 10.08.2012, at 08:38, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: kvm-ppc-owner@vger.kernel.org
> >> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
> >> Sent: Tuesday, August 07, 2012 4:16 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >> Bharat-R65777
> >> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception
> >> types
> >>
> >>
> >> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
> >>
> >>> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
> >>> all handlers are considered to be the same size. This will not be
> >>> the case if we want to use different macros for different handlers.
> >>>
> >>> This patch improves the kvmppc_booke_handler so that it can support
> >>> different macros for different handlers.
> >>>
> >>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> >>> [bharat.bhushan@freescale.com: Substantial changes]
> >>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>> ---
> >>> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
> >>> arch/powerpc/kvm/booke.c            |    9 ++++---
> >>> arch/powerpc/kvm/booke.h            |    1 +
> >>> arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++-
> -
> >>> arch/powerpc/kvm/e500.c             |   13 +++++++----
> >>> 5 files changed, 48 insertions(+), 14 deletions(-)
> >>>
> >>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
> >> b/arch/powerpc/include/asm/kvm_ppc.h
> >>> index 1438a5e..deb55bd 100644
> >>> --- a/arch/powerpc/include/asm/kvm_ppc.h
> >>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> >>> @@ -47,8 +47,6 @@ enum emulation_result {
> >>>
> >>> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu
> >>> *vcpu); extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct
> >>> kvm_vcpu *vcpu); -extern char kvmppc_handlers_start[]; -extern
> >>> unsigned long kvmppc_handler_len; extern void
> >>> kvmppc_handler_highmem(void);
> >>>
> >>> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); diff --git
> >>> a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> >>> aebbb8b..1338233 100644
> >>> --- a/arch/powerpc/kvm/booke.c
> >>> +++ b/arch/powerpc/kvm/booke.c
> >>> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void) { #ifndef
> >>> CONFIG_KVM_BOOKE_HV
> >>> 	unsigned long ivor[16];
> >>> +	unsigned long *handler = kvmppc_booke_handler_addr;
> >>> 	unsigned long max_ivor = 0;
> >>> 	int i;
> >>>
> >>> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
> >>>
> >>> 	for (i = 0; i < 16; i++) {
> >>> 		if (ivor[i] > max_ivor)
> >>> -			max_ivor = ivor[i];
> >>> +			max_ivor = i;
> >>>
> >>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> >>> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
> >>> -		       kvmppc_handler_len);
> >>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> >>> 	}
> >>> 	flush_icache_range(kvmppc_booke_handlers,
> >>> -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> >>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> >>> +                               handler[max_ivor + 1] -
> >>> +handler[max_ivor]);
> >>> #endif /* !BOOKE_HV */
> >>> 	return 0;
> >>> }
> >>> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> >>> index ba61974..de9e526 100644
> >>> --- a/arch/powerpc/kvm/booke.h
> >>> +++ b/arch/powerpc/kvm/booke.h
> >>> @@ -65,6 +65,7 @@
> >>> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
> >>>
> >>> extern unsigned long kvmppc_booke_handlers;
> >>> +extern unsigned long kvmppc_booke_handler_addr[];
> >>>
> >>> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr); void
> >>> kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr); diff
> >>> --git a/arch/powerpc/kvm/booke_interrupts.S
> >> b/arch/powerpc/kvm/booke_interrupts.S
> >>> index bb46b32..3539805 100644
> >>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>> 	bctr
> >>> .endm
> >>>
> >>> +.macro KVM_HANDLER_ADDR ivor_nr
> >>> +	.long	kvmppc_handler_\ivor_nr
> >>> +.endm
> >>> +
> >>> +.macro KVM_HANDLER_END
> >>> +	.long	kvmppc_handlers_end
> >>> +.endm
> >>> +
> >>> _GLOBAL(kvmppc_handlers_start)
> >>> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT
> >>> SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK
> >>> SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 @@ -93,9 +101,7 @@ KVM_HANDLER
> >>> BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
> >> SPRN_CSRR0
> >>> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0
> >>> SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
> >>> SPRN_SPRG_RSCRATCH0 SPRN_SRR0 KVM_HANDLER
> >>> BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> >>> -
> >>> -_GLOBAL(kvmppc_handler_len)
> >>> -	.long kvmppc_handler_1 - kvmppc_handler_0
> >>> +_GLOBAL(kvmppc_handlers_end)
> >>>
> >>> /* Registers:
> >>> *  SPRG_SCRATCH0: guest r4
> >>> @@ -463,6 +469,31 @@ lightweight_exit:
> >>> 	lwz	r4, VCPU_GPR(R4)(r4)
> >>> 	rfi
> >>>
> >>> +	.data
> >>> +	.align	4
> >>> +	.globl	kvmppc_booke_handler_addr
> >>> +kvmppc_booke_handler_addr:
> >>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_MACHINE_CHECK KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_DATA_STORAGE KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_INST_STORAGE KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_EXTERNAL KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
> >>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_FP_UNAVAIL KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
> >>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_DECREMENTER KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
> >>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_DTLB_MISS KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_ITLB_MISS KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
> >>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_SPE_FP_DATA KVM_HANDLER_ADDR
> >>> +BOOKE_INTERRUPT_SPE_FP_ROUND KVM_HANDLER_END /*Always keep this in
> >>> +end*/
> >>> +
> >>> #ifdef CONFIG_SPE
> >>> _GLOBAL(kvmppc_save_guest_spe)
> >>> 	cmpi	0,r3,0
> >>> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index
> >>> b479ed7..cb7a5e7 100644
> >>> --- a/arch/powerpc/kvm/e500.c
> >>> +++ b/arch/powerpc/kvm/e500.c
> >>> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void) {
> >>> 	int r, i;
> >>> 	unsigned long ivor[3];
> >>> +	unsigned long *handler = kvmppc_booke_handler_addr;
> >>
> >> /* Process remaining handlers above the generic first 16 */
> >> unsigned long *handler = &kvmppc_booke_handler_addr[16];
> >>
> >>> 	unsigned long max_ivor = 0;
> >>>
> >>> 	r = kvmppc_core_check_processor_compat();
> >>> 	if (r)
> >>> 		return r;
> >>>
> >>> +	handler += 16;
> >>> +
> >>> 	r = kvmppc_booke_init();
> >>> 	if (r)
> >>> 		return r;
> >>> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
> >>> 	ivor[1] = mfspr(SPRN_IVOR33);
> >>> 	ivor[2] = mfspr(SPRN_IVOR34);
> >>> 	for (i = 0; i < 3; i++) {
> >>> -		if (ivor[i] > max_ivor)
> >>> -			max_ivor = ivor[i];
> >>> +		if (ivor[i] > ivor[max_ivor])
> >>> +			max_ivor = i;
> >>>
> >>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> >>> -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
> >>> -		       kvmppc_handler_len);
> >>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> >>
> >> handler_len = handler[i + 1] - handler[i];
> >> handler_end = max(handler_end, handler[i] + handler_len);
> >
> > Ok .
> >
> >>
> >>> 	}
> >>> 	flush_icache_range(kvmppc_booke_handlers,
> >>> -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
> >>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> >>> +	                       handler[max_ivor + 1] - handler[max_ivor]);
> >>
> >> handler_end
> >
> > I do not get how this logic will work and simple. Can you please explain ?
> >
> > The end address here is calculated by IVOR offset (same as host ivor offset)
> where KVM handler[last] is copied in kvmppc_booke_handlers and length by
> handler[last + 1] - handler[last];
> 
> Hrm. You want to flush from [ kvmppc_booke_handlers ; kvmppc_booke_handlers +
> handlers_len ].
> 
> handlers_len = handler[0] - handler_end;

You do not know that handler[0] is placed at lowest memory or some other?

Thanks
-Bharat

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

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

* Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
  2012-08-10 10:41         ` Bhushan Bharat-R65777
@ 2012-08-10 10:57             ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-10 10:57 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc, kvm


On 10.08.2012, at 12:41, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of
>> Alexander Graf
>> Sent: Friday, August 10, 2012 2:49 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
>> 
>> 
>> On 10.08.2012, at 08:38, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: kvm-ppc-owner@vger.kernel.org
>>>> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
>>>> Sent: Tuesday, August 07, 2012 4:16 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception
>>>> types
>>>> 
>>>> 
>>>> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
>>>> 
>>>>> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
>>>>> all handlers are considered to be the same size. This will not be
>>>>> the case if we want to use different macros for different handlers.
>>>>> 
>>>>> This patch improves the kvmppc_booke_handler so that it can support
>>>>> different macros for different handlers.
>>>>> 
>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>>>> [bharat.bhushan@freescale.com: Substantial changes]
>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>> ---
>>>>> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
>>>>> arch/powerpc/kvm/booke.c            |    9 ++++---
>>>>> arch/powerpc/kvm/booke.h            |    1 +
>>>>> arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++-
>> -
>>>>> arch/powerpc/kvm/e500.c             |   13 +++++++----
>>>>> 5 files changed, 48 insertions(+), 14 deletions(-)
>>>>> 
>>>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>>>> b/arch/powerpc/include/asm/kvm_ppc.h
>>>>> index 1438a5e..deb55bd 100644
>>>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>>>> @@ -47,8 +47,6 @@ enum emulation_result {
>>>>> 
>>>>> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu
>>>>> *vcpu); extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct
>>>>> kvm_vcpu *vcpu); -extern char kvmppc_handlers_start[]; -extern
>>>>> unsigned long kvmppc_handler_len; extern void
>>>>> kvmppc_handler_highmem(void);
>>>>> 
>>>>> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); diff --git
>>>>> a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
>>>>> aebbb8b..1338233 100644
>>>>> --- a/arch/powerpc/kvm/booke.c
>>>>> +++ b/arch/powerpc/kvm/booke.c
>>>>> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void) { #ifndef
>>>>> CONFIG_KVM_BOOKE_HV
>>>>> 	unsigned long ivor[16];
>>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>>>>> 	unsigned long max_ivor = 0;
>>>>> 	int i;
>>>>> 
>>>>> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
>>>>> 
>>>>> 	for (i = 0; i < 16; i++) {
>>>>> 		if (ivor[i] > max_ivor)
>>>>> -			max_ivor = ivor[i];
>>>>> +			max_ivor = i;
>>>>> 
>>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>>>> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
>>>>> -		       kvmppc_handler_len);
>>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>>>>> 	}
>>>>> 	flush_icache_range(kvmppc_booke_handlers,
>>>>> -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>>>> +                               handler[max_ivor + 1] -
>>>>> +handler[max_ivor]);
>>>>> #endif /* !BOOKE_HV */
>>>>> 	return 0;
>>>>> }
>>>>> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
>>>>> index ba61974..de9e526 100644
>>>>> --- a/arch/powerpc/kvm/booke.h
>>>>> +++ b/arch/powerpc/kvm/booke.h
>>>>> @@ -65,6 +65,7 @@
>>>>> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
>>>>> 
>>>>> extern unsigned long kvmppc_booke_handlers;
>>>>> +extern unsigned long kvmppc_booke_handler_addr[];
>>>>> 
>>>>> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr); void
>>>>> kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr); diff
>>>>> --git a/arch/powerpc/kvm/booke_interrupts.S
>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>> index bb46b32..3539805 100644
>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> 	bctr
>>>>> .endm
>>>>> 
>>>>> +.macro KVM_HANDLER_ADDR ivor_nr
>>>>> +	.long	kvmppc_handler_\ivor_nr
>>>>> +.endm
>>>>> +
>>>>> +.macro KVM_HANDLER_END
>>>>> +	.long	kvmppc_handlers_end
>>>>> +.endm
>>>>> +
>>>>> _GLOBAL(kvmppc_handlers_start)
>>>>> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT
>>>>> SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK
>>>>> SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 @@ -93,9 +101,7 @@ KVM_HANDLER
>>>>> BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
>>>> SPRN_CSRR0
>>>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0
>>>>> SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
>>>>> SPRN_SPRG_RSCRATCH0 SPRN_SRR0 KVM_HANDLER
>>>>> BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>>>> -
>>>>> -_GLOBAL(kvmppc_handler_len)
>>>>> -	.long kvmppc_handler_1 - kvmppc_handler_0
>>>>> +_GLOBAL(kvmppc_handlers_end)
>>>>> 
>>>>> /* Registers:
>>>>> *  SPRG_SCRATCH0: guest r4
>>>>> @@ -463,6 +469,31 @@ lightweight_exit:
>>>>> 	lwz	r4, VCPU_GPR(R4)(r4)
>>>>> 	rfi
>>>>> 
>>>>> +	.data
>>>>> +	.align	4
>>>>> +	.globl	kvmppc_booke_handler_addr
>>>>> +kvmppc_booke_handler_addr:
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_MACHINE_CHECK KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_DATA_STORAGE KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_INST_STORAGE KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_EXTERNAL KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_FP_UNAVAIL KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_DECREMENTER KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_DTLB_MISS KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_ITLB_MISS KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_SPE_FP_DATA KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_SPE_FP_ROUND KVM_HANDLER_END /*Always keep this in
>>>>> +end*/
>>>>> +
>>>>> #ifdef CONFIG_SPE
>>>>> _GLOBAL(kvmppc_save_guest_spe)
>>>>> 	cmpi	0,r3,0
>>>>> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index
>>>>> b479ed7..cb7a5e7 100644
>>>>> --- a/arch/powerpc/kvm/e500.c
>>>>> +++ b/arch/powerpc/kvm/e500.c
>>>>> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void) {
>>>>> 	int r, i;
>>>>> 	unsigned long ivor[3];
>>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>>>> 
>>>> /* Process remaining handlers above the generic first 16 */
>>>> unsigned long *handler = &kvmppc_booke_handler_addr[16];
>>>> 
>>>>> 	unsigned long max_ivor = 0;
>>>>> 
>>>>> 	r = kvmppc_core_check_processor_compat();
>>>>> 	if (r)
>>>>> 		return r;
>>>>> 
>>>>> +	handler += 16;
>>>>> +
>>>>> 	r = kvmppc_booke_init();
>>>>> 	if (r)
>>>>> 		return r;
>>>>> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
>>>>> 	ivor[1] = mfspr(SPRN_IVOR33);
>>>>> 	ivor[2] = mfspr(SPRN_IVOR34);
>>>>> 	for (i = 0; i < 3; i++) {
>>>>> -		if (ivor[i] > max_ivor)
>>>>> -			max_ivor = ivor[i];
>>>>> +		if (ivor[i] > ivor[max_ivor])
>>>>> +			max_ivor = i;
>>>>> 
>>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>>>> -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
>>>>> -		       kvmppc_handler_len);
>>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>>>> 
>>>> handler_len = handler[i + 1] - handler[i];
>>>> handler_end = max(handler_end, handler[i] + handler_len);
>>> 
>>> Ok .
>>> 
>>>> 
>>>>> 	}
>>>>> 	flush_icache_range(kvmppc_booke_handlers,
>>>>> -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>>>> +	                       handler[max_ivor + 1] - handler[max_ivor]);
>>>> 
>>>> handler_end
>>> 
>>> I do not get how this logic will work and simple. Can you please explain ?
>>> 
>>> The end address here is calculated by IVOR offset (same as host ivor offset)
>> where KVM handler[last] is copied in kvmppc_booke_handlers and length by
>> handler[last + 1] - handler[last];
>> 
>> Hrm. You want to flush from [ kvmppc_booke_handlers ; kvmppc_booke_handlers +
>> handlers_len ].
>> 
>> handlers_len = handler[0] - handler_end;
> 
> You do not know that handler[0] is placed at lowest memory or some other?

I'm mostly concerned about readability here. The icache flush call should make it obvious what we are flushing, without having to trace 5 different variables on their semantics.


Alex

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

* Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
@ 2012-08-10 10:57             ` Alexander Graf
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Graf @ 2012-08-10 10:57 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc, kvm


On 10.08.2012, at 12:41, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of
>> Alexander Graf
>> Sent: Friday, August 10, 2012 2:49 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
>> 
>> 
>> On 10.08.2012, at 08:38, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: kvm-ppc-owner@vger.kernel.org
>>>> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
>>>> Sent: Tuesday, August 07, 2012 4:16 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception
>>>> types
>>>> 
>>>> 
>>>> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
>>>> 
>>>>> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
>>>>> all handlers are considered to be the same size. This will not be
>>>>> the case if we want to use different macros for different handlers.
>>>>> 
>>>>> This patch improves the kvmppc_booke_handler so that it can support
>>>>> different macros for different handlers.
>>>>> 
>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>>>> [bharat.bhushan@freescale.com: Substantial changes]
>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>> ---
>>>>> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
>>>>> arch/powerpc/kvm/booke.c            |    9 ++++---
>>>>> arch/powerpc/kvm/booke.h            |    1 +
>>>>> arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++-
>> -
>>>>> arch/powerpc/kvm/e500.c             |   13 +++++++----
>>>>> 5 files changed, 48 insertions(+), 14 deletions(-)
>>>>> 
>>>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>>>> b/arch/powerpc/include/asm/kvm_ppc.h
>>>>> index 1438a5e..deb55bd 100644
>>>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>>>> @@ -47,8 +47,6 @@ enum emulation_result {
>>>>> 
>>>>> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu
>>>>> *vcpu); extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct
>>>>> kvm_vcpu *vcpu); -extern char kvmppc_handlers_start[]; -extern
>>>>> unsigned long kvmppc_handler_len; extern void
>>>>> kvmppc_handler_highmem(void);
>>>>> 
>>>>> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); diff --git
>>>>> a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
>>>>> aebbb8b..1338233 100644
>>>>> --- a/arch/powerpc/kvm/booke.c
>>>>> +++ b/arch/powerpc/kvm/booke.c
>>>>> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void) { #ifndef
>>>>> CONFIG_KVM_BOOKE_HV
>>>>> 	unsigned long ivor[16];
>>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>>>>> 	unsigned long max_ivor = 0;
>>>>> 	int i;
>>>>> 
>>>>> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
>>>>> 
>>>>> 	for (i = 0; i < 16; i++) {
>>>>> 		if (ivor[i] > max_ivor)
>>>>> -			max_ivor = ivor[i];
>>>>> +			max_ivor = i;
>>>>> 
>>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>>>> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
>>>>> -		       kvmppc_handler_len);
>>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>>>>> 	}
>>>>> 	flush_icache_range(kvmppc_booke_handlers,
>>>>> -	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>>>> +                               handler[max_ivor + 1] -
>>>>> +handler[max_ivor]);
>>>>> #endif /* !BOOKE_HV */
>>>>> 	return 0;
>>>>> }
>>>>> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
>>>>> index ba61974..de9e526 100644
>>>>> --- a/arch/powerpc/kvm/booke.h
>>>>> +++ b/arch/powerpc/kvm/booke.h
>>>>> @@ -65,6 +65,7 @@
>>>>> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
>>>>> 
>>>>> extern unsigned long kvmppc_booke_handlers;
>>>>> +extern unsigned long kvmppc_booke_handler_addr[];
>>>>> 
>>>>> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr); void
>>>>> kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr); diff
>>>>> --git a/arch/powerpc/kvm/booke_interrupts.S
>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>> index bb46b32..3539805 100644
>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> 	bctr
>>>>> .endm
>>>>> 
>>>>> +.macro KVM_HANDLER_ADDR ivor_nr
>>>>> +	.long	kvmppc_handler_\ivor_nr
>>>>> +.endm
>>>>> +
>>>>> +.macro KVM_HANDLER_END
>>>>> +	.long	kvmppc_handlers_end
>>>>> +.endm
>>>>> +
>>>>> _GLOBAL(kvmppc_handlers_start)
>>>>> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT
>>>>> SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK
>>>>> SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 @@ -93,9 +101,7 @@ KVM_HANDLER
>>>>> BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
>>>> SPRN_CSRR0
>>>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0
>>>>> SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
>>>>> SPRN_SPRG_RSCRATCH0 SPRN_SRR0 KVM_HANDLER
>>>>> BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
>>>>> -
>>>>> -_GLOBAL(kvmppc_handler_len)
>>>>> -	.long kvmppc_handler_1 - kvmppc_handler_0
>>>>> +_GLOBAL(kvmppc_handlers_end)
>>>>> 
>>>>> /* Registers:
>>>>> *  SPRG_SCRATCH0: guest r4
>>>>> @@ -463,6 +469,31 @@ lightweight_exit:
>>>>> 	lwz	r4, VCPU_GPR(R4)(r4)
>>>>> 	rfi
>>>>> 
>>>>> +	.data
>>>>> +	.align	4
>>>>> +	.globl	kvmppc_booke_handler_addr
>>>>> +kvmppc_booke_handler_addr:
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_MACHINE_CHECK KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_DATA_STORAGE KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_INST_STORAGE KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_EXTERNAL KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_FP_UNAVAIL KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_DECREMENTER KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_DTLB_MISS KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_ITLB_MISS KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
>>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_SPE_FP_DATA KVM_HANDLER_ADDR
>>>>> +BOOKE_INTERRUPT_SPE_FP_ROUND KVM_HANDLER_END /*Always keep this in
>>>>> +end*/
>>>>> +
>>>>> #ifdef CONFIG_SPE
>>>>> _GLOBAL(kvmppc_save_guest_spe)
>>>>> 	cmpi	0,r3,0
>>>>> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index
>>>>> b479ed7..cb7a5e7 100644
>>>>> --- a/arch/powerpc/kvm/e500.c
>>>>> +++ b/arch/powerpc/kvm/e500.c
>>>>> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void) {
>>>>> 	int r, i;
>>>>> 	unsigned long ivor[3];
>>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
>>>> 
>>>> /* Process remaining handlers above the generic first 16 */
>>>> unsigned long *handler = &kvmppc_booke_handler_addr[16];
>>>> 
>>>>> 	unsigned long max_ivor = 0;
>>>>> 
>>>>> 	r = kvmppc_core_check_processor_compat();
>>>>> 	if (r)
>>>>> 		return r;
>>>>> 
>>>>> +	handler += 16;
>>>>> +
>>>>> 	r = kvmppc_booke_init();
>>>>> 	if (r)
>>>>> 		return r;
>>>>> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
>>>>> 	ivor[1] = mfspr(SPRN_IVOR33);
>>>>> 	ivor[2] = mfspr(SPRN_IVOR34);
>>>>> 	for (i = 0; i < 3; i++) {
>>>>> -		if (ivor[i] > max_ivor)
>>>>> -			max_ivor = ivor[i];
>>>>> +		if (ivor[i] > ivor[max_ivor])
>>>>> +			max_ivor = i;
>>>>> 
>>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
>>>>> -		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
>>>>> -		       kvmppc_handler_len);
>>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
>>>> 
>>>> handler_len = handler[i + 1] - handler[i];
>>>> handler_end = max(handler_end, handler[i] + handler_len);
>>> 
>>> Ok .
>>> 
>>>> 
>>>>> 	}
>>>>> 	flush_icache_range(kvmppc_booke_handlers,
>>>>> -			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
>>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
>>>>> +	                       handler[max_ivor + 1] - handler[max_ivor]);
>>>> 
>>>> handler_end
>>> 
>>> I do not get how this logic will work and simple. Can you please explain ?
>>> 
>>> The end address here is calculated by IVOR offset (same as host ivor offset)
>> where KVM handler[last] is copied in kvmppc_booke_handlers and length by
>> handler[last + 1] - handler[last];
>> 
>> Hrm. You want to flush from [ kvmppc_booke_handlers ; kvmppc_booke_handlers +
>> handlers_len ].
>> 
>> handlers_len = handler[0] - handler_end;
> 
> You do not know that handler[0] is placed at lowest memory or some other?

I'm mostly concerned about readability here. The icache flush call should make it obvious what we are flushing, without having to trace 5 different variables on their semantics.


Alex


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

* RE: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
  2012-08-10 10:57             ` Alexander Graf
@ 2012-08-10 10:59               ` Bhushan Bharat-R65777
  -1 siblings, 0 replies; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-10 10:59 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, August 10, 2012 4:27 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
> 
> 
> On 10.08.2012, at 12:41, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On
> >> Behalf Of Alexander Graf
> >> Sent: Friday, August 10, 2012 2:49 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception
> >> types
> >>
> >>
> >> On 10.08.2012, at 08:38, Bhushan Bharat-R65777 wrote:
> >>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: kvm-ppc-owner@vger.kernel.org
> >>>> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
> >>>> Sent: Tuesday, August 07, 2012 4:16 PM
> >>>> To: Bhushan Bharat-R65777
> >>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >>>> Bharat-R65777
> >>>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception
> >>>> types
> >>>>
> >>>>
> >>>> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
> >>>>
> >>>>> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER)
> >>>>> and all handlers are considered to be the same size. This will not
> >>>>> be the case if we want to use different macros for different handlers.
> >>>>>
> >>>>> This patch improves the kvmppc_booke_handler so that it can
> >>>>> support different macros for different handlers.
> >>>>>
> >>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> >>>>> [bharat.bhushan@freescale.com: Substantial changes]
> >>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>>>> ---
> >>>>> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
> >>>>> arch/powerpc/kvm/booke.c            |    9 ++++---
> >>>>> arch/powerpc/kvm/booke.h            |    1 +
> >>>>> arch/powerpc/kvm/booke_interrupts.S |   37
> ++++++++++++++++++++++++++++++++-
> >> -
> >>>>> arch/powerpc/kvm/e500.c             |   13 +++++++----
> >>>>> 5 files changed, 48 insertions(+), 14 deletions(-)
> >>>>>
> >>>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
> >>>> b/arch/powerpc/include/asm/kvm_ppc.h
> >>>>> index 1438a5e..deb55bd 100644
> >>>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
> >>>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> >>>>> @@ -47,8 +47,6 @@ enum emulation_result {
> >>>>>
> >>>>> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct
> >>>>> kvm_vcpu *vcpu); extern int __kvmppc_vcpu_run(struct kvm_run
> >>>>> *kvm_run, struct kvm_vcpu *vcpu); -extern char
> >>>>> kvmppc_handlers_start[]; -extern unsigned long kvmppc_handler_len;
> >>>>> extern void kvmppc_handler_highmem(void);
> >>>>>
> >>>>> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); diff --git
> >>>>> a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> >>>>> aebbb8b..1338233 100644
> >>>>> --- a/arch/powerpc/kvm/booke.c
> >>>>> +++ b/arch/powerpc/kvm/booke.c
> >>>>> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void) { #ifndef
> >>>>> CONFIG_KVM_BOOKE_HV
> >>>>> 	unsigned long ivor[16];
> >>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
> >>>>> 	unsigned long max_ivor = 0;
> >>>>> 	int i;
> >>>>>
> >>>>> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
> >>>>>
> >>>>> 	for (i = 0; i < 16; i++) {
> >>>>> 		if (ivor[i] > max_ivor)
> >>>>> -			max_ivor = ivor[i];
> >>>>> +			max_ivor = i;
> >>>>>
> >>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> >>>>> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
> >>>>> -		       kvmppc_handler_len);
> >>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> >>>>> 	}
> >>>>> 	flush_icache_range(kvmppc_booke_handlers,
> >>>>> -	                   kvmppc_booke_handlers + max_ivor +
> kvmppc_handler_len);
> >>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> >>>>> +                               handler[max_ivor + 1] -
> >>>>> +handler[max_ivor]);
> >>>>> #endif /* !BOOKE_HV */
> >>>>> 	return 0;
> >>>>> }
> >>>>> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> >>>>> index ba61974..de9e526 100644
> >>>>> --- a/arch/powerpc/kvm/booke.h
> >>>>> +++ b/arch/powerpc/kvm/booke.h
> >>>>> @@ -65,6 +65,7 @@
> >>>>> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
> >>>>>
> >>>>> extern unsigned long kvmppc_booke_handlers;
> >>>>> +extern unsigned long kvmppc_booke_handler_addr[];
> >>>>>
> >>>>> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr); void
> >>>>> kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr); diff
> >>>>> --git a/arch/powerpc/kvm/booke_interrupts.S
> >>>> b/arch/powerpc/kvm/booke_interrupts.S
> >>>>> index bb46b32..3539805 100644
> >>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>>>> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> 	bctr
> >>>>> .endm
> >>>>>
> >>>>> +.macro KVM_HANDLER_ADDR ivor_nr
> >>>>> +	.long	kvmppc_handler_\ivor_nr
> >>>>> +.endm
> >>>>> +
> >>>>> +.macro KVM_HANDLER_END
> >>>>> +	.long	kvmppc_handlers_end
> >>>>> +.endm
> >>>>> +
> >>>>> _GLOBAL(kvmppc_handlers_start)
> >>>>> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT
> >>>>> SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK
> >>>>> SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 @@ -93,9 +101,7 @@ KVM_HANDLER
> >>>>> BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
> >>>> SPRN_CSRR0
> >>>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0
> >>>>> SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
> >>>>> SPRN_SPRG_RSCRATCH0 SPRN_SRR0 KVM_HANDLER
> >>>>> BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> >>>>> -
> >>>>> -_GLOBAL(kvmppc_handler_len)
> >>>>> -	.long kvmppc_handler_1 - kvmppc_handler_0
> >>>>> +_GLOBAL(kvmppc_handlers_end)
> >>>>>
> >>>>> /* Registers:
> >>>>> *  SPRG_SCRATCH0: guest r4
> >>>>> @@ -463,6 +469,31 @@ lightweight_exit:
> >>>>> 	lwz	r4, VCPU_GPR(R4)(r4)
> >>>>> 	rfi
> >>>>>
> >>>>> +	.data
> >>>>> +	.align	4
> >>>>> +	.globl	kvmppc_booke_handler_addr
> >>>>> +kvmppc_booke_handler_addr:
> >>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_MACHINE_CHECK KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_DATA_STORAGE KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_INST_STORAGE KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_EXTERNAL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_ALIGNMENT KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_PROGRAM KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_FP_UNAVAIL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_SYSCALL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_AP_UNAVAIL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_DECREMENTER KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
> >>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_DTLB_MISS KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_ITLB_MISS KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
> >>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_SPE_FP_DATA KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_SPE_FP_ROUND KVM_HANDLER_END /*Always keep this
> >>>>> +in end*/
> >>>>> +
> >>>>> #ifdef CONFIG_SPE
> >>>>> _GLOBAL(kvmppc_save_guest_spe)
> >>>>> 	cmpi	0,r3,0
> >>>>> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> >>>>> index
> >>>>> b479ed7..cb7a5e7 100644
> >>>>> --- a/arch/powerpc/kvm/e500.c
> >>>>> +++ b/arch/powerpc/kvm/e500.c
> >>>>> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void) {
> >>>>> 	int r, i;
> >>>>> 	unsigned long ivor[3];
> >>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
> >>>>
> >>>> /* Process remaining handlers above the generic first 16 */
> >>>> unsigned long *handler = &kvmppc_booke_handler_addr[16];
> >>>>
> >>>>> 	unsigned long max_ivor = 0;
> >>>>>
> >>>>> 	r = kvmppc_core_check_processor_compat();
> >>>>> 	if (r)
> >>>>> 		return r;
> >>>>>
> >>>>> +	handler += 16;
> >>>>> +
> >>>>> 	r = kvmppc_booke_init();
> >>>>> 	if (r)
> >>>>> 		return r;
> >>>>> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
> >>>>> 	ivor[1] = mfspr(SPRN_IVOR33);
> >>>>> 	ivor[2] = mfspr(SPRN_IVOR34);
> >>>>> 	for (i = 0; i < 3; i++) {
> >>>>> -		if (ivor[i] > max_ivor)
> >>>>> -			max_ivor = ivor[i];
> >>>>> +		if (ivor[i] > ivor[max_ivor])
> >>>>> +			max_ivor = i;
> >>>>>
> >>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> >>>>> -		       kvmppc_handlers_start + (i + 16) *
> kvmppc_handler_len,
> >>>>> -		       kvmppc_handler_len);
> >>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> >>>>
> >>>> handler_len = handler[i + 1] - handler[i]; handler_end =
> >>>> max(handler_end, handler[i] + handler_len);
> >>>
> >>> Ok .
> >>>
> >>>>
> >>>>> 	}
> >>>>> 	flush_icache_range(kvmppc_booke_handlers,
> >>>>> -			kvmppc_booke_handlers + max_ivor +
> kvmppc_handler_len);
> >>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> >>>>> +	                       handler[max_ivor + 1] -
> >>>>> +handler[max_ivor]);
> >>>>
> >>>> handler_end
> >>>
> >>> I do not get how this logic will work and simple. Can you please explain ?
> >>>
> >>> The end address here is calculated by IVOR offset (same as host ivor
> >>> offset)
> >> where KVM handler[last] is copied in kvmppc_booke_handlers and length
> >> by handler[last + 1] - handler[last];
> >>
> >> Hrm. You want to flush from [ kvmppc_booke_handlers ;
> >> kvmppc_booke_handlers + handlers_len ].
> >>
> >> handlers_len = handler[0] - handler_end;
> >
> > You do not know that handler[0] is placed at lowest memory or some other?
> 
> I'm mostly concerned about readability here. The icache flush call should make
> it obvious what we are flushing, without having to trace 5 different variables
> on their semantics.

I will try to remove some variable or at least add comment to support readability .

Thanks
-Bharat

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

* RE: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
@ 2012-08-10 10:59               ` Bhushan Bharat-R65777
  0 siblings, 0 replies; 31+ messages in thread
From: Bhushan Bharat-R65777 @ 2012-08-10 10:59 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, August 10, 2012 4:27 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types
> 
> 
> On 10.08.2012, at 12:41, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On
> >> Behalf Of Alexander Graf
> >> Sent: Friday, August 10, 2012 2:49 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception
> >> types
> >>
> >>
> >> On 10.08.2012, at 08:38, Bhushan Bharat-R65777 wrote:
> >>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: kvm-ppc-owner@vger.kernel.org
> >>>> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
> >>>> Sent: Tuesday, August 07, 2012 4:16 PM
> >>>> To: Bhushan Bharat-R65777
> >>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >>>> Bharat-R65777
> >>>> Subject: Re: [PATCH 2/3] KVM: PPC: booke: Allow multiple exception
> >>>> types
> >>>>
> >>>>
> >>>> On 03.08.2012, at 09:08, Bharat Bhushan wrote:
> >>>>
> >>>>> Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER)
> >>>>> and all handlers are considered to be the same size. This will not
> >>>>> be the case if we want to use different macros for different handlers.
> >>>>>
> >>>>> This patch improves the kvmppc_booke_handler so that it can
> >>>>> support different macros for different handlers.
> >>>>>
> >>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> >>>>> [bharat.bhushan@freescale.com: Substantial changes]
> >>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>>>> ---
> >>>>> arch/powerpc/include/asm/kvm_ppc.h  |    2 -
> >>>>> arch/powerpc/kvm/booke.c            |    9 ++++---
> >>>>> arch/powerpc/kvm/booke.h            |    1 +
> >>>>> arch/powerpc/kvm/booke_interrupts.S |   37
> ++++++++++++++++++++++++++++++++-
> >> -
> >>>>> arch/powerpc/kvm/e500.c             |   13 +++++++----
> >>>>> 5 files changed, 48 insertions(+), 14 deletions(-)
> >>>>>
> >>>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
> >>>> b/arch/powerpc/include/asm/kvm_ppc.h
> >>>>> index 1438a5e..deb55bd 100644
> >>>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
> >>>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> >>>>> @@ -47,8 +47,6 @@ enum emulation_result {
> >>>>>
> >>>>> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct
> >>>>> kvm_vcpu *vcpu); extern int __kvmppc_vcpu_run(struct kvm_run
> >>>>> *kvm_run, struct kvm_vcpu *vcpu); -extern char
> >>>>> kvmppc_handlers_start[]; -extern unsigned long kvmppc_handler_len;
> >>>>> extern void kvmppc_handler_highmem(void);
> >>>>>
> >>>>> extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); diff --git
> >>>>> a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> >>>>> aebbb8b..1338233 100644
> >>>>> --- a/arch/powerpc/kvm/booke.c
> >>>>> +++ b/arch/powerpc/kvm/booke.c
> >>>>> @@ -1541,6 +1541,7 @@ int __init kvmppc_booke_init(void) { #ifndef
> >>>>> CONFIG_KVM_BOOKE_HV
> >>>>> 	unsigned long ivor[16];
> >>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
> >>>>> 	unsigned long max_ivor = 0;
> >>>>> 	int i;
> >>>>>
> >>>>> @@ -1574,14 +1575,14 @@ int __init kvmppc_booke_init(void)
> >>>>>
> >>>>> 	for (i = 0; i < 16; i++) {
> >>>>> 		if (ivor[i] > max_ivor)
> >>>>> -			max_ivor = ivor[i];
> >>>>> +			max_ivor = i;
> >>>>>
> >>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> >>>>> -		       kvmppc_handlers_start + i * kvmppc_handler_len,
> >>>>> -		       kvmppc_handler_len);
> >>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> >>>>> 	}
> >>>>> 	flush_icache_range(kvmppc_booke_handlers,
> >>>>> -	                   kvmppc_booke_handlers + max_ivor +
> kvmppc_handler_len);
> >>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> >>>>> +                               handler[max_ivor + 1] -
> >>>>> +handler[max_ivor]);
> >>>>> #endif /* !BOOKE_HV */
> >>>>> 	return 0;
> >>>>> }
> >>>>> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> >>>>> index ba61974..de9e526 100644
> >>>>> --- a/arch/powerpc/kvm/booke.h
> >>>>> +++ b/arch/powerpc/kvm/booke.h
> >>>>> @@ -65,6 +65,7 @@
> >>>>> 			  (1 << BOOKE_IRQPRIO_CRITICAL))
> >>>>>
> >>>>> extern unsigned long kvmppc_booke_handlers;
> >>>>> +extern unsigned long kvmppc_booke_handler_addr[];
> >>>>>
> >>>>> void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr); void
> >>>>> kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr); diff
> >>>>> --git a/arch/powerpc/kvm/booke_interrupts.S
> >>>> b/arch/powerpc/kvm/booke_interrupts.S
> >>>>> index bb46b32..3539805 100644
> >>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>>>> @@ -73,6 +73,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> 	bctr
> >>>>> .endm
> >>>>>
> >>>>> +.macro KVM_HANDLER_ADDR ivor_nr
> >>>>> +	.long	kvmppc_handler_\ivor_nr
> >>>>> +.endm
> >>>>> +
> >>>>> +.macro KVM_HANDLER_END
> >>>>> +	.long	kvmppc_handlers_end
> >>>>> +.endm
> >>>>> +
> >>>>> _GLOBAL(kvmppc_handlers_start)
> >>>>> KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT
> >>>>> SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK
> >>>>> SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 @@ -93,9 +101,7 @@ KVM_HANDLER
> >>>>> BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
> >>>> SPRN_CSRR0
> >>>>> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0
> >>>>> SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
> >>>>> SPRN_SPRG_RSCRATCH0 SPRN_SRR0 KVM_HANDLER
> >>>>> BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> >>>>> -
> >>>>> -_GLOBAL(kvmppc_handler_len)
> >>>>> -	.long kvmppc_handler_1 - kvmppc_handler_0
> >>>>> +_GLOBAL(kvmppc_handlers_end)
> >>>>>
> >>>>> /* Registers:
> >>>>> *  SPRG_SCRATCH0: guest r4
> >>>>> @@ -463,6 +469,31 @@ lightweight_exit:
> >>>>> 	lwz	r4, VCPU_GPR(R4)(r4)
> >>>>> 	rfi
> >>>>>
> >>>>> +	.data
> >>>>> +	.align	4
> >>>>> +	.globl	kvmppc_booke_handler_addr
> >>>>> +kvmppc_booke_handler_addr:
> >>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_MACHINE_CHECK KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_DATA_STORAGE KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_INST_STORAGE KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_EXTERNAL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_ALIGNMENT KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_PROGRAM KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_FP_UNAVAIL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_SYSCALL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_AP_UNAVAIL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_DECREMENTER KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
> >>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_DTLB_MISS KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_ITLB_MISS KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
> >>>>> +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_SPE_FP_DATA KVM_HANDLER_ADDR
> >>>>> +BOOKE_INTERRUPT_SPE_FP_ROUND KVM_HANDLER_END /*Always keep this
> >>>>> +in end*/
> >>>>> +
> >>>>> #ifdef CONFIG_SPE
> >>>>> _GLOBAL(kvmppc_save_guest_spe)
> >>>>> 	cmpi	0,r3,0
> >>>>> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> >>>>> index
> >>>>> b479ed7..cb7a5e7 100644
> >>>>> --- a/arch/powerpc/kvm/e500.c
> >>>>> +++ b/arch/powerpc/kvm/e500.c
> >>>>> @@ -491,12 +491,15 @@ static int __init kvmppc_e500_init(void) {
> >>>>> 	int r, i;
> >>>>> 	unsigned long ivor[3];
> >>>>> +	unsigned long *handler = kvmppc_booke_handler_addr;
> >>>>
> >>>> /* Process remaining handlers above the generic first 16 */
> >>>> unsigned long *handler = &kvmppc_booke_handler_addr[16];
> >>>>
> >>>>> 	unsigned long max_ivor = 0;
> >>>>>
> >>>>> 	r = kvmppc_core_check_processor_compat();
> >>>>> 	if (r)
> >>>>> 		return r;
> >>>>>
> >>>>> +	handler += 16;
> >>>>> +
> >>>>> 	r = kvmppc_booke_init();
> >>>>> 	if (r)
> >>>>> 		return r;
> >>>>> @@ -506,15 +509,15 @@ static int __init kvmppc_e500_init(void)
> >>>>> 	ivor[1] = mfspr(SPRN_IVOR33);
> >>>>> 	ivor[2] = mfspr(SPRN_IVOR34);
> >>>>> 	for (i = 0; i < 3; i++) {
> >>>>> -		if (ivor[i] > max_ivor)
> >>>>> -			max_ivor = ivor[i];
> >>>>> +		if (ivor[i] > ivor[max_ivor])
> >>>>> +			max_ivor = i;
> >>>>>
> >>>>> 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
> >>>>> -		       kvmppc_handlers_start + (i + 16) *
> kvmppc_handler_len,
> >>>>> -		       kvmppc_handler_len);
> >>>>> +		       (void *)handler[i], handler[i + 1] - handler[i]);
> >>>>
> >>>> handler_len = handler[i + 1] - handler[i]; handler_end > >>>> max(handler_end, handler[i] + handler_len);
> >>>
> >>> Ok .
> >>>
> >>>>
> >>>>> 	}
> >>>>> 	flush_icache_range(kvmppc_booke_handlers,
> >>>>> -			kvmppc_booke_handlers + max_ivor +
> kvmppc_handler_len);
> >>>>> +	                   kvmppc_booke_handlers + ivor[max_ivor] +
> >>>>> +	                       handler[max_ivor + 1] -
> >>>>> +handler[max_ivor]);
> >>>>
> >>>> handler_end
> >>>
> >>> I do not get how this logic will work and simple. Can you please explain ?
> >>>
> >>> The end address here is calculated by IVOR offset (same as host ivor
> >>> offset)
> >> where KVM handler[last] is copied in kvmppc_booke_handlers and length
> >> by handler[last + 1] - handler[last];
> >>
> >> Hrm. You want to flush from [ kvmppc_booke_handlers ;
> >> kvmppc_booke_handlers + handlers_len ].
> >>
> >> handlers_len = handler[0] - handler_end;
> >
> > You do not know that handler[0] is placed at lowest memory or some other?
> 
> I'm mostly concerned about readability here. The icache flush call should make
> it obvious what we are flushing, without having to trace 5 different variables
> on their semantics.

I will try to remove some variable or at least add comment to support readability .

Thanks
-Bharat


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

end of thread, other threads:[~2012-08-10 10:59 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-03  7:08 [PATCH 1/3] booke: Added ONE_REG interface for IAC/DAC debug registers Bharat Bhushan
2012-08-03  7:20 ` Bharat Bhushan
2012-08-03  7:08 ` [PATCH 2/3] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
2012-08-03  7:20   ` Bharat Bhushan
2012-08-07 10:46   ` Alexander Graf
2012-08-07 10:46     ` Alexander Graf
2012-08-10  6:38     ` Bhushan Bharat-R65777
2012-08-10  9:19       ` Alexander Graf
2012-08-10  9:19         ` Alexander Graf
2012-08-10 10:41         ` Bhushan Bharat-R65777
2012-08-10 10:57           ` Alexander Graf
2012-08-10 10:57             ` Alexander Graf
2012-08-10 10:59             ` Bhushan Bharat-R65777
2012-08-10 10:59               ` Bhushan Bharat-R65777
2012-08-03  7:08 ` [PATCH 3/3] KVM: PPC: booke: Added debug handler Bharat Bhushan
2012-08-03  7:20   ` Bharat Bhushan
2012-08-07 10:47   ` Alexander Graf
2012-08-07 10:47     ` Alexander Graf
2012-08-07 16:02     ` Bhushan Bharat-R65777
2012-08-07 16:02       ` Bhushan Bharat-R65777
2012-08-07 20:44     ` Scott Wood
2012-08-07 20:44       ` Scott Wood
2012-08-08  1:02       ` Bhushan Bharat-R65777
2012-08-08  1:02         ` Bhushan Bharat-R65777
2012-08-08 11:10         ` Alexander Graf
2012-08-08 11:10           ` Alexander Graf
2012-08-10  6:55           ` Bhushan Bharat-R65777
2012-08-10  9:21             ` Alexander Graf
2012-08-10  9:21               ` Alexander Graf
2012-08-07 10:30 ` [PATCH 1/3] booke: Added ONE_REG interface for IAC/DAC debug registers Alexander Graf
2012-08-07 10:30   ` Alexander Graf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.