public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Kinney, Michael D" <michael.d.kinney@intel.com>
To: Laszlo Ersek <lersek@redhat.com>,
	"Fan, Jeff" <jeff.fan@intel.com>,
	"edk2-devel@ml01.01.org" <edk2-devel@ml01.01.org>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	"Yao, Jiewen" <jiewen.yao@intel.com>,
	 "Tian, Feng" <feng.tian@intel.com>
Subject: Re: [PATCH v2 0/2] Add volatile for mNumberToFinish
Date: Wed, 16 Nov 2016 18:18:38 +0000	[thread overview]
Message-ID: <E92EE9817A31E24EB0585FDF735412F5648545B6@ORSMSX113.amr.corp.intel.com> (raw)
In-Reply-To: <605a5187-5b91-e0f8-5560-8a02ddad5057@redhat.com>

Laszlo,

Thanks for the details from and ANSI C spec.

For this compiler issue, are there more details on the 
assembly code generated by the GCC 5.4 compiler in the
failing mode?

I also see Liming's observation that the internal
implementation of the SynchronizationLib adds volatile
in some internal worker functions.  Other implementation
artifacts include the use of a read/write memory barrier
to prevent the optimizing compiler from optimizing
across a boundary.  These read/write barriers are used
in the spin lock functions, but not the Interlocked*()
functions.

I want to make sure we have studied the code generation
to see if the issue is related to volatile or a read/write
memory barrier.  It could be adding volatile forced the
compiler to internally add read/write barrier.

Also, given the implementation I see in the SynchronizationLib
I am not sure the cast to (UINT32 *) is required in the 
proposed patch.  Do we get compiler warnings/errors if those
casts are not included?

The second topic is what the SynchronizationLib API interfaces
should have been from the beginning.  In retrospect, I think
they should have been defined with volatile pointers.  The spin
lock APIs do use volatile pointers, but that is embedded in the 
typedef for SPIN_LOCK, so it is not as obvious.

Thanks,

Mike

> -----Original Message-----
> From: Laszlo Ersek [mailto:lersek@redhat.com]
> Sent: Tuesday, November 15, 2016 8:10 AM
> To: Fan, Jeff <jeff.fan@intel.com>; edk2-devel@ml01.01.org
> Cc: Paolo Bonzini <pbonzini@redhat.com>; Yao, Jiewen <jiewen.yao@intel.com>; Tian,
> Feng <feng.tian@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> Subject: Re: [PATCH v2 0/2] Add volatile for mNumberToFinish
> 
> Jeff,
> 
> On 11/15/16 15:08, Jeff Fan wrote:
> > v2:
> >   Add patch #1 per Laszlo's comments
> >   at https://lists.01.org/pipermail/edk2-devel/2016-November/004697.html
> >
> > About the comments updated SynchronizationLib to add volatile for
> > input parameter, I will send in another serial patches.
> >
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Feng Tian <feng.tian@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Jeff Fan <jeff.fan@intel.com>
> >
> > Jeff Fan (2):
> >   UefiCpuPkg/PiSmmCpuDxeSmm: Add volatile for parameter NumberToFinish
> >   UefiCpuPkg/PiSmmCpuDxeSmm: Add volatile for mNumberToFinish
> >
> >  UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c             | 4 ++--
> >  UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c | 4 ++--
> >  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h    | 2 +-
> >  UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c  | 2 +-
> >  4 files changed, 6 insertions(+), 6 deletions(-)
> >
> 
> if you want to keep GCC5.4 from optimizing away the access, the
> synchronization object itself, and all pointers  to it must remain
> volatile. Wherever you cast away the volatile qualifier, for example in
> a function call, GCC can break code on the next level, even if you don't
> actually access the object through that pointer (i.e., if you cast the
> pointer back to volatile just in time for the access).
> 
> So, the safe way to go about this is to change function prototypes from
> callee towards callers -- first change the callee (because both volatile
> and non-volatile can be accepted as volatile), then change the caller
> (make sure what you pass in is volatile, and propagate it outwards).
> 
> It is also okay to convert the original volatile pointer to UINTN, and
> to pass it to assembly code like that, or to convert it back to a
> volatile pointer from UINTN before use.
> 
> From the C99 standard:
> 
> 6.3 Conversions
> 6.3.2.3 Pointers
> 
>   2 For any qualifier q, a pointer to a non-q-qualified type may be
>     converted to a pointer to the q-qualified version of the type; the
>     values stored in the original and converted pointers shall compare
>     equal.
> 
>   5 An integer may be converted to any pointer type. Except as
>     previously specified, the result is implementation-defined, might
>     not be correctly aligned, might not point to an entity of the
>     referenced type, and might be a trap representation.
> 
>   6 Any pointer type may be converted to an integer type. Except as
>     previously specified, the result is implementation-defined. If the
>     result cannot be represented in the integer type, the behavior is
>     undefined. The result need not be in the range of values of any
>     integer type.
> 
> 6.7.3 Type qualifiers, paragraph 5:
> 
>     If an attempt is made to modify an object defined with a
>     const-qualified type through use of an lvalue with
>     non-const-qualified type, the behavior is undefined. If an attempt
>     is made to refer to an object defined with a volatile-qualified
>     type through use of an lvalue with non-volatile-qualified type, the
>     behavior is undefined.
> 
> In summary:
> 
> - casting away "volatile" even just temporarily (without actual
>   accesses) may give gcc license to break the code (6.3.2.3 p2)
> 
> - accessing without volatile is known to break the code (6.7.3 p5)
> 
> - you can always cast from non-volatile to volatile (6.3.2.3 p2),
>   but not the other way around!
> 
> - you can cast from (volatile VOID *) to UINTN and back as much as
>   you want (6.3.2.3 p5 p6), because our execution environment makes
>   that safe ("implementation-defined")
> 
> We might want to play loose with 6.3.2.3 p2 -- that is, cast away
> volatile from the pointer only temporarily, and cast it back just before
> accessing the object through the pointer --, but that could be unsafe in
> the long term. The *really* safe method is to cast it to UINTN, and then
> back the same way.
> 
> Yes, this would affect functions like SwitchStack() too -- the Context1
> and Context2 parameters would have to change their types to UINTN.
> 
> I think what we should discuss at this point is whether we'd like to
> care about 6.3.2.3 p2; that is, whether we consider casting away
> volatile temporarily.
> 
> The direction I've been experiencing with GCC is that its optimization
> methods are becoming more aggressive. For some optimizations, there are
> flags that disable them; I'm not sure they provide a specific flag for
> preventing GCC from exploiting violations of 6.3.2.3 p2.
> 
> Thanks
> Laszlo


  reply	other threads:[~2016-11-16 18:18 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-15 14:08 [PATCH v2 0/2] Add volatile for mNumberToFinish Jeff Fan
2016-11-15 14:08 ` [PATCH v2 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: Add volatile for parameter NumberToFinish Jeff Fan
2016-11-15 14:08 ` [PATCH v2 2/2] UefiCpuPkg/PiSmmCpuDxeSmm: Add volatile for mNumberToFinish Jeff Fan
2016-11-15 16:10 ` [PATCH v2 0/2] " Laszlo Ersek
2016-11-16 18:18   ` Kinney, Michael D [this message]
2016-11-16 19:21     ` Laszlo Ersek
2016-11-16 21:14       ` Andrew Fish
2016-11-17  1:10         ` Kinney, Michael D
2016-11-19  0:34           ` Andrew Fish
2016-11-16 19:40     ` Andrew Fish

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=E92EE9817A31E24EB0585FDF735412F5648545B6@ORSMSX113.amr.corp.intel.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