Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ILINK register is accessible from userspace #154

Open
kokas-a opened this issue Feb 23, 2023 · 2 comments · May be fixed by #209
Open

ILINK register is accessible from userspace #154

kokas-a opened this issue Feb 23, 2023 · 2 comments · May be fixed by #209
Labels
bug Something isn't working wontfix This will not be worked on

Comments

@kokas-a
Copy link

kokas-a commented Feb 23, 2023

Hi,

ARCv2 documentation contains the following: "The ILINK register is not accessible in user mode. Illegal accesses from user mode to ILINK raise a Privilege Violation exception". But QEMU allows ILINK access form user mode.

Examples are based on Zephyr.
The following is executed in userspace:

	uint32_t rd_ilink = 0;

	__asm__ volatile("mov %%[ilink], 0xaaaaaaaa\n"::);

	__asm__ volatile("mov %0, %%[ilink]\n": "=r"(rd_ilink) : );

	printf("Ilink was set in %s to 0x%x but we got no crashes\n",
	       k_is_user_context() ? "UserSpace!" : "privileged mode." , rd_ilink);

Expected behavior - raising exception

*** Booting Zephyr OS build v3.3.0-rc3-59-gf1b662ae17b5 ***
Hello World from UserSpace! (nsim)
E: ***** Exception vector: 0x7, cause code: 0x0, parameter 0x0
E: Address 0xe6
E: EV_PrivilegeV
E: Privilege violation
E:  r0: 0x1  r1: 0x2  r2: 0x600  r3: 0x857c
E:  r4: 0x0  r5: 0x0  r6: 0x176  r7: 0x0
E:  r8: 0x0  r9: 0x0 r10: 0x0 r11: 0x0
E: r12: 0x43 r13: 0x0  pc: 0xe6
E:  blink: 0xb6 status32: 0x80182282
E: lp_end: 0x0 lp_start: 0x0 lp_count: 0x0
E: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
E: Current thread: 0x80000000 (unknown)
E: Halting system

Current behavior - continuing execution

*** Booting Zephyr OS build v3.3.0-rc3-59-gf1b662ae17b5 ***
Hello World from UserSpace! (qemu_arc)
Ilink was set in UserSpace! to 0xaaaaaaaa but we got no crashes

How to reproduce

Download example and run it on recent version of qemu

qemu-system-arc -cpu archs -m 8M -nographic -no-reboot -monitor none -global cpu.firq=false -global cpu.num-irqlevels=15 -global cpu.num-irq=25 -global cpu.ext-irq=20 -global cpu.freq_hz=10000000 -global cpu.timer0=true -global cpu.timer1=true -global cpu.has-mpu=true -global cpu.mpu-numreg=16 -net none -pidfile qemu.pid -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -icount shift=6,align=off,sleep=off -rtc clock=vm -kernel <PATH_TO_ZEPHYR_ELF> 

Routine that contains example code with ILINK access is user_function()

zephyr_user_ilink.zip

@claziss claziss added the bug Something isn't working label Feb 23, 2023
@claziss claziss self-assigned this Feb 23, 2023
@shahab-vahedi
Copy link
Member

For what it's worth, auxiliary registers suffer the same. I re-iterate what has been submitted on a now-private repo:

At the moment, in user mode, most auxiliary registers are readable/writable;  while
according to PRM (section 4.2.3.2 Privileged Registers), only these should be accessible:

    PC
    STATS32
    LP_START
    LP_END

I consider this ...

The fix should look like this:

op_helper.c
-----------

target_ulong
arc_status_regs_get(const struct arc_aux_reg_detail *aux_reg_detail,
                    void *data)
{
    ...
    case AUX_ID_erstatus:
        if (is_user_mode(env)) {
            arc_raise_exception(env, GETPC(), EXCP_PRIVILEGEV);
        }
        reg = pack_status32(&env->stat_er);
        break;
    ...
}

@claziss claziss added the wontfix This will not be worked on label Jul 17, 2023
@shahab-vahedi
Copy link
Member

shahab-vahedi commented Jul 31, 2023

ilink is a GPR. In case of a GPR, every instructions that uses it, should take care of it. This requires adaptation to the decoder to insert the checking routine in place if one of the operands is ilink. By "checking routine" I mean the tcg code to check against status32.u, and raise an exception if indeed it is set. Something like seti and clri do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working wontfix This will not be worked on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants