xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: David Woodhouse <dwmw2@infradead.org>
To: Jan Beulich <jbeulich@suse.com>
Cc: xen-devel <xen-devel@lists.xenproject.org>,
	"Roger Pau Monné" <roger.pau@citrix.com>, "Wei Liu" <wl@xen.org>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>
Subject: Re: [Xen-devel] [PATCH v2 6/6] x86/boot: Do not use trampoline for no-real-mode boot paths
Date: Mon, 19 Aug 2019 17:25:30 +0200	[thread overview]
Message-ID: <a2143ee639599afb848e168d0f741c5130f7a241.camel@infradead.org> (raw)
In-Reply-To: <5f867a0d-036f-9800-5347-7c4d109cce47@suse.com>


[-- Attachment #1.1: Type: text/plain, Size: 7923 bytes --]

On Mon, 2019-08-12 at 12:55 +0200, Jan Beulich wrote:
> On 09.08.2019 17:02, David Woodhouse wrote:
> > From: David Woodhouse <dwmw@amazon.co.uk>
> > 
> > Where booted from EFI or with no-real-mode, there is no need to stomp
> > on low memory with the 16-boot code. Instead, just go straight to
> > trampoline_protmode_entry() at its physical location within the Xen
> > image.
> > 
> > For now, the boot code (including the EFI loader path) still determines
> > what the trampoline_phys address should be. The trampoline is actually
> > relocated for that address and copied into low memory, from a
> > relocate_trampoline() call made from __start_xen().
> 
> I assume this talks about the real mode part of the trampoline, as
> opposed to the next paragraph? Would be nice if you made this
> explicit.

This is the permanent real-mode trampoline used for AP startup and
wakeup, not the real-mode boot code (which the boot code has to have
put there for itself it it wanted it).

I will try to make the commit message clearer; thanks for pointing it
out.

> > For subsequent AP startup and wakeup, the 32-bit trampoline can't
> > trivially be used in-place as that region isn't mapped. So copy it
> > down to low memory too, having relocated it (again) to work from
> > there.
> 
> trampoline_protmode_entry gets entered with CR0.PG=0, i.e. at
> that point there's not even the question yet of there being a
> mapping. Subsequently idle_pg_table gets loaded into CR3. I wonder
> if, rather than relocating the 32-bit part of the trampoline, it
> wouldn't be better to install a 1:1 mapping into idle_pg_table.
> Such a mapping would need to have the G bits clear in order to
> not conflict with PV guest mappings of the same linear addresses.

Yeah, I tried making that happen. It made me sad. This seemed to be
simpler and less fragile.

> > --- a/xen/arch/x86/acpi/power.c
> > +++ b/xen/arch/x86/acpi/power.c
> > @@ -152,9 +152,9 @@ static void acpi_sleep_prepare(u32 state)
> >           return;
> >   
> >       if ( acpi_sinfo.vector_width == 32 )
> > -        *(uint32_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
> > +        *(uint32_t *)wakeup_vector_va = trampsym_phys(wakeup_start);
> >       else
> > -        *(uint64_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
> > +        *(uint64_t *)wakeup_vector_va = trampsym_phys(wakeup_start);
> >   }
> >   
> >   static void acpi_sleep_post(u32 state) {}
> > @@ -388,7 +388,7 @@ static void tboot_sleep(u8 sleep_state)
> >       g_tboot_shared->acpi_sinfo.wakeup_vector = acpi_sinfo.wakeup_vector;
> >       g_tboot_shared->acpi_sinfo.vector_width = acpi_sinfo.vector_width;
> >       g_tboot_shared->acpi_sinfo.kernel_s3_resume_vector =
> > -                                              bootsym_phys(wakeup_start);
> > +                                              trampsym_phys(wakeup_start);
> 
> Shouldn't changes like these have happened earlier, when you
> introduce the (logical only at that point) distinction between
> trampoline pieces?

That was in assembler code. This is C, which never had to be that
involved with the distinction. But now that all the dust has settled,
I'm making it consistent, using 'trampsym' for stuff in the permanent
trampoline just like the asm code does.


> > @@ -97,7 +100,7 @@ GLOBAL(trampoline_realmode_entry)
> >          cld
> >          cli
> >          lidt    trampsym(idt_48)
> > -        lgdt    trampsym(gdt_48)
> > +        lgdtl   trampsym(gdt_48)
> 
> Stray / unrelated change (and if needed, then also for lidt)?

The difference between 16bit l.dt and 32-bit l.dtl is that the former
only loads 24 bits of the actual table address (trampoline_gdt in this
case).

Thus, when trampoline_gdt is being used in-place, as it is during early
boot, and *if* the Xen image is loaded higher than 16MiB, lgdt doesn't
work. That's half a day of my life I want back.

It doesn't matter for lidt because we're just loading an empty limit
and pointer there, and we don't care about bits 24-31 of a zero value.

> > @@ -236,11 +239,23 @@ gdt_48: .word   7*8-1
> >   
> >   /* The first page of trampoline is permanent, the rest boot-time only. */
> >   /* Reuse the boot trampoline on the 1st trampoline page as stack for wakeup. */
> > -        .equ    wakeup_stack, boot_trampoline_start + PAGE_SIZE
> > +        .equ    wakeup_stack, perm_trampoline_start + PAGE_SIZE
> >           .global wakeup_stack
> >   
> > +ENTRY(perm_trampoline_end)
> > +
> >   /* From here on early boot only. */
> >   
> > +ENTRY(boot_trampoline_start)
> > +
> > +        .word   0
> > +boot16_idt:
> > +        .word   0, 0, 0 # base = limit = 0
> > +        .word   0
> > +boot16_gdt:
> > +        .word   7*8-1
> > +        .long   tramp32sym_rel(trampoline_gdt,4)
> 
> Can we really not get away without a second copy of these?

Probably, but my judgement was that the complexity and the pain of
doing so would exceed the benefit. I'll take another look at doing so.

> > @@ -304,8 +319,8 @@ trampoline_boot_cpu_entry:
> >           cli
> >   
> >           /* Reset GDT and IDT. Some BIOSes clobber GDTR. */
> > -        lidt    bootsym(idt_48)
> > -        lgdt    bootsym(gdt_48)
> > +        lidt    bootsym(boot16_idt)
> > +        lgdtl   bootsym(boot16_gdt)
> 
> As above - either both should gain a suffix, or neither of them.
> 
> > --- a/xen/arch/x86/setup.c
> > +++ b/xen/arch/x86/setup.c
> > @@ -682,6 +682,42 @@ static unsigned int __init copy_bios_e820(struct e820entry *map, unsigned int li
> >       return n;
> >   }
> >   
> > +extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
> > +extern const s32 __trampoline32_rel_start[], __trampoline32_rel_stop[];
> > +
> > +static void __init relocate_trampoline(unsigned long phys)
> > +{
> > +    const s32 *trampoline_ptr;
> > +    uint32_t tramp32_delta = 0;
> > +
> > +    /* Apply relocations to trampoline. */
> > +    for ( trampoline_ptr = __trampoline_rel_start;
> > +          trampoline_ptr < __trampoline_rel_stop;
> > +          ++trampoline_ptr )
> > +        *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
> > +
> > +    tramp32_delta = phys;
> 
> Any reason this can't be the initializer of the variable, or the
> zero initializer above can't be dropped?

I can't think of one. I think I quite like the initial setting of
tramp32_delta=phys to live *right* above the subsequent if(something)
tramp32_delta-=something, to make it very clear what that calculation
is.

So maybe I'll just drop the pointless =0 initialiser.

> > +    if (!efi_enabled(EFI_LOADER)) {
> 
> Style (missing blanks inside the parentheses, and brace to go on
> its own line).

Ack. You can take the Linux hacker out of the Linux kernel but...

> > --- a/xen/include/asm-x86/config.h
> > +++ b/xen/include/asm-x86/config.h
> > @@ -89,12 +89,12 @@
> >  
> >  #ifndef __ASSEMBLY__
> >  extern unsigned long trampoline_phys;
> > -#define bootsym_phys(sym)                                 \
> > -    (((unsigned long)&(sym)-(unsigned long)&boot_trampoline_start)+trampoline_phys)
> > -#define bootsym(sym)                                      \
> > +#define trampsym_phys(sym)                                 \
> > +    (((unsigned long)&(sym)-(unsigned long)&perm_trampoline_start)+trampoline_phys)
> > +#define trampsym(sym)                                      \
> >      (*RELOC_HIDE((typeof(&(sym)))__va(__pa(&(sym))),      \
> > -                 trampoline_phys-__pa(boot_trampoline_start)))
> > -extern char boot_trampoline_start[], boot_trampoline_end[];
> > +                 trampoline_phys-__pa(perm_trampoline_start)))
> 
> As you're touching these, could you please also insert the missing
> blanks around the binary + and - ?

Will do. Thanks.


[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5174 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2019-08-19 15:26 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1565362089.git.dwmw@amazon.co.uk>
2019-08-09 15:01 ` [Xen-devel] [PATCH v2 1/6] x86/boot: Remove gratuitous call back into low-memory code David Woodhouse
2019-08-09 15:01 ` [Xen-devel] [PATCH v2 2/6] x86/boot: Only jump into low trampoline code for real-mode boot David Woodhouse
2019-08-12  9:10   ` Jan Beulich
2019-08-21 14:04     ` David Woodhouse
2019-08-27  8:43       ` Jan Beulich
2019-08-09 15:01 ` [Xen-devel] [PATCH v2 3/6] x86/boot: Split bootsym() into four types of relocations David Woodhouse
2019-08-12  9:41   ` Jan Beulich
2019-08-19 15:24     ` David Woodhouse
2019-08-09 15:02 ` [Xen-devel] [PATCH v2 4/6] x86/boot: Rename trampoline_{start, end} to boot_trampoline_{start, end} David Woodhouse
2019-08-12  9:55   ` Jan Beulich
2019-08-19 15:24     ` David Woodhouse
2019-08-27  8:51       ` Jan Beulich
2019-08-27  9:31         ` David Woodhouse
2019-08-09 15:02 ` [Xen-devel] [PATCH v2 5/6] x86/boot: Copy 16-bit boot variables back up to Xen image David Woodhouse
2019-08-12 10:24   ` Jan Beulich
2019-08-19 15:25     ` David Woodhouse
2019-08-27  8:59       ` Jan Beulich
2019-08-27  9:19         ` David Woodhouse
2019-08-09 15:02 ` [Xen-devel] [PATCH v2 6/6] x86/boot: Do not use trampoline for no-real-mode boot paths David Woodhouse
2019-08-12 10:55   ` Jan Beulich
2019-08-19 15:25     ` David Woodhouse [this message]
2019-08-27  9:07       ` Jan Beulich
2019-08-27  9:12         ` David Woodhouse

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=a2143ee639599afb848e168d0f741c5130f7a241.camel@infradead.org \
    --to=dwmw2@infradead.org \
    --cc=andrew.cooper3@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=roger.pau@citrix.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).