All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <ajones@ventanamicro.com>
To: Robbin Ehn <rehn@rivosinc.com>
Cc: qemu-devel@nongnu.org, laurent@vivier.eu, qemu-riscv@nongnu.org,
	 richard.henderson@linaro.org
Subject: Re: [RFC v2] linux-user/riscv: Add syscall riscv_hwprobe
Date: Fri, 2 Jun 2023 16:02:07 +0200	[thread overview]
Message-ID: <20230602-86a3d8d9fad1fb3464d28702@orel> (raw)
In-Reply-To: <f59f948fc42fdf0b250afd6dcd6f232013480d9c.camel@rivosinc.com>

On Fri, Jun 02, 2023 at 11:41:11AM +0200, Robbin Ehn wrote:
> This patch adds the new syscall for the
> "RISC-V Hardware Probing Interface"
> (https://docs.kernel.org/riscv/hwprobe.html).
> 
> Signed-off-by: Robbin Ehn <rehn@rivosinc.com>
> ---
> v1->v2: Moved to syscall.c
> ---
>  linux-user/riscv/syscall32_nr.h |   1 +
>  linux-user/riscv/syscall64_nr.h |   1 +
>  linux-user/syscall.c            | 109 ++++++++++++++++++++++++++++++++
>  3 files changed, 111 insertions(+)
> 
> diff --git a/linux-user/riscv/syscall32_nr.h b/linux-user/riscv/syscall32_nr.h
> index 1327d7dffa..412e58e5b2 100644
> --- a/linux-user/riscv/syscall32_nr.h
> +++ b/linux-user/riscv/syscall32_nr.h

This file should not be modified, it should be generated, but this is an
RFC, so hacking it is OK, but the hack should be in a separate patch.

> @@ -228,6 +228,7 @@
>  #define TARGET_NR_accept4 242
>  #define TARGET_NR_arch_specific_syscall 244
>  #define TARGET_NR_riscv_flush_icache (TARGET_NR_arch_specific_syscall + 15)
> +#define TARGET_NR_riscv_hwprobe (TARGET_NR_arch_specific_syscall + 14)
>  #define TARGET_NR_prlimit64 261
>  #define TARGET_NR_fanotify_init 262
>  #define TARGET_NR_fanotify_mark 263
> diff --git a/linux-user/riscv/syscall64_nr.h b/linux-user/riscv/syscall64_nr.h
> index 6659751933..29e1eb2075 100644
> --- a/linux-user/riscv/syscall64_nr.h
> +++ b/linux-user/riscv/syscall64_nr.h

Same

> @@ -251,6 +251,7 @@
>  #define TARGET_NR_recvmmsg 243
>  #define TARGET_NR_arch_specific_syscall 244
>  #define TARGET_NR_riscv_flush_icache (TARGET_NR_arch_specific_syscall + 15)
> +#define TARGET_NR_riscv_hwprobe (TARGET_NR_arch_specific_syscall + 14)
>  #define TARGET_NR_wait4 260
>  #define TARGET_NR_prlimit64 261
>  #define TARGET_NR_fanotify_init 262
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 89b58b386b..cd394bbe26 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8772,6 +8772,74 @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
>  }
>  #endif /* TARGET_NR_getdents64 */
>  
> +#if defined(TARGET_RISCV)
> +
> +#define RISCV_HWPROBE_KEY_MVENDORID     0
> +#define RISCV_HWPROBE_KEY_MARCHID       1
> +#define RISCV_HWPROBE_KEY_MIMPID        2
> +
> +#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
> +#define     RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
> +
> +#define RISCV_HWPROBE_KEY_IMA_EXT_0     4
> +#define     RISCV_HWPROBE_IMA_FD       (1 << 0)
> +#define     RISCV_HWPROBE_IMA_C        (1 << 1)
> +
> +#define RISCV_HWPROBE_KEY_CPUPERF_0     5
> +#define     RISCV_HWPROBE_MISALIGNED_UNKNOWN     (0 << 0)
> +#define     RISCV_HWPROBE_MISALIGNED_EMULATED    (1 << 0)
> +#define     RISCV_HWPROBE_MISALIGNED_SLOW        (2 << 0)
> +#define     RISCV_HWPROBE_MISALIGNED_FAST        (3 << 0)
> +#define     RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
> +#define     RISCV_HWPROBE_MISALIGNED_MASK        (7 << 0)
> +
> +struct riscv_hwprobe {
> +    int64_t  key;
> +    uint64_t value;
> +};

The above is all uapi so Linux's arch/riscv/include/uapi/asm/hwprobe.h
should be picked up on Linux header update. You'll need to modify the
script, scripts/update-linux-headers.sh, to do that by adding a new
riscv-specific block. Hacking this by importing the header file manually
is fine for an RFC, but that should be a separate patch or part of the
syscall define hack patch. And hack patches should be clearly tagged as
"NOT FOR MERGE".

> +
> +static void risc_hwprobe_fill_pairs(CPURISCVState *env,
> +                                    struct riscv_hwprobe *pair,
> +                                    size_t pair_count)
> +{
> +    const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
> +
> +    for (; pair_count > 0; pair_count--, pair++) {
> +        pair->value = 0;
> +        switch (pair->key) {
> +        case RISCV_HWPROBE_KEY_MVENDORID:
> +            pair->value = cfg->mvendorid;
> +            break;
> +        case RISCV_HWPROBE_KEY_MARCHID:
> +            pair->value = cfg->marchid;
> +            break;
> +        case RISCV_HWPROBE_KEY_MIMPID:
> +            pair->value = cfg->mimpid;
> +            break;
> +        case RISCV_HWPROBE_KEY_BASE_BEHAVIOR:
> +            pair->value = riscv_has_ext(env, RVI) &&
> +                          riscv_has_ext(env, RVM) &&
> +                          riscv_has_ext(env, RVA) ?
> +                          RISCV_HWPROBE_BASE_BEHAVIOR_IMA : 0;
> +            break;
> +        case RISCV_HWPROBE_KEY_IMA_EXT_0:
> +            pair->value = riscv_has_ext(env, RVF) &&
> +                          riscv_has_ext(env, RVD) ?
> +                          RISCV_HWPROBE_IMA_FD : 0;
> +            pair->value |= riscv_has_ext(env, RVC) ?
> +                           RISCV_HWPROBE_IMA_C : pair->value;
> +            break;
> +        case RISCV_HWPROBE_KEY_CPUPERF_0:
> +            pair->value = RISCV_HWPROBE_MISALIGNED_UNKNOWN;
> +            break;
> +        default:
> +            pair->key = -1;
> +        break;
> +        }
> +    }
> +}
> +#endif
> +
>  #if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root)
>  _syscall2(int, pivot_root, const char *, new_root, const char *, put_old)
>  #endif
> @@ -13469,6 +13537,47 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
>          return ret;
>  #endif
>  
> +#if defined(TARGET_RISCV)
> +    case TARGET_NR_riscv_hwprobe:
> +        {

The { goes under the c of case, which will shift all the below four spaces
left as well.

> +            struct riscv_hwprobe *host_pairs;
> +
> +            /* flags must be 0 */
> +            if (arg5 != 0) {
> +                return -TARGET_EINVAL;
> +            }
> +
> +            /* check cpu_set */
> +            if (arg3 != 0) {
> +                int ccpu;
> +                size_t cpu_setsize = CPU_ALLOC_SIZE(arg3);
> +                cpu_set_t *host_cpus = lock_user(VERIFY_READ, arg4,
> +                                                 cpu_setsize, 0);
> +                if (!host_cpus) {
> +                    return -TARGET_EFAULT;
> +                }
> +                ccpu = CPU_COUNT_S(cpu_setsize, host_cpus);
> +                unlock_user(host_cpus, arg4, cpu_setsize);
> +                /* no selected cpu */
> +                if (ccpu == 0) {
> +                    return -TARGET_EINVAL;
> +                }
> +            } else if (arg4 != 0) {
> +                return -TARGET_EINVAL;
> +            }

I think we want

 if (arg2 == 0)
    return 0;

here.

> +
> +            host_pairs = lock_user(VERIFY_WRITE, arg1,
> +                                   sizeof(*host_pairs) * (size_t)arg2, 0);
> +            if (host_pairs == NULL) {
> +                return -TARGET_EFAULT;
> +            }
> +            risc_hwprobe_fill_pairs(cpu_env, host_pairs, arg2);
> +            unlock_user(host_pairs, arg1, sizeof(*host_pairs) * (size_t)arg2);
> +            ret = 0;
> +        }
> +        return ret;
> +#endif
> +
>      default:
>          qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
>          return -TARGET_ENOSYS;
> -- 
> 2.39.2
> 
>

Otherwise this looks good to me.

Thanks,
drew


  reply	other threads:[~2023-06-02 14:02 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-02  9:41 [RFC v2] linux-user/riscv: Add syscall riscv_hwprobe Robbin Ehn
2023-06-02 14:02 ` Andrew Jones [this message]
2023-06-02 14:39   ` Robbin Ehn
2023-06-02 15:07     ` Andrew Jones
2023-06-03  3:00       ` Richard Henderson
2023-06-05 14:27         ` Robbin Ehn
2023-06-03  2:58   ` Richard Henderson
2023-06-03 15:50     ` Andrew Jones
2023-06-03 17:48       ` Richard Henderson
2023-06-03  2:57 ` Richard Henderson
2023-06-05 14:23   ` Robbin Ehn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230602-86a3d8d9fad1fb3464d28702@orel \
    --to=ajones@ventanamicro.com \
    --cc=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=rehn@rivosinc.com \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.