public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* x86: asm doubt
@ 2009-03-15 14:16 Sergio Luis
  2009-03-15 16:41 ` Jeremy Fitzhardinge
  0 siblings, 1 reply; 5+ messages in thread
From: Sergio Luis @ 2009-03-15 14:16 UTC (permalink / raw)
  To: Ingo Molnar, Rafael J. Wysocki, Pavel Machek,
	Linux-kernel Mailing List

Hi there,

taking a look at arch/x86/power/cpu_(32|64).c, I saw the 32.c one
using the following macros

#define savesegment(seg, value)                         \
        asm("mov %%" #seg ",%0":"=r" (value) : : "memory")


#define loadsegment(seg, value)                 \
        asm volatile("\n"                       \
                     "1:\t"                     \
                     "movl %k0,%%" #seg "\n"    \
                     "2:\n"                     \
                     ".section .fixup,\"ax\"\n" \
                     "3:\t"                     \
                     "movl %k1, %%" #seg "\n\t" \
                     "jmp 2b\n"                 \
                     ".previous\n"              \
                     _ASM_EXTABLE(1b,3b)        \
                     : :"r" (value), "r" (0) : "memory")


saving and loading segment registers as in

savesegment(es, ctxt->es);
loadsegment(es, ctxt->es);

the code in cpu_64.c doesn't make use of such macros, doing the following:

saving:
 asm volatile ("movw %%es, %0" : "=m" (ctxt->es));

loading:
asm volatile ("movw %0, %%es" :: "r" (ctxt->es));

So, my question is... what's the actual difference between both
versions? Aren't the macros suitable for the 64 version as well?

Thanks,
Sergio.

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

* Re: x86: asm doubt
  2009-03-15 14:16 x86: asm doubt Sergio Luis
@ 2009-03-15 16:41 ` Jeremy Fitzhardinge
  2009-03-16 13:12   ` Sergio Luis
  2009-03-16 14:12   ` Avi Kivity
  0 siblings, 2 replies; 5+ messages in thread
From: Jeremy Fitzhardinge @ 2009-03-15 16:41 UTC (permalink / raw)
  To: Sergio Luis
  Cc: Ingo Molnar, Rafael J. Wysocki, Pavel Machek,
	Linux-kernel Mailing List

Sergio Luis wrote:
> Hi there,
>
> taking a look at arch/x86/power/cpu_(32|64).c, I saw the 32.c one
> using the following macros
>
> #define savesegment(seg, value)                         \
>         asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
>
>
> #define loadsegment(seg, value)                 \
>         asm volatile("\n"                       \
>                      "1:\t"                     \
>                      "movl %k0,%%" #seg "\n"    \
>                      "2:\n"                     \
>                      ".section .fixup,\"ax\"\n" \
>                      "3:\t"                     \
>                      "movl %k1, %%" #seg "\n\t" \
>                      "jmp 2b\n"                 \
>                      ".previous\n"              \
>                      _ASM_EXTABLE(1b,3b)        \
>                      : :"r" (value), "r" (0) : "memory")
>
>
> saving and loading segment registers as in
>
> savesegment(es, ctxt->es);
> loadsegment(es, ctxt->es);
>
> the code in cpu_64.c doesn't make use of such macros, doing the following:
>
> saving:
>  asm volatile ("movw %%es, %0" : "=m" (ctxt->es));
>
> loading:
> asm volatile ("movw %0, %%es" :: "r" (ctxt->es));
>
> So, my question is... what's the actual difference between both
> versions? Aren't the macros suitable for the 64 version as well?
>   

In 32-bit mode, moving to a segment register can fault if the underlying 
GDT/LDT entry is invalid.  In 64-bit mode, segment registers are mostly 
decorative and have no function, and moving arbitrary values into them 
doesn't fault, making the exception catching unnecessary.

But it would be good to use the same syntax to load segment registers 
for both architectures to help with unification.

    J

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

* Re: x86: asm doubt
  2009-03-15 16:41 ` Jeremy Fitzhardinge
@ 2009-03-16 13:12   ` Sergio Luis
  2009-03-16 14:12   ` Avi Kivity
  1 sibling, 0 replies; 5+ messages in thread
From: Sergio Luis @ 2009-03-16 13:12 UTC (permalink / raw)
  To: Jeremy Fitzhardinge
  Cc: Ingo Molnar, Rafael J. Wysocki, Pavel Machek,
	Linux-kernel Mailing List

On Sun, Mar 15, 2009 at 1:41 PM, Jeremy Fitzhardinge <jeremy@goop.org> wrote:
> Sergio Luis wrote:
>>
>> Hi there,
>>
>> taking a look at arch/x86/power/cpu_(32|64).c, I saw the 32.c one
>> using the following macros
>>
>> #define savesegment(seg, value)                         \
>>        asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
>>
>>
>> #define loadsegment(seg, value)                 \
>>        asm volatile("\n"                       \
>>                     "1:\t"                     \
>>                     "movl %k0,%%" #seg "\n"    \
>>                     "2:\n"                     \
>>                     ".section .fixup,\"ax\"\n" \
>>                     "3:\t"                     \
>>                     "movl %k1, %%" #seg "\n\t" \
>>                     "jmp 2b\n"                 \
>>                     ".previous\n"              \
>>                     _ASM_EXTABLE(1b,3b)        \
>>                     : :"r" (value), "r" (0) : "memory")
>>
>>
>> saving and loading segment registers as in
>>
>> savesegment(es, ctxt->es);
>> loadsegment(es, ctxt->es);
>>
>> the code in cpu_64.c doesn't make use of such macros, doing the following:
>>
>> saving:
>>  asm volatile ("movw %%es, %0" : "=m" (ctxt->es));
>>
>> loading:
>> asm volatile ("movw %0, %%es" :: "r" (ctxt->es));
>>
>> So, my question is... what's the actual difference between both
>> versions? Aren't the macros suitable for the 64 version as well?
>>
>
> In 32-bit mode, moving to a segment register can fault if the underlying
> GDT/LDT entry is invalid.  In 64-bit mode, segment registers are mostly
> decorative and have no function, and moving arbitrary values into them
> doesn't fault, making the exception catching unnecessary.
>
> But it would be good to use the same syntax to load segment registers for
> both architectures to help with unification.
>
>   J
>

Thanks for the explanation, Jeremy. So, maybe we could define those
same macros for X86_64 with something like the following? (sorry, it's
probably whitespace damaged since I am sending through this webmail
thing, but can you at least tell whether it's correct or not?)

diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 8e626ea..259b85e 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -262,6 +262,20 @@ static inline void native_write_cr8(unsigned long val)
 {
 	asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
 }
+
+/*
+ * In 64-bit mode, segment registers are mostly decorative
+ * and have no function, and moving arbitrary values into
+ * them doesn't fault, making the exception catching unnecessary.
+ */
+#define loadsegment(seg, value)			\
+	asm volatile ("movw %%" #seg ", %0" : "=r" (value) : : "memory");
+
+/*
+ * Save a segment register away
+ */
+#define savesegment(seg, value)			\
+	asm volatile ("movw %%" #seg ", %0" : "=m" (value) : : "memory");
 #endif

 static inline void native_wbinvd(void)

---

and a last unrelated question. why do we have a asm/system_64.h file
which defines only two functions read_cr8/write_cr8 that are exactly
identical to native_read_cr8/native_write_cr8 defined in system.h?

Thank you again,
Sergio.

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

* Re: x86: asm doubt
  2009-03-15 16:41 ` Jeremy Fitzhardinge
  2009-03-16 13:12   ` Sergio Luis
@ 2009-03-16 14:12   ` Avi Kivity
  2009-03-16 16:20     ` Jeremy Fitzhardinge
  1 sibling, 1 reply; 5+ messages in thread
From: Avi Kivity @ 2009-03-16 14:12 UTC (permalink / raw)
  To: Jeremy Fitzhardinge
  Cc: Sergio Luis, Ingo Molnar, Rafael J. Wysocki, Pavel Machek,
	Linux-kernel Mailing List

Jeremy Fitzhardinge wrote:
> In 32-bit mode, moving to a segment register can fault if the 
> underlying GDT/LDT entry is invalid.  In 64-bit mode, segment 
> registers are mostly decorative and have no function, and moving 
> arbitrary values into them doesn't fault, making the exception 
> catching unnecessary.

64-bit mode will in fact fault if an access is made outside the GDT/LDT, 
or of the descriptor is invalid.


-- 
error compiling committee.c: too many arguments to function


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

* Re: x86: asm doubt
  2009-03-16 14:12   ` Avi Kivity
@ 2009-03-16 16:20     ` Jeremy Fitzhardinge
  0 siblings, 0 replies; 5+ messages in thread
From: Jeremy Fitzhardinge @ 2009-03-16 16:20 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Sergio Luis, Ingo Molnar, Rafael J. Wysocki, Pavel Machek,
	Linux-kernel Mailing List

Avi Kivity wrote:
> Jeremy Fitzhardinge wrote:
>> In 32-bit mode, moving to a segment register can fault if the 
>> underlying GDT/LDT entry is invalid.  In 64-bit mode, segment 
>> registers are mostly decorative and have no function, and moving 
>> arbitrary values into them doesn't fault, making the exception 
>> catching unnecessary.
>
> 64-bit mode will in fact fault if an access is made outside the 
> GDT/LDT, or of the descriptor is invalid.

Oh, I didn't think it bothered.  I guess I'm conflating that with the 
fact that it doesn't apply any of the segment properties to memory 
accesses.  Anyway, in that case the 64-bit code should definitely be 
using the standard segment accessors.

    J


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

end of thread, other threads:[~2009-03-16 16:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-15 14:16 x86: asm doubt Sergio Luis
2009-03-15 16:41 ` Jeremy Fitzhardinge
2009-03-16 13:12   ` Sergio Luis
2009-03-16 14:12   ` Avi Kivity
2009-03-16 16:20     ` Jeremy Fitzhardinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox