All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: Janakarajan Natarajan <Janakarajan.Natarajan@amd.com>
Cc: Tim Deegan <tim@xen.org>, Kevin Tian <kevin.tian@intel.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Wei Liu <wei.liu2@citrix.com>,
	Jun Nakajima <jun.nakajima@intel.com>,
	George Dunlap <George.Dunlap@eu.citrix.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Ian Jackson <Ian.Jackson@eu.citrix.com>,
	xen-devel@lists.xen.org, Julien Grall <julien.grall@arm.com>,
	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>
Subject: Re: [PATCH v2 05/10] x86/SVM: Add AVIC vmexit handlers
Date: Wed, 16 May 2018 09:56:50 -0600	[thread overview]
Message-ID: <5AFC54C202000078001C35AC@prv1-mh.provo.novell.com> (raw)
In-Reply-To: <20180507210753.2280-6-Janakarajan.Natarajan@amd.com>

>>> On 07.05.18 at 23:07, <Janakarajan.Natarajan@amd.com> wrote:
> @@ -180,6 +185,293 @@ int svm_avic_init_vmcb(struct vcpu *v)
>  }
>  
>  /*
> + * Note:
> + * This function handles the AVIC_INCOMP_IPI #vmexit when AVIC is enabled.
> + * The hardware generates this fault when an IPI could not be delivered
> + * to all targeted guest virtual processors because at least one guest
> + * virtual processor was not allocated to a physical core at the time.
> + */
> +void svm_avic_vmexit_do_incomp_ipi(struct cpu_user_regs *regs)
> +{
> +    struct vcpu *curr = current;
> +    struct domain *currd = curr->domain;
> +    struct vmcb_struct *vmcb = curr->arch.hvm_svm.vmcb;
> +    u32 icrh = vmcb->exitinfo1 >> 32;
> +    u32 icrl = vmcb->exitinfo1;
> +    u32 id = vmcb->exitinfo2 >> 32;
> +    u32 index = vmcb->exitinfo2 && 0xFF;
> +
> +    switch ( id )
> +    {
> +    case AVIC_INCMP_IPI_ERR_INVALID_INT_TYPE:
> +        /*
> +         * AVIC hardware handles the delivery of
> +         * IPIs when the specified Message Type is Fixed
> +         * (also known as fixed delivery mode) and
> +         * the Trigger Mode is edge-triggered. The hardware
> +         * also supports self and broadcast delivery modes
> +         * specified via the Destination Shorthand(DSH)
> +         * field of the ICRL. Logical and physical APIC ID
> +         * formats are supported. All other IPI types cause
> +         * a #VMEXIT, which needs to emulated.

Please utilize the permitted line length (also elsewhere).

> +         */
> +        vlapic_reg_write(curr, APIC_ICR2, icrh);
> +        vlapic_reg_write(curr, APIC_ICR, icrl);
> +        break;
> +
> +    case AVIC_INCMP_IPI_ERR_TARGET_NOT_RUN:
> +    {
> +        /*
> +         * At this point, we expect that the AVIC HW has already
> +         * set the appropriate IRR bits on the valid target
> +         * vcpus. So, we just need to kick the appropriate vcpu.
> +         */
> +        struct vcpu *v;
> +        uint32_t dest = GET_xAPIC_DEST_FIELD(icrh);
> +        uint32_t short_hand = icrl & APIC_SHORT_MASK;
> +        bool dest_mode = icrl & APIC_DEST_MASK;
> +
> +        for_each_vcpu ( currd,  v )
> +        {
> +            if ( v != curr &&
> +                 vlapic_match_dest(vcpu_vlapic(v), vcpu_vlapic(curr),
> +                                   short_hand, dest, dest_mode) )
> +            {
> +                vcpu_kick(v);
> +                break;

Why do you break out of the loop here? With a shorthand more than
one vCPU might be the target.

> +            }
> +        }
> +        break;
> +    }
> +
> +    case AVIC_INCMP_IPI_ERR_INV_TARGET:
> +        gprintk(XENLOG_ERR,
> +                "SVM: %s: Invalid IPI target (icr=%#08x:%08x, idx=%u)\n",

%#08x produces something like 0x012345, rather than a full eight digits.
Preferably drop the #, or if you really think it's needed replace it be an
explicit 0x.

> +                __func__, icrh, icrl, index);

Please use __func__ only when a log message really can't be disambiguated
another way.

For both of these - same further down.

> +static avic_logical_id_entry_t *
> +avic_get_logical_id_entry(struct svm_domain *d, u32 ldr, bool flat)
> +{
> +    unsigned int index;
> +    unsigned int dest_id = GET_xAPIC_LOGICAL_ID(ldr);
> +
> +    if ( !dest_id )
> +        return NULL;
> +
> +    if ( flat )
> +    {
> +        index = ffs(dest_id) - 1;
> +        if ( index > 7 )
> +            return NULL;
> +    }
> +    else
> +    {
> +        unsigned int cluster = (dest_id & 0xf0) >> 4;
> +        int apic = ffs(dest_id & 0x0f) - 1;
> +
> +        if ( (apic < 0) || (apic > 7) || (cluster >= 0xf) )

I can't see a way for apic to be larger than 3 with the calculation above.

> +            return NULL;
> +        index = (cluster << 2) + apic;
> +    }
> +
> +    ASSERT(index <= 255);

Which of the many possible meanings of 255 is this?

> +static int avic_ldr_write(struct vcpu *v, u8 g_phy_id, u32 ldr, bool valid)
> +{
> +    avic_logical_id_entry_t *entry, new_entry;
> +    u32 dfr = vlapic_reg_read(vcpu_vlapic(v), APIC_DFR);

Just to give another example - looks like this too could be vlapic_get_reg().

> +static int avic_handle_ldr_update(struct vcpu *v)
> +{
> +    int ret = 0;

Pointless initializer.

> +    u32 ldr = vlapic_reg_read(vcpu_vlapic(v), APIC_LDR);
> +    u32 apic_id = vlapic_reg_read(vcpu_vlapic(v), APIC_ID);
> +
> +    if ( !ldr )
> +        return -EINVAL;
> +
> +    ret = avic_ldr_write(v, GET_xAPIC_ID(apic_id), ldr, true);
> +    if ( ret && v->arch.hvm_svm.avic_last_ldr )
> +    {
> +        /*
> +         * Note:
> +         * In case of failure to update LDR register,
> +         * we set the guest physical APIC ID to 0,
> +         * and set the entry logical APID ID entry
> +         * to invalid (false).
> +         */
> +        avic_ldr_write(v, 0, v->arch.hvm_svm.avic_last_ldr, false);
> +        v->arch.hvm_svm.avic_last_ldr = 0;
> +    }
> +    else
> +    {
> +        /*
> +         * Note:
> +         * This saves the last valid LDR so that we
> +         * know which entry in the local APIC ID
> +         * to clean up when the LDR is updated.
> +         */
> +        v->arch.hvm_svm.avic_last_ldr = ldr;

The comment says "last valid", but you may get here also when the
first avic_ldr_write() failed. I think you mean

    if ( !ret )
    ...
    else if ( v->arch.hvm_svm.avic_last_ldr )
    ...

> +static int avic_unaccel_trap_write(struct vcpu *v)
> +{
> +    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
> +    u32 offset = vmcb->exitinfo1 & AVIC_UNACCEL_ACCESS_OFFSET_MASK;
> +    u32 reg = vlapic_reg_read(vcpu_vlapic(v), offset);
> +
> +    switch ( offset )
> +    {
> +    case APIC_ID:
> +        /*
> +         * Currently, we do not support APIC_ID update while
> +         * the vcpus are running, which might require updating
> +         * AVIC max APIC ID in all VMCBs. This would require
> +         * synchronize update on all running VCPUs.
> +         */
> +        return X86EMUL_UNHANDLEABLE;
> +
> +    case APIC_LDR:
> +        if ( avic_handle_ldr_update(v) )
> +            return X86EMUL_UNHANDLEABLE;
> +        break;
> +
> +    case APIC_DFR:
> +        if ( avic_handle_dfr_update(v) )
> +            return X86EMUL_UNHANDLEABLE;
> +        break;
> +
> +    default:
> +        break;

This default case is unnecessary.

> +void svm_avic_vmexit_do_noaccel(struct cpu_user_regs *regs)
> +{
> +    struct vcpu *curr = current;
> +    struct vmcb_struct *vmcb = curr->arch.hvm_svm.vmcb;
> +    u32 offset = vmcb->exitinfo1 & 0xFF0;
> +    u32 rw = (vmcb->exitinfo1 >> 32) & 0x1;

bool?

> +    if ( avic_is_trap(offset) )
> +    {
> +        /* Handling AVIC Trap (intercept right after the access). */
> +        if ( !rw )
> +        {
> +            /*
> +             * If a read trap happens, the CPU microcode does not
> +             * implement the spec.
> +             */
> +            gprintk(XENLOG_ERR, "%s: Invalid #VMEXIT due to trap read (%#x)\n",
> +                    __func__, offset);
> +            domain_crash(curr->domain);
> +        }
> +
> +        if ( avic_unaccel_trap_write(curr) != X86EMUL_OKAY )

ITYM "else if" here.

> +        {
> +            gprintk(XENLOG_ERR, "%s: Failed to handle trap write (%#x)\n",
> +                    __func__, offset);
> +            domain_crash(curr->domain);
> +        }
> +    }
> +    else
> +        /* Handling AVIC Fault (intercept before the access). */
> +        hvm_emulate_one_vm_event(EMUL_KIND_NORMAL, TRAP_invalid_op,
> +                                 X86_EVENT_NO_EC);

What's the rationale behind having chosen this function? I don't think it is
supposed to be called from outside the VM event code.

> +    return;
> +}

Please omit such redundant return statements.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2018-05-16 15:56 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-07 21:07 [PATCH v2 00/10] Introduce AMD SVM AVIC Janakarajan Natarajan
2018-05-07 21:07 ` [PATCH v2 01/10] x86/SVM: Modify VMCB fields to add AVIC support Janakarajan Natarajan
2018-05-07 21:07 ` [PATCH v2 02/10] x86/HVM: Rename vlapic_read_aligned() to vlapic_reg_read() Janakarajan Natarajan
2018-05-08 10:12   ` Wei Liu
2018-05-16 14:36   ` Jan Beulich
2018-05-07 21:07 ` [PATCH v2 03/10] x86/HVM: Make vlapic_reg_read/write() non-static Janakarajan Natarajan
2018-05-16 14:38   ` Jan Beulich
2018-05-16 14:44   ` Jan Beulich
2018-05-07 21:07 ` [PATCH v2 04/10] x86/HVM/SVM: Add AVIC initialization code Janakarajan Natarajan
2018-05-16 15:29   ` Jan Beulich
2018-05-16 15:41     ` Andrew Cooper
2018-05-21 18:41     ` Natarajan, Janakarajan
2018-05-22  9:19       ` Jan Beulich
2018-05-07 21:07 ` [PATCH v2 05/10] x86/SVM: Add AVIC vmexit handlers Janakarajan Natarajan
2018-05-16 15:56   ` Jan Beulich [this message]
2018-05-29 21:49     ` Natarajan, Janakarajan
2018-05-29 23:33       ` Andrew Cooper
2018-05-30  7:24         ` Jan Beulich
2018-05-30 18:30           ` Natarajan, Janakarajan
2018-05-30 23:23             ` Andrew Cooper
2018-05-07 21:07 ` [PATCH v2 06/10] x86/SVM: Add vcpu scheduling support for AVIC Janakarajan Natarajan
2018-05-17 14:45   ` Jan Beulich
2018-05-07 21:07 ` [PATCH v2 07/10] x86/SVM: Add interrupt management code via AVIC Janakarajan Natarajan
2018-05-17 14:50   ` Jan Beulich
2018-05-30 19:47     ` Natarajan, Janakarajan
2018-05-07 21:07 ` [PATCH v2 08/10] x86/HVM: Hook up miscellaneous AVIC functions Janakarajan Natarajan
2018-05-07 21:07 ` [PATCH v2 09/10] x86/SVM: Introduce svm command line option Janakarajan Natarajan
2018-05-17 14:54   ` Jan Beulich
2018-05-07 21:07 ` [PATCH v2 10/10] x86/SVM: Append AMD AVIC related data to IRQ keyhandler 'i' Janakarajan Natarajan
2018-05-17 14:56   ` Jan Beulich

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=5AFC54C202000078001C35AC@prv1-mh.provo.novell.com \
    --to=jbeulich@suse.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=Janakarajan.Natarajan@amd.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=julien.grall@arm.com \
    --cc=jun.nakajima@intel.com \
    --cc=kevin.tian@intel.com \
    --cc=sstabellini@kernel.org \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.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.