All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-arm@nongnu.org
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-arm] [PATCH 11/13] target/arm/arm-semi: Implement support for semihosting feature detection
Date: Thu, 12 Sep 2019 12:56:05 +0100	[thread overview]
Message-ID: <87blvpzq22.fsf@linaro.org> (raw)
In-Reply-To: <20190910144428.32597-12-peter.maydell@linaro.org>


Peter Maydell <peter.maydell@linaro.org> writes:

> Version 2.0 of the semihosting specification added support for
> allowing a guest to detect whether the implementation supported
> particular features. This works by the guest opening a magic
> file ":semihosting-features", which contains a fixed set of
> data with some magic numbers followed by a sequence of bytes
> with feature flags. The file is expected to behave sensibly
> for the various semihosting calls which operate on files
> (SYS_FLEN, SYS_SEEK, etc).
>
> Implement this as another kind of guest FD using our function
> table dispatch mechanism. Initially we report no extended
> features, so we have just one feature flag byte which is zero.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

with your EACCESS suggestion:

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  target/arm/arm-semi.c | 107 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 106 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
> index f9019b00b8d..531084b7799 100644
> --- a/target/arm/arm-semi.c
> +++ b/target/arm/arm-semi.c
> @@ -117,6 +117,7 @@ typedef enum GuestFDType {
>      GuestFDUnused = 0,
>      GuestFDHost = 1,
>      GuestFDGDB = 2,
> +    GuestFDFeatureFile = 3,
>  } GuestFDType;
>
>  /*
> @@ -125,7 +126,10 @@ typedef enum GuestFDType {
>   */
>  typedef struct GuestFD {
>      GuestFDType type;
> -    int hostfd;
> +    union {
> +        int hostfd;
> +        target_ulong featurefile_offset;
> +    };
>  } GuestFD;
>
>  static GArray *guestfd_array;
> @@ -467,6 +471,87 @@ static uint32_t gdb_flenfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
>                             gf->hostfd, arm_flen_buf(cpu));
>  }
>
> +#define SHFB_MAGIC_0 0x53
> +#define SHFB_MAGIC_1 0x48
> +#define SHFB_MAGIC_2 0x46
> +#define SHFB_MAGIC_3 0x42
> +
> +static const uint8_t featurefile_data[] = {
> +    SHFB_MAGIC_0,
> +    SHFB_MAGIC_1,
> +    SHFB_MAGIC_2,
> +    SHFB_MAGIC_3,
> +    0, /* Feature byte 0 */
> +};
> +
> +static void init_featurefile_guestfd(int guestfd)
> +{
> +    GuestFD *gf = do_get_guestfd(guestfd);
> +
> +    assert(gf);
> +    gf->type = GuestFDFeatureFile;
> +    gf->featurefile_offset = 0;
> +}
> +
> +static uint32_t featurefile_closefn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
> +{
> +    /* Nothing to do */
> +    return 0;
> +}
> +
> +static uint32_t featurefile_writefn(TaskState *ts, ARMCPU *cpu, GuestFD *gf,
> +                                    target_ulong buf, uint32_t len)
> +{
> +    /* This fd can never be open for writing */
> +    errno = EBADF;
> +    return set_swi_errno(ts, -1);
> +}
> +
> +static uint32_t featurefile_readfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf,
> +                                   target_ulong buf, uint32_t len)
> +{
> +    uint32_t i;
> +#ifndef CONFIG_USER_ONLY
> +    CPUARMState *env = &cpu->env;
> +#endif
> +    char *s;
> +
> +    s = lock_user(VERIFY_WRITE, buf, len, 0);
> +    if (!s) {
> +        return len;
> +    }
> +
> +    for (i = 0; i < len; i++) {
> +        if (gf->featurefile_offset >= sizeof(featurefile_data)) {
> +            break;
> +        }
> +        s[i] = featurefile_data[gf->featurefile_offset];
> +        gf->featurefile_offset++;
> +    }
> +
> +    unlock_user(s, buf, len);
> +
> +    /* Return number of bytes not read */
> +    return len - i;
> +}
> +
> +static uint32_t featurefile_isattyfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
> +{
> +    return 0;
> +}
> +
> +static uint32_t featurefile_seekfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf,
> +                                   target_ulong offset)
> +{
> +    gf->featurefile_offset = offset;
> +    return 0;
> +}
> +
> +static uint32_t featurefile_flenfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
> +{
> +    return sizeof(featurefile_data);
> +}
> +
>  typedef struct GuestFDFunctions {
>      sys_closefn *closefn;
>      sys_writefn *writefn;
> @@ -493,6 +578,14 @@ static const GuestFDFunctions guestfd_fns[] = {
>          .seekfn = gdb_seekfn,
>          .flenfn = gdb_flenfn,
>      },
> +    [GuestFDFeatureFile] = {
> +        .closefn = featurefile_closefn,
> +        .writefn = featurefile_writefn,
> +        .readfn = featurefile_readfn,
> +        .isattyfn = featurefile_isattyfn,
> +        .seekfn = featurefile_seekfn,
> +        .flenfn = featurefile_flenfn,
> +    },
>  };
>
>  /* Read the input value from the argument block; fail the semihosting
> @@ -586,6 +679,18 @@ target_ulong do_arm_semihosting(CPUARMState *env)
>              unlock_user(s, arg0, 0);
>              return guestfd;
>          }
> +        if (strcmp(s, ":semihosting-features") == 0) {
> +            unlock_user(s, arg0, 0);
> +            /* We must fail opens for modes other than 0 ('r') or 1 ('rb') */
> +            if (arg1 != 0 && arg1 != 1) {
> +                dealloc_guestfd(guestfd);
> +                errno = EINVAL;
> +                return set_swi_errno(ts, -1);
> +            }
> +            init_featurefile_guestfd(guestfd);
> +            return guestfd;
> +        }
> +
>          if (use_gdb_syscalls()) {
>              ret = arm_gdb_syscall(cpu, arm_semi_cb, "open,%s,%x,1a4", arg0,
>                                    (int)arg2+1, gdb_open_modeflags[arg1]);


--
Alex Bennée

WARNING: multiple messages have this Message-ID (diff)
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-arm@nongnu.org
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [Qemu-arm] [PATCH 11/13] target/arm/arm-semi: Implement support for semihosting feature detection
Date: Thu, 12 Sep 2019 12:56:05 +0100	[thread overview]
Message-ID: <87blvpzq22.fsf@linaro.org> (raw)
In-Reply-To: <20190910144428.32597-12-peter.maydell@linaro.org>


Peter Maydell <peter.maydell@linaro.org> writes:

> Version 2.0 of the semihosting specification added support for
> allowing a guest to detect whether the implementation supported
> particular features. This works by the guest opening a magic
> file ":semihosting-features", which contains a fixed set of
> data with some magic numbers followed by a sequence of bytes
> with feature flags. The file is expected to behave sensibly
> for the various semihosting calls which operate on files
> (SYS_FLEN, SYS_SEEK, etc).
>
> Implement this as another kind of guest FD using our function
> table dispatch mechanism. Initially we report no extended
> features, so we have just one feature flag byte which is zero.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

with your EACCESS suggestion:

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  target/arm/arm-semi.c | 107 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 106 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
> index f9019b00b8d..531084b7799 100644
> --- a/target/arm/arm-semi.c
> +++ b/target/arm/arm-semi.c
> @@ -117,6 +117,7 @@ typedef enum GuestFDType {
>      GuestFDUnused = 0,
>      GuestFDHost = 1,
>      GuestFDGDB = 2,
> +    GuestFDFeatureFile = 3,
>  } GuestFDType;
>
>  /*
> @@ -125,7 +126,10 @@ typedef enum GuestFDType {
>   */
>  typedef struct GuestFD {
>      GuestFDType type;
> -    int hostfd;
> +    union {
> +        int hostfd;
> +        target_ulong featurefile_offset;
> +    };
>  } GuestFD;
>
>  static GArray *guestfd_array;
> @@ -467,6 +471,87 @@ static uint32_t gdb_flenfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
>                             gf->hostfd, arm_flen_buf(cpu));
>  }
>
> +#define SHFB_MAGIC_0 0x53
> +#define SHFB_MAGIC_1 0x48
> +#define SHFB_MAGIC_2 0x46
> +#define SHFB_MAGIC_3 0x42
> +
> +static const uint8_t featurefile_data[] = {
> +    SHFB_MAGIC_0,
> +    SHFB_MAGIC_1,
> +    SHFB_MAGIC_2,
> +    SHFB_MAGIC_3,
> +    0, /* Feature byte 0 */
> +};
> +
> +static void init_featurefile_guestfd(int guestfd)
> +{
> +    GuestFD *gf = do_get_guestfd(guestfd);
> +
> +    assert(gf);
> +    gf->type = GuestFDFeatureFile;
> +    gf->featurefile_offset = 0;
> +}
> +
> +static uint32_t featurefile_closefn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
> +{
> +    /* Nothing to do */
> +    return 0;
> +}
> +
> +static uint32_t featurefile_writefn(TaskState *ts, ARMCPU *cpu, GuestFD *gf,
> +                                    target_ulong buf, uint32_t len)
> +{
> +    /* This fd can never be open for writing */
> +    errno = EBADF;
> +    return set_swi_errno(ts, -1);
> +}
> +
> +static uint32_t featurefile_readfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf,
> +                                   target_ulong buf, uint32_t len)
> +{
> +    uint32_t i;
> +#ifndef CONFIG_USER_ONLY
> +    CPUARMState *env = &cpu->env;
> +#endif
> +    char *s;
> +
> +    s = lock_user(VERIFY_WRITE, buf, len, 0);
> +    if (!s) {
> +        return len;
> +    }
> +
> +    for (i = 0; i < len; i++) {
> +        if (gf->featurefile_offset >= sizeof(featurefile_data)) {
> +            break;
> +        }
> +        s[i] = featurefile_data[gf->featurefile_offset];
> +        gf->featurefile_offset++;
> +    }
> +
> +    unlock_user(s, buf, len);
> +
> +    /* Return number of bytes not read */
> +    return len - i;
> +}
> +
> +static uint32_t featurefile_isattyfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
> +{
> +    return 0;
> +}
> +
> +static uint32_t featurefile_seekfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf,
> +                                   target_ulong offset)
> +{
> +    gf->featurefile_offset = offset;
> +    return 0;
> +}
> +
> +static uint32_t featurefile_flenfn(TaskState *ts, ARMCPU *cpu, GuestFD *gf)
> +{
> +    return sizeof(featurefile_data);
> +}
> +
>  typedef struct GuestFDFunctions {
>      sys_closefn *closefn;
>      sys_writefn *writefn;
> @@ -493,6 +578,14 @@ static const GuestFDFunctions guestfd_fns[] = {
>          .seekfn = gdb_seekfn,
>          .flenfn = gdb_flenfn,
>      },
> +    [GuestFDFeatureFile] = {
> +        .closefn = featurefile_closefn,
> +        .writefn = featurefile_writefn,
> +        .readfn = featurefile_readfn,
> +        .isattyfn = featurefile_isattyfn,
> +        .seekfn = featurefile_seekfn,
> +        .flenfn = featurefile_flenfn,
> +    },
>  };
>
>  /* Read the input value from the argument block; fail the semihosting
> @@ -586,6 +679,18 @@ target_ulong do_arm_semihosting(CPUARMState *env)
>              unlock_user(s, arg0, 0);
>              return guestfd;
>          }
> +        if (strcmp(s, ":semihosting-features") == 0) {
> +            unlock_user(s, arg0, 0);
> +            /* We must fail opens for modes other than 0 ('r') or 1 ('rb') */
> +            if (arg1 != 0 && arg1 != 1) {
> +                dealloc_guestfd(guestfd);
> +                errno = EINVAL;
> +                return set_swi_errno(ts, -1);
> +            }
> +            init_featurefile_guestfd(guestfd);
> +            return guestfd;
> +        }
> +
>          if (use_gdb_syscalls()) {
>              ret = arm_gdb_syscall(cpu, arm_semi_cb, "open,%s,%x,1a4", arg0,
>                                    (int)arg2+1, gdb_open_modeflags[arg1]);


--
Alex Bennée


  parent reply	other threads:[~2019-09-12 11:56 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-10 14:44 [Qemu-arm] [PATCH 00/13] target/arm: Implement semihosting v2.0 Peter Maydell
2019-09-10 14:44 ` [Qemu-devel] " Peter Maydell
2019-09-10 14:44 ` [Qemu-arm] [PATCH 01/13] target/arm/arm-semi: Capture errno in softmmu version of set_swi_errno() Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 10:39   ` [Qemu-arm] " Alex Bennée
2019-09-12 10:39     ` [Qemu-devel] " Alex Bennée
2019-09-12 10:49     ` Peter Maydell
2019-09-12 10:49       ` [Qemu-devel] " Peter Maydell
2019-09-10 14:44 ` [Qemu-arm] [PATCH 02/13] target/arm/arm-semi: Always set some kind of errno for failed calls Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 10:42   ` [Qemu-arm] " Alex Bennée
2019-09-12 10:42     ` [Qemu-devel] " Alex Bennée
2019-09-12 10:50     ` Peter Maydell
2019-09-12 10:50       ` [Qemu-devel] " Peter Maydell
2019-09-12 11:09       ` Alex Bennée
2019-09-12 11:09         ` [Qemu-devel] " Alex Bennée
2019-09-10 14:44 ` [Qemu-arm] [PATCH 03/13] target/arm/arm-semi: Make semihosting code hand out its own file descriptors Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 11:02   ` [Qemu-arm] " Alex Bennée
2019-09-12 11:02     ` [Qemu-devel] " Alex Bennée
2019-09-10 14:44 ` [Qemu-arm] [PATCH 04/13] target/arm/arm-semi: clean up TaskState* usage in non-user-only code Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 11:42   ` [Qemu-arm] " Alex Bennée
2019-09-12 11:42     ` [Qemu-devel] " Alex Bennée
2019-09-12 11:49     ` Peter Maydell
2019-09-10 14:44 ` [Qemu-arm] [PATCH 05/13] target/arm/arm-semi: Factor out implementation of SYS_CLOSE Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 11:13   ` [Qemu-arm] " Alex Bennée
2019-09-12 11:13     ` [Qemu-devel] " Alex Bennée
2019-09-10 14:44 ` [Qemu-devel] [PATCH 06/13] target/arm/arm-semi: Factor out implementation of SYS_WRITE Peter Maydell
2019-09-12 11:18   ` Alex Bennée
2019-09-10 14:44 ` [Qemu-arm] [PATCH 07/13] target/arm/arm-semi: Factor out implementation of SYS_READ Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 11:19   ` [Qemu-arm] " Alex Bennée
2019-09-12 11:19     ` [Qemu-devel] " Alex Bennée
2019-09-10 14:44 ` [Qemu-arm] [PATCH 08/13] target/arm/arm-semi: Factor out implementation of SYS_ISTTY Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 11:20   ` [Qemu-arm] " Alex Bennée
2019-09-12 11:20     ` [Qemu-devel] " Alex Bennée
2019-09-10 14:44 ` [Qemu-devel] [PATCH 09/13] target/arm/arm-semi: Factor out implementation of SYS_SEEK Peter Maydell
2019-09-12 11:43   ` Alex Bennée
2019-09-10 14:44 ` [Qemu-arm] [PATCH 10/13] target/arm/arm-semi: Factor out implementation of SYS_FLEN Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 11:43   ` [Qemu-arm] " Alex Bennée
2019-09-12 11:43     ` [Qemu-devel] " Alex Bennée
2019-09-10 14:44 ` [Qemu-arm] [PATCH 11/13] target/arm/arm-semi: Implement support for semihosting feature detection Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-10 17:00   ` [Qemu-arm] " Peter Maydell
2019-09-10 17:00     ` [Qemu-devel] " Peter Maydell
2019-09-12 11:56   ` Alex Bennée [this message]
2019-09-12 11:56     ` [Qemu-devel] [Qemu-arm] " Alex Bennée
2019-09-10 14:44 ` [Qemu-devel] [PATCH 12/13] target/arm/arm-semi: Implement SH_EXT_STDOUT_STDERR extension Peter Maydell
2019-09-12 12:05   ` Alex Bennée
2019-09-12 12:09     ` [Qemu-arm] " Peter Maydell
2019-09-12 12:09       ` [Qemu-devel] [Qemu-arm] " Peter Maydell
2019-09-10 14:44 ` [Qemu-arm] [PATCH 13/13] target/arm/arm-semi: Implement SH_EXT_EXIT_EXTENDED extension Peter Maydell
2019-09-10 14:44   ` [Qemu-devel] " Peter Maydell
2019-09-12 12:07   ` [Qemu-arm] " Alex Bennée
2019-09-12 12:07     ` [Qemu-devel] " Alex Bennée

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=87blvpzq22.fsf@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.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.