[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220120211347.6gglputnh7n3wbvw@treble>
Date: Thu, 20 Jan 2022 13:13:47 -0800
From: Josh Poimboeuf <jpoimboe@...hat.com>
To: "Kirill A. Shutemov" <kirill@...temov.name>
Cc: bp@...en8.de, aarcange@...hat.com, ak@...ux.intel.com,
dan.j.williams@...el.com, dave.hansen@...el.com, david@...hat.com,
hpa@...or.com, jgross@...e.com, jmattson@...gle.com,
joro@...tes.org, kirill.shutemov@...ux.intel.com,
knsathya@...nel.org, linux-kernel@...r.kernel.org, luto@...nel.org,
mingo@...hat.com, pbonzini@...hat.com, peterz@...radead.org,
sathyanarayanan.kuppuswamy@...ux.intel.com, sdeep@...are.com,
seanjc@...gle.com, tglx@...utronix.de, tony.luck@...el.com,
vkuznets@...hat.com, wanpengli@...cent.com, x86@...nel.org
Subject: Re: [PATCH 2/3] x86/boot: Allow to hook up alternative port I/O
helpers
On Thu, Jan 20, 2022 at 07:38:26PM +0300, Kirill A. Shutemov wrote:
> On Thu, Jan 20, 2022 at 05:15:43AM +0300, Kirill A. Shutemov wrote:
> > diff --git a/arch/x86/boot/io.h b/arch/x86/boot/io.h
> > new file mode 100644
> > index 000000000000..640daa3925fb
> > --- /dev/null
> > +++ b/arch/x86/boot/io.h
> > @@ -0,0 +1,30 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef BOOT_IO_H
> > +#define BOOT_IO_H
> > +
> > +#include <asm/shared/io.h>
> > +
> > +struct port_io_ops {
> > + unsigned char (*inb)(int port);
> > + unsigned short (*inw)(int port);
> > + unsigned int (*inl)(int port);
> > + void (*outb)(unsigned char v, int port);
> > + void (*outw)(unsigned short v, int port);
> > + void (*outl)(unsigned int v, int port);
> > +};
> > +
> > +extern struct port_io_ops pio_ops;
> > +
> > +static inline void init_io_ops(void)
> > +{
> > + pio_ops = (struct port_io_ops){
> > + .inb = inb,
> > + .inw = inw,
> > + .inl = inl,
> > + .outb = outb,
> > + .outw = outw,
> > + .outl = outl,
> > + };
> > +}
> > +
> > +#endif
>
> It works fine on x86-64, but breaks on i386:
>
> ld: Unexpected run-time relocations (.rel) detected!
>
> I'll change it to
>
> pio_ops.inb = inb;
> pio_ops.inw = inw;
> pio_ops.inl = inl;
> pio_ops.outb = outb;
> pio_ops.outw = outw;
> pio_ops.outl = outl;
>
> It works, but I hate that I don't really have control here. I have no clue
> why compiler generate different code after the change. It is very fragile.
>
> Do we really have no way to say compiler to avoid relactions here?
This one:
pio_ops = (struct port_io_ops){
.inb = inb,
.inw = inw,
.inl = inl,
.outb = outb,
.outw = outw,
.outl = outl,
};
.. actually allocates an anonymous struct in the .data section, which is
memcpy'ed at runtime when the assignment occurs. That anonymous struct
has .data -> .text relocations which have to be resolved at runtime
because the distance between .data and .text isn't constant.
The working version:
pio_ops.inb = inb;
pio_ops.inw = inw;
pio_ops.inl = inl;
pio_ops.outb = outb;
pio_ops.outw = outw;
pio_ops.outl = outl;
... only needs .text -> .text relocations which can be resolved at link
time.
--
Josh
Powered by blists - more mailing lists