2022-07-25 17:06:36

by Maxim Blinov

[permalink] [raw]
Subject: How to read RISC-V mcycle CSR from Linux userspace app?

Hi all, stupid question but I can't for the life of me figure this out
even with all the docs open.

I need to get an estimate figure for the cyclecount of a busy loop in
one of my small Linux userspace apps. The app in question is running
in qemu-system-riscv64. I've compiled QEMU myself, and the full code
is like this:

#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

uint64_t get_mcycle() {
uint64_t mcycle = 0;

asm volatile ("csrr %0,mcycle" : "=r" (mcycle) );

return mcycle;
}

int main(int argc, char **argv) {
printf("Hello\n");
printf("mcycle is %lu\n", get_mcycle());

return 0;
}

Now I get SIGILL when I hit the `csrr` insn, which makes sense.
According to the "Privileged Architecture Version 1.10", page 32, [1]
we need to set mcounteren, hcounteren, and scounteren low bits to 1 in
order to get the mcycle csr to become available in userspace. So I add
the following function:

void enable_mcount() {
/* Enable IR, TM, CY */
uint64_t mcounteren = 0x5;
asm volatile ("csrw mcounteren,%0" : "=r" (mcounteren));
asm volatile ("csrw hcounteren,%0" : "=r" (mcounteren));
asm volatile ("csrw scounteren,%0" : "=r" (mcounteren));
}

And call it before I call get_mcycle(), but this triggers SIGILL
(unsurprisingly) also, since these CSRs are also privileged. So
there's a bit of a chicken and egg problem.

Could someone more knowledgeable please suggest what the course of
action here is? I've got QEMU revision f45fd24c90 checked out, and I'm
staring at qemu/target/riscv/csr.c:71, which seems to deal with
whether or not to raise a SIGILL upon access. I can see a condition
for when we're in 'S' mode, but nothing for 'U' mode. Does that mean
there is fundamentally no access to these CSR's from 'U' mode? Is it
possible to just hack it in?

Maxim

[1]: https://riscv.org/wp-content/uploads/2017/05/riscv-privileged-v1.10.pdf


2022-07-26 01:37:06

by Bin Meng

[permalink] [raw]
Subject: Re: How to read RISC-V mcycle CSR from Linux userspace app?

On Tue, Jul 26, 2022 at 12:58 AM Maxim Blinov <[email protected]> wrote:
>
> Hi all, stupid question but I can't for the life of me figure this out
> even with all the docs open.
>
> I need to get an estimate figure for the cyclecount of a busy loop in
> one of my small Linux userspace apps. The app in question is running
> in qemu-system-riscv64. I've compiled QEMU myself, and the full code
> is like this:
>
> #include <unistd.h>
> #include <stdint.h>
> #include <stdlib.h>
> #include <stdio.h>
>
> uint64_t get_mcycle() {
> uint64_t mcycle = 0;
>
> asm volatile ("csrr %0,mcycle" : "=r" (mcycle) );

Change this to "csrr %0,cycle" and you should be able to run your program.

>
> return mcycle;
> }
>
> int main(int argc, char **argv) {
> printf("Hello\n");
> printf("mcycle is %lu\n", get_mcycle());
>
> return 0;
> }
>
> Now I get SIGILL when I hit the `csrr` insn, which makes sense.
> According to the "Privileged Architecture Version 1.10", page 32, [1]
> we need to set mcounteren, hcounteren, and scounteren low bits to 1 in
> order to get the mcycle csr to become available in userspace. So I add
> the following function:
>
> void enable_mcount() {
> /* Enable IR, TM, CY */
> uint64_t mcounteren = 0x5;
> asm volatile ("csrw mcounteren,%0" : "=r" (mcounteren));
> asm volatile ("csrw hcounteren,%0" : "=r" (mcounteren));
> asm volatile ("csrw scounteren,%0" : "=r" (mcounteren));
> }
>
> And call it before I call get_mcycle(), but this triggers SIGILL
> (unsurprisingly) also, since these CSRs are also privileged. So
> there's a bit of a chicken and egg problem.
>
> Could someone more knowledgeable please suggest what the course of
> action here is? I've got QEMU revision f45fd24c90 checked out, and I'm
> staring at qemu/target/riscv/csr.c:71, which seems to deal with
> whether or not to raise a SIGILL upon access. I can see a condition
> for when we're in 'S' mode, but nothing for 'U' mode. Does that mean
> there is fundamentally no access to these CSR's from 'U' mode? Is it
> possible to just hack it in?

In the user space, you can only read the U-mode CSRs like cycle, but NOT mcycle.

>
> Maxim
>
> [1]: https://riscv.org/wp-content/uploads/2017/05/riscv-privileged-v1.10.pdf
>

Regards,
Bin