public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: Ruiyu Ni <ruiyu.ni@intel.com>, edk2-devel@lists.01.org
Cc: Michael D Kinney <michael.d.kinney@intel.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Liming Gao <liming.gao@intel.com>
Subject: Re: [PATCH v3] MdePkg/SynchronizationLib: fix Interlocked[De|In]crement return value
Date: Tue, 25 Sep 2018 16:22:40 +0200	[thread overview]
Message-ID: <f4217b25-a4f9-48ff-0a70-1e233016972d@redhat.com> (raw)
In-Reply-To: <20180913095046.9480-1-ruiyu.ni@intel.com>

On 09/13/18 11:50, Ruiyu Ni wrote:

> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> index 5224dd063f..4c4d6e3fc7 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> @@ -15,14 +15,12 @@
>
>
>
> -
>  /**
>    Performs an atomic increment of an 32-bit unsigned integer.
>
>    Performs an atomic increment of the 32-bit unsigned integer specified by
>    Value and returns the incremented value. The increment operation must be
> -  performed using MP safe mechanisms. The state of the return value is not
> -  guaranteed to be MP safe.
> +  performed using MP safe mechanisms.
>
>    @param  Value A pointer to the 32-bit value to increment.
>
> @@ -38,9 +36,10 @@ InternalSyncIncrement (
>    UINT32  Result;
>
>    __asm__ __volatile__ (
> +    "movl    $1, %%eax  \n\t"
>      "lock               \n\t"
> -    "incl    %2         \n\t"
> -    "mov     %2, %%eax      "
> +    "xadd    %%eax, %2  \n\t"
> +    "inc     %%eax          "
>      : "=a" (Result),          // %0
>        "=m" (*Value)           // %1
>      : "m"  (*Value)           // %2

The operand list for the inline assembly is incorrect, I suspect. When I
build this code with GCC48 as part of OVMF, for the NOOPT target, then
disassemble "CpuMpPei.debug", I get:

> 0000000000004383 <InternalSyncIncrement>:
> UINT32
> EFIAPI
> InternalSyncIncrement (
>   IN      volatile UINT32    *Value
>   )
> {
>     4383:       55                      push   %rbp
>     4384:       48 89 e5                mov    %rsp,%rbp
>     4387:       48 83 ec 10             sub    $0x10,%rsp
>     438b:       48 89 4d 10             mov    %rcx,0x10(%rbp)
>   UINT32  Result;
>
>   __asm__ __volatile__ (
>     438f:       48 8b 55 10             mov    0x10(%rbp),%rdx
>     4393:       48 8b 45 10             mov    0x10(%rbp),%rax
>     4397:       b8 01 00 00 00          mov    $0x1,%eax
>     439c:       f0 0f c1 00             lock xadd %eax,(%rax)
>     43a0:       ff c0                   inc    %eax
>     43a2:       89 45 fc                mov    %eax,-0x4(%rbp)
>     : "m"  (*Value)           // %2
>     : "memory",
>       "cc"
>     );
>
>   return Result;
>     43a5:       8b 45 fc                mov    -0x4(%rbp),%eax
> }
>     43a8:       c9                      leaveq
>     43a9:       c3                      retq
>

The generated code is trying to use EAX for both (a) the
exchange-and-add, i.e.  as the source operand of the XADD instruction,
and (b) as (part of) the address of the (*Value) argument.

In effect, before we reach the XADD instruction, the least significant
dword of Value's address is overwritten with 0x0000_0001. The exchange
then happens against that memory location.

It is interesting that GCC first spills the parameter from RCX to the
stack, and then it loads the parameter from the stack to both RDX and
RAX.

I think the operand list used with the inline assembly should be updated
to prevent GCC from associating %2 with EAX.

I'll try to experiment some more.

Thanks
Laszlo


  parent reply	other threads:[~2018-09-25 14:22 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-13  9:50 [PATCH v3] MdePkg/SynchronizationLib: fix Interlocked[De|In]crement return value Ruiyu Ni
2018-09-21  7:45 ` Gao, Liming
2018-09-25 14:08 ` Laszlo Ersek
2018-09-25 14:22 ` Laszlo Ersek [this message]
2018-09-25 16:18   ` Laszlo Ersek
2018-09-25 18:29     ` Laszlo Ersek
2018-09-25 19:25       ` Laszlo Ersek
2018-09-26 17:39         ` Kinney, Michael D

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-list 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=f4217b25-a4f9-48ff-0a70-1e233016972d@redhat.com \
    --to=devel@edk2.groups.io \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox