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)
next prev parent 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.