9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] extern register
@ 2014-07-19  1:57 cinap_lenrek
  2014-07-19  2:04 ` erik quanstrom
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: cinap_lenrek @ 2014-07-19  1:57 UTC (permalink / raw)
  To: 9fans

the amd64 compiler reserves R14 and R15 for extern register
declarations. these are used by the kernel for the mach
and up pointers, but currently are not preserved during
system calls.

would it make sense to save and restore the two registers
on syscall entry/exit, so userspace programs could make use
of them for per process data?

--
cinap



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  1:57 [9fans] extern register cinap_lenrek
@ 2014-07-19  2:04 ` erik quanstrom
  2014-07-19  2:19   ` erik quanstrom
  2014-07-19  2:27   ` cinap_lenrek
  2014-07-19 12:29 ` Aram Hăvărneanu
  2014-07-19 12:42 ` Charles Forsyth
  2 siblings, 2 replies; 15+ messages in thread
From: erik quanstrom @ 2014-07-19  2:04 UTC (permalink / raw)
  To: 9fans

On Fri Jul 18 21:58:37 EDT 2014, cinap_lenrek@felloff.net wrote:
> the amd64 compiler reserves R14 and R15 for extern register
> declarations. these are used by the kernel for the mach
> and up pointers, but currently are not preserved during
> system calls.
>
> would it make sense to save and restore the two registers
> on syscall entry/exit, so userspace programs could make use
> of them for per process data?

i think after some experience (i.e. mistakes) the answer is probablly, no.

the compiler needs to know for the kernel that r14 and r15 are special and
not allocate them for the kernel, but what about userland?  what about libraries
that are shared between them? ....

one can work around these problems by compiling all libraries twice, etc.
but these are painful compromises.

in reality, there is only one place in the code that i know of that chews
through 15 or more registers, and that's the alpha drawing code in
libmemdraw.  so the solution of just limiting the compiler to r0-r13
seems to be pretty effective for what we're doing.

- erik



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  2:04 ` erik quanstrom
@ 2014-07-19  2:19   ` erik quanstrom
  2014-07-19  2:33     ` cinap_lenrek
  2014-07-19  2:27   ` cinap_lenrek
  1 sibling, 1 reply; 15+ messages in thread
From: erik quanstrom @ 2014-07-19  2:19 UTC (permalink / raw)
  To: 9fans

On Fri Jul 18 22:05:32 EDT 2014, quanstro@quanstro.net wrote:
> On Fri Jul 18 21:58:37 EDT 2014, cinap_lenrek@felloff.net wrote:
> > the amd64 compiler reserves R14 and R15 for extern register
> > declarations. these are used by the kernel for the mach
> > and up pointers, but currently are not preserved during
> > system calls.
> >
> > would it make sense to save and restore the two registers
> > on syscall entry/exit, so userspace programs could make use
> > of them for per process data?
>
> i think after some experience (i.e. mistakes) the answer is probablly, no.
>
> the compiler needs to know for the kernel that r14 and r15 are special and
> not allocate them for the kernel, but what about userland?  what about libraries
> that are shared between them? ....
>
> one can work around these problems by compiling all libraries twice, etc.
> but these are painful compromises.
>
> in reality, there is only one place in the code that i know of that chews
> through 15 or more registers, and that's the alpha drawing code in
> libmemdraw.  so the solution of just limiting the compiler to r0-r13
> seems to be pretty effective for what we're doing.

i realize i didn't quite answer the question as asked.  restoring
the registers is independent of the compiler.  so yes, you're right!  the registers
should be restored.  but at least you know why it's not a disaster that
they are not.

- erik



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  2:04 ` erik quanstrom
  2014-07-19  2:19   ` erik quanstrom
@ 2014-07-19  2:27   ` cinap_lenrek
  2014-07-19  2:41     ` erik quanstrom
  1 sibling, 1 reply; 15+ messages in thread
From: cinap_lenrek @ 2014-07-19  2:27 UTC (permalink / raw)
  To: 9fans

so, we say r14 and r15 arent really special for user programs. and its
just a c compiler implementation detail that it doesnt allocate these
registers, but assembly code can freely use them for scratch space
or whatever. extern register will not work in userspace c programs
because syscalls will trash these registers.

makes any sense?

--
cinap



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  2:19   ` erik quanstrom
@ 2014-07-19  2:33     ` cinap_lenrek
  2014-07-19  2:37       ` erik quanstrom
  0 siblings, 1 reply; 15+ messages in thread
From: cinap_lenrek @ 2014-07-19  2:33 UTC (permalink / raw)
  To: 9fans

isnt that contradicting what you just said?

--
cinap



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  2:33     ` cinap_lenrek
@ 2014-07-19  2:37       ` erik quanstrom
  0 siblings, 0 replies; 15+ messages in thread
From: erik quanstrom @ 2014-07-19  2:37 UTC (permalink / raw)
  To: 9fans

On Fri Jul 18 22:34:43 EDT 2014, cinap_lenrek@felloff.net wrote:
> isnt that contradicting what you just said?

i didn't think so.  restated: you could restore the registers, and that
would be right proper, but it wouldn't make a difference unless you're
using some fancy assembly, or a different compiler; it doesn't give the
compiler more freedom.

- erik



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  2:27   ` cinap_lenrek
@ 2014-07-19  2:41     ` erik quanstrom
  0 siblings, 0 replies; 15+ messages in thread
From: erik quanstrom @ 2014-07-19  2:41 UTC (permalink / raw)
  To: 9fans

On Fri Jul 18 22:28:12 EDT 2014, cinap_lenrek@felloff.net wrote:
> so, we say r14 and r15 arent really special for user programs. and its
> just a c compiler implementation detail that it doesnt allocate these
> registers, but assembly code can freely use them for scratch space
> or whatever. extern register will not work in userspace c programs
> because syscalls will trash these registers.
>
> makes any sense?

certainly.

speaking for myself, the model that r14 and r15 are off limits for
esoteric reasons is preferrable, given the quite limited maximum
benefit, to the complications of sneaking by the limitation.

obviously, the mips port avoided this by never needing >28 live
registers at once.

- erik



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  1:57 [9fans] extern register cinap_lenrek
  2014-07-19  2:04 ` erik quanstrom
@ 2014-07-19 12:29 ` Aram Hăvărneanu
  2014-07-19 12:42 ` Charles Forsyth
  2 siblings, 0 replies; 15+ messages in thread
From: Aram Hăvărneanu @ 2014-07-19 12:29 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

I don't have any opinion on whether R14 and R15 should be saved, but
the justification posted in the top post seems weak.

The stack is already per-process data. One can use _tos for per-proc
data, just like privalloc(2) does.

-- 
Aram Hăvărneanu



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19  1:57 [9fans] extern register cinap_lenrek
  2014-07-19  2:04 ` erik quanstrom
  2014-07-19 12:29 ` Aram Hăvărneanu
@ 2014-07-19 12:42 ` Charles Forsyth
  2014-07-19 14:38   ` Aram Hăvărneanu
  2014-07-20  1:42   ` cinap_lenrek
  2 siblings, 2 replies; 15+ messages in thread
From: Charles Forsyth @ 2014-07-19 12:42 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 666 bytes --]

On 19 July 2014 02:57, <cinap_lenrek@felloff.net> wrote:

> would it make sense to save and restore the two registers
> on syscall entry/exit, so userspace programs could make use
> of them for per process data?
>

Good question. None of the others need to be saved and restored because
they are defined to be dead on entry to a function,
but you're right that rule doesn't really apply to extern register, and
they could be useful. _tos only works when every process has
at least one stack always at the same fixed virtual address. On the other
hand, a kernel that provides an alternative to that would
also know to save and restore extern registers.

[-- Attachment #2: Type: text/html, Size: 1118 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19 12:42 ` Charles Forsyth
@ 2014-07-19 14:38   ` Aram Hăvărneanu
  2014-07-19 14:55     ` erik quanstrom
  2014-07-20  1:42   ` cinap_lenrek
  1 sibling, 1 reply; 15+ messages in thread
From: Aram Hăvărneanu @ 2014-07-19 14:38 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Sat, Jul 19, 2014 at 2:42 PM, Charles Forsyth
<charles.forsyth@gmail.com> wrote:
> _tos only works when every process has
> at least one stack always at the same fixed virtual address.

Isn't this always true?

-- 
Aram Hăvărneanu



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19 14:38   ` Aram Hăvărneanu
@ 2014-07-19 14:55     ` erik quanstrom
  2014-07-19 15:53       ` Aram Hăvărneanu
  0 siblings, 1 reply; 15+ messages in thread
From: erik quanstrom @ 2014-07-19 14:55 UTC (permalink / raw)
  To: 9fans

On Sat Jul 19 10:40:49 EDT 2014, aram.h@mgk.ro wrote:
> On Sat, Jul 19, 2014 at 2:42 PM, Charles Forsyth
> <charles.forsyth@gmail.com> wrote:
> > _tos only works when every process has
> > at least one stack always at the same fixed virtual address.
>
> Isn't this always true?

does anyone have a use case for extern register in user space?

come to think of it, extern register is defined to be one register
per mach, which is a bit of a stretch for user space.

- erik



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19 14:55     ` erik quanstrom
@ 2014-07-19 15:53       ` Aram Hăvărneanu
  0 siblings, 0 replies; 15+ messages in thread
From: Aram Hăvărneanu @ 2014-07-19 15:53 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Sat, Jul 19, 2014 at 4:55 PM, erik quanstrom <quanstro@quanstro.net> wrote:
> does anyone have a use case for extern register in user space?

Well Go uses it, but the meaning is different than in the Plan 9
kernel; they reused it for a different storage class.

In Go, there were two external register variables, g and m (now
there is only one for reasons outside the scope of this discussion).
These variables are proc-local as oposed to mach-local. To make a
streched analogy, a proc is to Go as a mach is to the kernel. Both
are some "entities" which can "run" other schedulable entities (Go
now has g's, m's, and p's, so the analogy no longer holds, but that
was the original meaning).

On arm, these variables are kept in registers on all operating
systems. On 386 and amd64, non-Plan 9 systems use a form of TLS to
keep these variables. TLS usually requires libc.so and ld.so
interaction (ugh), so since Go doesn't usually use these, it usually
executes some system call which sets up the base segment registers
to some heap-allocated memory, and then accesses this space using
the segment registers.

On systems which don't have these special system calls, the base
registers are usually initialized by the kernel/libc.so/ld.so with
enough space for some slots, so the access is the same, only without
initialization.

Plan 9 has no such nonsense; the stack is at a fixed, and known
address, so these variables can be kept on the stack. I recently
simplified this for the plan9/386 Go port and made the plan9/amd64
Go port use the same mechanism.

-- 
Aram Hăvărneanu



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-19 12:42 ` Charles Forsyth
  2014-07-19 14:38   ` Aram Hăvărneanu
@ 2014-07-20  1:42   ` cinap_lenrek
  2014-07-20 10:12     ` Aram Hăvărneanu
  1 sibling, 1 reply; 15+ messages in thread
From: cinap_lenrek @ 2014-07-20  1:42 UTC (permalink / raw)
  To: 9fans

ok, i preserve user R14 and R15 now. also removed the saving and restoring
of DS/ES/FS/GS segment registers... they have no effect in long mode and
there are no 32 bit tasks.

someone write a proof of concept program that communicates with another
process by morsing data on the segment registers by loading them with
NULLSEL and UDSEL :)

--
cinap



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-20  1:42   ` cinap_lenrek
@ 2014-07-20 10:12     ` Aram Hăvărneanu
  2014-07-20 16:35       ` cinap_lenrek
  0 siblings, 1 reply; 15+ messages in thread
From: Aram Hăvărneanu @ 2014-07-20 10:12 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Sun, Jul 20, 2014 at 3:42 AM,  <cinap_lenrek@felloff.net> wrote:
> removed the saving and restoring
> of DS/ES/FS/GS segment registers... they have no effect in long mode

Actually FS and GS do work in long mode. Since we don't need them for
TLS, maybe we can do something useful with them.

-- 
Aram Hăvărneanu



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [9fans] extern register
  2014-07-20 10:12     ` Aram Hăvărneanu
@ 2014-07-20 16:35       ` cinap_lenrek
  0 siblings, 0 replies; 15+ messages in thread
From: cinap_lenrek @ 2014-07-20 16:35 UTC (permalink / raw)
  To: 9fans

it doenst matter to runtime what data segment selectors have been
loaded in the segment registers in long mode. we initially load
them with null seletors and then never touch them again.

but the processor *does* check the selectors index when you load
a selector into a segment register!

the reason i removed the saving and restoring is that i can stop
worrying about bad data selectors when devproc or noted sets the ureg
of a process.

we had todo this on 386 because otherwise the process would #GP when
trying to restore the bad selectors. now without restoring the segment
registers, it cant #GP and nothing needs to be checked.

for GS/FS theres new GS_BASE and FS_BASE msr register that the kernel
can set to change GS and FS segment offsets affetcing the offset used
by GS and FS segment prefixes. but the kernel would need to switch
these msrs in and out for each process and provide a interface
for userspace to set ther base. you will need this for something
like linuxemu.

--
cinap



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-07-20 16:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-19  1:57 [9fans] extern register cinap_lenrek
2014-07-19  2:04 ` erik quanstrom
2014-07-19  2:19   ` erik quanstrom
2014-07-19  2:33     ` cinap_lenrek
2014-07-19  2:37       ` erik quanstrom
2014-07-19  2:27   ` cinap_lenrek
2014-07-19  2:41     ` erik quanstrom
2014-07-19 12:29 ` Aram Hăvărneanu
2014-07-19 12:42 ` Charles Forsyth
2014-07-19 14:38   ` Aram Hăvărneanu
2014-07-19 14:55     ` erik quanstrom
2014-07-19 15:53       ` Aram Hăvărneanu
2014-07-20  1:42   ` cinap_lenrek
2014-07-20 10:12     ` Aram Hăvărneanu
2014-07-20 16:35       ` cinap_lenrek

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).