All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ross Lagerwall <ross.lagerwall@citrix.com>
To: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	xen-devel@lists.xenproject.org, mpohlack@amazon.com,
	andrew.cooper3@citrix.com, stefano.stabellini@citrix.com,
	jbeulich@suse.com, ian.jackson@eu.citrix.com,
	ian.campbell@citrix.com, wei.liu2@citrix.com,
	sasha.levin@oracle.com
Subject: Re: [PATCH v2 09/13] xsplice: Implement support for applying/reverting/replacing patches. (v2)
Date: Tue, 19 Jan 2016 14:39:40 +0000	[thread overview]
Message-ID: <569E4AAC.9070100@citrix.com> (raw)
In-Reply-To: <1452808031-706-10-git-send-email-konrad.wilk@oracle.com>

On 01/14/2016 09:47 PM, Konrad Rzeszutek Wilk wrote:
> From: Ross Lagerwall <ross.lagerwall@citrix.com>
>
> Implement support for the apply, revert and replace actions.
>
snip
> +#include <xen/cpu.h>
>   #include <xen/guest_access.h>
>   #include <xen/keyhandler.h>
>   #include <xen/lib.h>
> @@ -10,25 +11,38 @@
>   #include <xen/mm.h>
>   #include <xen/sched.h>
>   #include <xen/smp.h>
> +#include <xen/softirq.h>
>   #include <xen/spinlock.h>
> +#include <xen/wait.h>
>   #include <xen/xsplice_elf.h>
>   #include <xen/xsplice.h>
>
>   #include <asm/event.h>
> +#include <asm/nmi.h>
>   #include <public/sysctl.h>
>
> -static DEFINE_SPINLOCK(payload_list_lock);
> +/*
> + * Protects against payload_list operations and also allows only one
> + * caller in schedule_work.
> + */
> +static DEFINE_SPINLOCK(payload_lock);

I think it would be cleaner if all the payload_list_lock changes were 
folded into Patch 3.

>   static LIST_HEAD(payload_list);
>
> +static LIST_HEAD(applied_list);
> +
>   static unsigned int payload_cnt;
>   static unsigned int payload_version = 1;
>
>   struct payload {
>       int32_t state;                       /* One of the XSPLICE_STATE_*. */
>       int32_t rc;                          /* 0 or -XEN_EXX. */
> +    uint32_t timeout;                    /* Timeout to do the operation. */

This should go into struct xsplice_work.

>       struct list_head list;               /* Linked to 'payload_list'. */
>       void *payload_address;               /* Virtual address mapped. */
>       size_t payload_pages;                /* Nr of the pages. */
> +    struct list_head applied_list;       /* Linked to 'applied_list'. */
> +    struct xsplice_patch_func *funcs;    /* The array of functions to patch. */
> +    unsigned int nfuncs;                 /* Nr of functions to patch. */
>
>       char name[XEN_XSPLICE_NAME_SIZE + 1];/* Name of it. */
>   };
> @@ -36,6 +50,23 @@ struct payload {
>   static int load_payload_data(struct payload *payload, uint8_t *raw, ssize_t len);
>   static void free_payload_data(struct payload *payload);
>
> +/* Defines an outstanding patching action. */
> +struct xsplice_work
> +{
> +    atomic_t semaphore;          /* Used for rendezvous. First to grab it will
> +                                    do the patching. */
> +    atomic_t irq_semaphore;      /* Used to signal all IRQs disabled. */
> +    struct payload *data;        /* The payload on which to act. */
> +    volatile bool_t do_work;     /* Signals work to do. */
> +    volatile bool_t ready;       /* Signals all CPUs synchronized. */
> +    uint32_t cmd;                /* Action request: XSPLICE_ACTION_* */
> +};
> +
> +/* There can be only one outstanding patching action. */
> +static struct xsplice_work xsplice_work;
> +
> +static int schedule_work(struct payload *data, uint32_t cmd);
> +
snip
> +
> +/*
> + * This function is executed having all other CPUs with no stack (we may
> + * have cpu_idle on it) and IRQs disabled.
> + */
> +static int revert_payload(struct payload *data)
> +{
> +    unsigned int i;
> +
> +    printk(XENLOG_DEBUG "%s: Reverting.\n", data->name);
> +
> +    for ( i = 0; i < data->nfuncs; i++ )
> +        xsplice_revert_jmp(data->funcs + i);
> +
> +    list_del(&data->applied_list);
> +
> +    return 0;
> +}
> +
> +/* Must be holding the payload_list lock. */

payload lock?

> +static int schedule_work(struct payload *data, uint32_t cmd)
> +{
> +    /* Fail if an operation is already scheduled. */
> +    if ( xsplice_work.do_work )
> +        return -EAGAIN;

Hmm, I don't think EAGAIN is correct. It will cause xen-xsplice to poll 
for a status update, but the operation hasn't actually been submitted.

> +
> +    xsplice_work.cmd = cmd;
> +    xsplice_work.data = data;
> +    atomic_set(&xsplice_work.semaphore, -1);
> +    atomic_set(&xsplice_work.irq_semaphore, -1);
> +
> +    xsplice_work.ready = 0;
> +    smp_wmb();
> +    xsplice_work.do_work = 1;
> +    smp_wmb();
> +
> +    return 0;
> +}
> +
> +/*
> + * Note that because of this NOP code the do_nmi is not safely patchable.
> + * Also if we do receive 'real' NMIs we have lost them.
> + */
> +static int mask_nmi_callback(const struct cpu_user_regs *regs, int cpu)
> +{
> +    return 1;
> +}
> +
> +static void reschedule_fn(void *unused)
> +{
> +    smp_mb(); /* Synchronize with setting do_work */
> +    raise_softirq(SCHEDULE_SOFTIRQ);
> +}
> +
> +static int xsplice_do_wait(atomic_t *counter, s_time_t timeout,
> +                           unsigned int total_cpus, const char *s)
> +{
> +    int rc = 0;
> +
> +    while ( atomic_read(counter) != total_cpus && NOW() < timeout )
> +        cpu_relax();
> +
> +    /* Log & abort. */
> +    if ( atomic_read(counter) != total_cpus )
> +    {
> +        printk(XENLOG_DEBUG "%s: %s %u/%u\n", xsplice_work.data->name,
> +               s, atomic_read(counter), total_cpus);
> +        rc = -EBUSY;
> +        xsplice_work.data->rc = rc;
> +        xsplice_work.do_work = 0;
> +        smp_wmb();
> +        return rc;
> +    }
> +    return rc;
> +}
> +
> +static void xsplice_do_single(unsigned int total_cpus)
> +{
> +    nmi_callback_t saved_nmi_callback;
> +    s_time_t timeout;
> +    struct payload *data, *tmp;
> +    int rc;
> +
> +    data = xsplice_work.data;
> +    timeout = data->timeout ? data->timeout : MILLISECS(30);

The design doc says that a timeout of 0 means infinity.

> +    printk(XENLOG_DEBUG "%s: timeout is %"PRI_stime"ms\n", data->name,
> +           timeout / MILLISECS(1));
> +
> +    timeout += NOW();
> +
> +    if ( xsplice_do_wait(&xsplice_work.semaphore, timeout, total_cpus,
> +                         "Timed out on CPU semaphore") )
> +        return;
> +
> +    /* "Mask" NMIs. */
> +    saved_nmi_callback = set_nmi_callback(mask_nmi_callback);
> +
> +    /* All CPUs are waiting, now signal to disable IRQs. */
> +    xsplice_work.ready = 1;
> +    smp_wmb();
> +
> +    atomic_inc(&xsplice_work.irq_semaphore);
> +    if ( xsplice_do_wait(&xsplice_work.irq_semaphore, timeout, total_cpus,
> +                         "Timed out on IRQ semaphore.") )
> +        return;
> +
> +    local_irq_disable();

As far as I can tell, the mechanics of how this works haven't changed, 
the code has just been reorganized. Which means the points that Martin 
raised about this mechanism are still outstanding.

-- 
Ross Lagerwall

  reply	other threads:[~2016-01-19 14:39 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-14 21:46 [PATCH v2] xSplice v1 implementation Konrad Rzeszutek Wilk
2016-01-14 21:46 ` [PATCH v2 01/13] xsplice: Design document (v5) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:31   ` Ross Lagerwall
2016-02-05 18:27     ` Konrad Rzeszutek Wilk
2016-02-05 18:34     ` Konrad Rzeszutek Wilk
2016-02-05 15:25   ` Jan Beulich
2016-02-05 21:47     ` Konrad Rzeszutek Wilk
2016-02-09  8:25       ` Jan Beulich
2016-01-14 21:47 ` [PATCH v2 02/13] hypervisor/arm/keyhandler: Declare struct cpu_user_regs; Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 03/13] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op (v7) Konrad Rzeszutek Wilk
2016-01-19 14:30   ` Ross Lagerwall
2016-02-06 22:35   ` Doug Goldstein
2016-02-09  8:28     ` Jan Beulich
2016-02-09 14:39     ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 04/13] libxc: Implementation of XEN_XSPLICE_op in libxc (v4) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-14 21:47 ` [PATCH v2 05/13] xen-xsplice: Tool to manipulate xsplice payloads (v3) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:30   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 06/13] elf: Add relocation types to elfstructs.h Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 07/13] xsplice: Add helper elf routines (v2) Konrad Rzeszutek Wilk
2016-01-19 14:33   ` Ross Lagerwall
2016-02-05 18:38     ` Konrad Rzeszutek Wilk
2016-02-05 20:34       ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 08/13] xsplice: Implement payload loading (v2) Konrad Rzeszutek Wilk
2016-01-19 14:34   ` Ross Lagerwall
2016-01-19 16:59     ` Konrad Rzeszutek Wilk
2016-01-25 11:21       ` Ross Lagerwall
2016-01-19 16:45   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 09/13] xsplice: Implement support for applying/reverting/replacing patches. (v2) Konrad Rzeszutek Wilk
2016-01-19 14:39   ` Ross Lagerwall [this message]
2016-01-19 16:55     ` Konrad Rzeszutek Wilk
2016-01-25 11:43       ` Ross Lagerwall
2016-02-05 19:30         ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 10/13] xen_hello_world.xsplice: Test payload for patching 'xen_extra_version' Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:57   ` Ross Lagerwall
2016-01-19 16:47   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 11/13] xsplice: Add support for bug frames. (v2) Konrad Rzeszutek Wilk
2016-01-19 14:42   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 12/13] xsplice: Add support for exception tables. (v2) Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 13/13] xsplice: Add support for alternatives Konrad Rzeszutek Wilk
2016-01-15 16:58 ` [PATCH v2] xSplice v1 implementation Konrad Rzeszutek Wilk
2016-01-25 11:57   ` Ross Lagerwall

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=569E4AAC.9070100@citrix.com \
    --to=ross.lagerwall@citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=konrad.wilk@oracle.com \
    --cc=mpohlack@amazon.com \
    --cc=sasha.levin@oracle.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.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.