All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Alexander Graf <agraf@suse.de>
Cc: kvm list <kvm@vger.kernel.org>, kvm-ppc <kvm-ppc@vger.kernel.org>
Subject: Re: [PATCH 2/2] KVM: PPC: Book3S: Call into C interrupt handlers
Date: Thu, 26 Apr 2012 21:45:47 +0000	[thread overview]
Message-ID: <1335476747.21961.82.camel@pasglop> (raw)
In-Reply-To: <1335435543-19690-2-git-send-email-agraf@suse.de>


> +static void kvmppc_fill_pt_regs(struct pt_regs *regs)
> +{
> +	ulong r1, ip, msr, lr;
> +
> +	asm("mr %0, 1" : "=r"(r1));
> +	asm("mflr %0" : "=r"(lr));
> +	asm("mfmsr %0" : "=r"(msr));
> +	asm("bl 1f; 1: mflr %0" : "=r"(ip));
> +
> +	memset(regs, 0, sizeof(*regs));
> +	regs->gpr[1] = r1;
> +	regs->nip = ip;
> +	regs->msr = msr;
> +	regs->link = lr;
> +}

That is -very- gross ... I suppose it works but yuck :-)

> +static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
> +				     unsigned int exit_nr)
> +{
> +	struct pt_regs regs;
> +
> +	switch (exit_nr) {
> +	case BOOK3S_INTERRUPT_EXTERNAL:
> +	case BOOK3S_INTERRUPT_EXTERNAL_LEVEL:
> +	case BOOK3S_INTERRUPT_EXTERNAL_HV:
> +		kvmppc_fill_pt_regs(&regs);
> +		soft_irq_disable();
> +		do_IRQ(&regs);
> +		soft_irq_enable();

What are those soft_irq_disable/enable ? They look like sometimes
local_irq_disable/enable and sometimes something else ?

If you are hard disabled already (which you should be) and want to
"mark" things as soft disabled, I suppose that will work except that
you'll be missing PACA_IRQ_HARD_DIS in irq_happened, so
local_irq_enable() will not hard-enable.

> +		break;
> +	case BOOK3S_INTERRUPT_DECREMENTER:
> +	case BOOK3S_INTERRUPT_HV_DECREMENTER:
> +		kvmppc_fill_pt_regs(&regs);
> +		soft_irq_disable();
> +		timer_interrupt(&regs);
> +		soft_irq_enable();
> +		break;

Same.

> +	case BOOK3S_INTERRUPT_MACHINE_CHECK:
> +		/* FIXME */
> +		break;
> +	case BOOK3S_INTERRUPT_PERFMON:
> +		kvmppc_fill_pt_regs(&regs);
> +		soft_irq_disable();
> +		performance_monitor_exception(&regs);
> +		soft_irq_enable();
> +		break;

Same.

> +	}
> +}
> +
>  int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
>                         unsigned int exit_nr)
>  {
> @@ -548,6 +602,10 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
>  	run->exit_reason = KVM_EXIT_UNKNOWN;
>  	run->ready_for_interrupt_injection = 1;
>  
> +	/* restart interrupts if they were meant for the host */
> +	kvmppc_restart_interrupt(vcpu, exit_nr);
> +	__hard_irq_enable();
> +

I suppose that's to work around the above comment about missing
PACA_IRQ_HARD_DIS ?

>  	trace_kvm_book3s_exit(exit_nr, vcpu);
>  	preempt_enable();
>  	kvm_resched(vcpu);
> diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S
> index 6bae0a9..3a78b46 100644
> --- a/arch/powerpc/kvm/book3s_segment.S
> +++ b/arch/powerpc/kvm/book3s_segment.S
> @@ -308,28 +308,6 @@ no_dcbz32_off:
>  
>  #endif /* CONFIG_PPC_BOOK3S_64 */
>  
> -	/*
> -	 * For some interrupts, we need to call the real Linux
> -	 * handler, so it can do work for us. This has to happen
> -	 * as if the interrupt arrived from the kernel though,
> -	 * so let's fake it here where most state is restored.
> -	 *
> -	 * Having set up SRR0/1 with the address where we want
> -	 * to continue with relocation on (potentially in module
> -	 * space), we either just go straight there with rfi[d],
> -	 * or we jump to an interrupt handler with bctr if there
> -	 * is an interrupt to be handled first.  In the latter
> -	 * case, the rfi[d] at the end of the interrupt handler
> -	 * will get us back to where we want to continue.
> -	 */
> -
> -	cmpwi	r12, BOOK3S_INTERRUPT_EXTERNAL
> -	beq	1f
> -	cmpwi	r12, BOOK3S_INTERRUPT_DECREMENTER
> -	beq	1f
> -	cmpwi	r12, BOOK3S_INTERRUPT_PERFMON
> -1:	mtctr	r12
> -
>  	/* Register usage at this point:
>  	 *
>  	 * R1       = host R1
> @@ -348,7 +326,6 @@ no_dcbz32_off:
>  	/* Load highmem handler address */
>  	mtsrr0	r8
>  
> -	/* RFI into the highmem handler, or jump to interrupt handler */
> -	beqctr
> +	/* RFI into the highmem handler */
>  	RFI
>  kvmppc_handler_trampoline_exit_end:

Cheers,
Ben.



WARNING: multiple messages have this Message-ID (diff)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Alexander Graf <agraf@suse.de>
Cc: kvm list <kvm@vger.kernel.org>, kvm-ppc <kvm-ppc@vger.kernel.org>
Subject: Re: [PATCH 2/2] KVM: PPC: Book3S: Call into C interrupt handlers
Date: Fri, 27 Apr 2012 07:45:47 +1000	[thread overview]
Message-ID: <1335476747.21961.82.camel@pasglop> (raw)
In-Reply-To: <1335435543-19690-2-git-send-email-agraf@suse.de>


> +static void kvmppc_fill_pt_regs(struct pt_regs *regs)
> +{
> +	ulong r1, ip, msr, lr;
> +
> +	asm("mr %0, 1" : "=r"(r1));
> +	asm("mflr %0" : "=r"(lr));
> +	asm("mfmsr %0" : "=r"(msr));
> +	asm("bl 1f; 1: mflr %0" : "=r"(ip));
> +
> +	memset(regs, 0, sizeof(*regs));
> +	regs->gpr[1] = r1;
> +	regs->nip = ip;
> +	regs->msr = msr;
> +	regs->link = lr;
> +}

That is -very- gross ... I suppose it works but yuck :-)

> +static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
> +				     unsigned int exit_nr)
> +{
> +	struct pt_regs regs;
> +
> +	switch (exit_nr) {
> +	case BOOK3S_INTERRUPT_EXTERNAL:
> +	case BOOK3S_INTERRUPT_EXTERNAL_LEVEL:
> +	case BOOK3S_INTERRUPT_EXTERNAL_HV:
> +		kvmppc_fill_pt_regs(&regs);
> +		soft_irq_disable();
> +		do_IRQ(&regs);
> +		soft_irq_enable();

What are those soft_irq_disable/enable ? They look like sometimes
local_irq_disable/enable and sometimes something else ?

If you are hard disabled already (which you should be) and want to
"mark" things as soft disabled, I suppose that will work except that
you'll be missing PACA_IRQ_HARD_DIS in irq_happened, so
local_irq_enable() will not hard-enable.

> +		break;
> +	case BOOK3S_INTERRUPT_DECREMENTER:
> +	case BOOK3S_INTERRUPT_HV_DECREMENTER:
> +		kvmppc_fill_pt_regs(&regs);
> +		soft_irq_disable();
> +		timer_interrupt(&regs);
> +		soft_irq_enable();
> +		break;

Same.

> +	case BOOK3S_INTERRUPT_MACHINE_CHECK:
> +		/* FIXME */
> +		break;
> +	case BOOK3S_INTERRUPT_PERFMON:
> +		kvmppc_fill_pt_regs(&regs);
> +		soft_irq_disable();
> +		performance_monitor_exception(&regs);
> +		soft_irq_enable();
> +		break;

Same.

> +	}
> +}
> +
>  int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
>                         unsigned int exit_nr)
>  {
> @@ -548,6 +602,10 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
>  	run->exit_reason = KVM_EXIT_UNKNOWN;
>  	run->ready_for_interrupt_injection = 1;
>  
> +	/* restart interrupts if they were meant for the host */
> +	kvmppc_restart_interrupt(vcpu, exit_nr);
> +	__hard_irq_enable();
> +

I suppose that's to work around the above comment about missing
PACA_IRQ_HARD_DIS ?

>  	trace_kvm_book3s_exit(exit_nr, vcpu);
>  	preempt_enable();
>  	kvm_resched(vcpu);
> diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S
> index 6bae0a9..3a78b46 100644
> --- a/arch/powerpc/kvm/book3s_segment.S
> +++ b/arch/powerpc/kvm/book3s_segment.S
> @@ -308,28 +308,6 @@ no_dcbz32_off:
>  
>  #endif /* CONFIG_PPC_BOOK3S_64 */
>  
> -	/*
> -	 * For some interrupts, we need to call the real Linux
> -	 * handler, so it can do work for us. This has to happen
> -	 * as if the interrupt arrived from the kernel though,
> -	 * so let's fake it here where most state is restored.
> -	 *
> -	 * Having set up SRR0/1 with the address where we want
> -	 * to continue with relocation on (potentially in module
> -	 * space), we either just go straight there with rfi[d],
> -	 * or we jump to an interrupt handler with bctr if there
> -	 * is an interrupt to be handled first.  In the latter
> -	 * case, the rfi[d] at the end of the interrupt handler
> -	 * will get us back to where we want to continue.
> -	 */
> -
> -	cmpwi	r12, BOOK3S_INTERRUPT_EXTERNAL
> -	beq	1f
> -	cmpwi	r12, BOOK3S_INTERRUPT_DECREMENTER
> -	beq	1f
> -	cmpwi	r12, BOOK3S_INTERRUPT_PERFMON
> -1:	mtctr	r12
> -
>  	/* Register usage at this point:
>  	 *
>  	 * R1       = host R1
> @@ -348,7 +326,6 @@ no_dcbz32_off:
>  	/* Load highmem handler address */
>  	mtsrr0	r8
>  
> -	/* RFI into the highmem handler, or jump to interrupt handler */
> -	beqctr
> +	/* RFI into the highmem handler */
>  	RFI
>  kvmppc_handler_trampoline_exit_end:

Cheers,
Ben.

  reply	other threads:[~2012-04-26 21:45 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-26 10:19 [PATCH 1/2] PPC: Export some interrupt handlers Alexander Graf
2012-04-26 10:19 ` Alexander Graf
2012-04-26 10:19 ` [PATCH 2/2] KVM: PPC: Book3S: Call into C " Alexander Graf
2012-04-26 10:19   ` Alexander Graf
2012-04-26 21:45   ` Benjamin Herrenschmidt [this message]
2012-04-26 21:45     ` Benjamin Herrenschmidt
2012-04-26 22:24     ` Alexander Graf
2012-04-26 22:24       ` Alexander Graf
2012-04-26 23:12       ` Benjamin Herrenschmidt
2012-04-26 23:12         ` Benjamin Herrenschmidt
2012-04-26 23:30         ` Alexander Graf
2012-04-26 23:30           ` Alexander Graf
2012-04-26 23:37           ` Benjamin Herrenschmidt
2012-04-26 23:37             ` Benjamin Herrenschmidt
2012-04-26 23:50             ` Alexander Graf
2012-04-26 23:50               ` Alexander Graf
2012-04-27  0:00               ` Benjamin Herrenschmidt
2012-04-27  0:00                 ` Benjamin Herrenschmidt
2012-04-26 21:54   ` Scott Wood
2012-04-26 21:54     ` Scott Wood
2012-04-26 22:26     ` Alexander Graf
2012-04-26 22:26       ` Alexander Graf
2012-04-26 22:58     ` Benjamin Herrenschmidt
2012-04-26 22:58       ` Benjamin Herrenschmidt
2012-04-27  5:48   ` Paul Mackerras
2012-04-27  5:48     ` Paul Mackerras
2012-04-27 11:23     ` Alexander Graf
2012-04-27 11:23       ` Alexander Graf
2012-04-27 14:19       ` Alexander Graf
2012-04-27 14:19         ` Alexander Graf
2012-04-27 16:37       ` Scott Wood
2012-04-27 16:37         ` Scott Wood
2012-04-27 16:54         ` Alexander Graf
2012-04-27 16:54           ` Alexander Graf
2012-04-27 22:20       ` Benjamin Herrenschmidt
2012-04-27 22:20         ` Benjamin Herrenschmidt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1335476747.21961.82.camel@pasglop \
    --to=benh@kernel.crashing.org \
    --cc=agraf@suse.de \
    --cc=kvm-ppc@vger.kernel.org \
    --cc=kvm@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.