Message ID | 20220201150545.1512822-14-guoren@kernel.org |
---|---|
State | New |
Headers | show |
Series | riscv: compat: Add COMPAT mode support for rv64 | expand |
On Tue, 01 Feb 2022 07:05:37 PST (-0800), guoren@kernel.org wrote: > From: Guo Ren <guoren@linux.alibaba.com> > > If the current task is in COMPAT mode, set SR_UXL_32 in status for > returning userspace. We need CONFIG _COMPAT to prevent compiling > errors with rv32 defconfig. > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > Signed-off-by: Guo Ren <guoren@kernel.org> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Palmer Dabbelt <palmer@dabbelt.com> > --- > arch/riscv/kernel/process.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c > index 03ac3aa611f5..1a666ad299b4 100644 > --- a/arch/riscv/kernel/process.c > +++ b/arch/riscv/kernel/process.c > @@ -97,6 +97,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc, > } > regs->epc = pc; > regs->sp = sp; > + > +#ifdef CONFIG_COMPAT > + if (is_compat_task()) > + regs->status |= SR_UXL_32; Not sure if I'm just misunderstanding the bit ops here, but aren't we trying to set the UXL field to 1 (for UXL=32)? That should be a bit field set op, not just an OR. > +#endif > } > > void flush_thread(void) Additionally: this isn't really an issue so much with this patch, but it does bring up that we're relying on someone else to have set UXL=64 on CONFIG_COMPAT=n systems. I don't see that in any spec anywhere, so we should really be setting UXL in Linux for all systems (ie, not just those with COMPAT=y).
On Wed, Feb 23, 2022 at 9:42 AM Palmer Dabbelt <palmer@dabbelt.com> wrote: > > On Tue, 01 Feb 2022 07:05:37 PST (-0800), guoren@kernel.org wrote: > > From: Guo Ren <guoren@linux.alibaba.com> > > > > If the current task is in COMPAT mode, set SR_UXL_32 in status for > > returning userspace. We need CONFIG _COMPAT to prevent compiling > > errors with rv32 defconfig. > > > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > > Signed-off-by: Guo Ren <guoren@kernel.org> > > Cc: Arnd Bergmann <arnd@arndb.de> > > Cc: Palmer Dabbelt <palmer@dabbelt.com> > > --- > > arch/riscv/kernel/process.c | 5 +++++ > > 1 file changed, 5 insertions(+) > > > > diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c > > index 03ac3aa611f5..1a666ad299b4 100644 > > --- a/arch/riscv/kernel/process.c > > +++ b/arch/riscv/kernel/process.c > > @@ -97,6 +97,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc, > > } > > regs->epc = pc; > > regs->sp = sp; > > + > > +#ifdef CONFIG_COMPAT > > + if (is_compat_task()) > > + regs->status |= SR_UXL_32; > > Not sure if I'm just misunderstanding the bit ops here, but aren't we > trying to set the UXL field to 1 (for UXL=32)? That should be a bit > field set op, not just an OR. You are right, I would modify like this: + if (is_compat_task()) + regs->status = (regs->status & ~SR_UXL) | SR_UXL_32; + else +. regs->status = (regs->status & ~SR_UXL) | SR_UXL_64; > > > +#endif > > } > > > > void flush_thread(void) > > Additionally: this isn't really an issue so much with this patch, but it > does bring up that we're relying on someone else to have set UXL=64 on > CONFIG_COMPAT=n systems. I don't see that in any spec anywhere, so we > should really be setting UXL in Linux for all systems (ie, not just those with > COMPAT=y).
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 03ac3aa611f5..1a666ad299b4 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -97,6 +97,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc, } regs->epc = pc; regs->sp = sp; + +#ifdef CONFIG_COMPAT + if (is_compat_task()) + regs->status |= SR_UXL_32; +#endif } void flush_thread(void)