2004-11-02 08:56:00

by Jin, Gordon

[permalink] [raw]
Subject: [PATCH x86_64]: Setup PER_LINUX32 on x86_64

On x86_64, PER_LINUX32 is not setup but used by syscall personality and uname.
This patch sets PER_LINUX32 when x86 binary loaded so it can be used correctly.
- Set personality to PER_LINUX32 when x86 binary loaded.
- Set personality to PER_LINUX when x86_64 binary loaded.
- Use sys32_personality instead of sys_personality.
- Add sys32_newuname() for syscall newuname.
- Remove the unnecessary check for PER_LINUX32 in sys_uname().

Signed-off-by: Gordon Jin <[email protected]>

Index: linux-2.6.9/arch/x86_64/kernel/process.c
===================================================================
--- linux-2.6.9/arch/x86_64/kernel/process.c (revision 1)
+++ linux-2.6.9/arch/x86_64/kernel/process.c (revision 3)
@@ -550,7 +550,7 @@ long sys_execve(char __user *name, char

void set_personality_64bit(void)
{
- /* inherit personality from parent */
+ set_personality(PER_LINUX);

/* Make sure to be in 64bit mode */
clear_thread_flag(TIF_IA32);
Index: linux-2.6.9/arch/x86_64/kernel/sys_x86_64.c
===================================================================
--- linux-2.6.9/arch/x86_64/kernel/sys_x86_64.c (revision 1)
+++ linux-2.6.9/arch/x86_64/kernel/sys_x86_64.c (revision 3)
@@ -148,8 +148,6 @@ asmlinkage long sys_uname(struct new_uts
down_read(&uts_sem);
err = copy_to_user(name, &system_utsname, sizeof (*name));
up_read(&uts_sem);
- if (personality(current->personality) == PER_LINUX32)
- err |= copy_to_user(&name->machine, "i686", 5);
return err ? -EFAULT : 0;
}

Index: linux-2.6.9/arch/x86_64/ia32/ia32entry.S
===================================================================
--- linux-2.6.9/arch/x86_64/ia32/ia32entry.S (revision 1)
+++ linux-2.6.9/arch/x86_64/ia32/ia32entry.S (revision 3)
@@ -424,7 +424,7 @@ ia32_sys_call_table:
.quad stub32_sigreturn
.quad stub32_clone /* 120 */
.quad sys_setdomainname
- .quad sys_uname
+ .quad sys32_newuname
.quad sys_modify_ldt
.quad sys32_adjtimex
.quad sys32_mprotect /* 125 */
@@ -438,7 +438,7 @@ ia32_sys_call_table:
.quad sys_fchdir
.quad quiet_ni_syscall /* bdflush */
.quad sys_sysfs /* 135 */
- .quad sys_personality
+ .quad sys32_personality
.quad quiet_ni_syscall /* for afs_syscall */
.quad sys_setfsuid16
.quad sys_setfsgid16
Index: linux-2.6.9/arch/x86_64/ia32/ia32_aout.c
===================================================================
--- linux-2.6.9/arch/x86_64/ia32/ia32_aout.c (revision 1)
+++ linux-2.6.9/arch/x86_64/ia32/ia32_aout.c (revision 3)
@@ -297,7 +297,7 @@ static int load_aout_binary(struct linux
regs->r13 = regs->r14 = regs->r15 = 0;

/* OK, This is the point of no return */
- set_personality(PER_LINUX);
+ set_personality(PER_LINUX32);
set_thread_flag(TIF_IA32);
clear_thread_flag(TIF_ABI_PENDING);

Index: linux-2.6.9/arch/x86_64/ia32/sys_ia32.c
===================================================================
--- linux-2.6.9/arch/x86_64/ia32/sys_ia32.c (revision 1)
+++ linux-2.6.9/arch/x86_64/ia32/sys_ia32.c (revision 3)
@@ -1103,6 +1103,16 @@ long sys32_uname(struct old_utsname __us
return err?-EFAULT:0;
}

+asmlinkage long sys32_newuname (struct new_utsname __user *name)
+{
+ int ret = sys_newuname(name);
+
+ if (!ret)
+ if (copy_to_user(name->machine, "i686", 5))
+ ret = -EFAULT;
+ return ret;
+}
+
long sys32_ustat(unsigned dev, struct ustat32 __user *u32p)
{
struct ustat u;
Index: linux-2.6.9/arch/x86_64/ia32/ia32_binfmt.c
===================================================================
--- linux-2.6.9/arch/x86_64/ia32/ia32_binfmt.c (revision 1)
+++ linux-2.6.9/arch/x86_64/ia32/ia32_binfmt.c (revision 3)
@@ -254,8 +254,10 @@ elf_core_copy_task_xfpregs(struct task_s
#define SET_PERSONALITY(ex, ibcs2) \
do { \
unsigned long new_flags = 0; \
- if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
+ set_personality(PER_LINUX32); \
new_flags = _TIF_IA32; \
+ } \
if ((current_thread_info()->flags & _TIF_IA32) \
!= new_flags) \
set_thread_flag(TIF_ABI_PENDING); \

Thanks,
Gordon


2004-11-02 10:02:17

by Jin, Gordon

[permalink] [raw]
Subject: RE: [PATCH x86_64]: Setup PER_LINUX32 on x86_64

Jin, Gordon <> wrote on Tuesday, November 02, 2004 4:48 PM:

> On x86_64, PER_LINUX32 is not setup but used by syscall personality
> and uname. This patch sets PER_LINUX32 when x86 binary loaded so it
> can be used correctly.
> - Set personality to PER_LINUX32 when x86 binary loaded.
> - Set personality to PER_LINUX when x86_64 binary loaded.
> - Use sys32_personality instead of sys_personality.
> - Add sys32_newuname() for syscall newuname.
> - Remove the unnecessary check for PER_LINUX32 in sys_uname().
>
A side question is:
To distinguish 32-bit and native 64-bit app on x86-64(and some other archs),
somewhere PER_LINUX32 is used, while somewhere TIF_IA32 is used.
So both of them need maintained, respectively in task_struct and thread_info.
Is it redundant? Can we do away TIF_IA32?

Thanks,
Gordon

2004-11-02 14:09:32

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH x86_64]: Setup PER_LINUX32 on x86_64

"Jin, Gordon" <[email protected]> writes:

> On x86_64, PER_LINUX32 is not setup but used by syscall personality and uname.
> This patch sets PER_LINUX32 when x86 binary loaded so it can be used correctly.
> - Set personality to PER_LINUX32 when x86 binary loaded.
> - Set personality to PER_LINUX when x86_64 binary loaded.
> - Use sys32_personality instead of sys_personality.
> - Add sys32_newuname() for syscall newuname.
> - Remove the unnecessary check for PER_LINUX32 in sys_uname().

Rejected. This was separated intentionally. Otherwise
e.g. you can never get x86_64 out of uname with a 32bit uname.

-Andi


2004-11-10 09:55:48

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [discuss] [PATCH x86_64]: Setup PER_LINUX32 on x86_64

On Dinsdag 02 November 2004 09:47, Jin, Gordon wrote:
> On x86_64, PER_LINUX32 is not setup but used by syscall personality and uname.
> This patch sets PER_LINUX32 when x86 binary loaded so it can be used correctly.
> - Set personality to PER_LINUX32 when x86 binary loaded.
> - Set personality to PER_LINUX when x86_64 binary loaded.
> - Use sys32_personality instead of sys_personality.
> - Add sys32_newuname() for syscall newuname.
> - Remove the unnecessary check for PER_LINUX32 in sys_uname().

That behavior would be significantly different from the current one,
which is also used on all other biarch architectures. This probably
breaks lots of user setups.

I also think the current behavior is the right one. For things like
configure, you need a way to set the uname independent of the binary
format of your shell. Another example is building rpm packages
on a mixed system, where should be able to set the personality
to decide which target architecture to build for.

Arnd <><



Attachments:
(No filename) (995.00 B)
(No filename) (189.00 B)
signature
Download all attachments