> -----Original Message----- > From: kvm-owner@xxxxxxxxxxxxxxx [mailto:kvm-owner@xxxxxxxxxxxxxxx] On Behalf Of > Alexander Graf > Sent: Friday, August 10, 2012 2:49 PM > To: Bhushan Bharat-R65777 > Cc: kvm-ppc@xxxxxxxxxxxxxxx; kvm@xxxxxxxxxxxxxxx > 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@xxxxxxxxxxxxxxx > >> [mailto:kvm-ppc-owner@xxxxxxxxxxxxxxx] On Behalf Of Alexander Graf > >> Sent: Tuesday, August 07, 2012 4:16 PM > >> To: Bhushan Bharat-R65777 > >> Cc: kvm-ppc@xxxxxxxxxxxxxxx; kvm@xxxxxxxxxxxxxxx; 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@xxxxxxxxxxxxx> > >>> [bharat.bhushan@xxxxxxxxxxxxx: Substantial changes] > >>> Signed-off-by: Bharat Bhushan <bharat.bhushan@xxxxxxxxxxxxx> > >>> --- > >>> 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@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html