> -----Original Message----- > From: Alexander Graf [mailto:agraf@xxxxxxx] > Sent: Friday, August 10, 2012 4:27 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 12:41, Bhushan Bharat-R65777 wrote: > > > > > > >> -----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? > > 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 -- 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