All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Kevin Tian <kevin.tian@intel.com>, Keir Fraser <keir@xen.org>,
	Ian Campbell <ian.campbell@citrix.com>,
	Jun Nakajima <jun.nakajima@intel.com>,
	jinsong.liu@alibaba-inc.com, xen-devel@lists.xen.org,
	mpohlack@amazon.de, ross.lagerwall@citrix.com,
	Stefano Stabellini <stefano.stabellini@citrix.com>,
	Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>,
	Jan Beulich <jbeulich@suse.com>,
	xen-devel@lists.xenproject.org,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>,
	sasha.levin@citrix.com
Subject: Re: [PATCH v3 07/23] xsplice: Implement support for applying/reverting/replacing patches. (v5)
Date: Tue, 23 Feb 2016 21:10:30 +0000	[thread overview]
Message-ID: <56CCCAC6.3080600@citrix.com> (raw)
In-Reply-To: <20160223204157.GB15838@char.us.oracle.com>

On 23/02/2016 20:41, Konrad Rzeszutek Wilk wrote:
> . snip..
>>> + * 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.
>> The MCE path needs consideration as well.  Unlike the NMI path however,
>> that one cannot be ignored.
>>
>> In both cases, it might be best to see about raising a tasklet or
>> softirq to pick up some deferred work.
> I will put that in a seperate patch as this is patch is big enough.

Actually, after subsequent thought, raising a tasklet wont help.

The biggest risk is the SMAP alternative in the asm entrypoints.  The
only way patching that can be made safe is to play fun and games with
debug traps. i.e.

Patch a 0xcc first
Then patch the rest of the bytes in the replacement
Then replace the 0xcc with the first byte of the replacement

This way if the codepath is hit while patching is in progress, you will
end up in the debug trap handler rather than executing junk.  There then
has to be some scheduling games for the NMI/MCE handler to take over
patching the code if it interrupted the patching pcpu.  Patching in
principle is a short operation, so performing it the handlers is not too
much of a problem.

The tricky part is patching the top of the debug trap handler and not
ending in an infinite loop.  I have a cunning idea, and will see if I
can find some copious free time to experiment with.

For v1 however, the implementation is fine.  It can be documented that
patching functions on the NMI/MCE path is liable to end in sadness, and
the asm entry points will have been taken care of during boot.

>
>>> + */
>>> +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);
>> As you have to IPI each processor to raise a schedule softirq, you can
>> set a per-cpu "xsplice enter rendezvous" variable.  This prevents the
>> need for the return-to-guest path to poll one single byte.
> .. Not sure I follow. The IPI we send to the other CPU is 0xfb - which
> makes the smp_call_function_interrupt run, which calls this function:
> reschedule_fn(). Then raise_softirq sets the bit on softirq_pending.

Correct

>
> Great. Since we caused an IPI that means we ended up calling VMEXIT which
> eventually ends calling process_pending_softirqs() which calls schedule().
> And after that it calls check_for_xsplice_work().

Correct

> Are you suggesting to add new softirq that would call in check_for_xsplice_work()?

No.  I am concerned that check_for_xsplice_work() is reading a single
global variable which, when patching is occurring, will be in a
repeatedly-dirtied cacheline.

> Or are you suggesting to skip the softirq_pending check and all the
> code around that and instead have each VMEXIT code path check this
> per-cpu "xsplice enter" variable? If so, why not use the existing
> softirq infrastructure? 

What I am suggesting is having reschedule_fn() set
this_cpu(xsplice_work_pending) = 1 and have check_for_xsplice_work()
check this_cpu(xsplice_work_pending) rather than the global semaphore.

This should ease the impact on the cache coherency fabric.

>
> .. snip..
>>> +}
>>> +
>>> +void do_xsplice(void)
>>> +{
>>> +    struct payload *p = xsplice_work.data;
>>> +    unsigned int cpu = smp_processor_id();
>>> +
>>> +    /* Fast path: no work to do. */
>>> +    if ( likely(!xsplice_work.do_work) )
>>> +        return;
>>> +    ASSERT(local_irq_is_enabled());
>>> +
>>> +    /* Set at -1, so will go up to num_online_cpus - 1 */
>>> +    if ( atomic_inc_and_test(&xsplice_work.semaphore) )
>>> +    {
>>> +        unsigned int total_cpus;
>>> +
>>> +        if ( !get_cpu_maps() )
>>> +        {
>>> +            printk(XENLOG_DEBUG "%s: CPU%u - unable to get cpu_maps lock.\n",
>>> +                   p->name, cpu);
>>> +            xsplice_work.data->rc = -EBUSY;
>>> +            xsplice_work.do_work = 0;
>>> +            return;
>> This error path leaves a ref in the semaphore.
> It does. And it also does so in xsplice_do_single() - if the xsplice_do_wait()
> fails, 
>>> +        }
>>> +
>>> +        barrier(); /* MUST do it after get_cpu_maps. */
>>> +        total_cpus = num_online_cpus() - 1;
>>> +
>>> +        if ( total_cpus )
>>> +        {
>>> +            printk(XENLOG_DEBUG "%s: CPU%u - IPIing the %u CPUs.\n", p->name,
>>> +                   cpu, total_cpus);
>>> +            smp_call_function(reschedule_fn, NULL, 0);
>>> +        }
>>> +        (void)xsplice_do_single(total_cpus);
> .. here, we never decrement the semaphore.
>
> Which is a safe-guard (documenting that).
>
> The issue here is that say we have two CPUs:
>
> CPU0				CPU1
>
> semaphore=0			semaphore=1
>  !get_cpu_maps()
>   do_work = 0;			.. now goes in the 'slave' part below and exits out
>                                 as do_work=0
>
> Now if we decremented the semaphore back on the error path:
>
> CPU0				CPU1
>
> semaphore=0			
>  !get_cpu_maps()
> 				.. do_work is still set.
>   do_work = 0;			
>                    
>   semaphore=-1
> 				atomic_inc_and_test(semaphore) == 0
> 				.. now it assumes the role of a master.
>
> 				.. it will fail as the other CPU will never
>                                 renezvous (the do_work is set to zero).
> 				But we waste another 30ms spinning.
>
>
> The end result is that after patching the semaphore should equal
> num_online_cpus-1.

Yay concurrency!  I am going to have to consider this more closely.

~Andrew

  parent reply	other threads:[~2016-02-23 21:10 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-12 18:05 [PATCH v3] xSplice v1 implementation and design Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 01/23] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op (v10) Konrad Rzeszutek Wilk
2016-02-12 20:11   ` Andrew Cooper
2016-02-12 20:40     ` Konrad Rzeszutek Wilk
2016-02-12 20:53       ` Andrew Cooper
2016-02-15  8:16       ` Jan Beulich
2016-02-19 19:36     ` Konrad Rzeszutek Wilk
2016-02-19 19:43       ` Andrew Cooper
2016-02-12 18:05 ` [PATCH v3 02/23] libxc: Implementation of XEN_XSPLICE_op in libxc (v5) Konrad Rzeszutek Wilk
2016-02-15 12:35   ` Wei Liu
2016-02-19 20:04     ` Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 03/23] xen-xsplice: Tool to manipulate xsplice payloads (v4) Konrad Rzeszutek Wilk
2016-02-15 12:59   ` Wei Liu
2016-02-19 20:46     ` Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 04/23] elf: Add relocation types to elfstructs.h Konrad Rzeszutek Wilk
2016-02-12 20:13   ` Andrew Cooper
2016-02-15  8:34   ` Jan Beulich
2016-02-19 21:05     ` Konrad Rzeszutek Wilk
2016-02-22 10:17       ` Jan Beulich
2016-02-22 15:19       ` Ross Lagerwall
2016-02-12 18:05 ` [PATCH v3 05/23] xsplice: Add helper elf routines (v4) Konrad Rzeszutek Wilk
2016-02-12 20:24   ` Andrew Cooper
2016-02-12 20:47     ` Konrad Rzeszutek Wilk
2016-02-12 20:52       ` Andrew Cooper
2016-02-12 18:05 ` [PATCH v3 06/23] xsplice: Implement payload loading (v4) Konrad Rzeszutek Wilk
2016-02-12 20:48   ` Andrew Cooper
2016-02-19 22:03     ` Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 07/23] xsplice: Implement support for applying/reverting/replacing patches. (v5) Konrad Rzeszutek Wilk
2016-02-16 19:11   ` Andrew Cooper
2016-02-17  8:58     ` Ross Lagerwall
2016-02-17 10:50     ` Jan Beulich
2016-02-19  9:30     ` Ross Lagerwall
2016-02-23 20:41     ` Konrad Rzeszutek Wilk
2016-02-23 20:53       ` Konrad Rzeszutek Wilk
2016-02-23 20:57       ` Konrad Rzeszutek Wilk
2016-02-23 21:10       ` Andrew Cooper [this message]
2016-02-24  9:31         ` Jan Beulich
2016-02-22 15:00   ` Ross Lagerwall
2016-02-22 17:06     ` Ross Lagerwall
2016-02-23 20:47       ` Konrad Rzeszutek Wilk
2016-02-23 20:43     ` Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 08/23] x86/xen_hello_world.xsplice: Test payload for patching 'xen_extra_version'. (v2) Konrad Rzeszutek Wilk
2016-02-16 11:31   ` Ross Lagerwall
2016-02-12 18:05 ` [PATCH v3 09/23] xsplice: Add support for bug frames. (v4) Konrad Rzeszutek Wilk
2016-02-16 19:35   ` Andrew Cooper
2016-02-24 16:22     ` Konrad Rzeszutek Wilk
2016-02-24 16:30       ` Andrew Cooper
2016-02-24 16:26     ` Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 10/23] xsplice: Add support for exception tables. (v2) Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 11/23] xsplice: Add support for alternatives Konrad Rzeszutek Wilk
2016-02-16 19:41   ` Andrew Cooper
2016-02-12 18:05 ` [PATCH v3 12/23] xsm/xen_version: Add XSM for the xen_version hypercall (v8) Konrad Rzeszutek Wilk
2016-02-12 21:52   ` Daniel De Graaf
2016-02-12 18:05 ` [PATCH v3 13/23] XENVER_build_id: Provide ld-embedded build-ids (v10) Konrad Rzeszutek Wilk
2016-02-12 21:52   ` Daniel De Graaf
2016-02-16 20:09   ` Andrew Cooper
2016-02-16 20:22     ` Konrad Rzeszutek Wilk
2016-02-16 20:26       ` Andrew Cooper
2016-02-16 20:40         ` Konrad Rzeszutek Wilk
2016-02-24 18:52     ` Konrad Rzeszutek Wilk
2016-02-24 19:13       ` Andrew Cooper
2016-02-24 20:54         ` Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 14/23] libxl: info: Display build_id of the hypervisor Konrad Rzeszutek Wilk
2016-02-15 12:45   ` Wei Liu
2016-02-12 18:05 ` [PATCH v3 15/23] xsplice: Print build_id in keyhandler Konrad Rzeszutek Wilk
2016-02-16 20:13   ` Andrew Cooper
2016-02-12 18:05 ` [PATCH v3 16/23] xsplice: basic build-id dependency checking Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 17/23] xsplice: Print dependency and payloads build_id in the keyhandler Konrad Rzeszutek Wilk
2016-02-16 20:20   ` Andrew Cooper
2016-02-17 11:10     ` Jan Beulich
2016-02-24 21:54       ` Konrad Rzeszutek Wilk
2016-02-25  8:47         ` Jan Beulich
2016-02-12 18:05 ` [PATCH v3 18/23] xsplice: Prevent duplicate payloads to be loaded Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 19/23] xsplice, symbols: Implement symbol name resolution on address. (v2) Konrad Rzeszutek Wilk
2016-02-22 14:57   ` Ross Lagerwall
2016-02-12 18:05 ` [PATCH v3 20/23] x86, xsplice: Print payload's symbol name and module in backtraces Konrad Rzeszutek Wilk
2016-02-12 18:05 ` [PATCH v3 21/23] xsplice: Add support for shadow variables Konrad Rzeszutek Wilk
2016-03-07  7:40   ` Martin Pohlack
2016-03-15 18:02     ` Konrad Rzeszutek Wilk
2016-03-07 18:52   ` Martin Pohlack
2016-02-12 18:06 ` [PATCH v3 22/23] xsplice: Add hooks functions and other macros Konrad Rzeszutek Wilk
2016-02-12 18:06 ` [PATCH v3 23/23] xsplice, hello_world: Use the XSPLICE_[UN|]LOAD_HOOK hooks for two functions Konrad Rzeszutek Wilk
2016-02-12 21:57 ` [PATCH v3] xSplice v1 implementation and design Konrad Rzeszutek Wilk
2016-02-12 21:57   ` [PATCH v3 MISSING/23] xsplice: Design document (v7) Konrad Rzeszutek Wilk
2016-02-18 16:20     ` Jan Beulich
2016-02-19 18:36       ` Konrad Rzeszutek Wilk

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=56CCCAC6.3080600@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=Aravind.Gopalakrishnan@amd.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=ian.campbell@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=jinsong.liu@alibaba-inc.com \
    --cc=jun.nakajima@intel.com \
    --cc=keir@xen.org \
    --cc=kevin.tian@intel.com \
    --cc=konrad.wilk@oracle.com \
    --cc=mpohlack@amazon.de \
    --cc=ross.lagerwall@citrix.com \
    --cc=sasha.levin@citrix.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=xen-devel@lists.xen.org \
    --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.