[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2-ish] x86/boot: Factor move_xen() out of __start_xen()


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>
  • Date: Wed, 4 Jan 2023 20:04:30 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Q8lqIglA3cLE3gjKfVs53dWzklNgm/Z2M2j8Ey4rR3I=; b=P3EdI7bC16DC/fWxWhGKHMsY4AOzgiBqg0+dSfVT2fGrkQdDIdxgf/6N4WeNzT+IL0E7y9qG7RLUMzl36X3fAmqvn708OuPnUsi5s3jJyaZe4sji66IiSZ+BoRZyoUHxd6wNcetLCvEIVKkXtiBt3as9vPrQ+TlmQxo1pR0ZpwcKzLs2G5ZD8FtogAIq3GqaXNWt8ARcaPtMtZcUcJLO+nHcNuMpcrII3dzTQ+bEASxx3Zs92kF8mWKal1G8X94YA40UeZVWk3DDsr3qnGK9BNjyk/8ckZiNJY51eFdu/vNrSaNdbFCfgbwH1pbdvD4zOUSFTWjuWB28RUEnKgC5xQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BUduF74z8gtOEPoxpvdB+b9Zk3G3cOqbVwGagme4YFA4hlu4+7GOtXe/j5QswTA8JERYkLOiVKHSfXwHZoM8VQp8KEYO7iRPtl4mPRpy5SnliedMKbZP8uoJ8t5x02QREPdNLLRKV7wUj4TpMxQrUR779fWU8hrU3oc9OltZLE5ZkNPA/iGHMMr5vUCT2y9R2WYIHzNIBKKEyOqkSoPTOoUHm5VmZFDN5L4xYNr91Av1a5ffAzNH71eDztK7CRZpsbvAcRGYNdA5AVmR55QBdpqNTGmGJVaZxsfK7/69ffLqqIOLDFDn00f1t75wSzeo38XWoQtzJxd9HMpZOoC+RA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Wed, 04 Jan 2023 20:04:54 +0000
  • Ironport-data: A9a23:5/XurqrtoCwaTiObZQ520C9RH0deBmI6ZBIvgKrLsJaIsI4StFCzt garIBnXaa7eajP3c9pzYI22/E0DvZTUnYU2SVc4+Ck1QisQ8ZuZCYyVIHmrMnLJJKUvbq7FA +Y2MYCccZ9uHhcwgj/3b9ANeFEljfngqoLUUbKCYWYpAFc+E0/NsDo788YhmIlknNOlNA2Ev NL2sqX3NUSsnjV5KQr40YrawP9UlKm06W1wUmAWP6gR5weHzyVNUPrzGInqR5fGatgMdgKFb 76rIIGRpgvx4xorA9W5pbf3GmVirmn6ZFXmZtJ+AsBOszAazsAA+v9T2Mk0MC+7vw6hjdFpo OihgLTrIesf0g8gr8xGO/VQO3kW0aSrY9YrK1Dn2SCY5xWun3cBX5yCpaz5VGEV0r8fPI1Ay RAXABQURQ+ju+a1/LW6G8lVvskOEunZE4xK7xmMzRmBZRonabbqZvyToPN9gnI3jM0IGuvCb c0EbzYpdA7HfxBEJlYQDtQ5gfusgX78NTZfrTp5p4JuuzSVkFM3jeeraYWNEjCJbZw9ckKwj 2TK5WnmRDodM8SS02Gt+XOwnO7f2yj8Xer+EZXprqc32QXOnAT/DjVRVVKqgeGGknW3WvZmK 3IR8ycJlogLoRnDot7VGkfQTGS/lhwWVsdUEuY6wBqQ0aeS6AGcbkAbShZRZdpgs9U5LRQ62 1nMk973CDhHtLyOVWnb5rqStSm1OyUeMSkFfyBscOcey9zqoYV2gheRSN9mSfexloesRmm2x C2Wpi8jgblVldQMy6iw4VHAhXSru4TNSQk2oA7QWwpJ8z9EWWJsXKTwgXCz0BqKBN/xooWp1 JTcp/Wj0Q==
  • Ironport-hdrordr: A9a23:OCvYYqo++QmBgGtBG2IkRPcaV5scL9V00zEX/kB9WHVpm5Oj+v xGzc5w6farsl0ssRYb6Kq90ci7MAjhHPtOjbX5Uo3SOTUO1FHYSL2Kj7GSpQEIaheOjtK1vJ 0IG8cReb6Ab2SWlfyb3ODRKade/DDtytHQuQ6x9QYLcehCUdAd0+5MMHfkLqQ6fngxObMJUL 6nouZXrTupfnoaKuy9G3k+RuDG4+bGkZr3CCR2ciLOvGO17A+A2frfKVy1zx0eWzRAzfMJ6m 7eiTH04a2lrrWS1gLc/3W71eUYpPLRjv94QOCcgMkcLTvhziyyYp56ZrGEtDcp5Mmy9VcRls XWqRtIBbU+15roRBD6nfLR4Xir7N9u0Q6o9baguwqqnSUtfkN2NyJD7bgpACcxpXBQ/e2U65 g7rF6xht5yN1fngDn54d7LEyFjkk65ulYyjOIVlXxVVIc1brhNoYsD0UtJGP47bV/HAbAcYZ hT5f7nlYZrmHOhHgTkVzpUsauRtzIIb167fnQ=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHZEYuAyVgzwEEad0Cj70OyJmEML6520VMAgAB2soCAALPugIAW0HgA
  • Thread-topic: [PATCH v2-ish] x86/boot: Factor move_xen() out of __start_xen()

On 21/12/2022 7:40 am, Jan Beulich wrote:
> On 20.12.2022 21:56, Andrew Cooper wrote:
>> On 20/12/2022 1:51 pm, Jan Beulich wrote:
>>> On 16.12.2022 21:17, Andrew Cooper wrote:
>>>> +        "mov    %[cr4], %%cr4\n\t"     /* CR4.PGE = 1 */
>>>> +        : [cr4] "=&a" (tmp) /* Could be "r", but "a" makes better asm */
>>>> +        : [cr3] "r" (__pa(idle_pg_table)),
>>>> +          [pge] "i" (X86_CR4_PGE)
>>>> +        : "memory" );
>>> The removed stack copying worries me, to be honest. Yes, for local
>>> variables of ours it doesn't matter because they are about to go out
>>> of scope. But what if the compiler instantiates any for its own use,
>>> e.g. ...
>>>
>>>> +    /*
>>>> +     * End of the critical region.  Updates to locals and globals now 
>>>> work as
>>>> +     * expected.
>>>> +     *
>>>> +     * Updates to local variables which have been spilled to the stack 
>>>> since
>>>> +     * the memcpy() have been lost.  But we don't care, because they're 
>>>> all
>>>> +     * going out of scope imminently.
>>>> +     */
>>>> +
>>>> +    printk("New Xen image base address: %#lx\n", xen_phys_start);
>>> ... the result of the address calculation for the string literal
>>> here? Such auxiliary calculations can happen at any point in the
>>> function, and won't necessarily (hence the example chosen) become
>>> impossible for the compiler to do with the memory clobber in the
>>> asm(). And while the string literal's address is likely cheap
>>> enough to calculate right in the function invocation sequence (and
>>> an option would also be to retain the printk() in the caller),
>>> other instrumentation options could be undermined by this as well.
>> Right now, the compiler is free to calculate the address of the string
>> literal in a register, and move it the other side of the TLB flush. 
>> This will work just fine.
>>
>> However, the compiler cannot now, or ever in the future, spill such a
>> calculation to the stack.
> I'm afraid the compiler's view at things is different: Whatever it puts
> on the stack is viewed as virtual registers, unaffected by a memory
> clobber (of course there can be effects resulting from uses of named
> variables). Look at -O3 output of gcc12 (which is what I happened to
> play with; I don't think it's overly version dependent) for this
> (clearly contrived) piece of code:
>
> int __attribute__((const)) calc(int);
>
> int test(int i) {
>       int j = calc(i);
>
>       asm("nopl %0" : "+m" (j));
>       asm("nopq %%rsp" ::: "memory", "ax", "cx", "dx", "bx", "bp", "si", "di",
>                            "r8", "r9", "r10", "r11", "r12", "r13", "r14", 
> "r15");
>       j = calc(i);
>       asm("nopl %0" :: "m" (j));
>
>       return j;
> }
>
> It instantiates a local on the stack for the result of calc(); it does
> not re-invoke calc() a 2nd time. Which means the memory clobber in the
> middle asm() does not affect that (and by implication: any) stack slot.
>
> Using godbolt I can also see that clang15 agrees with gcc12 in this
> regard. I didn't bother trying other versions.

Well this is problematic, because it contradicts what we depend on
asm("":::"memory") doing...

https://godbolt.org/z/xeGMc3sM9

But I don't fully agree with the conclusions drawn by this example.

It only instantiates a local on the stack because you force a memory
operand to satisfy the "m" constraints, not to satisfy the "memory"
constraint.

By declaring calc as const, you are permitting the compiler to make an
explicit transformation to delete one of the calls, irrespective of
anything else in the function.

It is weird that 'j' ends up taking two stack slots when would be
absolutely fine for it to only have 1, and indeed this is what happens
when you remove the first and third asm()'s.  It is these which force
'j' to be on the stack, not the memory clobber in the middle.

Observe that after commenting those two out, Clang transforms things to
spill 'i' onto the stack, rather than 'j', and then tail-call calc() on
the way out.  This is actually deleting the first calc() call, rather
than the second.

~Andrew

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.