Re: [PATCH v3] kvmppc/booke: Set ESR and DEAR when inject interrupt to guest
On 02.02.2010, at 12:44, Liu Yu wrote: > Old method prematurely sets ESR and DEAR. > Move this part after we decide to inject interrupt, > which is more like hardware behave. > > Signed-off-by: Liu Yu Acked-by: Alexander Graf Alex -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] kvmppc/booke: Set ESR and DEAR when inject interrupt to guest
Old method prematurely sets ESR and DEAR. Move this part after we decide to inject interrupt, which is more like hardware behave. Signed-off-by: Liu Yu --- v3: change some functions to static arch/powerpc/include/asm/kvm_host.h |2 + arch/powerpc/kvm/booke.c| 59 ++- arch/powerpc/kvm/emulate.c |4 +- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 715aa6b..5e5bae7 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -259,6 +259,8 @@ struct kvm_vcpu_arch { #endif ulong fault_dear; ulong fault_esr; + ulong queued_dear; + ulong queued_esr; gpa_t paddr_accessed; u8 io_gpr; /* GPR used as IO source/target */ diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index e283e44..4d686cc 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -82,9 +82,32 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, set_bit(priority, &vcpu->arch.pending_exceptions); } -void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags) +static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, +ulong dear_flags, ulong esr_flags) { - /* BookE does flags in ESR, so ignore those we get here */ + vcpu->arch.queued_dear = dear_flags; + vcpu->arch.queued_esr = esr_flags; + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); +} + +static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, + ulong dear_flags, ulong esr_flags) +{ + vcpu->arch.queued_dear = dear_flags; + vcpu->arch.queued_esr = esr_flags; + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); +} + +static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, + ulong esr_flags) +{ + vcpu->arch.queued_esr = esr_flags; + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); +} + +void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags) +{ + vcpu->arch.queued_esr = esr_flags; kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); } @@ -115,14 +138,19 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, { int allowed = 0; ulong msr_mask; + bool update_esr = false, update_dear = false; switch (priority) { - case BOOKE_IRQPRIO_PROGRAM: case BOOKE_IRQPRIO_DTLB_MISS: - case BOOKE_IRQPRIO_ITLB_MISS: - case BOOKE_IRQPRIO_SYSCALL: case BOOKE_IRQPRIO_DATA_STORAGE: + update_dear = true; + /* fall through */ case BOOKE_IRQPRIO_INST_STORAGE: + case BOOKE_IRQPRIO_PROGRAM: + update_esr = true; + /* fall through */ + case BOOKE_IRQPRIO_ITLB_MISS: + case BOOKE_IRQPRIO_SYSCALL: case BOOKE_IRQPRIO_FP_UNAVAIL: case BOOKE_IRQPRIO_SPE_UNAVAIL: case BOOKE_IRQPRIO_SPE_FP_DATA: @@ -157,6 +185,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, vcpu->arch.srr0 = vcpu->arch.pc; vcpu->arch.srr1 = vcpu->arch.msr; vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; + if (update_esr == true) + vcpu->arch.esr = vcpu->arch.queued_esr; + if (update_dear == true) + vcpu->arch.dear = vcpu->arch.queued_dear; kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask); clear_bit(priority, &vcpu->arch.pending_exceptions); @@ -229,8 +261,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, if (vcpu->arch.msr & MSR_PR) { /* Program traps generated by user-level software must be handled * by the guest kernel. */ - vcpu->arch.esr = vcpu->arch.fault_esr; - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); + kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr); r = RESUME_GUEST; kvmppc_account_exit(vcpu, USR_PR_INST); break; @@ -286,16 +317,14 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, break; case BOOKE_INTERRUPT_DATA_STORAGE: - vcpu->arch.dear = vcpu->arch.fault_dear; - vcpu->arch.esr = vcpu->arch.fault_esr; - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); + kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear, + vcpu->arch.fault_esr); kvmppc_account_exit(vcpu, DSI_EXITS); r = RESUME_GUES
Re: [PATCH v2] kvmppc/booke: Set ESR and DEAR when inject interrupt to guest
On 02.02.2010, at 12:01, Liu Yu wrote: > Old method prematurely sets ESR and DEAR. > Move this part after we decide to inject interrupt, > which is more like hardware behave. In general the patch looks good. I only have minor questions. > > Signed-off-by: Liu Yu > --- > v2: > use new fields queued_esr queued_dear to queue flags > > arch/powerpc/include/asm/kvm_host.h |2 + > arch/powerpc/kvm/booke.c| 58 ++- > arch/powerpc/kvm/emulate.c |4 +- > 3 files changed, 47 insertions(+), 17 deletions(-) > > diff --git a/arch/powerpc/include/asm/kvm_host.h > b/arch/powerpc/include/asm/kvm_host.h > index 715aa6b..5e5bae7 100644 > --- a/arch/powerpc/include/asm/kvm_host.h > +++ b/arch/powerpc/include/asm/kvm_host.h > @@ -259,6 +259,8 @@ struct kvm_vcpu_arch { > #endif > ulong fault_dear; > ulong fault_esr; > + ulong queued_dear; > + ulong queued_esr; > gpa_t paddr_accessed; > > u8 io_gpr; /* GPR used as IO source/target */ > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c > index e283e44..ba93088 100644 > --- a/arch/powerpc/kvm/booke.c > +++ b/arch/powerpc/kvm/booke.c > @@ -82,9 +82,31 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu > *vcpu, > set_bit(priority, &vcpu->arch.pending_exceptions); > } > > -void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags) > +void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, > + ulong dear_flags, ulong esr_flags) Is this a new function? I don't see it getting removed anywhere else by this patch. Since it's not static, it needs a header change too, right? Or you just make it static. > { > - /* BookE does flags in ESR, so ignore those we get here */ > + vcpu->arch.queued_dear = dear_flags; > + vcpu->arch.queued_esr = esr_flags; > + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); > +} > + > +void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, > +ulong dear_flags, ulong esr_flags) Same as above. > +{ > + vcpu->arch.queued_dear = dear_flags; > + vcpu->arch.queued_esr = esr_flags; > + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); > +} > + > +void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong esr_flags) Same as above. > +{ > + vcpu->arch.queued_esr = esr_flags; > + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); > +} > + > +void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags) arch/powerpc/include/asm/kvm_ppc.h:extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags); > This is good. > +{ > + vcpu->arch.queued_esr = esr_flags; > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); > } > > @@ -115,14 +137,19 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu > *vcpu, > { > int allowed = 0; > ulong msr_mask; > + bool update_esr = false, update_dear = false; > > switch (priority) { > - case BOOKE_IRQPRIO_PROGRAM: > case BOOKE_IRQPRIO_DTLB_MISS: > - case BOOKE_IRQPRIO_ITLB_MISS: > - case BOOKE_IRQPRIO_SYSCALL: > case BOOKE_IRQPRIO_DATA_STORAGE: > + update_dear = true; > + /* fall through */ > case BOOKE_IRQPRIO_INST_STORAGE: > + case BOOKE_IRQPRIO_PROGRAM: > + update_esr = true; > + /* fall through */ > + case BOOKE_IRQPRIO_ITLB_MISS: > + case BOOKE_IRQPRIO_SYSCALL: > case BOOKE_IRQPRIO_FP_UNAVAIL: > case BOOKE_IRQPRIO_SPE_UNAVAIL: > case BOOKE_IRQPRIO_SPE_FP_DATA: > @@ -157,6 +184,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu > *vcpu, > vcpu->arch.srr0 = vcpu->arch.pc; > vcpu->arch.srr1 = vcpu->arch.msr; > vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; > + if (update_esr == true) > + vcpu->arch.esr = vcpu->arch.queued_esr; > + if (update_dear == true) > + vcpu->arch.dear = vcpu->arch.queued_dear; > kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask); > > clear_bit(priority, &vcpu->arch.pending_exceptions); > @@ -229,8 +260,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct > kvm_vcpu *vcpu, > if (vcpu->arch.msr & MSR_PR) { > /* Program traps generated by user-level software must > be handled >* by the guest kernel. */ > - vcpu->arch.esr = vcpu->arch.fault_esr; > - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); > + kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr); > r = RESUME_GUEST; > kvmppc_account_exit(vcpu, USR_PR_INST); > break; > @@ -286,16 +316,14 @@ int kvmppc_handle_exit(struct kvm_run *run, struct > kvm_vcp
[PATCH v2] kvmppc/booke: Set ESR and DEAR when inject interrupt to guest
Old method prematurely sets ESR and DEAR. Move this part after we decide to inject interrupt, which is more like hardware behave. Signed-off-by: Liu Yu --- v2: use new fields queued_esr queued_dear to queue flags arch/powerpc/include/asm/kvm_host.h |2 + arch/powerpc/kvm/booke.c| 58 ++- arch/powerpc/kvm/emulate.c |4 +- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 715aa6b..5e5bae7 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -259,6 +259,8 @@ struct kvm_vcpu_arch { #endif ulong fault_dear; ulong fault_esr; + ulong queued_dear; + ulong queued_esr; gpa_t paddr_accessed; u8 io_gpr; /* GPR used as IO source/target */ diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index e283e44..ba93088 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -82,9 +82,31 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, set_bit(priority, &vcpu->arch.pending_exceptions); } -void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags) +void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, + ulong dear_flags, ulong esr_flags) { - /* BookE does flags in ESR, so ignore those we get here */ + vcpu->arch.queued_dear = dear_flags; + vcpu->arch.queued_esr = esr_flags; + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); +} + +void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, +ulong dear_flags, ulong esr_flags) +{ + vcpu->arch.queued_dear = dear_flags; + vcpu->arch.queued_esr = esr_flags; + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); +} + +void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong esr_flags) +{ + vcpu->arch.queued_esr = esr_flags; + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); +} + +void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags) +{ + vcpu->arch.queued_esr = esr_flags; kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); } @@ -115,14 +137,19 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, { int allowed = 0; ulong msr_mask; + bool update_esr = false, update_dear = false; switch (priority) { - case BOOKE_IRQPRIO_PROGRAM: case BOOKE_IRQPRIO_DTLB_MISS: - case BOOKE_IRQPRIO_ITLB_MISS: - case BOOKE_IRQPRIO_SYSCALL: case BOOKE_IRQPRIO_DATA_STORAGE: + update_dear = true; + /* fall through */ case BOOKE_IRQPRIO_INST_STORAGE: + case BOOKE_IRQPRIO_PROGRAM: + update_esr = true; + /* fall through */ + case BOOKE_IRQPRIO_ITLB_MISS: + case BOOKE_IRQPRIO_SYSCALL: case BOOKE_IRQPRIO_FP_UNAVAIL: case BOOKE_IRQPRIO_SPE_UNAVAIL: case BOOKE_IRQPRIO_SPE_FP_DATA: @@ -157,6 +184,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, vcpu->arch.srr0 = vcpu->arch.pc; vcpu->arch.srr1 = vcpu->arch.msr; vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; + if (update_esr == true) + vcpu->arch.esr = vcpu->arch.queued_esr; + if (update_dear == true) + vcpu->arch.dear = vcpu->arch.queued_dear; kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask); clear_bit(priority, &vcpu->arch.pending_exceptions); @@ -229,8 +260,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, if (vcpu->arch.msr & MSR_PR) { /* Program traps generated by user-level software must be handled * by the guest kernel. */ - vcpu->arch.esr = vcpu->arch.fault_esr; - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); + kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr); r = RESUME_GUEST; kvmppc_account_exit(vcpu, USR_PR_INST); break; @@ -286,16 +316,14 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, break; case BOOKE_INTERRUPT_DATA_STORAGE: - vcpu->arch.dear = vcpu->arch.fault_dear; - vcpu->arch.esr = vcpu->arch.fault_esr; - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); + kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear, + vcpu->arch.fault_esr); kvmppc_account_exit(vcpu, DSI_EXITS); r = RESUME_GUEST; break; case BOOKE_INTERRUPT_I