All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jason J. Herne" <jjherne@linux.ibm.com>
To: Christian Borntraeger <borntraeger@de.ibm.com>,
	qemu-devel@nongnu.org, qemu-s390x@nongnu.org, cohuck@redhat.com
Subject: Re: [PATCH] pc-bios/s390x: Pack ResetInfo struct
Date: Tue, 25 Feb 2020 05:23:56 -0500	[thread overview]
Message-ID: <91910082-ffeb-c588-7434-3de5fbfcbfa6@linux.ibm.com> (raw)
In-Reply-To: <941cc201-4c33-0ad3-ecc8-eab2709d350d@de.ibm.com>

On 2/13/20 1:24 PM, Christian Borntraeger wrote:
...
>>> diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
>>> index da13c43cc0..8839226803 100644
>>> --- a/pc-bios/s390-ccw/jump2ipl.c
>>> +++ b/pc-bios/s390-ccw/jump2ipl.c
>>> @@ -18,6 +18,7 @@
>>>    typedef struct ResetInfo {
>>>        uint64_t ipl_psw;
>>>        uint32_t ipl_continue;
>>> +    uint32_t pad;
>>>    } ResetInfo;
>>>      static ResetInfo save;
>>>
>>>
>>> also work? If yes, both variants are valid. Either packed or explicit padding.
>>>
>>
>> I don't believe this will work. I think the problem is that we're overwriting too much memory when we cast address 0 as a ResetInfo and then overwrite it (*current = save). I think we need the struct to be sized at 12-bytes instead of 16.
>>
> 
> The idea of the code is that we _save_ the original content from address 0 to save and _restore_ it before jumping into final code. I do not yet understand why this does not work.
> 

I've found the real problem here. Legacy operating systems that expect to start
in 32-bit addressing mode can fail if we leave junk in the high halves of our
64-bit registers. This is because some instructions (LA for example) are
bi-modal and operate differently depending on the machine's current addressing
mode.

In the case where we pack the struct, the compiler happens to use the mvc
instruction to load/store the current/save memory areas.

       *current = save;
   1fc:	e3 10 b0 a8 00 04 	lg	%r1,168(%r11)
   202:	c0 20 00 00 00 00 	larl	%r2,202 <jump_to_IPL_2+0x32>
			204: R_390_PC32DBL	.bss+0x2
   208:	d2 0b 10 00 20 00 	mvc	0(12,%r1),0(%r2)

Everything works as expected here, our legacy OS boots without issue.
However, in the case where we've packed this struct the compiler optimizes the
code and uses lmg/stmg instead of mvc to copy the data:

       *current = save;
   1fc:	e3 10 b0 a8 00 04 	lg	%r1,168(%r11)
   202:	c0 20 00 00 00 00 	larl	%r2,202 <jump_to_IPL_2+0x32>
			204: R_390_PC32DBL	.bss+0x2
   208:	eb 23 20 00 00 04 	lmg	%r2,%r3,0(%r2)
   20e:	eb 23 10 00 00 24 	stmg	%r2,%r3,0(%r1)

Depending on the data being copied, the high halves of the registers may contain
non-zero values. Example:

     r2             0x108000080000780        74309395999098752
     r3             0x601001800004368        432627142283510632

So, by sheer luck of the generated assembler, the patch happens to "fix" the
problem.  A real fix might be to insert inline assembler that clears the high
halves of the registers before we call ipl() in jump_to_IPL_2(). Can we think of
a better way to do that than 15 LLGTR instructions? :) Let me know your
thoughts.

jump_to_IPL_2 for easy reference:
     static void jump_to_IPL_2(void)
     {
         ResetInfo *current = 0;

         void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
         *current = save;
         ipl(); /* should not return */
     }


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)


  reply	other threads:[~2020-02-25 10:24 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-05 18:21 [PATCH] pc-bios/s390x: Pack ResetInfo struct Jason J. Herne
2020-02-06  9:55 ` Cornelia Huck
2020-02-06 10:09 ` Christian Borntraeger
2020-02-06 11:00   ` Thomas Huth
2020-02-07 11:28     ` Christian Borntraeger
2020-02-07 14:02       ` Jason J. Herne
2020-08-27 10:07         ` Thomas Huth
2020-09-01 13:02           ` Jason J. Herne
2020-02-13 18:02   ` Jason J. Herne
2020-02-13 18:24     ` Christian Borntraeger
2020-02-25 10:23       ` Jason J. Herne [this message]
2020-02-25 11:13         ` Christian Borntraeger
2020-02-25 12:58           ` Jason J. Herne
2020-02-25 15:00             ` Christian Borntraeger
2020-02-25 15:05               ` Christian Borntraeger

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=91910082-ffeb-c588-7434-3de5fbfcbfa6@linux.ibm.com \
    --to=jjherne@linux.ibm.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@nongnu.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.