All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: "Radim Krčmář" <rkrcmar@redhat.com>, linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org, Nadav Amit <namit@cs.technion.ac.il>,
	Gleb Natapov <gleb@kernel.org>
Subject: Re: [PATCH 5/8] KVM: x86: use MDA for interrupt matching
Date: Fri, 30 Jan 2015 10:03:49 +0100	[thread overview]
Message-ID: <54CB48F5.9060503@redhat.com> (raw)
In-Reply-To: <1422568135-28402-6-git-send-email-rkrcmar@redhat.com>



On 29/01/2015 22:48, Radim Krčmář wrote:
> In mixed modes, we musn't deliver xAPIC IPIs like x2APIC and vice versa.
> Instead of preserving the information in apic_send_ipi(), we regain it
> by converting all destinations into correct APIC MDA in the slow path.
> This allows easier reasoning about subsequent matching.
> 
> kvm_apic_broadcast() had an interesting design decision:
> it didn't consider IOxAPIC 0xff as broadcast in x2APIC mode ...
> everything worked because IOxAPIC can't set that in physical mode and
> logical mode considered it as a message for first 8 VCPUs.
> This patch interprets IOxAPIC 0xff as x2APIC broadcast.
> 
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  arch/x86/kvm/lapic.c | 40 +++++++++++++++++++++++++++++++++-------
>  1 file changed, 33 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index aae043f38548..871ce6a2485b 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -581,15 +581,24 @@ static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr)
>  	apic_update_ppr(apic);
>  }
>  
> -static bool kvm_apic_broadcast(struct kvm_lapic *apic, u32 dest)
> +static bool kvm_apic_broadcast(struct kvm_lapic *apic, u32 mda)
>  {
> -	return dest == (apic_x2apic_mode(apic) ?
> -			X2APIC_BROADCAST : APIC_BROADCAST);
> +	if (apic_x2apic_mode(apic))
> +		return mda == X2APIC_BROADCAST;
> +
> +	/* XXX: verify that xAPIC accepts x2APIC broadcast */
> +	return GET_APIC_DEST_FIELD(mda) == APIC_BROADCAST;
>  }
>  
> -static bool kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 dest)
> +static bool kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 mda)
>  {
> -	return kvm_apic_id(apic) == dest || kvm_apic_broadcast(apic, dest);
> +	if (kvm_apic_broadcast(apic, mda))
> +		return true;
> +
> +	if (apic_x2apic_mode(apic))
> +		return mda == kvm_apic_id(apic);
> +
> +	return mda == SET_APIC_DEST_FIELD(kvm_apic_id(apic));
>  }
>  
>  static bool kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda)
> @@ -606,6 +615,7 @@ static bool kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda)
>  		       && (logical_id & mda & 0xffff);
>  
>  	logical_id = GET_APIC_LOGICAL_ID(logical_id);
> +	mda = GET_APIC_DEST_FIELD(mda);
>  
>  	switch (kvm_apic_get_reg(apic, APIC_DFR)) {
>  	case APIC_DFR_FLAT:
> @@ -620,10 +630,26 @@ static bool kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda)
>  	}
>  }
>  
> +/* KVM APIC implementation has two quirks
> + *  - dest always begins at 0 while xAPIC MDA has offset 24,
> + *  - IOxAPIC messages have to be delivered (directly) to x2APIC.
> + */
> +static u32
> +kvm_apic_mda(unsigned int dest, struct kvm_lapic *ipi, bool x2apic_dest)

Please pass two struct kvm_lapic, so that you can write

	bool ipi = source != NULL;
	bool x2apic_mda = apic_x2apic_mode(ipi ? source : dest);

Looks a little nicer to me at least.

> +{
> +	bool x2apic_mda = ipi ? apic_x2apic_mode(ipi) : x2apic_dest;
> +
> +	if (!ipi && dest == APIC_BROADCAST)
> +		dest = X2APIC_BROADCAST;

This works, but it is not super-clear that you are shifting left by 24
here, and right in kvm_apic_broadcast().  What if you just make it

	if (!ipi && dest == APIC_BROADCAST && x2apic_mda)
		return X2APIC_BROADCAST.

?

Paolo

> +
> +	return x2apic_mda ? dest : SET_APIC_DEST_FIELD(dest);
> +}
> +
>  bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
>  			   int short_hand, unsigned int dest, int dest_mode)
>  {
>  	struct kvm_lapic *target = vcpu->arch.apic;
> +	u32 mda = kvm_apic_mda(dest, source, apic_x2apic_mode(target));
>  
>  	apic_debug("target %p, source %p, dest 0x%x, "
>  		   "dest_mode 0x%x, short_hand 0x%x\n",
> @@ -633,9 +659,9 @@ bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
>  	switch (short_hand) {
>  	case APIC_DEST_NOSHORT:
>  		if (dest_mode == APIC_DEST_PHYSICAL)
> -			return kvm_apic_match_physical_addr(target, dest);
> +			return kvm_apic_match_physical_addr(target, mda);
>  		else
> -			return kvm_apic_match_logical_addr(target, dest);
> +			return kvm_apic_match_logical_addr(target, mda);
>  	case APIC_DEST_SELF:
>  		return target == source;
>  	case APIC_DEST_ALLINC:
> 

  reply	other threads:[~2015-01-30  9:03 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-29 21:48 [PATCH 0/8] KVM: minor APIC fixes and cleanups Radim Krčmář
2015-01-29 21:48 ` [PATCH 1/8] KVM: x86: return bool from kvm_apic_match*() Radim Krčmář
2015-01-29 22:10   ` Joe Perches
2015-01-30  8:50     ` Paolo Bonzini
2015-01-29 21:48 ` [PATCH 2/8] KVM: x86: cleanup kvm_apic_match_*() Radim Krčmář
2015-01-30  8:52   ` Paolo Bonzini
2015-01-30 13:06     ` Radim Krčmář
2015-02-02 14:26     ` Radim Krčmář
2015-02-02 14:28       ` Paolo Bonzini
2015-02-02 14:30         ` Radim Krčmář
2015-02-02 14:29       ` Radim Krčmář
2015-01-29 21:48 ` [PATCH 3/8] KVM: x86: replace 0 with APIC_DEST_PHYSICAL Radim Krčmář
2015-01-29 21:48 ` [PATCH 4/8] KVM: x86: fix x2apic logical address matching Radim Krčmář
2015-01-29 21:48 ` [PATCH 5/8] KVM: x86: use MDA for interrupt matching Radim Krčmář
2015-01-30  9:03   ` Paolo Bonzini [this message]
2015-01-30 13:09     ` Radim Krčmář
2015-01-29 21:48 ` [PATCH 6/8] KVM: x86: allow mixed APIC mode broadcast Radim Krčmář
2015-01-29 21:48 ` [PATCH 7/8] KVM: x86: avoid logical_map when it is invalid Radim Krčmář
2015-01-30  9:19   ` Paolo Bonzini
2015-01-30 14:21     ` Radim Krčmář
2015-01-30 14:21       ` Paolo Bonzini
2015-01-30  9:38   ` Paolo Bonzini
2015-01-30 14:56     ` Radim Krčmář
2015-01-30 15:10       ` Paolo Bonzini
2015-01-30 17:09         ` Radim Krčmář
2015-01-29 21:48 ` [PATCH 8/8] KVM: x86: simplify kvm_apic_map Radim Krčmář
2015-01-30  9:18   ` Paolo Bonzini
2015-01-30 15:14     ` Radim Krčmář
2015-01-30 15:23       ` Paolo Bonzini
2015-01-30 16:57         ` Radim Krčmář
2015-01-30 21:15           ` Paolo Bonzini
2015-01-30  9:22 ` [PATCH 0/8] KVM: minor APIC fixes and cleanups Paolo Bonzini
2015-01-30 15:20   ` Radim Krčmář
2015-01-30 15:24     ` Paolo Bonzini

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=54CB48F5.9060503@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=gleb@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=namit@cs.technion.ac.il \
    --cc=rkrcmar@redhat.com \
    /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.