Re: Re: [PATCH] linux-user/i386: Properly align signal frame

2023-05-25 Thread fanwj--- via

"The beginning of the structure, with pretaddr, should be just below 16-byte 
alignment."

It is incorrect! The beginning of the structure, with pretaddr not aligned as 
16-byte!
On x86-64, It aligned as (16n - sizeof(void*)) because of instruction "call" !





> -原始邮件-
> 发件人: "Richard Henderson" 
> 发送时间: 2023-05-24 13:50:43 (星期三)
> 收件人: qemu-devel@nongnu.org
> 抄送: fa...@mail.ustc.edu.cn, laur...@vivier.eu
> 主题: Re: [PATCH] linux-user/i386: Properly align signal frame
> 
> On 5/23/23 22:46, Richard Henderson wrote:
> > The beginning of the structure, with pretaddr, should be just below
> > 16-byte alignment.  Disconnect fpstate from sigframe, just like the
> > kernel does.
> > 
> > Signed-off-by: Richard Henderson 
> > ---
> >   linux-user/i386/signal.c | 104 +--
> >   tests/tcg/x86_64/sigstack.c  |  33 ++
> >   tests/tcg/x86_64/Makefile.target |   1 +
> >   3 files changed, 90 insertions(+), 48 deletions(-)
> >   create mode 100644 tests/tcg/x86_64/sigstack.c
> 
> Oops, meant to add
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1648
> 
> r~
> 
> > 
> > diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c
> > index 60fa07d6f9..c49467de78 100644
> > --- a/linux-user/i386/signal.c
> > +++ b/linux-user/i386/signal.c
> > @@ -191,16 +191,7 @@ struct sigframe {
> >   struct target_fpstate fpstate_unused;
> >   abi_ulong extramask[TARGET_NSIG_WORDS-1];
> >   char retcode[8];
> > -
> > -/*
> > - * This field will be 16-byte aligned in memory.  Applying QEMU_ALIGNED
> > - * to it ensures that the base of the frame has an appropriate 
> > alignment
> > - * too.
> > - */
> > -struct target_fpstate fpstate QEMU_ALIGNED(8);
> >   };
> > -#define TARGET_SIGFRAME_FXSAVE_OFFSET (
> > \
> > -offsetof(struct sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
> >   
> >   struct rt_sigframe {
> >   abi_ulong pretcode;
> > @@ -210,27 +201,21 @@ struct rt_sigframe {
> >   struct target_siginfo info;
> >   struct target_ucontext uc;
> >   char retcode[8];
> > -struct target_fpstate fpstate QEMU_ALIGNED(8);
> >   };
> > -#define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( 
> > \
> > -offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
> >   #else
> > -
> >   struct rt_sigframe {
> >   abi_ulong pretcode;
> >   struct target_ucontext uc;
> >   struct target_siginfo info;
> > -struct target_fpstate fpstate QEMU_ALIGNED(16);
> >   };
> > -#define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( 
> > \
> > -offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
> >   #endif
> >   
> >   /*
> >* Set up a signal frame.
> >*/
> >   
> > -static void xsave_sigcontext(CPUX86State *env, struct 
> > target_fpstate_fxsave *fxsave,
> > +static void xsave_sigcontext(CPUX86State *env,
> > + struct target_fpstate_fxsave *fxsave,
> >abi_ulong fxsave_addr)
> >   {
> >   if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
> > @@ -266,8 +251,9 @@ static void xsave_sigcontext(CPUX86State *env, struct 
> > target_fpstate_fxsave *fxs
> >   }
> >   
> >   static void setup_sigcontext(struct target_sigcontext *sc,
> > -struct target_fpstate *fpstate, CPUX86State *env, abi_ulong mask,
> > -abi_ulong fpstate_addr)
> > + struct target_fpstate *fpstate,
> > + CPUX86State *env, abi_ulong mask,
> > + abi_ulong fpstate_addr)
> >   {
> >   CPUState *cs = env_cpu(env);
> >   #ifndef TARGET_X86_64
> > @@ -347,10 +333,11 @@ static void setup_sigcontext(struct target_sigcontext 
> > *sc,
> >* Determine which stack to use..
> >*/
> >   
> > -static inline abi_ulong
> > -get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t 
> > fxsave_offset)
> > +static abi_ulong get_sigframe(struct target_sigaction *ka, CPUX86State 
> > *env,
> > +  size_t *frame_size, abi_ulong *fpsave_addr)
> >   {
> > -unsigned long esp;
> > +abi_ulong esp, orig;
> > +size_t fpsave_size;
> >   
> >   /* Default to using normal stack */
> >   esp = get_sp_from_cpustate(env);
> > @@ -371,16 +358,23 @@ get_sigframe(struct target_sigaction *ka, CPUX86State 
> > *env, size_t fxsave_offset
> >   }
> >   #endif
> >   }
> > +orig = esp;
> >   
> > -if (!(env->features[FEAT_1_EDX] & CPUID_FXSR)) {
> > -return (esp - (fxsave_offset + TARGET_FXSAVE_SIZE)) & -8ul;
> > -} else if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
> > -return ((esp - TARGET_FXSAVE_SIZE) & -16ul) - fxsave_offset;
> > +if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
> > +fpsave_size = TARGET_FXSAVE_SIZE;
> > +esp = ROUND_DOWN(esp - fpsave_size, 

[PATCH] linux-user: fix incorrect alignment of pretcode

2023-05-12 Thread fanwj
sigframe::pretcode & rt_sigframe::pretcode must align of 16n-sizeof(void*) 
instead of 16n, Because rsp align of 16n before instruction "call" in caller, 
After "call", push address of "call" in caller. sp of begin in callee is 
16n-sizeof(void*)

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1648
Signed-off-by: Fan WenJie 

---
 linux-user/i386/signal.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c
index 60fa07d6f9c..1f019689ae7 100644
--- a/linux-user/i386/signal.c
+++ b/linux-user/i386/signal.c
@@ -197,7 +197,8 @@ struct sigframe {
  * to it ensures that the base of the frame has an appropriate alignment
  * too.
  */
-struct target_fpstate fpstate QEMU_ALIGNED(8);
+abi_ulong unused QEMU_ALIGNED(8);
+struct target_fpstate fpstate;
 };
 #define TARGET_SIGFRAME_FXSAVE_OFFSET (\
 offsetof(struct sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
@@ -210,7 +211,8 @@ struct rt_sigframe {
 struct target_siginfo info;
 struct target_ucontext uc;
 char retcode[8];
-struct target_fpstate fpstate QEMU_ALIGNED(8);
+abi_ulong unused QEMU_ALIGNED(8);
+struct target_fpstate fpstate;
 };
 #define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \
 offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
@@ -220,7 +222,8 @@ struct rt_sigframe {
 abi_ulong pretcode;
 struct target_ucontext uc;
 struct target_siginfo info;
-struct target_fpstate fpstate QEMU_ALIGNED(16);
+abi_ulong unused QEMU_ALIGNED(16);
+struct target_fpstate fpstate;
 };
 #define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \
 offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
-- 
2.40.1




Wine CE 8.5 Released, Cross Architecture Windows Emulator, Support Wow64, Base on wine and qemu

2023-04-03 Thread fanwj--- via
Wine CE is a compatibility layer capable of running Windows applications on 
Cross-architecture paltform of Linux, It base on wine and qemu, and support 
aarch64 and riscv64 Linux. It can emulate x86(32bit) x64, aarch64 windows app.

Project Address: https://gitlab.com/wine-ce/wine-ce
Binary Downnload: https://gitlab.com/wine-ce/wine-ce/-/releases/v8.5


Demo Video:
RISCV 64: https://www.bilibili.com/video/BV1gv4y1578t
AARCH 64: https://www.bilibili.com/video/BV1yc41157iS

[PATCH] linux-user: fix bug about incorrect base addresss of gdt on i386 and x86_64

2023-02-08 Thread fanwj
On linux user mode, CPUX86State::gdt::base from Different CPUX86State Objects 
have same value, It is incorrect! Every CPUX86State::gdt::base Must points to 
independent memory space. 

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1405
Signed-off-by: fanwenjie 
---
 linux-user/i386/cpu_loop.c | 9 +
 linux-user/main.c  | 7 +++
 2 files changed, 16 insertions(+)

diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index 865413c..48511cd 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -314,8 +314,17 @@ void cpu_loop(CPUX86State *env)
 }
 }
 
+static void target_cpu_free(void *obj)
+{
+CPUArchState* env = ((CPUState*)obj)->env_ptr;
+target_munmap(env->gdt.base, sizeof(uint64_t) * TARGET_GDT_ENTRIES);
+g_free(obj);
+}
+
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
+CPUState* cpu = env_cpu(env);
+OBJECT(cpu)->free = target_cpu_free;
 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
 env->hflags |= HF_PE_MASK | HF_CPL_MASK;
 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
diff --git a/linux-user/main.c b/linux-user/main.c
index a17fed0..3acd9b4 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -234,6 +234,13 @@ CPUArchState *cpu_copy(CPUArchState *env)
 
 new_cpu->tcg_cflags = cpu->tcg_cflags;
 memcpy(new_env, env, sizeof(CPUArchState));
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+new_env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+PROT_READ|PROT_WRITE,
+MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+memcpy((void*)g2h_untagged(new_env->gdt.base), 
(void*)g2h_untagged(env->gdt.base), sizeof(uint64_t) * TARGET_GDT_ENTRIES);
+OBJECT(new_cpu)->free = OBJECT(cpu)->free;
+#endif
 
 /* Clone all break/watchpoints.
Note: Once we support ptrace with hw-debug register access, make sure
-- 
2.34.1





Re: Re: Please review a important patch abort fix setting of CPUX86State::gdt::base

2023-01-30 Thread fanwj--- via

1. "The memcpy is definitely wrong, because you're casting a guest address into 
a host address, which is incorrect. You have to use g2h()."
There is no need to use g2h(), Because there are both guest address whether 
source or dest memory. refer to "linux-user/i386/cpu_loop.c" 
target_cpu_copy_regs function, Only use g2h_untagged when convert gdt::base to 
gdt_table. I don't use and modify gdt_table, Only copy gdt::base from source 
CPU to dest CPU. They are same type so no needed to convert by g2h.

2. "I'm actually surprised that you need this for TARGET_X86_64 at all ..."
GDT on QEMU User Mode is Pseudorandom GDT,It is NOT kernel private data 
structures. It is NOT Global Descriptor Table. It IS index table of fs and gs. 
And It is Thread local data. The Memory which gdt::base point can be modified 
by syscall SYS_set_thread_data.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/tls.c

SYS_get_thread_area and SYS_set_thread_area used on x32 usually, But They can 
be syscalled on x64 when emulate Wow64 environment. 





-
From:   Richard Henderson
Subject:Re: [PATCH] linux-user: fix bug about incorrect base addresss 
of gdt on i386 and x86_64
Date:   Sat, 14 Jan 2023 19:32:59 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 
Thunderbird/102.4.2
> On 1/3/23 01:38, fanwenjie wrote:
On linux user mode, CPUX86State::gdt::base from Different CPUX86State Objects 
have same value, It is incorrect! Every CPUX86State::gdt::base Must points to 
independent memory space.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1405
Signed-off-by: fanwenjie 
---
  linux-user/i386/cpu_loop.c | 9 +
  linux-user/main.c  | 7 +++
  2 files changed, 16 insertions(+)

diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index 865413c..48511cd 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -314,8 +314,17 @@ void cpu_loop(CPUX86State *env)
  }
  }
+static void target_cpu_free(void *obj)
+{
+CPUArchState* env = ((CPUState*)obj)->env_ptr;
+target_munmap(env->gdt.base, sizeof(uint64_t) * TARGET_GDT_ENTRIES);
+g_free(obj);
+}
+
  void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
  {
+CPUState* cpu = env_cpu(env);
+OBJECT(cpu)->free = target_cpu_free;
  env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
  env->hflags |= HF_PE_MASK | HF_CPL_MASK;
  if (env->features[FEAT_1_EDX] & CPUID_SSE) {
diff --git a/linux-user/main.c b/linux-user/main.c
index a17fed0..3acd9b4 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -234,6 +234,13 @@ CPUArchState *cpu_copy(CPUArchState *env)
new_cpu->tcg_cflags = cpu->tcg_cflags;
  memcpy(new_env, env, sizeof(CPUArchState));
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+new_env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+PROT_READ|PROT_WRITE,
+MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+memcpy((void*)new_env->gdt.base, (void*)env->gdt.base, sizeof(uint64_t) * 
TARGET_GDT_ENTRIES);
+OBJECT(new_cpu)->free = OBJECT(cpu)->free;
+#endif

This isn't a fantastic solution, because neither the ldt nor the gdt should be 
mapped into the user address space -- these are kernel private data structures. 
But cpu.h uses a target_ulong, and seg_helper.c is set up to load data from the 
guest, and it would be a medium sized job to address that.

The memcpy is definitely wrong, because you're casting a guest address into a 
host address, which is incorrect. You have to use g2h().

I'm actually surprised that you need this for TARGET_X86_64 at all -- the two 
TLS segments don't really use the GDT at all, since fs_base and gs_base may be 
set directly.


Please review a important patch abort fix setting of CPUX86State::gdt::base

2023-01-29 Thread fanwj
The patch fix bug abort settting CPUX86State::gdt::base on linux-user, the bug 
can write dirty data to emulated segment registers of x86

Patch address:  
https://lists.nongnu.org/archive/html/qemu-devel/2023-01/msg00142.html
Bug description: https://gitlab.com/qemu-project/qemu/-/issues/1405




Because this bug has been fixed, Wine-CE Project can be succeeded, Wine-CE is a 
compatibility layer capable of running Windows applications on 
Cross-architecture paltform of Linux. It is base on Wine Project and Qemu 
Project.


Project Address: https://gitlab.com/wine-ce/wine-ce

[PATCH] linux-user: fix bug about incorrect base addresss of idt and gdt on i386 and x86_64

2023-01-02 Thread fanwj
On linux user mode, CPUX86State::idt::base and CPUX86State::gdt::base from 
Different CPUX86State Objects have same value, It is incorrect! Every 
CPUX86State::idt::base and Every CPUX86State::gdt::base Must points to 
independent memory space. Resolves: 
https://gitlab.com/qemu-project/qemu/-/issues/1405 Signed-off-by: fanwenjie --- 
linux-user/i386/cpu_loop.c | 10 ++ linux-user/main.c | 11 +++ 2 
files changed, 21 insertions(+) diff --git a/linux-user/i386/cpu_loop.c 
b/linux-user/i386/cpu_loop.c index 865413c08f..1f23bc5e3a 100644 --- 
a/linux-user/i386/cpu_loop.c +++ b/linux-user/i386/cpu_loop.c @@ -314,8 +314,18 
@@ void cpu_loop(CPUX86State *env) } } +static void target_cpu_free(void *obj) 
+{ + CPUArchState* env = ((CPUState*)obj)->env_ptr; + 
target_munmap(env->idt.base, sizeof(uint64_t) * (env->idt.limit + 1)); + 
target_munmap(env->gdt.base, sizeof(uint64_t) * TARGET_GDT_ENTRIES); + 
g_free(obj); +} + void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs) { + CPUState* cpu = env_cpu(env); + OBJECT(cpu)->free = 
target_cpu_free; env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; 
env->hflags |= HF_PE_MASK | HF_CPL_MASK; if (env->features[FEAT_1_EDX] & 
CPUID_SSE) { diff --git a/linux-user/main.c b/linux-user/main.c index 
a17fed045b..2276040548 100644 --- a/linux-user/main.c +++ b/linux-user/main.c 
@@ -234,6 +234,17 @@ CPUArchState *cpu_copy(CPUArchState *env) 
new_cpu->tcg_cflags = cpu->tcg_cflags; memcpy(new_env, env, 
sizeof(CPUArchState)); +#if defined(TARGET_I386) || defined(TARGET_X86_64) + 
new_env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES, + 
PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + new_env->idt.base 
= target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1), + 
PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + 
memcpy((void*)new_env->gdt.base, (void*)env->gdt.base, sizeof(uint64_t) * 
TARGET_GDT_ENTRIES); + memcpy((void*)new_env->idt.base, (void*)env->idt.base, 
sizeof(uint64_t) * (env->idt.limit + 1)); + OBJECT(new_cpu)->free = 
OBJECT(cpu)->free; +#endif /* Clone all break/watchpoints. Note: Once we 
support ptrace with hw-debug register access, make sure -- 2.34.1

[PATCH] linux-user: fix bug about incorrect base addresss of idt and gdt on i386 and x86_64

2023-01-01 Thread fanwj
From: fanwenjie 


On linux user mode, CPUX86State::idt::base and CPUX86State::gdt::base from 
Different CPUX86State Objects have same value, It is incorrect! Every 
CPUX86State::idt::base and Every CPUX86State::gdt::base Must points to 
independent memory space.  


Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1405
Signed-off-by: fanwenjie 


---
 linux-user/i386/cpu_loop.c | 10 ++
 linux-user/main.c  | 11 +++
 2 files changed, 21 insertions(+)


diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index 865413c08f..1f23bc5e3a 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -314,8 +314,18 @@ void cpu_loop(CPUX86State *env)
 }
 }
 
+static void target_cpu_free(void *obj)
+{
+CPUArchState* env = ((CPUState*)obj)->env_ptr;
+target_munmap(env->idt.base, sizeof(uint64_t) * (env->idt.limit + 1));
+target_munmap(env->gdt.base, sizeof(uint64_t) * TARGET_GDT_ENTRIES);
+g_free(obj);
+}
+
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
+CPUState* cpu = env_cpu(env);
+OBJECT(cpu)->free = target_cpu_free;
 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
 env->hflags |= HF_PE_MASK | HF_CPL_MASK;
 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
diff --git a/linux-user/main.c b/linux-user/main.c
index a17fed045b..2276040548 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -234,6 +234,17 @@ CPUArchState *cpu_copy(CPUArchState *env)
 
 new_cpu->tcg_cflags = cpu->tcg_cflags;
 memcpy(new_env, env, sizeof(CPUArchState));
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+new_env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+PROT_READ|PROT_WRITE,
+MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+new_env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
+PROT_READ|PROT_WRITE,
+MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+memcpy((void*)new_env->gdt.base, (void*)env->gdt.base, sizeof(uint64_t) * 
TARGET_GDT_ENTRIES);
+memcpy((void*)new_env->idt.base, (void*)env->idt.base, sizeof(uint64_t) * 
(env->idt.limit + 1));
+OBJECT(new_cpu)->free = OBJECT(cpu)->free;
+#endif
 
 /* Clone all break/watchpoints.
Note: Once we support ptrace with hw-debug register access, make sure
-- 
2.34.1





Recall: [PATCH] linux-user: fix bug about incorrect base addresss of idt and gdt on i386 and x86_64

2023-01-01 Thread fanwj
The Patch has some problem, Please RECALL it!


-原始邮件-
发件人:fa...@mail.ustc.edu.cn
发送时间:2023-01-01 23:57:06 (星期日)
收件人: qemu-devel@nongnu.org
抄送: qemu-devel@nongnu.org
主题: [PATCH] linux-user: fix bug about incorrect base addresss of idt and gdt on 
i386 and x86_64


From 4601a624f40b2c89e7df2dec1adffb4f4308ba2d Mon Sep 17 00:00:00 2001
From: fanwenjie 
Date: Sun, 1 Jan 2023 23:13:34 +0800
Subject: [PATCH] linux-user: fix bug about incorrect base addresss of idt and
 gdt on i386 and x86_64


Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1405
Signed-off-by: fanwenjie 
---
 linux-user/main.c | 13 +
 1 file changed, 13 insertions(+)


diff --git a/linux-user/main.c b/linux-user/main.c
index a17fed045b..5d673c95b3 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -171,6 +171,12 @@ void fork_end(int child)
 
 __thread CPUState *thread_cpu;
 
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+#include 
+__thread alignas(TARGET_PAGE_SIZE) static uint64_t 
gdt_base[TARGET_GDT_ENTRIES];
+__thread alignas(TARGET_PAGE_SIZE) static uint64_t idt_base[TARGET_PAGE_SIZE / 
sizeof(uint64_t)];
+#endif
+
 bool qemu_cpu_is_self(CPUState *cpu)
 {
 return thread_cpu == cpu;
@@ -235,6 +241,13 @@ CPUArchState *cpu_copy(CPUArchState *env)
 new_cpu->tcg_cflags = cpu->tcg_cflags;
 memcpy(new_env, env, sizeof(CPUArchState));
 
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+memcpy(idt_base, (void*)new_env->idt.base, sizeof(uint64_t) * 
(new_env->idt.limit + 1));
+memcpy(gdt_base, (void*)new_env->gdt.base, sizeof(uint64_t) * 
TARGET_GDT_ENTRIES);
+new_env->idt.base = (target_ulong)idt_base;
+new_env->gdt.base = (target_ulong)gdt_base;
+#endif
+
 /* Clone all break/watchpoints.
Note: Once we support ptrace with hw-debug register access, make sure
BP_CPU break/watchpoints are handled correctly on clone. */
-- 
2.34.1



[PATCH] linux-user: fix bug about incorrect base addresss of idt and gdt on i386 and x86_64

2023-01-01 Thread fanwj
From 4601a624f40b2c89e7df2dec1adffb4f4308ba2d Mon Sep 17 00:00:00 2001
From: fanwenjie 
Date: Sun, 1 Jan 2023 23:13:34 +0800
Subject: [PATCH] linux-user: fix bug about incorrect base addresss of idt and
 gdt on i386 and x86_64


Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1405
Signed-off-by: fanwenjie 
---
 linux-user/main.c | 13 +
 1 file changed, 13 insertions(+)


diff --git a/linux-user/main.c b/linux-user/main.c
index a17fed045b..5d673c95b3 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -171,6 +171,12 @@ void fork_end(int child)
 
 __thread CPUState *thread_cpu;
 
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+#include 
+__thread alignas(TARGET_PAGE_SIZE) static uint64_t 
gdt_base[TARGET_GDT_ENTRIES];
+__thread alignas(TARGET_PAGE_SIZE) static uint64_t idt_base[TARGET_PAGE_SIZE / 
sizeof(uint64_t)];
+#endif
+
 bool qemu_cpu_is_self(CPUState *cpu)
 {
 return thread_cpu == cpu;
@@ -235,6 +241,13 @@ CPUArchState *cpu_copy(CPUArchState *env)
 new_cpu->tcg_cflags = cpu->tcg_cflags;
 memcpy(new_env, env, sizeof(CPUArchState));
 
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+memcpy(idt_base, (void*)new_env->idt.base, sizeof(uint64_t) * 
(new_env->idt.limit + 1));
+memcpy(gdt_base, (void*)new_env->gdt.base, sizeof(uint64_t) * 
TARGET_GDT_ENTRIES);
+new_env->idt.base = (target_ulong)idt_base;
+new_env->gdt.base = (target_ulong)gdt_base;
+#endif
+
 /* Clone all break/watchpoints.
Note: Once we support ptrace with hw-debug register access, make sure
BP_CPU break/watchpoints are handled correctly on clone. */
-- 
2.34.1



[PATCH] linux-user: fix bug about missing signum convert of sigqueue

2022-08-30 Thread fanwj
From 4ebe8a67ed7c4b1220957b2b67a62ba60e0e80ec Mon Sep 17 00:00:00 2001
From: fanwenjie 
Date: Wed, 31 Aug 2022 11:55:25 +0800
Subject: [PATCH] linux-user: fix bug about missing signum convert of sigqueue


Signed-off-by: fanwenjie 
---
 linux-user/syscall.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)


diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f409121202..3e5ab4f0b2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9690,7 +9690,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 }
 target_to_host_siginfo(, p);
 unlock_user(p, arg3, 0);
-ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, ));
+ret = get_errno(sys_rt_sigqueueinfo(arg1, 
target_to_host_signal(arg2), ));
 }
 return ret;
 case TARGET_NR_rt_tgsigqueueinfo:
@@ -9703,7 +9703,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 }
 target_to_host_siginfo(, p);
 unlock_user(p, arg4, 0);
-ret = get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, arg3, ));
+ret = get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, 
target_to_host_signal(arg3), ));
 }
 return ret;
 #ifdef TARGET_NR_sigreturn
--