Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 6/6] migration: Block migration while handling machine check

2019-05-19 Thread Aravinda Prasad



On Thursday 16 May 2019 07:47 PM, Dr. David Alan Gilbert wrote:
> * Aravinda Prasad (aravi...@linux.vnet.ibm.com) wrote:
>>
>>
>> On Thursday 16 May 2019 04:24 PM, Greg Kurz wrote:
>>> On Mon, 22 Apr 2019 12:33:45 +0530
>>> Aravinda Prasad  wrote:
>>>
 Block VM migration requests until the machine check
 error handling is complete as (i) these errors are
 specific to the source hardware and is irrelevant on
 the target hardware, (ii) these errors cause data
 corruption and should be handled before migration.

 Signed-off-by: Aravinda Prasad 
 ---
  hw/ppc/spapr_events.c  |   17 +
  hw/ppc/spapr_rtas.c|4 
  include/hw/ppc/spapr.h |3 +++
  3 files changed, 24 insertions(+)

 diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
 index 4032db0..45b990c 100644
 --- a/hw/ppc/spapr_events.c
 +++ b/hw/ppc/spapr_events.c
 @@ -41,6 +41,7 @@
  #include "qemu/bcd.h"
  #include "hw/ppc/spapr_ovec.h"
  #include 
 +#include "migration/blocker.h"
  
  #define RTAS_LOG_VERSION_MASK   0xff00
  #define   RTAS_LOG_VERSION_60x0600
 @@ -864,6 +865,22 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, 
 bool recovered)
  void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
  {
  SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 +int ret;
 +Error *local_err = NULL;
 +
 +error_setg(>migration_blocker,
 +"Live migration not supported during machine check handling");
 +ret = migrate_add_blocker(spapr->migration_blocker, _err);
>>>
>>> migrate_add_blocker() propagates the reason of the failure in local_err,
>>> ie. because a migration is already in progress or --only-migratable was
>>> passed on the QEMU command line, along with the error message passed in
>>> the first argument. This means that...
>>>
 +if (ret < 0) {
 +/*
 + * We don't want to abort and let the migration to continue. In a
 + * rare case, the machine check handler will run on the target
 + * hardware. Though this is not preferable, it is better than 
 aborting
 + * the migration or killing the VM.
 + */
 +error_free(spapr->migration_blocker);
 +fprintf(stderr, "Warning: Machine check during VM migration\n");
>>>
>>> ... you should just do:
>>>
>>> error_report_err(local_err);
>>>
>>> This also takes care of freeing local_err which would be leaked otherwise.
>>
>> Sure. I am planning to use warn_report_err() as I don't want to abort.
> 
> I worry what the high level effect of this blocker will be.
> Since failing hardware is a common reason for wanting to do a migrate
> I worry that if the hardware is reporting lots of errors you might not
> be able to migrate the VM to more solid hardware because of this
> blocker.

We handle two cases, (i) migration initiated during error handling which
we block as we don't want to migrate when we are handling the error. For
example, for memory errors, we need to take some actions like poisoning
the page. If we allow migration during error handling, the handler may
execute on the target host and may poison a clean page on the target.
But, a migration retry will succeed, (ii) errors reported after
migration is initiated: in such cases we let the migration continue
without blocking/aborting.

This is because memory errors are not very frequent, but are still
important to handle as it can cause data corruption. However, if the
hardware is reporting lots of errors, then the chances of host itself
crashing is very high.

> 
> Dave
> 
>> Regards,
>> Aravinda
>>
>>>
 +}
  
  while (spapr->mc_status != -1) {
  /*
 diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
 index 997cf19..1229a0e 100644
 --- a/hw/ppc/spapr_rtas.c
 +++ b/hw/ppc/spapr_rtas.c
 @@ -50,6 +50,7 @@
  #include "target/ppc/mmu-hash64.h"
  #include "target/ppc/mmu-book3s-v3.h"
  #include "kvm_ppc.h"
 +#include "migration/blocker.h"
  
  static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState 
 *spapr,
 uint32_t token, uint32_t nargs,
 @@ -396,6 +397,9 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
  spapr->mc_status = -1;
  qemu_cond_signal(>mc_delivery_cond);
  rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 +migrate_del_blocker(spapr->migration_blocker);
 +error_free(spapr->migration_blocker);
 +spapr->migration_blocker = NULL;
  }
  }
  
 diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
 index 9d16ad1..dda5fd2 100644
 --- a/include/hw/ppc/spapr.h
 +++ b/include/hw/ppc/spapr.h
 @@ -10,6 +10,7 @@
  #include 

Re: [Qemu-devel] [PATCH v9 20/27] gdbstub: Implement target halted (? pkt) with new infra

2019-05-19 Thread Jon Doron
On Wed, May 15, 2019 at 8:20 PM Alex Bennée  wrote:
>
>
> Jon Doron  writes:
>
> > Signed-off-by: Jon Doron 
> > ---
> >  gdbstub.c | 36 ++--
> >  1 file changed, 26 insertions(+), 10 deletions(-)
> >
> > diff --git a/gdbstub.c b/gdbstub.c
> > index 2fd0d66f4d..d678191705 100644
> > --- a/gdbstub.c
> > +++ b/gdbstub.c
> > @@ -2239,13 +2239,30 @@ static void handle_gen_set(GdbCmdContext *gdb_ctx, 
> > void *user_ctx)
> >  put_packet(gdb_ctx->s, "");
> >  }
> >
> > +static void handle_target_halt(GdbCmdContext *gdb_ctx, void *user_ctx)
> > +{
> > +char thread_id[16];
> > +
> > +/* TODO: Make this return the correct value for user-mode.  */
>
> Can this be cleaned up as we convert?
>

To be honest i have no idea what the "correct value" is or how to get
it, can you tell me what it should be and ill add it to the patch?

> > +gdb_fmt_thread_id(gdb_ctx->s, gdb_ctx->s->c_cpu, thread_id,
> > +  sizeof(thread_id));
> > +snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "T%02xthread:%s;",
> > + GDB_SIGNAL_TRAP, thread_id);
> > +put_packet(gdb_ctx->s, gdb_ctx->str_buf);
> > +/*
> > + * Remove all the breakpoints when this query is issued,
> > + * because gdb is doing and initial connect and the state
>
> s/and/an/
>
> > + * should be cleaned up.
> > + */
> > +gdb_breakpoint_remove_all();
> > +}
> > +
> >  static int gdb_handle_packet(GDBState *s, const char *line_buf)
> >  {
> >  const char *p;
> >  int ch;
> >  uint8_t mem_buf[MAX_PACKET_LENGTH];
> >  char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
> > -char thread_id[16];
> >  const GdbCmdParseEntry *cmd_parser = NULL;
> >
> >  trace_gdbstub_io_command(line_buf);
> > @@ -2257,15 +2274,14 @@ static int gdb_handle_packet(GDBState *s, const 
> > char *line_buf)
> >  put_packet(s, "OK");
> >  break;
> >  case '?':
> > -/* TODO: Make this return the correct value for user-mode.  */
> > -snprintf(buf, sizeof(buf), "T%02xthread:%s;", GDB_SIGNAL_TRAP,
> > - gdb_fmt_thread_id(s, s->c_cpu, thread_id, 
> > sizeof(thread_id)));
> > -put_packet(s, buf);
> > -/* Remove all the breakpoints when this query is issued,
> > - * because gdb is doing and initial connect and the state
> > - * should be cleaned up.
> > - */
> > -gdb_breakpoint_remove_all();
> > +{
> > +static const GdbCmdParseEntry target_halted_cmd_desc = {
> > +.handler = handle_target_halt,
> > +.cmd = "?",
> > +.cmd_startswith = 1
> > +};
> > +cmd_parser = _halted_cmd_desc;
> > +}
> >  break;
> >  case 'c':
> >  {
>
>
> --
> Alex Bennée



Re: [Qemu-devel] [PATCH v2 10/13] tests/vm: freebsd autoinstall, using serial console

2019-05-19 Thread Gerd Hoffmann
On Sun, May 19, 2019 at 12:55:09AM +0200, Philippe Mathieu-Daudé wrote:
> Hi Gerd,
> 
> On 5/10/19 12:46 PM, Gerd Hoffmann wrote:
> > Instead of fetching the prebuilt image from patchew download the install
> > iso and prepare the image locally.  Install to disk, using the serial
> > console.  Create qemu user, configure ssh login.  Install packages
> > needed for qemu builds.
> 
> I'm impressed how charmly this works :)
> 
> 3 comments so far.
> 
> 1/ We could record (in tests/vm/freebsd header?) roughly how many local
> storage will be used (or display in 'make vm-help'?). FYI this image
> takes ~3.1GiB.

vm-help would be more useful I think.

> 2/ "Autoboot in 9 seconds, hit [Enter] to boot or any other key to stop"

Probably tweakable via loader.conf, I'll check.

> 3/ I am a bit annoyed it overwrote my previous
> ~/.cache/qemu-vm/images/freebsd.img VM. Not sure what's the best hash to
> use, maybe "git log -n 1 --pretty=format:%H -- tests/vm/freebsd"?
> (Similarly for other images).

Then use ~/.cache/qemu-vm/images/freebsd-${hash}.img ?

Which will fill ~/.cache/qemu-vm/images with stale images over time,
which isn't great either ...

Or do you have something else in mind?

cheers,
  Gerd




Re: [Qemu-devel] [PATCH v9 26/27] gdbstub: Add support to read a MSR for KVM target

2019-05-19 Thread Jon Doron
Ah cool did not know about that I will look into it and perhaps can do
a different patchset just for this no need to add it on top of this
patchset

On Wed, May 15, 2019 at 8:48 PM Alex Bennée  wrote:
>
>
> Jon Doron  writes:
>
> > gdb> maint packet qqemu.kvm.Rdmsr:MsrIndex
>
> gdbserver already has a mechanism for exposing system registers see:
>
>   commit 200bf5b7ffea635079cc05fdfb363372b9544ce7
>   Author: Abdallah Bouassida 
>   Date:   Fri May 18 17:48:07 2018 +0100
>
> for an example. As MSR's are very specific to x86 all this should be
> handled via target/i386/gdbstub and kept out of the generic code.
>
> >
> > Signed-off-by: Jon Doron 
> > ---
> >  gdbstub.c | 38 +-
> >  1 file changed, 37 insertions(+), 1 deletion(-)
> >
> > diff --git a/gdbstub.c b/gdbstub.c
> > index 34da10260d..f48c3a2b5f 100644
> > --- a/gdbstub.c
> > +++ b/gdbstub.c
> > @@ -2141,7 +2141,14 @@ static void handle_query_attached(GdbCmdContext 
> > *gdb_ctx, void *user_ctx)
> >
> >  static void handle_query_qemu_supported(GdbCmdContext *gdb_ctx, void 
> > *user_ctx)
> >  {
> > -put_packet(gdb_ctx->s, "sstepbits;sstep;PhyMemMode");
> > +snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
> > + "sstepbits;sstep;PhyMemMode");
> > +
> > +if (kvm_enabled()) {
> > +pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";kvm.Rdmsr");
> > +}
> > +
> > +put_packet(gdb_ctx->s, gdb_ctx->str_buf);
> >  }
> >
> >  static void handle_query_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx,
> > @@ -2166,6 +2173,29 @@ static void 
> > handle_set_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx, void *user_ctx)
> >  put_packet(gdb_ctx->s, "OK");
> >  }
> >
> > +static void handle_query_kvm_read_msr(GdbCmdContext *gdb_ctx, void 
> > *user_ctx)
> > +{
> > +uint64_t msr_val;
> > +
> > +if (!kvm_enabled()) {
> > +return;
> > +}
> > +
> > +if (!gdb_ctx->num_params) {
> > +put_packet(gdb_ctx->s, "E22");
> > +return;
> > +}
> > +
> > +if (kvm_arch_read_msr(gdbserver_state->c_cpu, 
> > gdb_ctx->params[0].val_ul,
> > +  _val)) {
> > +put_packet(gdb_ctx->s, "E00");
> > +return;
> > +}
> > +
> > +snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "0x%" PRIx64, 
> > msr_val);
> > +put_packet(gdb_ctx->s, gdb_ctx->str_buf);
> > +}
> > +
> >  static GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
> >  /* Order is important if has same prefix */
> >  {
> > @@ -2250,6 +2280,12 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
> >  .handler = handle_query_qemu_phy_mem_mode,
> >  .cmd = "qemu.PhyMemMode",
> >  },
> > +{
> > +.handler = handle_query_kvm_read_msr,
> > +.cmd = "qemu.kvm.Rdmsr:",
> > +.cmd_startswith = 1,
> > +.schema = "l0"
> > +},
> >  };
> >
> >  static GdbCmdParseEntry gdb_gen_set_table[] = {
>
>
> --
> Alex Bennée



Re: [Qemu-devel] [PATCH v9 24/27] gdbstub: Add another handler for setting qemu.sstep

2019-05-19 Thread Jon Doron
On Wed, May 15, 2019 at 8:44 PM Alex Bennée  wrote:
>
>
> Jon Doron  writes:
>
> > Follow GDB general query/set packet conventions, qemu.sstep can now
> > be set with the following command as well:
> > gdb> maint packet Qqemu.sstep:Value
>
> I;m not sure about exposing internal values to a protocol like this.
> Maybe text based flags would be better?
>

We kinda have to at this point as this was the original implementation
or we might end up breaking up the "API"
see commit: 60897d369f10b464720d8a6de4553c47943ea927

> >
> > Signed-off-by: Jon Doron 
> > ---
> >  gdbstub.c | 6 ++
> >  1 file changed, 6 insertions(+)
> >
> > diff --git a/gdbstub.c b/gdbstub.c
> > index 88ff6224e6..34da10260d 100644
> > --- a/gdbstub.c
> > +++ b/gdbstub.c
> > @@ -2260,6 +2260,12 @@ static GdbCmdParseEntry gdb_gen_set_table[] = {
> >  .cmd_startswith = 1,
> >  .schema = "l0"
> >  },
> > +{
> > +.handler = handle_set_qemu_sstep,
> > +.cmd = "qemu.sstep:",
> > +.cmd_startswith = 1,
> > +.schema = "l0"
> > +},
>
> Hmm the implementation seems to have gone in earlier. These should be
> together as a feature patch (along with changing the query/probe
> responses).
>
Done
> >  };
> >
> >  static void handle_gen_query(GdbCmdContext *gdb_ctx, void *user_ctx)
>
>
> --
> Alex Bennée



Re: [Qemu-devel] [PATCH v9 22/27] gdbstub: Implement generic query qemu.Supported

2019-05-19 Thread Jon Doron
I suggest then that I'll squash this commit into the commit that
refactors the the Q/q packets and will add the required documentation
about this
in the commit message.

Do you agree?
-- Jon.

On Wed, May 15, 2019 at 8:41 PM Alex Bennée  wrote:
>
>
> Jon Doron  writes:
>
> > qemu.Supported query reply back with the supported qemu query/set
> > commands (commands are seperated with a semicolon from each other).
> >
> > gdb> maint packet qqemu.Supported
> >
> > Signed-off-by: Jon Doron 
> > ---
> >  gdbstub.c | 9 +
> >  1 file changed, 9 insertions(+)
> >
> > diff --git a/gdbstub.c b/gdbstub.c
> > index 8bdfae4b29..00c07d6ec0 100644
> > --- a/gdbstub.c
> > +++ b/gdbstub.c
> > @@ -2127,6 +2127,11 @@ static void handle_query_attached(GdbCmdContext 
> > *gdb_ctx, void *user_ctx)
> >  put_packet(gdb_ctx->s, GDB_ATTACHED);
> >  }
> >
> > +static void handle_query_qemu_supported(GdbCmdContext *gdb_ctx, void 
> > *user_ctx)
> > +{
> > +put_packet(gdb_ctx->s, "sstepbits;sstep");
>
> To maintain bisectability this response should be extended as each
> feature is added.
>
> > +}
> > +
> >  static GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
> >  /* Order is important if has same prefix */
> >  {
> > @@ -2203,6 +2208,10 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
> >  .handler = handle_query_attached,
> >  .cmd = "Attached",
> >  },
> > +{
> > +.handler = handle_query_qemu_supported,
> > +.cmd = "qemu.Supported",
> > +},
> >  };
> >
> >  static void handle_gen_query(GdbCmdContext *gdb_ctx, void *user_ctx)
>
>
> --
> Alex Bennée



Re: [Qemu-devel] [PATCH v9 17/27] gdbstub: Implement v commands with new infra

2019-05-19 Thread Jon Doron
On Wed, May 15, 2019 at 8:06 PM Alex Bennée  wrote:
>
>
> Jon Doron  writes:
>
> > Signed-off-by: Jon Doron 
> > ---
> >  gdbstub.c | 170 +++---
> >  1 file changed, 110 insertions(+), 60 deletions(-)
> >
> > diff --git a/gdbstub.c b/gdbstub.c
> > index 9b0556f8be..d56d0fd235 100644
> > --- a/gdbstub.c
> > +++ b/gdbstub.c
> > @@ -1815,6 +1815,106 @@ static void handle_step(GdbCmdContext *gdb_ctx, 
> > void *user_ctx)
> >  gdb_continue(gdb_ctx->s);
> >  }
> >
> > +static void handle_v_cont_query(GdbCmdContext *gdb_ctx, void *user_ctx)
> > +{
> > +put_packet(gdb_ctx->s, "vCont;c;C;s;S");
> > +}
> > +
> > +static void handle_v_cont(GdbCmdContext *gdb_ctx, void *user_ctx)
> > +{
> > +int res;
> > +
> > +if (!gdb_ctx->num_params) {
> > +return;
> > +}
> > +
> > +res = gdb_handle_vcont(gdb_ctx->s, gdb_ctx->params[0].data);
> > +if ((res == -EINVAL) || (res == -ERANGE)) {
> > +put_packet(gdb_ctx->s, "E22");
> > +} else if (res) {
> > +put_packet(gdb_ctx->s, "\0");
>
> Isn't this just ""?
>
> Either way my reading of the spec say the response needs to be a "Stop
> Reply Packet" which I don't think includes empty or E codes.
>

>From my understanding reading the spec and the gdbserver
implementation in binutils a null packet tells the client
the command is unsupported, so it makes sense to reply with this null
packet if handle_vcont replied with something
we dont know (i.e -ENOTSUP)

> > +}
> > +}
> > +
> > +static void handle_v_attach(GdbCmdContext *gdb_ctx, void *user_ctx)
> > +{
> > +GDBProcess *process;
> > +CPUState *cpu;
> > +char thread_id[16];
> > +
> > +strcpy(gdb_ctx->str_buf, "E22");
>
> pstrcpy (see HACKING about strncpy) but...
>
> > +if (!gdb_ctx->num_params) {
> > +goto cleanup;
> > +}
> > +
> > +process = gdb_get_process(gdb_ctx->s, gdb_ctx->params[0].val_ul);
> > +if (!process) {
> > +goto cleanup;
> > +}
> > +
> > +cpu = get_first_cpu_in_process(gdb_ctx->s, process);
> > +if (!cpu) {
> > +goto cleanup;
> > +}
> > +
> > +process->attached = true;
> > +gdb_ctx->s->g_cpu = cpu;
> > +gdb_ctx->s->c_cpu = cpu;
> > +
> > +gdb_fmt_thread_id(gdb_ctx->s, cpu, thread_id, sizeof(thread_id));
> > +snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "T%02xthread:%s;",
> > + GDB_SIGNAL_TRAP, thread_id);
>
> again this would be an argument for using GString to build-up our reply 
> packets.
>
Perhaps we will need to make another patchset which fixes all the
strings/buffers stuff and move to Glib
but like you said probably too much for this patchset
> > +cleanup:
> > +put_packet(gdb_ctx->s, gdb_ctx->str_buf);
> > +}
> > +
> > +static void handle_v_kill(GdbCmdContext *gdb_ctx, void *user_ctx)
> > +{
> > +/* Kill the target */
> > +put_packet(gdb_ctx->s, "OK");
> > +error_report("QEMU: Terminated via GDBstub");
> > +exit(0);
> > +}
> > +
> > +static GdbCmdParseEntry gdb_v_commands_table[] = {
> > +/* Order is important if has same prefix */
> > +{
> > +.handler = handle_v_cont_query,
> > +.cmd = "Cont?",
> > +.cmd_startswith = 1
> > +},
> > +{
> > +.handler = handle_v_cont,
> > +.cmd = "Cont",
> > +.cmd_startswith = 1,
> > +.schema = "s0"
> > +},
> > +{
> > +.handler = handle_v_attach,
> > +.cmd = "Attach;",
> > +.cmd_startswith = 1,
> > +.schema = "l0"
> > +},
> > +{
> > +.handler = handle_v_kill,
> > +.cmd = "Kill;",
> > +.cmd_startswith = 1
> > +},
> > +};
> > +
> > +static void handle_v_commands(GdbCmdContext *gdb_ctx, void *user_ctx)
> > +{
> > +if (!gdb_ctx->num_params) {
> > +return;
> > +}
> > +
> > +if (process_string_cmd(gdb_ctx->s, NULL, gdb_ctx->params[0].data,
> > +   gdb_v_commands_table,
> > +   ARRAY_SIZE(gdb_v_commands_table))) {
> > +put_packet(gdb_ctx->s, "");
> > +}
> > +}
> > +
> >  static int gdb_handle_packet(GDBState *s, const char *line_buf)
> >  {
> >  CPUState *cpu;
> > @@ -1822,7 +1922,7 @@ static int gdb_handle_packet(GDBState *s, const char 
> > *line_buf)
> >  CPUClass *cc;
> >  const char *p;
> >  uint32_t pid, tid;
> > -int ch, type, res;
> > +int ch, type;
> >  uint8_t mem_buf[MAX_PACKET_LENGTH];
> >  char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
> >  char thread_id[16];
> > @@ -1871,66 +1971,16 @@ static int gdb_handle_packet(GDBState *s, const 
> > char *line_buf)
> >  }
> >  break;
> >  case 'v':
> > -if (strncmp(p, "Cont", 4) == 0) {
> > -p += 4;
> > -if (*p == '?') {
> > -put_packet(s, "vCont;c;C;s;S");
> > -break;
> > -}
> > -
> > -res = gdb_handle_vcont(s, p);
> > -
> > -   

Re: [Qemu-devel] [PATCH v9 2/7] virtio-pmem: Add virtio pmem driver

2019-05-19 Thread Pankaj Gupta


> 
> 
> > On 5/16/19 10:35 PM, Pankaj Gupta wrote:
> > > Can I take it your reviewed/acked-by? or tested-by tag? for the virtio
> > > patch :)I don't feel that I have enough expertise to give the reviewed-by
> > > tag, but you can
> > take my acked-by + tested-by.
> > 
> > Acked-by: Jakub Staron 
> > Tested-by: Jakub Staron 
> > 
> > No kernel panics/stalls encountered during testing this patches (v9) with
> > QEMU + xfstests.
> 
> Thank you for testing and confirming the results. I will add your tested &
> acked-by in v10.
> 
> > Some CPU stalls encountered while testing with crosvm instead of QEMU with
> > xfstests
> > (test generic/464) but no repro for QEMU, so the fault may be on the side
> > of
> > crosvm.
> 
> yes, looks like crosvm related as we did not see any of this in my and your
> testing with Qemu.

Also, they don't seem to be related with virtio-pmem.

Thanks,
Pankaj



Re: [Qemu-devel] [PATCH v9 2/7] virtio-pmem: Add virtio pmem driver

2019-05-19 Thread Pankaj Gupta


> On 5/16/19 10:35 PM, Pankaj Gupta wrote:
> > Can I take it your reviewed/acked-by? or tested-by tag? for the virtio
> > patch :)I don't feel that I have enough expertise to give the reviewed-by
> > tag, but you can
> take my acked-by + tested-by.
> 
> Acked-by: Jakub Staron 
> Tested-by: Jakub Staron 
> 
> No kernel panics/stalls encountered during testing this patches (v9) with
> QEMU + xfstests.

Thank you for testing and confirming the results. I will add your tested &
acked-by in v10.

> Some CPU stalls encountered while testing with crosvm instead of QEMU with
> xfstests
> (test generic/464) but no repro for QEMU, so the fault may be on the side of
> crosvm.

yes, looks like crosvm related as we did not see any of this in my and your
testing with Qemu. 

> 
> 
> The dump for the crosvm/xfstests stall:
> [ 2504.175276] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
> [ 2504.176681] rcu: 0-...!: (1 GPs behind) idle=9b2/1/0x4000
> softirq=1089198/1089202 fqs=0
> [ 2504.178270] rcu: 2-...!: (1 ticks this GP)
> idle=cfe/1/0x4002 softirq=1055108/1055110 fqs=0
> [ 2504.179802] rcu: 3-...!: (1 GPs behind) idle=1d6/1/0x4002
> softirq=1046798/1046802 fqs=0
> [ 2504.181215] rcu: 4-...!: (2 ticks this GP)
> idle=522/1/0x4002 softirq=1249063/1249064 fqs=0
> [ 2504.182625] rcu: 5-...!: (1 GPs behind) idle=6da/1/0x4000
> softirq=1131036/1131047 fqs=0
> [ 2504.183955]  (detected by 3, t=0 jiffies, g=1232529, q=1370)
> [ 2504.184762] Sending NMI from CPU 3 to CPUs 0:
> [ 2504.186400] NMI backtrace for cpu 0
> [ 2504.186401] CPU: 0 PID: 6670 Comm: 464 Not tainted 5.1.0+ #1
> [ 2504.186401] Hardware name: ChromiumOS crosvm, BIOS 0
> [ 2504.186402] RIP: 0010:queued_spin_lock_slowpath+0x1c/0x1e0
> [ 2504.186402] Code: e7 89 c8 f0 44 0f b1 07 39 c1 75 dc f3 c3 0f 1f 44 00 00
> ba 01 00 00 00 8b 07 85 c0 75 0a f0 0f b1 17 85 c0 75 f2 f3 c3 f3 90  ec
> 81 fe 00 01 00 00 0f 84 ab 00 00 00 81 e6 00 ff ff ff 75 44
> [ 2504.186403] RSP: 0018:c9003ee8 EFLAGS: 0002
> [ 2504.186404] RAX: 0001 RBX: 0246 RCX:
> 00404044
> [ 2504.186404] RDX: 0001 RSI: 0001 RDI:
> 8244a280
> [ 2504.186405] RBP: 8244a280 R08: 000f4200 R09:
> 024709ed6c32
> [ 2504.186405] R10:  R11: 0001 R12:
> 8244a280
> [ 2504.186405] R13: 0009 R14: 0009 R15:
> 
> [ 2504.186406] FS:  () GS:8880cc60()
> knlGS:
> [ 2504.186406] CS:  0010 DS:  ES:  CR0: 80050033
> [ 2504.186406] CR2: 7efd6b0f15d8 CR3: 0260a006 CR4:
> 00360ef0
> [ 2504.186407] DR0:  DR1:  DR2:
> 
> [ 2504.186407] DR3:  DR6: fffe0ff0 DR7:
> 0400
> [ 2504.186407] Call Trace:
> [ 2504.186408]  
> [ 2504.186408]  _raw_spin_lock_irqsave+0x1d/0x30
> [ 2504.186408]  rcu_core+0x3b6/0x740
> [ 2504.186408]  ? __hrtimer_run_queues+0x133/0x280
> [ 2504.186409]  ? recalibrate_cpu_khz+0x10/0x10
> [ 2504.186409]  __do_softirq+0xd8/0x2e4
> [ 2504.186409]  irq_exit+0xa3/0xb0
> [ 2504.186410]  smp_apic_timer_interrupt+0x67/0x120
> [ 2504.186410]  apic_timer_interrupt+0xf/0x20
> [ 2504.186410]  
> [ 2504.186410] RIP: 0010:unmap_page_range+0x47a/0x9b0
> [ 2504.186411] Code: 0f 46 46 10 49 39 6e 18 49 89 46 10 48 89 e8 49 0f 43 46
> 18 41 80 4e 20 08 4d 85 c9 49 89 46 18 0f 84 68 ff ff ff 49 8b 51 08 <48> 8d
> 42 ff 83 e2 01 49 0f 44 c1 f6 40 18 01 75 38 48 ba ff 0f 00
> [ 2504.186411] RSP: 0018:c900036cbcc8 EFLAGS: 0282 ORIG_RAX:
> ff13
> [ 2504.186412] RAX:  RBX: 80003751d045 RCX:
> 0001
> [ 2504.186413] RDX: ea0002e09288 RSI: 0269b000 RDI:
> 8880b6525e40
> [ 2504.186413] RBP: 0269c000 R08:  R09:
> eadd4740
> [ 2504.186413] R10: ea0001755700 R11: 8880cc62d120 R12:
> 02794000
> [ 2504.186414] R13: 0269b000 R14: c900036cbdf0 R15:
> 8880572434d8
> [ 2504.186414]  ? unmap_page_range+0x420/0x9b0
> [ 2504.186414]  ? release_pages+0x175/0x390
> [ 2504.186414]  unmap_vmas+0x7c/0xe0
> [ 2504.186415]  exit_mmap+0xa4/0x190
> [ 2504.186415]  mmput+0x3b/0x100
> [ 2504.186415]  do_exit+0x276/0xc10
> [ 2504.186415]  do_group_exit+0x35/0xa0
> [ 2504.186415]  __x64_sys_exit_group+0xf/0x10
> [ 2504.186416]  do_syscall_64+0x43/0x120
> [ 2504.186416]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> [ 2504.186416] RIP: 0033:0x7efd6ae10618
> [ 2504.186416] Code: Bad RIP value.
> [ 2504.186417] RSP: 002b:7ffcac9bde38 EFLAGS: 0246 ORIG_RAX:
> 00e7
> [ 2504.186417] RAX: ffda RBX:  RCX:
> 7efd6ae10618
> [ 2504.186418] RDX:  RSI: 003c RDI:
> 
> [ 2504.186418] RBP: 7efd6b0ed8e0 R08: 00e7 R09:
> 

[Qemu-devel] [PATCH v2 15/15] migration: Split log_clear() into smaller chunks

2019-05-19 Thread Peter Xu
Currently we are doing log_clear() right after log_sync() which mostly
keeps the old behavior when log_clear() was still part of log_sync().

This patch tries to further optimize the migration log_clear() code
path to split huge log_clear()s into smaller chunks.

We do this by spliting the whole guest memory region into memory
chunks, whose size is decided by MigrationState.clear_bitmap_shift (an
example will be given below).  With that, we don't do the dirty bitmap
clear operation on the remote node (e.g., KVM) when we fetch the dirty
bitmap, instead we explicitly clear the dirty bitmap for the memory
chunk for each of the first time we send a page in that chunk.

Here comes an example.

Assuming the guest has 64G memory, then before this patch the KVM
ioctl KVM_CLEAR_DIRTY_LOG will be a single one covering 64G memory.
If after the patch, let's assume when the clear bitmap shift is 18,
then the memory chunk size on x86_64 will be 1UL<<18 * 4K = 1GB.  Then
instead of sending a big 64G ioctl, we'll send 64 small ioctls, each
of the ioctl will cover 1G of the guest memory.  For each of the 64
small ioctls, we'll only send if any of the page in that small chunk
was going to be sent right away.

Signed-off-by: Peter Xu 
---
 include/exec/ram_addr.h | 75 +++--
 migration/migration.c   |  4 +++
 migration/migration.h   | 27 +++
 migration/ram.c | 44 
 migration/trace-events  |  1 +
 5 files changed, 149 insertions(+), 2 deletions(-)

diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 896324281a..c2db157d98 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -50,8 +50,69 @@ struct RAMBlock {
 unsigned long *unsentmap;
 /* bitmap of already received pages in postcopy */
 unsigned long *receivedmap;
+
+/*
+ * bitmap of already cleared dirty bitmap.  Set this up to
+ * non-NULL to enable the capability to postpone and split
+ * clearing of dirty bitmap on the remote node (e.g., KVM).  The
+ * bitmap will be set only when doing global sync.
+ *
+ * NOTE: this bitmap is different comparing to the other bitmaps
+ * in that one bit can represent multiple guest pages (which is
+ * decided by the `clear_bmap_shift' variable below).  On
+ * destination side, this should always be NULL, and the variable
+ * `clear_bmap_shift' is meaningless.
+ */
+unsigned long *clear_bmap;
+uint8_t clear_bmap_shift;
 };
 
+/**
+ * clear_bmap_size: calculate clear bitmap size
+ *
+ * @pages: number of guest pages
+ * @shift: guest page number shift
+ *
+ * Returns: number of bits for the clear bitmap
+ */
+static inline long clear_bmap_size(uint64_t pages, uint8_t shift)
+{
+return DIV_ROUND_UP(pages, 1UL << shift);
+}
+
+/**
+ * clear_bmap_set: set clear bitmap for the page range
+ *
+ * @rb: the ramblock to operate on
+ * @start: the start page number
+ * @size: number of pages to set in the bitmap
+ *
+ * Returns: None
+ */
+static inline void clear_bmap_set(RAMBlock *rb, uint64_t start,
+  uint64_t npages)
+{
+uint8_t shift = rb->clear_bmap_shift;
+
+bitmap_set_atomic(rb->clear_bmap, start >> shift,
+  clear_bmap_size(npages, shift));
+}
+
+/**
+ * clear_bmap_test_and_clear: test clear bitmap for the page, clear if set
+ *
+ * @rb: the ramblock to operate on
+ * @page: the page number to check
+ *
+ * Returns: true if the bit was set, false otherwise
+ */
+static inline bool clear_bmap_test_and_clear(RAMBlock *rb, uint64_t page)
+{
+uint8_t shift = rb->clear_bmap_shift;
+
+return bitmap_test_and_clear_atomic(rb->clear_bmap, page >> shift, 1);
+}
+
 static inline bool offset_in_ramblock(RAMBlock *b, ram_addr_t offset)
 {
 return (b && b->host && offset < b->used_length) ? true : false;
@@ -462,8 +523,18 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock 
*rb,
 }
 }
 
-/* TODO: split the huge bitmap into smaller chunks */
-memory_region_clear_dirty_bitmap(rb->mr, start, length);
+if (rb->clear_bmap) {
+/*
+ * Postpone the dirty bitmap clear to the point before we
+ * really send the pages, also we will split the clear
+ * dirty procedure into smaller chunks.
+ */
+clear_bmap_set(rb, start >> TARGET_PAGE_BITS,
+   length >> TARGET_PAGE_BITS);
+} else {
+/* Slow path - still do that in a huge chunk */
+memory_region_clear_dirty_bitmap(rb->mr, start, length);
+}
 } else {
 ram_addr_t offset = rb->offset;
 
diff --git a/migration/migration.c b/migration/migration.c
index d0a0f68f11..780d8af404 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3362,6 +3362,8 @@ void migration_global_dump(Monitor *mon)
ms->send_section_footer ? "on" : "off");
 

[Qemu-devel] [PATCH v2 13/15] qmp: Expose manual_dirty_log_protect via "query-kvm"

2019-05-19 Thread Peter Xu
Expose the new capability via "query-kvm" QMP command too so we know
whether that's turned on on the source VM when we want.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c  | 5 +
 include/sysemu/kvm.h | 2 ++
 qapi/misc.json   | 6 +-
 qmp.c| 1 +
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 062bf8b5b0..c79d6b51e2 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -169,6 +169,11 @@ int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
 return 1;
 }
 
+bool kvm_manual_dirty_log_protect_enabled(void)
+{
+return kvm_state && kvm_state->manual_dirty_log_protect;
+}
+
 /* Must be with slots_lock held */
 static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
 {
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index a6d1cd190f..30757f1425 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -547,4 +547,6 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void 
*source);
 int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
 struct ppc_radix_page_info *kvm_get_radix_page_info(void);
 int kvm_get_max_memslots(void);
+bool kvm_manual_dirty_log_protect_enabled(void);
+
 #endif
diff --git a/qapi/misc.json b/qapi/misc.json
index 8b3ca4fdd3..ce7a76755a 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -253,9 +253,13 @@
 #
 # @present: true if KVM acceleration is built into this executable
 #
+# @manual-dirty-log-protect: true if manual dirty log protect is enabled
+#
 # Since: 0.14.0
 ##
-{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
+{ 'struct': 'KvmInfo', 'data':
+  {'enabled': 'bool', 'present': 'bool',
+   'manual-dirty-log-protect': 'bool' } }
 
 ##
 # @query-kvm:
diff --git a/qmp.c b/qmp.c
index b92d62cd5f..047bef032e 100644
--- a/qmp.c
+++ b/qmp.c
@@ -73,6 +73,7 @@ KvmInfo *qmp_query_kvm(Error **errp)
 
 info->enabled = kvm_enabled();
 info->present = kvm_available();
+info->manual_dirty_log_protect = kvm_manual_dirty_log_protect_enabled();
 
 return info;
 }
-- 
2.17.1




[Qemu-devel] [PATCH v2 12/15] kvm: Support KVM_CLEAR_DIRTY_LOG

2019-05-19 Thread Peter Xu
Firstly detect the interface using KVM_CAP_MANUAL_DIRTY_LOG_PROTECT
and mark it.  When failed to enable the new feature we'll fall back to
the old sync.

Provide the log_clear() hook for the memory listeners for both address
spaces of KVM (normal system memory, and SMM) and deliever the clear
message to kernel.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c| 180 +
 accel/kvm/trace-events |   1 +
 2 files changed, 181 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index a19535bf6a..062bf8b5b0 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -91,6 +91,7 @@ struct KVMState
 int many_ioeventfds;
 int intx_set_mask;
 bool sync_mmu;
+bool manual_dirty_log_protect;
 /* The man page (and posix) say ioctl numbers are signed int, but
  * they're not.  Linux, glibc and *BSD all treat ioctl numbers as
  * unsigned, and treating them as signed here can break things */
@@ -536,6 +537,157 @@ out:
 return ret;
 }
 
+/* Alignment requirement for KVM_CLEAR_DIRTY_LOG - 64 pages */
+#define KVM_CLEAR_LOG_SHIFT  6
+#define KVM_CLEAR_LOG_ALIGN  (qemu_real_host_page_size << KVM_CLEAR_LOG_SHIFT)
+#define KVM_CLEAR_LOG_MASK   (-KVM_CLEAR_LOG_ALIGN)
+
+/**
+ * kvm_physical_log_clear - Clear the kernel's dirty bitmap for range
+ *
+ * NOTE: this will be a no-op if we haven't enabled manual dirty log
+ * protection in the host kernel because in that case this operation
+ * will be done within log_sync().
+ *
+ * @kml: the kvm memory listener
+ * @section: the memory range to clear dirty bitmap
+ */
+static int kvm_physical_log_clear(KVMMemoryListener *kml,
+  MemoryRegionSection *section)
+{
+KVMState *s = kvm_state;
+struct kvm_clear_dirty_log d;
+uint64_t start, end, bmap_start, start_delta, bmap_npages, size;
+unsigned long *bmap_clear = NULL, psize = qemu_real_host_page_size;
+KVMSlot *mem = NULL;
+int ret, i;
+
+if (!s->manual_dirty_log_protect) {
+/* No need to do explicit clear */
+return 0;
+}
+
+start = section->offset_within_address_space;
+size = int128_get64(section->size);
+
+if (!size) {
+/* Nothing more we can do... */
+return 0;
+}
+
+kvm_slots_lock(kml);
+
+/* Find any possible slot that covers the section */
+for (i = 0; i < s->nr_slots; i++) {
+mem = >slots[i];
+if (mem->start_addr <= start &&
+start + size <= mem->start_addr + mem->memory_size) {
+break;
+}
+}
+
+/*
+ * We should always find one memslot until this point, otherwise
+ * there could be something wrong from the upper layer
+ */
+assert(mem && i != s->nr_slots);
+
+/*
+ * We need to extend either the start or the size or both to
+ * satisfy the KVM interface requirement.  Firstly, do the start
+ * page alignment on 64 host pages
+ */
+bmap_start = (start - mem->start_addr) & KVM_CLEAR_LOG_MASK;
+start_delta = start - mem->start_addr - bmap_start;
+bmap_start /= psize;
+
+/*
+ * The kernel interface has restriction on the size too, that either:
+ *
+ * (1) the size is 64 host pages aligned (just like the start), or
+ * (2) the size fills up until the end of the KVM memslot.
+ */
+bmap_npages = DIV_ROUND_UP(size + start_delta, KVM_CLEAR_LOG_ALIGN)
+<< KVM_CLEAR_LOG_SHIFT;
+end = mem->memory_size / psize;
+if (bmap_npages > end - bmap_start) {
+bmap_npages = end - bmap_start;
+}
+start_delta /= psize;
+
+/*
+ * Prepare the bitmap to clear dirty bits.  Here we must guarantee
+ * that we won't clear any unknown dirty bits otherwise we might
+ * accidentally clear some set bits which are not yet synced from
+ * the kernel into QEMU's bitmap, then we'll lose track of the
+ * guest modifications upon those pages (which can directly lead
+ * to guest data loss or panic after migration).
+ *
+ * Layout of the KVMSlot.dirty_bmap:
+ *
+ *   |< bmap_npages ---..>|
+ * [1]
+ * start_delta size
+ *  ||-|--||
+ *  ^^ ^   ^
+ *  || |   |
+ * start  bmap_start (start) end
+ * of memslot of memslot
+ *
+ * [1] bmap_npages can be aligned to either 64 pages or the end of slot
+ */
+
+assert(bmap_start % BITS_PER_LONG == 0);
+if (start_delta) {
+/* Slow path - we need to manipulate a temp bitmap */
+bmap_clear = bitmap_new(bmap_npages);
+bitmap_copy_with_src_offset(bmap_clear, mem->dirty_bmap,
+

[Qemu-devel] [PATCH v2 14/15] hmp: Expose manual_dirty_log_protect via "info kvm"

2019-05-19 Thread Peter Xu
Signed-off-by: Peter Xu 
---
 hmp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hmp.c b/hmp.c
index 56a3ed7375..f203a25740 100644
--- a/hmp.c
+++ b/hmp.c
@@ -102,6 +102,8 @@ void hmp_info_kvm(Monitor *mon, const QDict *qdict)
 } else {
 monitor_printf(mon, "not compiled\n");
 }
+monitor_printf(mon, "kvm manual dirty logging: %s\n",
+   info->manual_dirty_log_protect ? "enabled" : "disabled");
 
 qapi_free_KvmInfo(info);
 }
-- 
2.17.1




[Qemu-devel] [PATCH v2 09/15] kvm: Update comments for sync_dirty_bitmap

2019-05-19 Thread Peter Xu
It's obviously obsolete.  Do some update.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 524c4ddfbd..b686531586 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -473,13 +473,13 @@ static int 
kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
 
 /**
- * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
- * This function updates qemu's dirty bitmap using
- * memory_region_set_dirty().  This means all bits are set
- * to dirty.
+ * kvm_physical_sync_dirty_bitmap - Sync dirty bitmap from kernel space
  *
- * @start_add: start of logged region.
- * @end_addr: end of logged region.
+ * This function will first try to fetch dirty bitmap from the kernel,
+ * and then updates qemu's dirty bitmap.
+ *
+ * @kml: the KVM memory listener object
+ * @section: the memory section to sync the dirty bitmap with
  */
 static int kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
   MemoryRegionSection *section)
-- 
2.17.1




[Qemu-devel] [PATCH v2 10/15] kvm: Persistent per kvmslot dirty bitmap

2019-05-19 Thread Peter Xu
When synchronizing dirty bitmap from kernel KVM we do it in a
per-kvmslot fashion and we allocate the userspace bitmap for each of
the ioctl.  This patch instead make the bitmap cache be persistent
then we don't need to g_malloc0() every time.

More importantly, the cached per-kvmslot dirty bitmap will be further
used when we want to add support for the KVM_CLEAR_DIRTY_LOG and this
cached bitmap will be used to guarantee we won't clear any unknown
dirty bits otherwise that can be a severe data loss issue for
migration code.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c  | 39 +--
 include/sysemu/kvm_int.h |  2 ++
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index b686531586..334c610918 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -497,31 +497,14 @@ static int 
kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
 return 0;
 }
 
-/* XXX bad kernel interface alert
- * For dirty bitmap, kernel allocates array of size aligned to
- * bits-per-long.  But for case when the kernel is 64bits and
- * the userspace is 32bits, userspace can't align to the same
- * bits-per-long, since sizeof(long) is different between kernel
- * and user space.  This way, userspace will provide buffer which
- * may be 4 bytes less than the kernel will use, resulting in
- * userspace memory corruption (which is not detectable by valgrind
- * too, in most cases).
- * So for now, let's align to 64 instead of HOST_LONG_BITS here, in
- * a hope that sizeof(long) won't become >8 any time soon.
- */
-size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
- /*HOST_LONG_BITS*/ 64) / 8;
-d.dirty_bitmap = g_malloc0(size);
-
+d.dirty_bitmap = mem->dirty_bmap;
 d.slot = mem->slot | (kml->as_id << 16);
 if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, ) == -1) {
 DPRINTF("ioctl failed %d\n", errno);
-g_free(d.dirty_bitmap);
 return -1;
 }
 
 kvm_get_dirty_pages_log_range(section, d.dirty_bitmap);
-g_free(d.dirty_bitmap);
 }
 
 return 0;
@@ -765,6 +748,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 MemoryRegion *mr = section->mr;
 bool writeable = !mr->readonly && !mr->rom_device;
 hwaddr start_addr, size;
+unsigned long bmap_size;
 void *ram;
 
 if (!memory_region_is_ram(mr)) {
@@ -796,6 +780,8 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 }
 
 /* unregister the slot */
+g_free(mem->dirty_bmap);
+mem->dirty_bmap = NULL;
 mem->memory_size = 0;
 mem->flags = 0;
 err = kvm_set_user_memory_region(kml, mem, false);
@@ -807,12 +793,29 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 return;
 }
 
+/*
+ * XXX bad kernel interface alert For dirty bitmap, kernel
+ * allocates array of size aligned to bits-per-long.  But for case
+ * when the kernel is 64bits and the userspace is 32bits,
+ * userspace can't align to the same bits-per-long, since
+ * sizeof(long) is different between kernel and user space.  This
+ * way, userspace will provide buffer which may be 4 bytes less
+ * than the kernel will use, resulting in userspace memory
+ * corruption (which is not detectable by valgrind too, in most
+ * cases).  So for now, let's align to 64 instead of
+ * HOST_LONG_BITS here, in a hope that sizeof(long) won't become
+ * >8 any time soon.
+ */
+bmap_size = ALIGN((size >> TARGET_PAGE_BITS),
+  /*HOST_LONG_BITS*/ 64) / 8;
+
 /* register the new slot */
 mem = kvm_alloc_slot(kml);
 mem->memory_size = size;
 mem->start_addr = start_addr;
 mem->ram = ram;
 mem->flags = kvm_mem_flags(mr);
+mem->dirty_bmap = g_malloc0(bmap_size);
 
 err = kvm_set_user_memory_region(kml, mem, true);
 if (err) {
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index f838412491..687a2ee423 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -21,6 +21,8 @@ typedef struct KVMSlot
 int slot;
 int flags;
 int old_flags;
+/* Dirty bitmap cache for the slot */
+unsigned long *dirty_bmap;
 } KVMSlot;
 
 typedef struct KVMMemoryListener {
-- 
2.17.1




[Qemu-devel] [PATCH v2 08/15] memory: Introduce memory listener hook log_clear()

2019-05-19 Thread Peter Xu
Introduce a new memory region listener hook log_clear() to allow the
listeners to hook onto the points where the dirty bitmap is cleared by
the bitmap users.

Previously log_sync() contains two operations:

  - dirty bitmap collection, and,
  - dirty bitmap clear on remote site.

Let's take KVM as example - log_sync() for KVM will first copy the
kernel dirty bitmap to userspace, and at the same time we'll clear the
dirty bitmap there along with re-protecting all the guest pages again.

We add this new log_clear() interface only to split the old log_sync()
into two separated procedures:

  - use log_sync() to collect the collection only, and,
  - use log_clear() to clear the remote dirty bitmap.

With the new interface, the memory listener users will still be able
to decide how to implement the log synchronization procedure, e.g.,
they can still only provide log_sync() method only and put all the two
procedures within log_sync() (that's how the old KVM works before
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT is introduced).  However with this
new interface the memory listener users will start to have a chance to
postpone the log clear operation explicitly if the module supports.
That can really benefit users like KVM at least for host kernels that
support KVM_CAP_MANUAL_DIRTY_LOG_PROTECT.

There are three places that can clear dirty bits in any one of the
dirty bitmap in the ram_list.dirty_memory[3] array:

cpu_physical_memory_snapshot_and_clear_dirty
cpu_physical_memory_test_and_clear_dirty
cpu_physical_memory_sync_dirty_bitmap

Currently we hook directly into each of the functions to notify about
the log_clear().

Signed-off-by: Peter Xu 
---
 exec.c  | 12 ++
 include/exec/memory.h   | 17 ++
 include/exec/ram_addr.h |  3 +++
 memory.c| 51 +
 4 files changed, 83 insertions(+)

diff --git a/exec.c b/exec.c
index 2615b4cfed..ab595e1e4b 100644
--- a/exec.c
+++ b/exec.c
@@ -1355,6 +1355,8 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t 
start,
 DirtyMemoryBlocks *blocks;
 unsigned long end, page;
 bool dirty = false;
+RAMBlock *ramblock;
+uint64_t mr_offset, mr_size;
 
 if (length == 0) {
 return false;
@@ -1366,6 +1368,10 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t 
start,
 rcu_read_lock();
 
 blocks = atomic_rcu_read(_list.dirty_memory[client]);
+ramblock = qemu_get_ram_block(start);
+/* Range sanity check on the ramblock */
+assert(start >= ramblock->offset &&
+   start + length <= ramblock->offset + ramblock->used_length);
 
 while (page < end) {
 unsigned long idx = page / DIRTY_MEMORY_BLOCK_SIZE;
@@ -1377,6 +1383,10 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t 
start,
 page += num;
 }
 
+mr_offset = (ram_addr_t)(page << TARGET_PAGE_BITS) - ramblock->offset;
+mr_size = (end - page) << TARGET_PAGE_BITS;
+memory_region_clear_dirty_bitmap(ramblock->mr, mr_offset, mr_size);
+
 rcu_read_unlock();
 
 if (dirty && tcg_enabled()) {
@@ -1432,6 +1442,8 @@ DirtyBitmapSnapshot 
*cpu_physical_memory_snapshot_and_clear_dirty
 tlb_reset_dirty_range_all(start, length);
 }
 
+memory_region_clear_dirty_bitmap(mr, addr, length);
+
 return snap;
 }
 
diff --git a/include/exec/memory.h b/include/exec/memory.h
index f29300c54d..d752b2a758 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -416,6 +416,7 @@ struct MemoryListener {
 void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section,
  int old, int new);
 void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section);
+void (*log_clear)(MemoryListener *listener, MemoryRegionSection *section);
 void (*log_global_start)(MemoryListener *listener);
 void (*log_global_stop)(MemoryListener *listener);
 void (*eventfd_add)(MemoryListener *listener, MemoryRegionSection *section,
@@ -1269,6 +1270,22 @@ void memory_region_set_log(MemoryRegion *mr, bool log, 
unsigned client);
 void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr,
  hwaddr size);
 
+/**
+ * memory_region_clear_dirty_bitmap - clear dirty bitmap for memory range
+ *
+ * This function is called when the caller wants to clear the remote
+ * dirty bitmap of a memory range within the memory region.  This can
+ * be used by e.g. KVM to manually clear dirty log when
+ * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT is declared support by the host
+ * kernel.
+ *
+ * @mr: the memory region to clear the dirty log upon
+ * @start:  start address offset within the memory region
+ * @len:length of the memory region to clear dirty bitmap
+ */
+void memory_region_clear_dirty_bitmap(MemoryRegion *mr, hwaddr start,
+  hwaddr len);
+
 /**
  * memory_region_snapshot_and_clear_dirty: Get a snapshot of the dirty
  *  

[Qemu-devel] [PATCH v2 07/15] memory: Pass mr into snapshot_and_clear_dirty

2019-05-19 Thread Peter Xu
Also we change the 2nd parameter of it to be the relative offset
within the memory region. This is to be used in follow up patches.

Signed-off-by: Peter Xu 
---
 exec.c  | 3 ++-
 include/exec/ram_addr.h | 2 +-
 memory.c| 3 +--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/exec.c b/exec.c
index 4e734770c2..2615b4cfed 100644
--- a/exec.c
+++ b/exec.c
@@ -1387,9 +1387,10 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t 
start,
 }
 
 DirtyBitmapSnapshot *cpu_physical_memory_snapshot_and_clear_dirty
- (ram_addr_t start, ram_addr_t length, unsigned client)
+(MemoryRegion *mr, hwaddr addr, hwaddr length, unsigned client)
 {
 DirtyMemoryBlocks *blocks;
+ram_addr_t start = memory_region_get_ram_addr(mr) + addr;
 unsigned long align = 1UL << (TARGET_PAGE_BITS + BITS_PER_LEVEL);
 ram_addr_t first = QEMU_ALIGN_DOWN(start, align);
 ram_addr_t last  = QEMU_ALIGN_UP(start + length, align);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 86bc8e1a4a..69cc528c98 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -403,7 +403,7 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t 
start,
   unsigned client);
 
 DirtyBitmapSnapshot *cpu_physical_memory_snapshot_and_clear_dirty
-(ram_addr_t start, ram_addr_t length, unsigned client);
+(MemoryRegion *mr, ram_addr_t start, hwaddr length, unsigned client);
 
 bool cpu_physical_memory_snapshot_get_dirty(DirtyBitmapSnapshot *snap,
 ram_addr_t start,
diff --git a/memory.c b/memory.c
index cff0ea8f40..84bba7b65c 100644
--- a/memory.c
+++ b/memory.c
@@ -2071,8 +2071,7 @@ DirtyBitmapSnapshot 
*memory_region_snapshot_and_clear_dirty(MemoryRegion *mr,
 {
 assert(mr->ram_block);
 memory_region_sync_dirty_bitmap(mr);
-return cpu_physical_memory_snapshot_and_clear_dirty(
-memory_region_get_ram_addr(mr) + addr, size, client);
+return cpu_physical_memory_snapshot_and_clear_dirty(mr, addr, size, 
client);
 }
 
 bool memory_region_snapshot_get_dirty(MemoryRegion *mr, DirtyBitmapSnapshot 
*snap,
-- 
2.17.1




[Qemu-devel] [PATCH v2 02/15] linux-headers: Update to Linux 5.2-rc1

2019-05-19 Thread Peter Xu
Signed-off-by: Peter Xu 
---
 .../infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h |  15 +-
 include/standard-headers/drm/drm_fourcc.h | 114 +++-
 include/standard-headers/linux/ethtool.h  |  48 +++--
 .../linux/input-event-codes.h |   9 +-
 include/standard-headers/linux/input.h|   6 +-
 include/standard-headers/linux/pci_regs.h | 140 ---
 .../standard-headers/linux/virtio_config.h|   6 +
 include/standard-headers/linux/virtio_gpu.h   |  12 +-
 include/standard-headers/linux/virtio_ring.h  |  10 --
 .../standard-headers/rdma/vmw_pvrdma-abi.h|   1 +
 linux-headers/asm-arm/unistd-common.h |  32 
 linux-headers/asm-arm64/kvm.h |  43 +
 linux-headers/asm-arm64/unistd.h  |   2 +
 linux-headers/asm-generic/mman-common.h   |   4 +-
 linux-headers/asm-generic/unistd.h| 170 ++
 linux-headers/asm-mips/mman.h |   4 +-
 linux-headers/asm-mips/unistd_n32.h   |  30 
 linux-headers/asm-mips/unistd_n64.h   |  10 ++
 linux-headers/asm-mips/unistd_o32.h   |  40 +
 linux-headers/asm-powerpc/kvm.h   |  48 +
 linux-headers/asm-powerpc/unistd_32.h |  40 +
 linux-headers/asm-powerpc/unistd_64.h |  21 +++
 linux-headers/asm-s390/kvm.h  |   5 +-
 linux-headers/asm-s390/unistd_32.h|  43 +
 linux-headers/asm-s390/unistd_64.h|  24 +++
 linux-headers/asm-x86/kvm.h   |   1 +
 linux-headers/asm-x86/unistd_32.h |  40 +
 linux-headers/asm-x86/unistd_64.h |  10 ++
 linux-headers/asm-x86/unistd_x32.h|  10 ++
 linux-headers/linux/kvm.h |  15 +-
 linux-headers/linux/mman.h|   4 +
 linux-headers/linux/psci.h|   7 +
 linux-headers/linux/psp-sev.h |  18 +-
 linux-headers/linux/vfio.h|   4 +
 linux-headers/linux/vfio_ccw.h|  12 ++
 35 files changed, 854 insertions(+), 144 deletions(-)

diff --git 
a/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h 
b/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
index 422eb3f4c1..d019872608 100644
--- a/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
+++ b/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
@@ -57,7 +57,8 @@
 
 #define PVRDMA_ROCEV1_VERSION  17
 #define PVRDMA_ROCEV2_VERSION  18
-#define PVRDMA_VERSION PVRDMA_ROCEV2_VERSION
+#define PVRDMA_PPN64_VERSION   19
+#define PVRDMA_VERSION PVRDMA_PPN64_VERSION
 
 #define PVRDMA_BOARD_ID1
 #define PVRDMA_REV_ID  1
@@ -279,8 +280,10 @@ struct pvrdma_device_shared_region {
/* W: Async ring page info. */
struct pvrdma_ring_page_info cq_ring_pages;
/* W: CQ ring page info. */
-   uint32_t uar_pfn;   /* W: UAR pageframe. */
-   uint32_t pad2;  /* Pad to 8-byte align. */
+   union {
+   uint32_t uar_pfn;   /* W: UAR pageframe. */
+   uint64_t uar_pfn64; /* W: 64-bit UAR page 
frame. */
+   };
struct pvrdma_device_caps caps; /* R: Device capabilities. */
 };
 
@@ -411,8 +414,10 @@ struct pvrdma_cmd_query_pkey_resp {
 
 struct pvrdma_cmd_create_uc {
struct pvrdma_cmd_hdr hdr;
-   uint32_t pfn; /* UAR page frame number */
-   uint8_t reserved[4];
+   union {
+   uint32_t pfn; /* UAR page frame number */
+   uint64_t pfn64; /* 64-bit UAR page frame number */
+   };
 };
 
 struct pvrdma_cmd_create_uc_resp {
diff --git a/include/standard-headers/drm/drm_fourcc.h 
b/include/standard-headers/drm/drm_fourcc.h
index 44490607f9..a308c91b4f 100644
--- a/include/standard-headers/drm/drm_fourcc.h
+++ b/include/standard-headers/drm/drm_fourcc.h
@@ -143,6 +143,17 @@ extern "C" {
 #define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0') /* [31:0] 
R:G:B:A 10:10:10:2 little endian */
 #define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') /* [31:0] 
B:G:R:A 10:10:10:2 little endian */
 
+/*
+ * Floating point 64bpp RGB
+ * IEEE 754-2008 binary16 half-precision float
+ * [15:0] sign:exponent:mantissa 1:5:10
+ */
+#define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H') /* [63:0] 
x:R:G:B 16:16:16:16 little endian */
+#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H') /* [63:0] 
x:B:G:R 16:16:16:16 little endian */
+
+#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H') /* [63:0] 
A:R:G:B 16:16:16:16 little endian */
+#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') /* [63:0] 
A:B:G:R 16:16:16:16 little 

Re: [Qemu-devel] [PATCH v2 3/8] target/sparc: Define an enumeration for accessing env->regwptr

2019-05-19 Thread Richard Henderson
On 5/14/19 10:44 PM, Philippe Mathieu-Daudé wrote:
>> +/* Windowed register indexes.  */
>> +enum {
>> +WREG_O0,
>> +WREG_O1,
>> +WREG_O2,
>> +WREG_O3,
>> +WREG_O4,
>> +WREG_O5,
>> +WREG_O6,
>> +WREG_O7,
>> +
>> +WREG_L0,
>> +WREG_L1,
>> +WREG_L2,
>> +WREG_L3,
>> +WREG_L4,
>> +WREG_L5,
>> +WREG_L6,
>> +WREG_L7,
>> +
>> +WREG_I0,
>> +WREG_I1,
>> +WREG_I2,
>> +WREG_I3,
>> +WREG_I4,
>> +WREG_I5,
>> +WREG_I6,
>> +WREG_I7,
> 
> I'd feel safer if you initialize those enums (better safe than sorry!).

What are you suggesting?  This is how C works, and always has...


r~



[Qemu-devel] [PATCH v2 06/15] bitmap: Add bitmap_copy_with_{src|dst}_offset()

2019-05-19 Thread Peter Xu
These helpers copy the source bitmap to destination bitmap with a
shift either on the src or dst bitmap.

Meanwhile, we never have bitmap tests but we should.

This patch also introduces the initial test cases for utils/bitmap.c
but it only tests the newly introduced functions.

Signed-off-by: Peter Xu 
---
 include/qemu/bitmap.h  |  9 +
 tests/Makefile.include |  2 ++
 tests/test-bitmap.c| 81 ++
 util/bitmap.c  | 73 +
 4 files changed, 165 insertions(+)
 create mode 100644 tests/test-bitmap.c

diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
index 5c313346b9..cdaa953371 100644
--- a/include/qemu/bitmap.h
+++ b/include/qemu/bitmap.h
@@ -41,6 +41,10 @@
  * bitmap_find_next_zero_area(buf, len, pos, n, mask)  Find bit free area
  * bitmap_to_le(dst, src, nbits)  Convert bitmap to little endian
  * bitmap_from_le(dst, src, nbits)Convert bitmap from little endian
+ * bitmap_copy_with_src_offset(dst, src, offset, nbits)
+ **dst = *src (with an offset upon src)
+ * bitmap_copy_with_dst_offset(dst, src, offset, nbits)
+ **dst = *src (with an offset upon dst)
  */
 
 /*
@@ -271,4 +275,9 @@ void bitmap_to_le(unsigned long *dst, const unsigned long 
*src,
 void bitmap_from_le(unsigned long *dst, const unsigned long *src,
 long nbits);
 
+void bitmap_copy_with_src_offset(unsigned long *dst, const unsigned long *src,
+ long offset, long nbits);
+void bitmap_copy_with_dst_offset(unsigned long *dst, const unsigned long *src,
+ long shift, long nbits);
+
 #endif /* BITMAP_H */
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 1865f6b322..5e2d7dddff 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -64,6 +64,7 @@ check-unit-y += tests/test-opts-visitor$(EXESUF)
 check-unit-$(CONFIG_BLOCK) += tests/test-coroutine$(EXESUF)
 check-unit-y += tests/test-visitor-serialization$(EXESUF)
 check-unit-y += tests/test-iov$(EXESUF)
+check-unit-y += tests/test-bitmap$(EXESUF)
 check-unit-$(CONFIG_BLOCK) += tests/test-aio$(EXESUF)
 check-unit-$(CONFIG_BLOCK) += tests/test-aio-multithread$(EXESUF)
 check-unit-$(CONFIG_BLOCK) += tests/test-throttle$(EXESUF)
@@ -529,6 +530,7 @@ tests/test-image-locking$(EXESUF): 
tests/test-image-locking.o $(test-block-obj-y
 tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
 tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
 tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) 
$(test-crypto-obj-y)
+tests/test-bitmap$(EXESUF): tests/test-bitmap.o $(test-util-obj-y)
 tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
 tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o 
migration/page_cache.o $(test-util-obj-y)
 tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o 
$(test-util-obj-y)
diff --git a/tests/test-bitmap.c b/tests/test-bitmap.c
new file mode 100644
index 00..36b4c07bf2
--- /dev/null
+++ b/tests/test-bitmap.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Bitmap.c unit-tests.
+ *
+ * Copyright (C) 2019, Red Hat, Inc.
+ *
+ * Author: Peter Xu 
+ */
+
+#include 
+#include "qemu/osdep.h"
+#include "qemu/bitmap.h"
+
+#define BMAP_SIZE  1024
+
+static void check_bitmap_copy_with_offset(void)
+{
+int i;
+unsigned long *bmap1, *bmap2, *bmap3, total;
+
+bmap1 = bitmap_new(BMAP_SIZE);
+bmap2 = bitmap_new(BMAP_SIZE);
+bmap3 = bitmap_new(BMAP_SIZE);
+
+*bmap1 = random();
+*(bmap1 + 1) = random();
+*(bmap1 + 2) = random();
+*(bmap1 + 3) = random();
+total = BITS_PER_LONG * 4;
+
+/* Shift 115 bits into bmap2 */
+bitmap_copy_with_dst_offset(bmap2, bmap1, 115, total);
+/* Shift another 85 bits into bmap3 */
+bitmap_copy_with_dst_offset(bmap3, bmap2, 85, total + 115);
+/* Shift back 200 bits back */
+bitmap_copy_with_src_offset(bmap2, bmap3, 200, total);
+
+for (i = 0; i < 3; i++) {
+g_assert(*(bmap1 + i) == *(bmap2 + i));
+}
+
+bitmap_clear(bmap1, 0, BMAP_SIZE);
+/* Set bits in bmap1 are 100-245 */
+bitmap_set(bmap1, 100, 145);
+
+/* Set bits in bmap2 are 60-205 */
+bitmap_copy_with_src_offset(bmap2, bmap1, 40, 250);
+for (i = 0; i < 60; i++) {
+g_assert(test_bit(i, bmap2) == 0);
+}
+for (i = 60; i < 205; i++) {
+g_assert(test_bit(i, bmap2));
+}
+g_assert(test_bit(205, bmap2) == 0);
+
+/* Set bits in bmap3 are 135-280 */
+bitmap_copy_with_dst_offset(bmap3, bmap1, 35, 250);
+for (i = 0; i < 135; i++) {
+g_assert(test_bit(i, bmap3) == 0);
+}
+for (i = 135; i < 280; i++) {
+g_assert(test_bit(i, bmap3));
+}
+g_assert(test_bit(280, bmap3) == 0);
+
+g_free(bmap1);
+g_free(bmap2);
+g_free(bmap3);
+}
+
+int main(int argc, char 

[Qemu-devel] [PATCH v2 05/15] memory: Don't set migration bitmap when without migration

2019-05-19 Thread Peter Xu
Similar to 9460dee4b2 ("memory: do not touch code dirty bitmap unless
TCG is enabled", 2015-06-05) but for the migration bitmap - we can
skip the MIGRATION bitmap update if migration not enabled.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 include/exec/memory.h   |  2 ++
 include/exec/ram_addr.h | 12 +++-
 memory.c|  2 +-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index e6140e8a04..f29300c54d 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -46,6 +46,8 @@
 OBJECT_GET_CLASS(IOMMUMemoryRegionClass, (obj), \
  TYPE_IOMMU_MEMORY_REGION)
 
+extern bool global_dirty_log;
+
 typedef struct MemoryRegionOps MemoryRegionOps;
 typedef struct MemoryRegionMmio MemoryRegionMmio;
 
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 993fb760f3..86bc8e1a4a 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -348,8 +348,13 @@ static inline void 
cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
 if (bitmap[k]) {
 unsigned long temp = leul_to_cpu(bitmap[k]);
 
-atomic_or([DIRTY_MEMORY_MIGRATION][idx][offset], temp);
 atomic_or([DIRTY_MEMORY_VGA][idx][offset], temp);
+
+if (global_dirty_log) {
+atomic_or([DIRTY_MEMORY_MIGRATION][idx][offset],
+  temp);
+}
+
 if (tcg_enabled()) {
 atomic_or([DIRTY_MEMORY_CODE][idx][offset], temp);
 }
@@ -366,6 +371,11 @@ static inline void 
cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
 xen_hvm_modified_memory(start, pages << TARGET_PAGE_BITS);
 } else {
 uint8_t clients = tcg_enabled() ? DIRTY_CLIENTS_ALL : 
DIRTY_CLIENTS_NOCODE;
+
+if (!global_dirty_log) {
+clients &= ~(1 << DIRTY_MEMORY_MIGRATION);
+}
+
 /*
  * bitmap-traveling is faster than memory-traveling (for addr...)
  * especially when most of the memory is not dirty.
diff --git a/memory.c b/memory.c
index 0920c105aa..cff0ea8f40 100644
--- a/memory.c
+++ b/memory.c
@@ -38,7 +38,7 @@
 static unsigned memory_region_transaction_depth;
 static bool memory_region_update_pending;
 static bool ioeventfd_update_pending;
-static bool global_dirty_log = false;
+bool global_dirty_log;
 
 static QTAILQ_HEAD(, MemoryListener) memory_listeners
 = QTAILQ_HEAD_INITIALIZER(memory_listeners);
-- 
2.17.1




[Qemu-devel] [PATCH v2 04/15] memory: Remove memory_region_get_dirty()

2019-05-19 Thread Peter Xu
It's never used anywhere.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 include/exec/memory.h | 17 -
 memory.c  |  8 
 2 files changed, 25 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 9144a47f57..e6140e8a04 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1254,23 +1254,6 @@ void memory_region_ram_resize(MemoryRegion *mr, 
ram_addr_t newsize,
  */
 void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client);
 
-/**
- * memory_region_get_dirty: Check whether a range of bytes is dirty
- *  for a specified client.
- *
- * Checks whether a range of bytes has been written to since the last
- * call to memory_region_reset_dirty() with the same @client.  Dirty logging
- * must be enabled.
- *
- * @mr: the memory region being queried.
- * @addr: the address (relative to the start of the region) being queried.
- * @size: the size of the range being queried.
- * @client: the user of the logging information; %DIRTY_MEMORY_MIGRATION or
- *  %DIRTY_MEMORY_VGA.
- */
-bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr,
- hwaddr size, unsigned client);
-
 /**
  * memory_region_set_dirty: Mark a range of bytes as dirty in a memory region.
  *
diff --git a/memory.c b/memory.c
index 3071c4bdad..0920c105aa 100644
--- a/memory.c
+++ b/memory.c
@@ -2027,14 +2027,6 @@ void memory_region_set_log(MemoryRegion *mr, bool log, 
unsigned client)
 memory_region_transaction_commit();
 }
 
-bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr,
- hwaddr size, unsigned client)
-{
-assert(mr->ram_block);
-return cpu_physical_memory_get_dirty(memory_region_get_ram_addr(mr) + addr,
- size, client);
-}
-
 void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr,
  hwaddr size)
 {
-- 
2.17.1




[Qemu-devel] [PATCH v2 00/15] kvm/migration: support KVM_CLEAR_DIRTY_LOG

2019-05-19 Thread Peter Xu
This is v2 of the QEMU's KVM_CLEAR_DIRTY_LOG series.  The major reason
for the repost is due to the new kvm capability recently introduced in
Linux 5.2-rc1 which is released just one day ago while the old cap is
obsolete now, so we'll need a linux header update.

v2:
- rebase, add r-bs from Paolo
- added a few patches
  - linux-headers: Update to Linux 5.2-rc1
this is needed because we've got a new cap in kvm
  - checkpatch: Allow SPDX-License-Identifier
picked up the standalone patch into the series in case it got lost
  - hmp: Expose manual_dirty_log_protect via "info kvm"
qmp: Expose manual_dirty_log_protect via "query-kvm"
add interface to detect the new kvm capability
- switched default chunk size to 128M

Performance update is here:

  https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg03621.html

Summary
=

This series allows QEMU to start using the new KVM_CLEAR_DIRTY_LOG
interface. For more on KVM_CLEAR_DIRTY_LOG itself, please refer to:

  
https://github.com/torvalds/linux/blob/master/Documentation/virtual/kvm/api.txt#L3810

The QEMU work (which is this series) is pushed too, please find the
tree here:

  https://github.com/xzpeter/qemu/tree/kvm-clear-dirty-log

Meanwhile, For anyone who really wants to try this out, please also
upgrade the host kernel to linux 5.2-rc1.

Design
===

I started with a naive/stupid design that I always pass all 1's to the
KVM for a memory range to clear all the dirty bits within that memory
range, but then I encountered guest oops - it's simply because we
can't clear any dirty bit from QEMU if we are not _sure_ that the bit
is dirty in the kernel.  Otherwise we might accidentally clear a bit
that we don't even know of (e.g., the bit was clear in migration's
dirty bitmap in QEMU) but actually that page was just being written so
QEMU will never remember to migrate that new page again.

The new design is focused on a dirty bitmap cache within the QEMU kvm
layer (which is per kvm memory slot).  With that we know what's dirty
in the kernel previously (note! the kernel bitmap is still growing all
the time so the cache will only be a subset of the realtime kernel
bitmap but that's far enough for us) and with that we'll be sure to
not accidentally clear unknown dirty pages.

With this method, we can also avoid race when multiple users (e.g.,
DIRTY_MEMORY_VGA and DIRTY_MEMORY_MIGRATION) want to clear the bit for
multiple time.  If without the kvm memory slot cached dirty bitmap we
won't be able to know which bit has been cleared and then if we send
the CLEAR operation upon the same bit twice (or more) we can still
face the same issue to clear something accidentally while we
shouldn't.

Summary: we really need to be careful on what bit to clear otherwise
we can face anything after the migration completes.  And I hope this
series has considered all about this.

Besides the new KVM cache layer and the new ioctl support, this series
introduced the memory_region_clear_dirty_bitmap() in the memory API
layer to allow clearing dirty bits of a specific memory range within
the memory region.

Implementations


Patch 1-3:  these should be nothing directly related to the series but
they are things I found during working on it.  They can be
picked even earlier if reviewers are happy with them.

Patch 4:pre-work on bitmap operations, and within the patch I added
the first unit test for utils/bitmap.c.

Patch 5-6:  the new memory API interface.  Since no one is providing
log_clear() yet so it's not working yet.  Note that this
only splits the dirty clear operation from sync but it
hasn't yet been splitted into smaller chunk so it's not
really helpful for us yet.

Patch 7-10: kvm support of KVM_CLEAR_DIRTY_LOG.

Patch 11:   do the log_clear() splitting for the case of migration.
Also a new parameter is introduced to define the block
size of the small chunks (the unit to clear dirty bits)

Tests
===

- make check
- migrate idle/memory-heavy guests

(Not yet tested with huge guests but it'll be more than welcomed if
 someone has the resource and wants to give it a shot)

Please have a look, thanks.

Peter Xu (15):
  checkpatch: Allow SPDX-License-Identifier
  linux-headers: Update to Linux 5.2-rc1
  migration: No need to take rcu during sync_dirty_bitmap
  memory: Remove memory_region_get_dirty()
  memory: Don't set migration bitmap when without migration
  bitmap: Add bitmap_copy_with_{src|dst}_offset()
  memory: Pass mr into snapshot_and_clear_dirty
  memory: Introduce memory listener hook log_clear()
  kvm: Update comments for sync_dirty_bitmap
  kvm: Persistent per kvmslot dirty bitmap
  kvm: Introduce slots lock for memory listener
  kvm: Support KVM_CLEAR_DIRTY_LOG
  qmp: Expose manual_dirty_log_protect via "query-kvm"
  hmp: Expose manual_dirty_log_protect via "info 

[Qemu-devel] [PATCH v2 11/15] kvm: Introduce slots lock for memory listener

2019-05-19 Thread Peter Xu
Introduce KVMMemoryListener.slots_lock to protect the slots inside the
kvm memory listener.  Currently it is close to useless because all the
KVM code path now is always protected by the BQL.  But it'll start to
make sense in follow up patches where we might do remote dirty bitmap
clear and also we'll update the per-slot cached dirty bitmap even
without the BQL.  So let's prepare for it.

We can also use per-slot lock for above reason but it seems to be an
overkill.  Let's just use this bigger one (which covers all the slots
of a single address space) but anyway this lock is still much smaller
than the BQL.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c  | 58 +++-
 include/sysemu/kvm_int.h |  2 ++
 2 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 334c610918..a19535bf6a 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -138,6 +138,9 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = 
{
 KVM_CAP_LAST_INFO
 };
 
+#define kvm_slots_lock(kml)  qemu_mutex_lock(&(kml)->slots_lock)
+#define kvm_slots_unlock(kml)qemu_mutex_unlock(&(kml)->slots_lock)
+
 int kvm_get_max_memslots(void)
 {
 KVMState *s = KVM_STATE(current_machine->accelerator);
@@ -165,6 +168,7 @@ int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
 return 1;
 }
 
+/* Must be with slots_lock held */
 static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
 {
 KVMState *s = kvm_state;
@@ -182,10 +186,17 @@ static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
 bool kvm_has_free_slot(MachineState *ms)
 {
 KVMState *s = KVM_STATE(ms->accelerator);
+bool result;
+KVMMemoryListener *kml = >memory_listener;
+
+kvm_slots_lock(kml);
+result = !!kvm_get_free_slot(kml);
+kvm_slots_unlock(kml);
 
-return kvm_get_free_slot(>memory_listener);
+return result;
 }
 
+/* Must be with slots_lock held */
 static KVMSlot *kvm_alloc_slot(KVMMemoryListener *kml)
 {
 KVMSlot *slot = kvm_get_free_slot(kml);
@@ -244,18 +255,21 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void 
*ram,
hwaddr *phys_addr)
 {
 KVMMemoryListener *kml = >memory_listener;
-int i;
+int i, ret = 0;
 
+kvm_slots_lock(kml);
 for (i = 0; i < s->nr_slots; i++) {
 KVMSlot *mem = >slots[i];
 
 if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
 *phys_addr = mem->start_addr + (ram - mem->ram);
-return 1;
+ret = 1;
+break;
 }
 }
+kvm_slots_unlock(kml);
 
-return 0;
+return ret;
 }
 
 static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, 
bool new)
@@ -391,6 +405,7 @@ static int kvm_mem_flags(MemoryRegion *mr)
 return flags;
 }
 
+/* Must be with slots_lock held */
 static int kvm_slot_update_flags(KVMMemoryListener *kml, KVMSlot *mem,
  MemoryRegion *mr)
 {
@@ -409,19 +424,26 @@ static int kvm_section_update_flags(KVMMemoryListener 
*kml,
 {
 hwaddr start_addr, size;
 KVMSlot *mem;
+int ret = 0;
 
 size = kvm_align_section(section, _addr);
 if (!size) {
 return 0;
 }
 
+kvm_slots_lock(kml);
+
 mem = kvm_lookup_matching_slot(kml, start_addr, size);
 if (!mem) {
 /* We don't have a slot if we want to trap every access. */
-return 0;
+goto out;
 }
 
-return kvm_slot_update_flags(kml, mem, section->mr);
+ret = kvm_slot_update_flags(kml, mem, section->mr);
+
+out:
+kvm_slots_unlock(kml);
+return ret;
 }
 
 static void kvm_log_start(MemoryListener *listener,
@@ -478,6 +500,8 @@ static int 
kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
  * This function will first try to fetch dirty bitmap from the kernel,
  * and then updates qemu's dirty bitmap.
  *
+ * NOTE: caller must be with kml->slots_lock held.
+ *
  * @kml: the KVM memory listener object
  * @section: the memory section to sync the dirty bitmap with
  */
@@ -488,26 +512,28 @@ static int 
kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
 struct kvm_dirty_log d = {};
 KVMSlot *mem;
 hwaddr start_addr, size;
+int ret = 0;
 
 size = kvm_align_section(section, _addr);
 if (size) {
 mem = kvm_lookup_matching_slot(kml, start_addr, size);
 if (!mem) {
 /* We don't have a slot if we want to trap every access. */
-return 0;
+goto out;
 }
 
 d.dirty_bitmap = mem->dirty_bmap;
 d.slot = mem->slot | (kml->as_id << 16);
 if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, ) == -1) {
 DPRINTF("ioctl failed %d\n", errno);
-return -1;
+ret = -1;
+goto out;
 }
 
 kvm_get_dirty_pages_log_range(section, d.dirty_bitmap);
 }
-
-return 0;
+out:
+return ret;
 }
 
 static void 

[Qemu-devel] [PATCH v2 03/15] migration: No need to take rcu during sync_dirty_bitmap

2019-05-19 Thread Peter Xu
cpu_physical_memory_sync_dirty_bitmap() has one RAMBlock* as
parameter, which means that it must be with RCU read lock held
already.  Taking it again inside seems redundant.  Removing it.
Instead comment on the functions about the RCU read lock.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 include/exec/ram_addr.h | 5 +
 migration/ram.c | 1 +
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 139ad79390..993fb760f3 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -408,6 +408,7 @@ static inline void 
cpu_physical_memory_clear_dirty_range(ram_addr_t start,
 }
 
 
+/* Must be with rcu read lock held */
 static inline
 uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
ram_addr_t start,
@@ -431,8 +432,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
 DIRTY_MEMORY_BLOCK_SIZE);
 unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS);
 
-rcu_read_lock();
-
 src = atomic_rcu_read(
 _list.dirty_memory[DIRTY_MEMORY_MIGRATION])->blocks;
 
@@ -452,8 +451,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
 idx++;
 }
 }
-
-rcu_read_unlock();
 } else {
 ram_addr_t offset = rb->offset;
 
diff --git a/migration/ram.c b/migration/ram.c
index 4c60869226..05f9f36c7c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1678,6 +1678,7 @@ static inline bool migration_bitmap_clear_dirty(RAMState 
*rs,
 return ret;
 }
 
+/* Must be with rcu read lock held */
 static void migration_bitmap_sync_range(RAMState *rs, RAMBlock *rb,
 ram_addr_t length)
 {
-- 
2.17.1




[Qemu-devel] [PATCH v2 01/15] checkpatch: Allow SPDX-License-Identifier

2019-05-19 Thread Peter Xu
According to: https://spdx.org/ids-how, let's still allow QEMU to use
the SPDX license identifier:

// SPDX-License-Identifier: ***

Signed-off-by: Peter Xu 
---
 scripts/checkpatch.pl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 88682cb0a9..c2aaf421da 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1949,7 +1949,8 @@ sub process {
}
 
 # no C99 // comments
-   if ($line =~ m{//}) {
+   if ($line =~ m{//} &&
+   $rawline !~ m{// SPDX-License-Identifier: }) {
ERROR("do not use C99 // comments\n" . $herecurr);
}
# Remove C99 comments.
-- 
2.17.1




Re: [Qemu-devel] [PATCH v2 2/2] linux-user: add pseudo /proc/hardware for m68k

2019-05-19 Thread Richard Henderson
On 5/17/19 6:31 AM, Laurent Vivier wrote:
> Debian console-setup uses /proc/hardware to guess the keyboard layout.
> If the file /proc/hardware cannot be opened, the installation fails.
> 
> This patch adds a pseudo /proc/hardware file to report the model of
> the machine. Instead of reporting a known and fake model, it
> reports "qemu-m68k", which is true, and avoids to set the configuration
> for an Amiga/Apple/Atari and let the user to chose the good one.
> 
> Bug: https://github.com/vivier/qemu-m68k/issues/34
> Signed-off-by: Laurent Vivier 
> ---
>  linux-user/syscall.c | 13 -
>  1 file changed, 12 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~




Re: [Qemu-devel] [PATCH v2 1/2] linux-user: add pseudo /proc/cpuinfo for sparc

2019-05-19 Thread Richard Henderson
On 5/17/19 6:31 AM, Laurent Vivier wrote:
> SPARC libc6 debian package wants to check the cpu level to be
> installed or not:
> 
>   WARNING: This machine has a SPARC V8 or earlier class processor.
>   Debian lenny and later does not support such old hardware
>   any longer.
> 
> To avoid this, it only needs to know if the machine type is sun4u or sun4v,
> for that it reads the information from /proc/cpuinfo.
> 
> Fixes: 9a93c152fcdb4ab2cd85094487b33578fd693915
>("linux-user: fix UNAME_MACHINE for sparc/sparc64")
> Signed-off-by: Laurent Vivier 
> ---
>  linux-user/syscall.c | 16 +++-
>  1 file changed, 15 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH v5 5/6] hw/acpi: Consolidate build_mcfg to pci.c

2019-05-19 Thread Wei Yang
On Mon, May 20, 2019 at 08:59:56AM +0800, Wei Yang wrote:
>Now we have two identical build_mcfg functions.
>
>Consolidate them in acpi/pci.c.
>
>Signed-off-by: Wei Yang 
>Reviewed-by: Philippe Mathieu-Daudé 
>Reviewed-by: Igor Mammedov 

Oops, I should drop these SOB.

>
>---
>v4:
>  * ACPI_PCI depends on both ACPI and PCI
>  * rebase on latest master, adjust arm Kconfig
>v3:
>  * adjust changelog based on Igor's suggestion
>---
> default-configs/i386-softmmu.mak |  1 +
> hw/acpi/Kconfig  |  4 +++
> hw/acpi/Makefile.objs|  1 +
> hw/acpi/pci.c| 46 
> hw/arm/Kconfig   |  1 +
> hw/arm/virt-acpi-build.c | 17 
> hw/i386/acpi-build.c | 18 +
> include/hw/acpi/pci.h|  1 +
> 8 files changed, 55 insertions(+), 34 deletions(-)
> create mode 100644 hw/acpi/pci.c
>
>diff --git a/default-configs/i386-softmmu.mak 
>b/default-configs/i386-softmmu.mak
>index ba3fb3ff50..cd5ea391e8 100644
>--- a/default-configs/i386-softmmu.mak
>+++ b/default-configs/i386-softmmu.mak
>@@ -25,3 +25,4 @@
> CONFIG_ISAPC=y
> CONFIG_I440FX=y
> CONFIG_Q35=y
>+CONFIG_ACPI_PCI=y
>diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
>index eca3beed75..7c59cf900b 100644
>--- a/hw/acpi/Kconfig
>+++ b/hw/acpi/Kconfig
>@@ -23,6 +23,10 @@ config ACPI_NVDIMM
> bool
> depends on ACPI
> 
>+config ACPI_PCI
>+bool
>+depends on ACPI && PCI
>+
> config ACPI_VMGENID
> bool
> default y
>diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
>index 2d46e3789a..661a9b8c2f 100644
>--- a/hw/acpi/Makefile.objs
>+++ b/hw/acpi/Makefile.objs
>@@ -11,6 +11,7 @@ common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
> common-obj-y += acpi_interface.o
> common-obj-y += bios-linker-loader.o
> common-obj-y += aml-build.o
>+common-obj-$(CONFIG_ACPI_PCI) += pci.o
> common-obj-$(CONFIG_TPM) += tpm.o
> 
> common-obj-$(CONFIG_IPMI) += ipmi.o
>diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
>new file mode 100644
>index 00..fa0fa30bb9
>--- /dev/null
>+++ b/hw/acpi/pci.c
>@@ -0,0 +1,46 @@
>+/*
>+ * Support for generating PCI related ACPI tables and passing them to Guests
>+ *
>+ * Copyright (C) 2006 Fabrice Bellard
>+ * Copyright (C) 2008-2010  Kevin O'Connor 
>+ * Copyright (C) 2013-2019 Red Hat Inc
>+ * Copyright (C) 2019 Intel Corporation
>+ *
>+ * Author: Wei Yang 
>+ * Author: Michael S. Tsirkin 
>+ *
>+ * This program is free software; you can redistribute it and/or modify
>+ * it under the terms of the GNU General Public License as published by
>+ * the Free Software Foundation; either version 2 of the License, or
>+ * (at your option) any later version.
>+
>+ * This program is distributed in the hope that it will be useful,
>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>+ * GNU General Public License for more details.
>+
>+ * You should have received a copy of the GNU General Public License along
>+ * with this program; if not, see .
>+ */
>+
>+#include "qemu/osdep.h"
>+#include "hw/acpi/aml-build.h"
>+#include "hw/acpi/pci.h"
>+#include "hw/pci/pcie_host.h"
>+
>+void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
>+{
>+AcpiTableMcfg *mcfg;
>+int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
>+
>+mcfg = acpi_data_push(table_data, len);
>+mcfg->allocation[0].address = cpu_to_le64(info->base);
>+
>+/* Only a single allocation so no need to play with segments */
>+mcfg->allocation[0].pci_segment = cpu_to_le16(0);
>+mcfg->allocation[0].start_bus_number = 0;
>+mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);
>+
>+build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, 
>NULL);
>+}
>+
>diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
>index af8cffde9c..9aced9d54d 100644
>--- a/hw/arm/Kconfig
>+++ b/hw/arm/Kconfig
>@@ -19,6 +19,7 @@ config ARM_VIRT
> select PLATFORM_BUS
> select SMBIOS
> select VIRTIO_MMIO
>+select ACPI_PCI
> 
> config CHEETAH
> bool
>diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>index e7c96d658e..4a64f9985c 100644
>--- a/hw/arm/virt-acpi-build.c
>+++ b/hw/arm/virt-acpi-build.c
>@@ -546,23 +546,6 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
>VirtMachineState *vms)
>  "SRAT", table_data->len - srat_start, 3, NULL, NULL);
> }
> 
>-static void
>-build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
>-{
>-AcpiTableMcfg *mcfg;
>-int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
>-
>-mcfg = acpi_data_push(table_data, len);
>-mcfg->allocation[0].address = cpu_to_le64(info->base);
>-
>-/* Only a single allocation so no need to play with segments */
>-mcfg->allocation[0].pci_segment = cpu_to_le16(0);
>-mcfg->allocation[0].start_bus_number = 0;
>-

Re: [Qemu-devel] [PATCH v3 3/8] tests: Add migration multifd test

2019-05-19 Thread Wei Yang
On Wed, May 15, 2019 at 02:15:39PM +0200, Juan Quintela wrote:
>We set multifd-channels.
>
>Reviewed-by: Dr. David Alan Gilbert 
>Reviewed-by: Thomas Huth 
>Signed-off-by: Juan Quintela 
>---
> tests/migration-test.c | 48 ++
> 1 file changed, 48 insertions(+)
>
>diff --git a/tests/migration-test.c b/tests/migration-test.c
>index 0b25aa3d6c..ff480e0682 100644
>--- a/tests/migration-test.c
>+++ b/tests/migration-test.c
>@@ -1028,6 +1028,53 @@ static void test_precopy_tcp(void)
> g_free(uri);
> }
> 
>+static void test_multifd_tcp(void)
>+{
>+char *uri;
>+QTestState *from, *to;
>+
>+if (test_migrate_start(, , "tcp:127.0.0.1:0", false, false)) {
>+return;
>+}
>+
>+/*
>+ * We want to pick a speed slow enough that the test completes
>+ * quickly, but that it doesn't complete precopy even on a slow
>+ * machine, so also set the downtime.
>+ */
>+/* 1 ms should make it not converge*/
>+migrate_set_parameter_int(from, "downtime-limit", 1);
>+/* 1GB/s */
>+migrate_set_parameter_int(from, "max-bandwidth", 10);
>+
>+migrate_set_parameter_int(from, "multifd-channels", 2);
>+migrate_set_parameter_int(to, "multifd-channels", 2);
>+
>+migrate_set_capability(from, "multifd", "true");
>+migrate_set_capability(to, "multifd", "true");

Hi, Juan

In case to test multifd, what's the minimum configuration? Set multifd
capability at both side is fine?

>+/* Wait for the first serial output from the source */
>+wait_for_serial("src_serial");
>+
>+uri = migrate_get_socket_address(to, "socket-address");
>+
>+migrate(from, uri, "{}");
>+
>+wait_for_migration_pass(from);
>+
>+/* 300ms it should converge */
>+migrate_set_parameter_int(from, "downtime-limit", 600);
>+
>+if (!got_stop) {
>+qtest_qmp_eventwait(from, "STOP");
>+}
>+qtest_qmp_eventwait(to, "RESUME");
>+
>+wait_for_serial("dest_serial");
>+wait_for_migration_complete(from);
>+
>+test_migrate_end(from, to, true);
>+}
>+
> int main(int argc, char **argv)
> {
> char template[] = "/tmp/migration-test-XX";
>@@ -1082,6 +1129,7 @@ int main(int argc, char **argv)
> qtest_add_func("/migration/precopy/tcp", test_precopy_tcp);
> /* qtest_add_func("/migration/ignore_shared", test_ignore_shared); */
> qtest_add_func("/migration/xbzrle/unix", test_xbzrle_unix);
>+qtest_add_func("/migration/multifd/tcp", test_multifd_tcp);
> 
> ret = g_test_run();
> 
>-- 
>2.21.0
>

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH 2/4] hw: vfio: drop TYPE_FOO MACRO in VMStateDescription

2019-05-19 Thread Li Qiang
Alex Williamson  于2019年5月18日周六 下午10:20写道:

> On Fri, 17 May 2019 20:28:09 -0700
> Li Qiang  wrote:
>
> > As the vmstate structure names aren't related with
> > the QOM type names.
>
> Seems contrary to the first patch in the series.
>
>
No, once there is a discussion of this:
-->https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg02175.html

Thanks,
Li Qiang



> > CC: qemu-triv...@nongnu.org
> > Signed-off-by: Li Qiang 
> > ---
> >  hw/vfio/amd-xgbe.c  | 2 +-
> >  hw/vfio/ap.c| 2 +-
> >  hw/vfio/calxeda-xgmac.c | 2 +-
> >  hw/vfio/ccw.c   | 2 +-
> >  hw/vfio/platform.c  | 2 +-
> >  5 files changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/vfio/amd-xgbe.c b/hw/vfio/amd-xgbe.c
> > index ee64a3b4a2..1b06c0f3ea 100644
> > --- a/hw/vfio/amd-xgbe.c
> > +++ b/hw/vfio/amd-xgbe.c
> > @@ -26,7 +26,7 @@ static void amd_xgbe_realize(DeviceState *dev, Error
> **errp)
> >  }
> >
> >  static const VMStateDescription vfio_platform_amd_xgbe_vmstate = {
> > -.name = TYPE_VFIO_AMD_XGBE,
> > +.name = "vfio-amd-xgbe",
> >  .unmigratable = 1,
> >  };
> >
> > diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
> > index d8b79ebe53..564751650f 100644
> > --- a/hw/vfio/ap.c
> > +++ b/hw/vfio/ap.c
> > @@ -155,7 +155,7 @@ static void vfio_ap_reset(DeviceState *dev)
> >  }
> >
> >  static const VMStateDescription vfio_ap_vmstate = {
> > -.name = VFIO_AP_DEVICE_TYPE,
> > +.name = "vfio-ap",
> >  .unmigratable = 1,
> >  };
> >
> > diff --git a/hw/vfio/calxeda-xgmac.c b/hw/vfio/calxeda-xgmac.c
> > index e7767c4b02..6cc608b6ca 100644
> > --- a/hw/vfio/calxeda-xgmac.c
> > +++ b/hw/vfio/calxeda-xgmac.c
> > @@ -26,7 +26,7 @@ static void calxeda_xgmac_realize(DeviceState *dev,
> Error **errp)
> >  }
> >
> >  static const VMStateDescription vfio_platform_calxeda_xgmac_vmstate = {
> > -.name = TYPE_VFIO_CALXEDA_XGMAC,
> > +.name = "vfio-calxeda-xgmac",
> >  .unmigratable = 1,
> >  };
> >
> > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > index 31dd3a2a87..d9e39552e2 100644
> > --- a/hw/vfio/ccw.c
> > +++ b/hw/vfio/ccw.c
> > @@ -468,7 +468,7 @@ static Property vfio_ccw_properties[] = {
> >  };
> >
> >  static const VMStateDescription vfio_ccw_vmstate = {
> > -.name = TYPE_VFIO_CCW,
> > +.name = "vfio-ccw",
> >  .unmigratable = 1,
> >  };
> >
> > diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
> > index 398db38f14..e59a0234dd 100644
> > --- a/hw/vfio/platform.c
> > +++ b/hw/vfio/platform.c
> > @@ -697,7 +697,7 @@ out:
> >  }
> >
> >  static const VMStateDescription vfio_platform_vmstate = {
> > -.name = TYPE_VFIO_PLATFORM,
> > +.name = "vfio-platform",
> >  .unmigratable = 1,
> >  };
> >
>
>


Re: [Qemu-devel] [PATCH 1/4] vfio: pci: make "vfio-pci-nohotplug" as MACRO

2019-05-19 Thread Li Qiang
Alex Williamson  于2019年5月18日周六 下午10:18写道:

> On Fri, 17 May 2019 20:28:08 -0700
> Li Qiang  wrote:
>
> Why?  (No commit message, nor cover letter)
>
>
Once I think these are trivial so no cover letter and lack some commit
message.
I will add some commit message in the next revision.

For this patch, this is more consistent with QOMConventions:
-->https://wiki.qemu.org/Documentation/QOMConventions

Thanks,
Li Qiang


> > CC: qemu-triv...@nongnu.org
> > Signed-off-by: Li Qiang 
> > ---
> >  hw/vfio/pci.c | 6 --
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> > index 8cecb53d5c..08729e5875 100644
> > --- a/hw/vfio/pci.c
> > +++ b/hw/vfio/pci.c
> > @@ -40,6 +40,8 @@
> >  #define TYPE_VFIO_PCI "vfio-pci"
> >  #define PCI_VFIO(obj)OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI)
> >
> > +#define TYPE_VIFO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
> > +
> >  static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
> >  static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
> >
> > @@ -3304,8 +3306,8 @@ static void
> vfio_pci_nohotplug_dev_class_init(ObjectClass *klass, void *data)
> >  }
> >
> >  static const TypeInfo vfio_pci_nohotplug_dev_info = {
> > -.name = "vfio-pci-nohotplug",
> > -.parent = "vfio-pci",
> > +.name = TYPE_VIFO_PCI_NOHOTPLUG,
> > +.parent = TYPE_VFIO_PCI,
> >  .instance_size = sizeof(VFIOPCIDevice),
> >  .class_init = vfio_pci_nohotplug_dev_class_init,
> >  };
>
>


[Qemu-devel] [PATCH v5 5/6] hw/acpi: Consolidate build_mcfg to pci.c

2019-05-19 Thread Wei Yang
Now we have two identical build_mcfg functions.

Consolidate them in acpi/pci.c.

Signed-off-by: Wei Yang 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Igor Mammedov 

---
v4:
  * ACPI_PCI depends on both ACPI and PCI
  * rebase on latest master, adjust arm Kconfig
v3:
  * adjust changelog based on Igor's suggestion
---
 default-configs/i386-softmmu.mak |  1 +
 hw/acpi/Kconfig  |  4 +++
 hw/acpi/Makefile.objs|  1 +
 hw/acpi/pci.c| 46 
 hw/arm/Kconfig   |  1 +
 hw/arm/virt-acpi-build.c | 17 
 hw/i386/acpi-build.c | 18 +
 include/hw/acpi/pci.h|  1 +
 8 files changed, 55 insertions(+), 34 deletions(-)
 create mode 100644 hw/acpi/pci.c

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index ba3fb3ff50..cd5ea391e8 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -25,3 +25,4 @@
 CONFIG_ISAPC=y
 CONFIG_I440FX=y
 CONFIG_Q35=y
+CONFIG_ACPI_PCI=y
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index eca3beed75..7c59cf900b 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -23,6 +23,10 @@ config ACPI_NVDIMM
 bool
 depends on ACPI
 
+config ACPI_PCI
+bool
+depends on ACPI && PCI
+
 config ACPI_VMGENID
 bool
 default y
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 2d46e3789a..661a9b8c2f 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -11,6 +11,7 @@ common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
 common-obj-y += acpi_interface.o
 common-obj-y += bios-linker-loader.o
 common-obj-y += aml-build.o
+common-obj-$(CONFIG_ACPI_PCI) += pci.o
 common-obj-$(CONFIG_TPM) += tpm.o
 
 common-obj-$(CONFIG_IPMI) += ipmi.o
diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
new file mode 100644
index 00..fa0fa30bb9
--- /dev/null
+++ b/hw/acpi/pci.c
@@ -0,0 +1,46 @@
+/*
+ * Support for generating PCI related ACPI tables and passing them to Guests
+ *
+ * Copyright (C) 2006 Fabrice Bellard
+ * Copyright (C) 2008-2010  Kevin O'Connor 
+ * Copyright (C) 2013-2019 Red Hat Inc
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * Author: Wei Yang 
+ * Author: Michael S. Tsirkin 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
+#include "hw/pci/pcie_host.h"
+
+void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
+{
+AcpiTableMcfg *mcfg;
+int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
+
+mcfg = acpi_data_push(table_data, len);
+mcfg->allocation[0].address = cpu_to_le64(info->base);
+
+/* Only a single allocation so no need to play with segments */
+mcfg->allocation[0].pci_segment = cpu_to_le16(0);
+mcfg->allocation[0].start_bus_number = 0;
+mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);
+
+build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
+}
+
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index af8cffde9c..9aced9d54d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -19,6 +19,7 @@ config ARM_VIRT
 select PLATFORM_BUS
 select SMBIOS
 select VIRTIO_MMIO
+select ACPI_PCI
 
 config CHEETAH
 bool
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index e7c96d658e..4a64f9985c 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -546,23 +546,6 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
  "SRAT", table_data->len - srat_start, 3, NULL, NULL);
 }
 
-static void
-build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
-{
-AcpiTableMcfg *mcfg;
-int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
-
-mcfg = acpi_data_push(table_data, len);
-mcfg->allocation[0].address = cpu_to_le64(info->base);
-
-/* Only a single allocation so no need to play with segments */
-mcfg->allocation[0].pci_segment = cpu_to_le16(0);
-mcfg->allocation[0].start_bus_number = 0;
-mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);
-
-build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
-}
-
 /* GTDT */
 static void
 build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
diff --git 

[Qemu-devel] [PATCH v5 3/6] i386, acpi: remove mcfg_ prefix in AcpiMcfgInfo members

2019-05-19 Thread Wei Yang
This is obvious the member in AcpiMcfgInfo describe MCFG's property.

Remove the mcfg_ prefix.

Signed-off-by: Wei Yang 
Suggested-by: Igor Mammedov 
Reviewed-by: Igor Mammedov 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/i386/acpi-build.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4fb6184cbc..9c1152c819 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -88,8 +88,8 @@
 #define ACPI_BUILD_IOAPIC_ID 0x0
 
 typedef struct AcpiMcfgInfo {
-uint64_t mcfg_base;
-uint32_t mcfg_size;
+uint64_t base;
+uint32_t size;
 } AcpiMcfgInfo;
 
 typedef struct AcpiPmInfo {
@@ -2416,11 +2416,11 @@ build_mcfg_q35(GArray *table_data, BIOSLinker *linker, 
AcpiMcfgInfo *info)
 int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
 
 mcfg = acpi_data_push(table_data, len);
-mcfg->allocation[0].address = cpu_to_le64(info->mcfg_base);
+mcfg->allocation[0].address = cpu_to_le64(info->base);
 /* Only a single allocation so no need to play with segments */
 mcfg->allocation[0].pci_segment = cpu_to_le16(0);
 mcfg->allocation[0].start_bus_number = 0;
-mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->mcfg_size - 1);
+mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);
 
 build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
 }
@@ -2589,15 +2589,15 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 if (!o) {
 return false;
 }
-mcfg->mcfg_base = qnum_get_uint(qobject_to(QNum, o));
+mcfg->base = qnum_get_uint(qobject_to(QNum, o));
 qobject_unref(o);
-if (mcfg->mcfg_base == PCIE_BASE_ADDR_UNMAPPED) {
+if (mcfg->base == PCIE_BASE_ADDR_UNMAPPED) {
 return false;
 }
 
 o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
 assert(o);
-mcfg->mcfg_size = qnum_get_uint(qobject_to(QNum, o));
+mcfg->size = qnum_get_uint(qobject_to(QNum, o));
 qobject_unref(o);
 return true;
 }
-- 
2.19.1




[Qemu-devel] [PATCH v5 4/6] hw/arm/virt-acpi-build: pass AcpiMcfgInfo to build_mcfg()

2019-05-19 Thread Wei Yang
To build MCFG, two information is necessary:

* bus number
* base address

Abstract these two information to AcpiMcfgInfo so that build_mcfg and
build_mcfg_q35 will have the same declaration.

Signed-off-by: Wei Yang 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Igor Mammedov 

---
v4:
  * rebase on latest master
v3:
  * move AcpiMcfgInfo to pci.h
v2:
  * for arm platform, construct a AcpiMcfgInfo directly
---
 hw/arm/virt-acpi-build.c | 18 +++---
 hw/i386/acpi-build.c |  6 +-
 include/hw/acpi/pci.h| 33 +
 3 files changed, 45 insertions(+), 12 deletions(-)
 create mode 100644 include/hw/acpi/pci.h

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 12dbaf3846..e7c96d658e 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -40,6 +40,7 @@
 #include "hw/loader.h"
 #include "hw/hw.h"
 #include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci.h"
 #include "hw/arm/virt.h"
@@ -546,21 +547,18 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 }
 
 static void
-build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
 {
 AcpiTableMcfg *mcfg;
-const MemMapEntry *memmap = vms->memmap;
-int ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
 int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
 
 mcfg = acpi_data_push(table_data, len);
-mcfg->allocation[0].address = cpu_to_le64(memmap[ecam_id].base);
+mcfg->allocation[0].address = cpu_to_le64(info->base);
 
 /* Only a single allocation so no need to play with segments */
 mcfg->allocation[0].pci_segment = cpu_to_le16(0);
 mcfg->allocation[0].start_bus_number = 0;
-mcfg->allocation[0].end_bus_number =
-PCIE_MMCFG_BUS(memmap[ecam_id].size - 1);
+mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);
 
 build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
 }
@@ -801,7 +799,13 @@ void virt_acpi_build(VirtMachineState *vms, 
AcpiBuildTables *tables)
 build_gtdt(tables_blob, tables->linker, vms);
 
 acpi_add_table(table_offsets, tables_blob);
-build_mcfg(tables_blob, tables->linker, vms);
+{
+AcpiMcfgInfo mcfg = {
+   .base = vms->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].base,
+   .size = vms->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].size,
+};
+build_mcfg(tables_blob, tables->linker, );
+}
 
 acpi_add_table(table_offsets, tables_blob);
 build_spcr(tables_blob, tables->linker, vms);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9c1152c819..0d78d73894 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -59,6 +59,7 @@
 #include "hw/i386/x86-iommu.h"
 
 #include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
 
 #include "qom/qom-qobject.h"
 #include "hw/i386/amd_iommu.h"
@@ -87,11 +88,6 @@
 /* Default IOAPIC ID */
 #define ACPI_BUILD_IOAPIC_ID 0x0
 
-typedef struct AcpiMcfgInfo {
-uint64_t base;
-uint32_t size;
-} AcpiMcfgInfo;
-
 typedef struct AcpiPmInfo {
 bool s3_disabled;
 bool s4_disabled;
diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
new file mode 100644
index 00..124af7d32a
--- /dev/null
+++ b/include/hw/acpi/pci.h
@@ -0,0 +1,33 @@
+/*
+ * Support for generating PCI related ACPI tables and passing them to Guests
+ *
+ * Copyright (C) 2006 Fabrice Bellard
+ * Copyright (C) 2008-2010  Kevin O'Connor 
+ * Copyright (C) 2013-2019 Red Hat Inc
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * Author: Wei Yang 
+ * Author: Michael S. Tsirkin 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+#ifndef HW_ACPI_PCI_H
+#define HW_ACPI_PCI_H
+
+typedef struct AcpiMcfgInfo {
+uint64_t base;
+uint32_t size;
+} AcpiMcfgInfo;
+
+#endif
-- 
2.19.1




[Qemu-devel] [PATCH v5 6/6] acpi: pci: use build_append_foo() API to construct MCFG

2019-05-19 Thread Wei Yang
build_append_foo() API doesn't need explicit endianness conversions
which eliminates a source of errors and it makes build_mcfg() look like
declarative definition of MCFG table in ACPI spec, which makes it easy
to review.

Signed-off-by: Wei Yang 
Suggested-by: Igor Mammedov 
Reviewed-by: Igor Mammedov 

---
v2:
   * miss the reserved[8] of MCFG in last version, add it back
   * drop SOBs and make sure bios-tables-test all OK
---
 hw/acpi/pci.c   | 35 +++
 include/hw/acpi/acpi-defs.h | 18 --
 2 files changed, 23 insertions(+), 30 deletions(-)

diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
index fa0fa30bb9..49df7b7d54 100644
--- a/hw/acpi/pci.c
+++ b/hw/acpi/pci.c
@@ -30,17 +30,28 @@
 
 void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
 {
-AcpiTableMcfg *mcfg;
-int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
-
-mcfg = acpi_data_push(table_data, len);
-mcfg->allocation[0].address = cpu_to_le64(info->base);
-
-/* Only a single allocation so no need to play with segments */
-mcfg->allocation[0].pci_segment = cpu_to_le16(0);
-mcfg->allocation[0].start_bus_number = 0;
-mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);
-
-build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
+int mcfg_start = table_data->len;
+
+acpi_data_push(table_data, sizeof(AcpiTableHeader));
+
+/*
+ * PCI Firmware Specification, Revision 3.0
+ * 4.1.2 MCFG Table Description.
+ */
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 8);
+/* Base address, processor-relative */
+build_append_int_noprefix(table_data, info->base, 8);
+/* PCI segment group number */
+build_append_int_noprefix(table_data, 0, 2);
+/* Starting PCI Bus number */
+build_append_int_noprefix(table_data, 0, 1);
+/* Final PCI Bus number */
+build_append_int_noprefix(table_data, PCIE_MMCFG_BUS(info->size - 1), 1);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 4);
+
+build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
+ "MCFG", table_data->len - mcfg_start, 1, NULL, NULL);
 }
 
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index f9aa4bd398..57a3f58b0c 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -449,24 +449,6 @@ struct AcpiSratProcessorGiccAffinity {
 
 typedef struct AcpiSratProcessorGiccAffinity AcpiSratProcessorGiccAffinity;
 
-/* PCI fw r3.0 MCFG table. */
-/* Subtable */
-struct AcpiMcfgAllocation {
-uint64_t address;/* Base address, processor-relative */
-uint16_t pci_segment;/* PCI segment group number */
-uint8_t start_bus_number;   /* Starting PCI Bus number */
-uint8_t end_bus_number; /* Final PCI Bus number */
-uint32_t reserved;
-} QEMU_PACKED;
-typedef struct AcpiMcfgAllocation AcpiMcfgAllocation;
-
-struct AcpiTableMcfg {
-ACPI_TABLE_HEADER_DEF;
-uint8_t reserved[8];
-AcpiMcfgAllocation allocation[0];
-} QEMU_PACKED;
-typedef struct AcpiTableMcfg AcpiTableMcfg;
-
 /*
  * TCPA Description Table
  *
-- 
2.19.1




[Qemu-devel] [PATCH v5 1/6] q35: acpi: do not create dummy MCFG table

2019-05-19 Thread Wei Yang
From: Igor Mammedov 

Dummy table (with signature "QEMU") creation came from original SeaBIOS
codebase. And QEMU would have to keep it around if there were Q35 machine
that depended on keeping ACPI tables blob constant size. Luckily there
were no versioned Q35 machine types before commit:
  (since 2.3) a1666142db acpi-build: make ROMs RAM blocks resizeable
which obsoleted need to keep ACPI tables blob the same size on 
source/destination.

Considering the 1st versioned machine is pc-q35-2.4, the dummy table
is not really necessary and it's safe to drop it without breaking
cross version migration in both directions unconditionally.

Signed-off-by: Igor Mammedov 
Signed-off-by: Wei Yang 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/i386/acpi-build.c | 18 --
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b4ec14e349..4fb6184cbc 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2413,7 +2413,6 @@ static void
 build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
 {
 AcpiTableMcfg *mcfg;
-const char *sig;
 int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
 
 mcfg = acpi_data_push(table_data, len);
@@ -2423,19 +2422,7 @@ build_mcfg_q35(GArray *table_data, BIOSLinker *linker, 
AcpiMcfgInfo *info)
 mcfg->allocation[0].start_bus_number = 0;
 mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->mcfg_size - 1);
 
-/* MCFG is used for ECAM which can be enabled or disabled by guest.
- * To avoid table size changes (which create migration issues),
- * always create the table even if there are no allocations,
- * but set the signature to a reserved value in this case.
- * ACPI spec requires OSPMs to ignore such tables.
- */
-if (info->mcfg_base == PCIE_BASE_ADDR_UNMAPPED) {
-/* Reserved signature: ignored by OSPM */
-sig = "QEMU";
-} else {
-sig = "MCFG";
-}
-build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL);
+build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
 }
 
 /*
@@ -2604,6 +2591,9 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 }
 mcfg->mcfg_base = qnum_get_uint(qobject_to(QNum, o));
 qobject_unref(o);
+if (mcfg->mcfg_base == PCIE_BASE_ADDR_UNMAPPED) {
+return false;
+}
 
 o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
 assert(o);
-- 
2.19.1




[Qemu-devel] [PATCH v5 2/6] hw/arm/virt-acpi-build: remove unnecessary variable mcfg_start

2019-05-19 Thread Wei Yang
mcfg_start points to the start of MCFG table and is used in
build_header. While this information could be derived from mcfg.

This patch removes the unnecessary variable mcfg_start.

Signed-off-by: Wei Yang 
Reviewed-by: Igor Mammedov 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/virt-acpi-build.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index bf9c0bc2f4..12dbaf3846 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -552,7 +552,6 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 const MemMapEntry *memmap = vms->memmap;
 int ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
 int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
-int mcfg_start = table_data->len;
 
 mcfg = acpi_data_push(table_data, len);
 mcfg->allocation[0].address = cpu_to_le64(memmap[ecam_id].base);
@@ -563,8 +562,7 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 mcfg->allocation[0].end_bus_number =
 PCIE_MMCFG_BUS(memmap[ecam_id].size - 1);
 
-build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
- "MCFG", table_data->len - mcfg_start, 1, NULL, NULL);
+build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
 }
 
 /* GTDT */
-- 
2.19.1




[Qemu-devel] [PATCH v5 0/6] Extract build_mcfg

2019-05-19 Thread Wei Yang
This patch set tries to generalize MCFG table build process. And it is
based on one un-merged patch from Igor, which is included in this serials.

v4->v5:
* ACPI_PCI depends on both ACPI and PCI
* rebase on latest master, adjust arm Kconfig
* miss the reserved[8] of MCFG, add it back
* make sure bios-tables-test all OK

v3->v4:
* adjust comment to give more information about MCFG table

v2->v3:
* Includes the un-merged patch from Igor
* use build_append_foo() API to construct MCFG

Igor Mammedov (1):
  q35: acpi: do not create dummy MCFG table

Wei Yang (5):
  hw/arm/virt-acpi-build: remove unnecessary variable mcfg_start
  i386, acpi: remove mcfg_ prefix in AcpiMcfgInfo members
  hw/arm/virt-acpi-build: pass AcpiMcfgInfo to build_mcfg()
  hw/acpi: Consolidate build_mcfg to pci.c
  acpi: pci: use build_append_foo() API to construct MCFG

 default-configs/i386-softmmu.mak |  1 +
 hw/acpi/Kconfig  |  4 +++
 hw/acpi/Makefile.objs|  1 +
 hw/acpi/pci.c| 57 
 hw/arm/Kconfig   |  1 +
 hw/arm/virt-acpi-build.c | 31 +
 hw/i386/acpi-build.c | 44 
 include/hw/acpi/acpi-defs.h  | 18 --
 include/hw/acpi/pci.h| 34 +++
 9 files changed, 113 insertions(+), 78 deletions(-)
 create mode 100644 hw/acpi/pci.c
 create mode 100644 include/hw/acpi/pci.h

-- 
2.19.1




Re: [Qemu-devel] [PATCH] hw/acpi: ACPI_PCI should depends on both ACPI and PCI

2019-05-19 Thread Wei Yang
On Fri, May 17, 2019 at 04:29:03PM +0200, Igor Mammedov wrote:
>On Fri, 17 May 2019 12:59:57 +
>Wei Yang  wrote:
>
>> On Fri, May 17, 2019 at 01:11:16PM +0200, Igor Mammedov wrote:
>> >On Fri, 17 May 2019 08:51:14 +0800
>> >Wei Yang  wrote:
>> >
>> >> Pointed out by Philippe Mathieu-Daud?? .
>> >> 
>> >> Signed-off-by: Wei Yang 
>> >> ---
>> >>  hw/acpi/Kconfig | 2 +-
>> >>  1 file changed, 1 insertion(+), 1 deletion(-)
>> >> 
>> >> diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
>> >> index 7265843cc3..7c59cf900b 100644
>> >> --- a/hw/acpi/Kconfig
>> >> +++ b/hw/acpi/Kconfig
>> >> @@ -25,7 +25,7 @@ config ACPI_NVDIMM
>> >>  
>> >>  config ACPI_PCI
>> >>  bool
>> >> -depends on ACPI
>> >> +depends on ACPI && PCI
>> >>  
>> >>  config ACPI_VMGENID
>> >>  bool
>> >
>> >are you sure you didn't miss anything?
>> >
>> 
>> This patch is based on the comment in
>> http://qemu.11.n7.nabble.com/PATCH-v4-0-6-Extract-build-mcfg-tt650106.html#a655913
>> 
>> My understanding is not correct?
>
>That wasn't the end of discussion, it continued on until Philippe suggested
>the below changes
>

Yep, just see the latest reply.

>> 
>> >On Fri, 17 May 2019 10:37:42 +0200
>> >Philippe Mathieu-Daud??  wrote:
>> >
>> >[...]
>> >> 
>> >> config ARM_VIRT
>> >> ...
>> >> select ACPI_PCI
>> >> 
>> >> config ACPI_PCI
>> >> bool
>> >> depends on ACPI && PCI
>> >> 
>> >
>> >
>> 

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PULL 00/37] pci, pc, virtio: features, fixes

2019-05-19 Thread Wei Yang
On Fri, May 17, 2019 at 01:13:15PM +0200, Igor Mammedov wrote:
>On Fri, 17 May 2019 10:59:03 +0800
>Wei Yang  wrote:
>

[..]

>> 
>> Well, I hope this will not block the merge.
>> 
>> I took a look in the change of default-configs/arm-softmmu.mak. The general
>> idea from Thomas is put those hard-coded config to Kconfig.
>> 
>> This is fine and what I need to change in my patch is to select ACPI_PCI in
>> the proper place, if my understanding is correct.
>> 
>> Two things I need to fix:
>> 
>>   * add select ACPI_PCI in proper place of hw/arm/Kconfig
>>   * add a dummy build_mcfg() for link when ACPI_PCI is not configured.
>> 
>> Then I have two questions:
>> 
>>   * In hw/arm/Kconfig, I don't see one option contains both PCI and ACPI. I 
>> am
>> confused where to put the select.
>>   * put dummy build_mcfg() in aml-build.c works. Igor, do you like this? Or
>> you haver other preference?
>
>could you point out why we need dummy build_mcfg(), in the first place?
>

I may made a misunderstanding about hw/arm/Kconfig in recent upstream change.

I thought there would be no configuration to choose both ACPI and PCI at the
same time, which leads to build_mcfg() will not be compiled.

While seems Philip decides to select ACPI_PCI for ARM_VIRT.

>> 
>> >Sadly both series clash :(
>> >
>> >Regards,
>> >
>> >Phil.
>> 

-- 
Wei Yang
Help you, Help me



[Qemu-devel] [Bug 1829682] [NEW] QEMU PPC SYSTEM regression - 3.1.0 and GIT - Fail to boot AIX

2019-05-19 Thread Ivan Warren via Qemu-devel
Public bug reported:

Built from source on a debian system

Linux db08 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux
gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)

Last git commit (from queued gdibson repository)

starting AIX 7.2 TL 2 SP 2 with the following : (the install was done
under qemu 3.1.0)

qemu-system-ppc64 -M pseries \
-cpu power7 \
-cdrom AIX_v7.2_Install_7200-02-02-1806_DVD_1_of_2_32018.iso \
-net nic \
-net tap,ifname=tap2,script=no \
-drive file=DISK1.IMG,if=none,id=drive-virtio-disk0 \
-device virtio-scsi-pci,id=scsi -device scsi-hd,drive=drive-virtio-disk0 \
-m 4G \
-serial stdio \
-monitor unix:ms,server,nowait \
-accel tcg \
-k fr \
-nographic \
-prom-env input-device=/vdevice/vty@7100 \
-prom-env output-device=/vdevice/vty@7100 \
-prom-env diag-switch?=false \
-prom-env boot-command="boot 
/pci@8002000/scsi@2/disk@100 -s verbose"

Yields this :


^M
SLOF^[[0m^[[?25l 
**^M
^[[1mQEMU Starting^M
^[[0m Build Date = Jan 14 2019 18:00:39^M
 FW Version = git-a5b428e1c1eae703^M
 Press "s" to enter Open Firmware.^M^M
^M^M
^[[0m^[[?25hC^MC0100^MC0120^MC0140^MC0200^MC0240^MC0260^MC02E0^MC0300^MC0320^MC0340^MC0360^MC0370^MC0380^MC0371^MC0372^MC0373^MC0374^MC03F0^MC0400^MC0480^MC04C0^MC04D0^MC0500^MPopulating
 /vdevice methods^M
Populating /vdevice/vty@7100^M
Populating /vdevice/nvram@7101^M
Populating /vdevice/l-lan@7102^M
Populating /vdevice/v-scsi@7103^M
   SCSI: Looking for devices^M
  8200 CD-ROM   : "QEMU QEMU CD-ROM  2.5+"^M
C05A0^MPopulating /pci@8002000^M
 00  (D) : 1234 qemu vga^M
 00 0800 (D) : 1033 0194serial bus [ usb-xhci ]^M
 00 1000 (D) : 1af4 1004virtio [ scsi ]^M
Populating /pci@8002000/scsi@2^M
   SCSI: Looking for devices^M
  100 DISK : "QEMU QEMU HARDDISK2.5+"^M
C0600^MC06C0^MC0700^MC0800^MC0880^MC0890^MC08A0^MC08A8^MInstalling QEMU fb^M
^M
^M
^M
C08B0^MScanning USB ^M
  XHCI: Initializing^M
USB Keyboard ^M
USB mouse ^M
C08C0^MC08D0^MNo console specified using screen & keyboard^M
User selected input-device console: /vdevice/vty@7100^M
User selected output-device console: /vdevice/vty@7100^M
C08E0^MC08E8^MC08FF^M ^M
  Welcome to Open Firmware^M
^M
  Copyright (c) 2004, 2017 IBM Corporation All rights reserved.^M
  This program and the accompanying materials are made available^M
  under the terms of the BSD License available at^M
  http://www.opensource.org/licenses/bsd-license.php^M
^M
^M
Trying to load: -s verbose from: 
/pci@8002000/scsi@2/disk@100 ...   Successfully loaded^M
^M
---> qemu,pseries detected <---^M
^M
^M
^M
^M
^M
^M
^M
---^M
Welcome to AIX.^M
   boot image timestamp: 05:56:13 04/20/2019^M
processor count: 1;  memory size: 4096MB;  kernel size: 38426884^M
 boot device: /pci@8002000/scsi@2/disk@100^M
^M
8000FFEC bytes of free memory remain at address 7FFF0014^M
load address: 0x4000   aixmon size: 0x000D2C00   boot image size: 
0x01A6B430^M
^LAIX vm,uuid property contains invalid data^Mload address: 0x4000   aixmon 
size: 0x000D2C00   boot image size: 0x01A6B430^M
^LAIX vm,uuid property contains invalid data^M
get_ppp return code: 0xFFFE^M
^M
AKVM: hcall-multi-tce detected but overridden, allow with "multce" boot 
argument^M
The temporary memory region list is at 1 percent capacity.^M
The temporary IPLCB is at 1 percent capacity.^M
The IPLCB address is 0x0FFF9000^M
name offset   size^M
ipl_cb_and_bit_map  ..5958^M
bit_map... 0790 ..0006^M
ipl_info.. 01C8 ..0024^M
splpar_info... 01EC ..0048^M
system_info... 0234 ..00C4^M
processor_info 02F8 ..0148^M
lpar_id_info.. 0440 ..0088^M
dr_proc_info.. 04C8 ..0008^M
dr_mem_info... 04D0 ..0028^M
lpar_info. 04F8 ..0014^M
segment page.. 0518 ..0028^M
processor page 0540 ..0010^M
res_asso_id... 0550 ..0050^M
res_asso_group 05A0 ..0048^M
asso_ref_pnt.. 05E8 ..0010^M
residual.. 0820 ..5138^M
fwad_info. 05F8 ..0040^M
contig mem rsv 0738 ..0058^M
region address  region length   attr  label^M
0   0x  0x0FFF7000  0x01  0x01^M
1   0x0FFF7000  0x2000  0x01  0x03^M
2   0x0FFF9000  0x6000  0x01  0x02^M
3   0x0000  

[Qemu-devel] [Bug 1829682] Re: QEMU PPC SYSTEM regression - 3.1.0 and GIT - Fail to boot AIX

2019-05-19 Thread Ivan Warren via Qemu-devel
Forgot that part (debugger output)
KDB(0)> wherre^H ^H^H ^He^M
si_pvthread+00 STACK:^M
[0008F418]dispatch+98 (0338, 02DC3838,^M
   F1000816B0036CF0 [??])^M
[00234E34]flih_util+000440 ()^M
 Exception (02743408) ^M
iar   : 00AD0088  msr   : 80001032  cr: 22000888^M
lr: 00AD0078  ctr   :   xer   : 0010^M
mq:   ^M
r0  : 00C0  r1  : 02E22280  r2  : 032B5D20^M
r3  : 0A00  r4  : F10008008012BFF8  r5  : ^M
r6  : F200800011400010  r7  : 4002  r8  : 0A00^M
r9  : 0404  r10 :   r11 : ^M
r12 : 00AD0078  r13 : 025933F0  r14 : 00B9D470^M
r15 : F10008008012C000  r16 : F20080001143C000  r17 : 0003C000^M
r18 : 02004324  r19 : F20080001146  r20 : ^M
r21 :   r22 : 02004338  r23 : ^M
r24 : 0A00  r25 : 0002  r26 : 0E3F^M
r27 : 0001  r28 : 4002  r29 : ^M
r30 : 0A00  r31 : F20080001140  ^M
^M
prev   stackfix   int_ticks  ^M
cfar  00163154 capi  0^M
(0)> more (^C to quit) ? ^H ^H^G^M
^M   ^Mkjmpbuf    excbranch 
 no_pfault 00 ^M
intpri00   backt 00   flags 00 ^M
hw_fru_id  hw_cpu_id ^M
fpscr  fpscrx fpowner   00 ^M
fpeu  00   fpinfo00   alloc F000 ^M
tmstate   00   tmcontext 00   prevowner 00 ^M
o_iar  o_toc  ^M
o_arg1 o_vaddr    ^M
krlockp    rmgrwa ^M
amrstackhigh  054B22B8 amrstacklow   054B21B8 ^M
amrstackcur   054B22B8 amrstackfix    ^M
kstackhigh kstacksize ^M
frrstart  700DFEED frrend700DFEED ^M
frrcur700DFEED frrstatic  kjmpfrroff  ^M
frrovcnt   frrbarrcnt  frrmask 00 callrmgr 00 ^M
Except :^M
excp_type 0106  EXCEPT_DSI ^M
 orgea F10008008012C000 dsisr 4000  bit set: DSISR_PFT^M
 vmh   18008400 curea F10008008012C000 pftyp 0106^M
[00AD0088]IPRA.$initxpt+0001A8 (0A00, F10008008012BFF8,^M
    [??])^M
[00AD02E4]IPRA.$initxpt_vmsi+C4 ()^M
(0)> more (^C to quit) ? ^H ^H^G^M
^M   ^M[00ACBB08]vmsi+000968 ()^M
[00AC0DF8]main+98 ()^M
[0053A748].start1+B8 ()^M

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1829682

Title:
  QEMU PPC SYSTEM regression - 3.1.0 and GIT - Fail to boot AIX

Status in QEMU:
  New

Bug description:
  Built from source on a debian system

  Linux db08 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux
  gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)

  Last git commit (from queued gdibson repository)

  starting AIX 7.2 TL 2 SP 2 with the following : (the install was done
  under qemu 3.1.0)

  qemu-system-ppc64 -M pseries \
  -cpu power7 \
  -cdrom AIX_v7.2_Install_7200-02-02-1806_DVD_1_of_2_32018.iso \
  -net nic \
  -net tap,ifname=tap2,script=no \
  -drive file=DISK1.IMG,if=none,id=drive-virtio-disk0 \
  -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=drive-virtio-disk0 \
  -m 4G \
  -serial stdio \
  -monitor unix:ms,server,nowait \
  -accel tcg \
  -k fr \
  -nographic \
  -prom-env input-device=/vdevice/vty@7100 \
  -prom-env output-device=/vdevice/vty@7100 \
  -prom-env diag-switch?=false \
  -prom-env boot-command="boot 
/pci@8002000/scsi@2/disk@100 -s verbose"

  Yields this :

  
  ^M
  SLOF^[[0m^[[?25l 
**^M
  ^[[1mQEMU Starting^M
  ^[[0m Build Date = Jan 14 2019 18:00:39^M
   FW Version = git-a5b428e1c1eae703^M
   Press "s" to enter Open Firmware.^M^M
  ^M^M
  
^[[0m^[[?25hC^MC0100^MC0120^MC0140^MC0200^MC0240^MC0260^MC02E0^MC0300^MC0320^MC0340^MC0360^MC0370^MC0380^MC0371^MC0372^MC0373^MC0374^MC03F0^MC0400^MC0480^MC04C0^MC04D0^MC0500^MPopulating
 /vdevice methods^M
  Populating /vdevice/vty@7100^M
  Populating /vdevice/nvram@7101^M
  Populating /vdevice/l-lan@7102^M
  Populating /vdevice/v-scsi@7103^M
 SCSI: Looking for devices^M
8200 CD-ROM   : "QEMU QEMU CD-ROM  2.5+"^M
  C05A0^MPopulating /pci@8002000^M
   00  (D) : 1234 qemu vga^M
   00 0800 (D) : 1033 0194serial bus [ usb-xhci 

[Qemu-devel] [PATCH v7 74/74] linux-user: Split out getpriority, setpriority

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  2 ++
 linux-user/syscall-proc.inc.c | 28 
 linux-user/syscall.c  | 18 --
 linux-user/strace.list|  6 --
 4 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 8b2d95d19e..3b45250977 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -80,6 +80,7 @@ SYSCALL_DEF(getpid);
 #ifdef TARGET_NR_getppid
 SYSCALL_DEF(getppid);
 #endif
+SYSCALL_DEF(getpriority, ARG_DEC, ARG_DEC);
 #ifdef TARGET_NR_getrlimit
 SYSCALL_DEF(getrlimit, ARG_DEC, ARG_PTR);
 #endif
@@ -238,6 +239,7 @@ SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
 SYSCALL_DEF(sethostname, ARG_STR);
 SYSCALL_DEF(setpgid, ARG_DEC, ARG_DEC);
+SYSCALL_DEF(setpriority, ARG_DEC, ARG_DEC, ARG_DEC);
 #ifdef TARGET_NR_setrlimit
 SYSCALL_DEF(setrlimit, ARG_DEC, ARG_PTR);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 408e96a834..e85151cc2e 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -479,6 +479,29 @@ SYSCALL_IMPL(getppid)
 }
 #endif
 
+SYSCALL_IMPL(getpriority)
+{
+abi_long ret;
+
+/*
+ * Note that negative values are valid for getpriority, so we must
+ * differentiate based on errno settings.
+ */
+errno = 0;
+ret = getpriority(arg1, arg2);
+if (ret == -1 && errno != 0) {
+return -host_to_target_errno(errno);
+}
+#ifdef TARGET_ALPHA
+/* Return value is the unbiased priority.  Signal no error.  */
+((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
+#else
+/* Return value is a biased priority to avoid negative numbers.  */
+ret = 20 - ret;
+#endif
+return ret;
+}
+
 #ifdef TARGET_NR_getrlimit
 SYSCALL_IMPL(getrlimit)
 {
@@ -568,6 +591,11 @@ SYSCALL_IMPL(setpgid)
 return get_errno(setpgid(arg1, arg2));
 }
 
+SYSCALL_IMPL(setpriority)
+{
+return get_errno(setpriority(arg1, arg2, arg3));
+}
+
 #ifdef TARGET_NR_setrlimit
 SYSCALL_IMPL(setrlimit)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1b1d44bf32..6e7cccbdd5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4144,24 +4144,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_getpriority:
-/* Note that negative values are valid for getpriority, so we must
-   differentiate based on errno settings.  */
-errno = 0;
-ret = getpriority(arg1, arg2);
-if (ret == -1 && errno != 0) {
-return -host_to_target_errno(errno);
-}
-#ifdef TARGET_ALPHA
-/* Return value is the unbiased priority.  Signal no error.  */
-((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
-#else
-/* Return value is a biased priority to avoid negative numbers.  */
-ret = 20 - ret;
-#endif
-return ret;
-case TARGET_NR_setpriority:
-return get_errno(setpriority(arg1, arg2, arg3));
 #ifdef TARGET_NR_statfs
 case TARGET_NR_statfs:
 if (!(p = lock_user_string(arg1))) {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 55b617239c..a0d2b3f9c5 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -256,9 +256,6 @@
 #ifdef TARGET_NR_getpmsg
 { TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getpriority
-{ TARGET_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL },
-#endif
 #ifdef TARGET_NR_getrandom
 { TARGET_NR_getrandom, "getrandom", NULL, NULL, NULL },
 #endif
@@ -1007,9 +1004,6 @@
 #ifdef TARGET_NR_setpgrp
 { TARGET_NR_setpgrp, "setpgrp" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setpriority
-{ TARGET_NR_setpriority, "setpriority" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setregid
 { TARGET_NR_setregid, "setregid" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 72/74] linux-user: Split out reboot

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/syscall-proc.inc.c | 18 ++
 linux-user/syscall.c  | 13 -
 linux-user/strace.list|  3 ---
 4 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 34e799d206..67c908448d 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -188,6 +188,7 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
 #ifdef TARGET_NR_readlinkat
 SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
 #endif
+SYSCALL_DEF(reboot, ARG_HEX, ARG_HEX, ARG_DEC, ARG_PTR);
 #ifdef TARGET_NR_rename
 SYSCALL_DEF(rename, ARG_STR, ARG_STR);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index bf9e278bf0..408e96a834 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -532,6 +532,24 @@ SYSCALL_IMPL(nice)
 }
 #endif
 
+SYSCALL_IMPL(reboot)
+{
+abi_long ret;
+
+if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
+/* arg4 must be ignored in all other cases */
+char *p = lock_user_string(arg4);
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(reboot(arg1, arg2, arg3, p));
+unlock_user(p, arg4, 0);
+} else {
+ret = get_errno(reboot(arg1, arg2, arg3, NULL));
+}
+return ret;
+}
+
 SYSCALL_IMPL(sethostname)
 {
 void *p = lock_user_string(arg1);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ead2e5c2b8..80e8b360a9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4158,19 +4158,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_reboot:
-if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
-   /* arg4 must be ignored in all other cases */
-   p = lock_user_string(arg4);
-   if (!p) {
-   return -TARGET_EFAULT;
-   }
-   ret = get_errno(reboot(arg1, arg2, arg3, p));
-   unlock_user(p, arg4, 0);
-} else {
-   ret = get_errno(reboot(arg1, arg2, arg3, NULL));
-}
-return ret;
 #ifdef TARGET_NR_truncate
 case TARGET_NR_truncate:
 if (!(p = lock_user_string(arg1)))
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 3d2e398439..3326541f17 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -866,9 +866,6 @@
 #ifdef TARGET_NR_readdir
 { TARGET_NR_readdir, "readdir" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_reboot
-{ TARGET_NR_reboot, "reboot" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_recv
 { TARGET_NR_recv, "recv" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 68/74] linux-user: Split out select, _newselect

2019-05-19 Thread Richard Henderson
This removes the printing of the fdset outputs.  It's hard to see how
this could have been reliable in a multi-threaded program, saving
syscall arguments to global variables.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  11 
 linux-user/strace.c   |  80 -
 linux-user/syscall-file.inc.c |  91 
 linux-user/syscall.c  | 110 --
 linux-user/strace.list|   6 --
 5 files changed, 112 insertions(+), 186 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index d109754c5f..01143414c7 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -143,6 +143,10 @@ SYSCALL_DEF(munlockall);
 SYSCALL_DEF(munmap, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(name_to_handle_at,
 ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
+#ifdef TARGET_NR__newselect
+SYSCALL_DEF_FULL(_newselect, .impl = impl_select,
+ .arg_type = { ARG_DEC, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR });
+#endif
 #ifdef TARGET_NR_nice
 SYSCALL_DEF(nice, ARG_DEC);
 #endif
@@ -209,6 +213,13 @@ SYSCALL_DEF(rt_sigreturn);
 SYSCALL_DEF(rt_sigsuspend, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigtimedwait, ARG_PTR, ARG_PTR, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_tgsigqueueinfo, ARG_DEC, ARG_DEC, ARG_SIGNAL, ARG_PTR);
+#ifdef TARGET_NR_select
+# if defined(TARGET_WANT_NI_OLD_SELECT)
+SYSCALL_DEF_NOSYS(select);
+# else
+SYSCALL_DEF_ARGS(select, ARG_DEC, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
+# endif
+#endif
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 2e70a3910c..669eca7fa6 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -384,34 +384,6 @@ print_socket_protocol(int domain, int type, int protocol)
 }
 
 
-#ifdef TARGET_NR__newselect
-static void
-print_fdset(int n, abi_ulong target_fds_addr)
-{
-int i;
-
-gemu_log("[");
-if( target_fds_addr ) {
-abi_long *target_fds;
-
-target_fds = lock_user(VERIFY_READ,
-   target_fds_addr,
-   sizeof(*target_fds)*(n / TARGET_ABI_BITS + 1),
-   1);
-
-if (!target_fds)
-return;
-
-for (i=n; i>=0; i--) {
-if ((tswapal(target_fds[i / TARGET_ABI_BITS]) >> (i & 
(TARGET_ABI_BITS - 1))) & 1)
-gemu_log("%d,", i );
-}
-unlock_user(target_fds, target_fds_addr, 0);
-}
-gemu_log("]");
-}
-#endif
-
 #ifdef TARGET_NR_clock_adjtime
 /* IDs of the various system clocks */
 #define TARGET_CLOCK_REALTIME  0
@@ -479,58 +451,6 @@ print_clockid(int clockid, int last)
  * Sysycall specific output functions
  */
 
-/* select */
-#ifdef TARGET_NR__newselect
-static long newselect_arg1 = 0;
-static long newselect_arg2 = 0;
-static long newselect_arg3 = 0;
-static long newselect_arg4 = 0;
-static long newselect_arg5 = 0;
-
-static void
-print_newselect(const struct syscallname *name,
-abi_long arg1, abi_long arg2, abi_long arg3,
-abi_long arg4, abi_long arg5, abi_long arg6)
-{
-gemu_log("%s(" TARGET_ABI_FMT_ld ",", name->name, arg1);
-print_fdset(arg1, arg2);
-gemu_log(",");
-print_fdset(arg1, arg3);
-gemu_log(",");
-print_fdset(arg1, arg4);
-gemu_log(",");
-print_timeval(arg5, 1);
-gemu_log(")");
-
-/* save for use in the return output function below */
-newselect_arg1=arg1;
-newselect_arg2=arg2;
-newselect_arg3=arg3;
-newselect_arg4=arg4;
-newselect_arg5=arg5;
-}
-#endif
-
-/*
- * Variants for the return value output function
- */
-
-#ifdef TARGET_NR__newselect
-static void
-print_syscall_ret_newselect(const struct syscallname *name, abi_long ret)
-{
-gemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
-print_fdset(newselect_arg1,newselect_arg2);
-gemu_log(",");
-print_fdset(newselect_arg1,newselect_arg3);
-gemu_log(",");
-print_fdset(newselect_arg1,newselect_arg4);
-gemu_log(",");
-print_timeval(newselect_arg5, 1);
-gemu_log(")\n");
-}
-#endif
-
 /* special meanings of adjtimex()' non-negative return values */
 #define TARGET_TIME_OK   0   /* clock synchronized, no leap second */
 #define TARGET_TIME_INS  1   /* insert leap second */
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 6e730e3152..1d66dc3323 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -1067,6 +1067,97 @@ SYSCALL_IMPL(renameat2)
 return do_renameat2(arg1, arg2, arg3, arg4, arg5);
 }
 
+#if defined(TARGET_NR_select) && defined(TARGET_WANT_OLD_SYS_SELECT)
+SYSCALL_ARGS(select)
+{
+struct target_sel_arg_struct *sel;
+abi_ulong inp, outp, exp, tvp;
+abi_long nsel;
+
+if (!lock_user_struct(VERIFY_READ, sel, in[0], 1)) {
+errno = 

[Qemu-devel] [PATCH v7 69/74] linux-user: Split out pselect6

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |   1 +
 linux-user/syscall-file.inc.c |  96 +++
 linux-user/syscall.c  | 103 --
 linux-user/strace.list|   3 -
 4 files changed, 97 insertions(+), 106 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 01143414c7..c179f69d9f 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -180,6 +180,7 @@ SYSCALL_DEF_FULL(preadv, .impl = impl_preadv,
 SYSCALL_DEF_FULL(pwritev, .impl = impl_pwritev,
  .args = args_preadv_pwritev,
  .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 });
+SYSCALL_DEF(pselect6, ARG_DEC, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);
 #ifdef TARGET_NR_readlink
 SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 1d66dc3323..0a25d39d28 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -934,6 +934,102 @@ SYSCALL_IMPL(pwritev)
 return ret;
 }
 
+SYSCALL_IMPL(pselect6)
+{
+abi_long n = arg1;
+abi_ulong rfd_addr = arg2;
+abi_ulong wfd_addr = arg3;
+abi_ulong efd_addr = arg4;
+abi_ulong ts_addr = arg5;
+fd_set rfds, wfds, efds;
+fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+struct timespec ts, *ts_ptr = NULL;
+abi_long ret;
+
+/*
+ * The 6th arg is actually two args smashed together, and since
+ * we are using safe_syscall, we must handle this ourselves.
+ */
+sigset_t set;
+struct {
+sigset_t *set;
+size_t size;
+} sig, *sig_ptr = NULL;
+
+abi_ulong arg_sigset, arg_sigsize, *arg7;
+target_sigset_t *target_sigset;
+
+ret = copy_from_user_fdset_ptr(, _ptr, rfd_addr, n);
+if (ret) {
+return ret;
+}
+ret = copy_from_user_fdset_ptr(, _ptr, wfd_addr, n);
+if (ret) {
+return ret;
+}
+ret = copy_from_user_fdset_ptr(, _ptr, efd_addr, n);
+if (ret) {
+return ret;
+}
+
+if (ts_addr) {
+if (target_to_host_timespec(, ts_addr)) {
+return -TARGET_EFAULT;
+}
+ts_ptr = 
+}
+
+/* Extract the two packed args for the sigset */
+if (arg6) {
+sig_ptr = 
+sig.size = SIGSET_T_SIZE;
+
+arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
+if (!arg7) {
+return -TARGET_EFAULT;
+}
+arg_sigset = tswapal(arg7[0]);
+arg_sigsize = tswapal(arg7[1]);
+unlock_user(arg7, arg6, 0);
+
+if (arg_sigset) {
+sig.set = 
+if (arg_sigsize != sizeof(*target_sigset)) {
+/* Like the kernel, we enforce correct size sigsets */
+return -TARGET_EINVAL;
+}
+target_sigset = lock_user(VERIFY_READ, arg_sigset,
+  sizeof(*target_sigset), 1);
+if (!target_sigset) {
+return -TARGET_EFAULT;
+}
+target_to_host_sigset(, target_sigset);
+unlock_user(target_sigset, arg_sigset, 0);
+} else {
+sig.set = NULL;
+}
+}
+
+ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
+  ts_ptr, sig_ptr));
+
+if (!is_error(ret)) {
+if (rfd_addr && copy_to_user_fdset(rfd_addr, , n)) {
+return -TARGET_EFAULT;
+}
+if (wfd_addr && copy_to_user_fdset(wfd_addr, , n)) {
+return -TARGET_EFAULT;
+}
+if (efd_addr && copy_to_user_fdset(efd_addr, , n)) {
+return -TARGET_EFAULT;
+}
+if (ts_addr && host_to_target_timespec(ts_addr, )) {
+return -TARGET_EFAULT;
+}
+}
+return ret;
+}
+
 SYSCALL_IMPL(read)
 {
 int fd = arg1;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 2c8d74a450..6355fd62d8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4158,109 +4158,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_pselect6
-case TARGET_NR_pselect6:
-{
-abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
-fd_set rfds, wfds, efds;
-fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
-struct timespec ts, *ts_ptr;
-
-/*
- * The 6th arg is actually two args smashed together,
- * so we cannot use the C library.
- */
-sigset_t set;
-struct {
-sigset_t *set;
-size_t size;
-} sig, *sig_ptr;
-
-abi_ulong arg_sigset, arg_sigsize, *arg7;
-target_sigset_t *target_sigset;
-
-n = arg1;
-rfd_addr = arg2;
-wfd_addr = arg3;
-efd_addr 

[Qemu-devel] [PATCH v7 73/74] linux-user: Split out truncate, truncate64, ftruncate, ftruncate64

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h | 16 +++
 linux-user/syscall-file.inc.c | 32 +
 linux-user/syscall.c  | 38 ---
 linux-user/strace.list| 12 ---
 4 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 67c908448d..8b2d95d19e 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -59,6 +59,14 @@ SYSCALL_DEF(futimesat, ARG_ATDIRFD, ARG_STR, ARG_PTR);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
+#ifdef TARGET_NR_ftruncate
+SYSCALL_DEF(ftruncate, ARG_DEC, ARG_DEC);
+#endif
+#ifdef TARGET_NR_ftruncate64
+SYSCALL_DEF_FULL(ftruncate64, .impl = impl_ftruncate,
+ .args = args_ftruncate64_truncate64,
+ .arg_type = { ARG_DEC, ARG_DEC64 });
+#endif
 #ifdef TARGET_NR_gethostname
 SYSCALL_DEF(gethostname, ARG_PTR, ARG_DEC);
 #endif
@@ -292,6 +300,14 @@ SYSCALL_DEF(syncfs, ARG_DEC);
 SYSCALL_DEF(time, ARG_PTR);
 #endif
 SYSCALL_DEF(times, ARG_PTR);
+#ifdef TARGET_NR_truncate
+SYSCALL_DEF(truncate, ARG_STR, ARG_DEC);
+#endif
+#ifdef TARGET_NR_truncate64
+SYSCALL_DEF_FULL(truncate64, .impl = impl_truncate,
+ .args = args_ftruncate64_truncate64,
+ .arg_type = { ARG_STR, ARG_DEC64 });
+#endif
 SYSCALL_DEF(umask, ARG_OCT);
 #ifdef TARGET_NR_umount
 SYSCALL_DEF(umount, ARG_STR);
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index bdf42ad437..7697cb304a 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -182,6 +182,25 @@ SYSCALL_IMPL(fchmodat)
 return do_fchmodat(arg1, arg2, arg3);
 }
 
+#ifdef TARGET_NR_ftruncate64
+# if TARGET_ABI_BITS == 32
+SYSCALL_ARGS(ftruncate64_truncate64)
+{
+/* We have already assigned out[0].  */
+int off = regpairs_aligned(cpu_env, TARGET_NR_ftruncate64);
+out[1] = target_offset64(in[1 + off], in[2 + off]);
+return def;
+}
+# else
+#  define args_ftruncate64_truncate64 NULL
+# endif
+#endif
+
+SYSCALL_IMPL(ftruncate)
+{
+return get_errno(ftruncate(arg1, arg2));
+}
+
 #ifdef TARGET_NR_futimesat
 SYSCALL_IMPL(futimesat)
 {
@@ -1319,6 +1338,19 @@ SYSCALL_IMPL(syncfs)
 return get_errno(syncfs(arg1));
 }
 
+SYSCALL_IMPL(truncate)
+{
+char *p = lock_user_string(arg1);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(truncate(p, arg2));
+unlock_user(p, arg1, 0);
+return ret;
+}
+
 static abi_long do_umount2(abi_ulong target_path, int flags)
 {
 char *p = lock_user_string(target_path);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 80e8b360a9..1b1d44bf32 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3721,20 +3721,6 @@ static inline abi_long target_truncate64(void *cpu_env, 
const char *arg1,
 }
 #endif
 
-#ifdef TARGET_NR_ftruncate64
-static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
-  abi_long arg2,
-  abi_long arg3,
-  abi_long arg4)
-{
-if (regpairs_aligned(cpu_env, TARGET_NR_ftruncate64)) {
-arg2 = arg3;
-arg3 = arg4;
-}
-return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
-}
-#endif
-
 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
abi_ulong target_addr)
 {
@@ -4158,18 +4144,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_truncate
-case TARGET_NR_truncate:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(truncate(p, arg2));
-unlock_user(p, arg1, 0);
-return ret;
-#endif
-#ifdef TARGET_NR_ftruncate
-case TARGET_NR_ftruncate:
-return get_errno(ftruncate(arg1, arg2));
-#endif
 case TARGET_NR_getpriority:
 /* Note that negative values are valid for getpriority, so we must
differentiate based on errno settings.  */
@@ -5371,18 +5345,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return ret;
 }
 #endif
-#ifdef TARGET_NR_truncate64
-case TARGET_NR_truncate64:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-   ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
-unlock_user(p, arg1, 0);
-return ret;
-#endif
-#ifdef TARGET_NR_ftruncate64
-case TARGET_NR_ftruncate64:
-return target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
-#endif
 #ifdef TARGET_NR_stat64
 case TARGET_NR_stat64:
 if (!(p = lock_user_string(arg1))) {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 3326541f17..55b617239c 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -193,12 

[Qemu-devel] [PATCH v7 64/74] linux-user: Split out gethostname, sethostname

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/syscall-proc.inc.c | 28 
 linux-user/syscall.c  | 19 ---
 linux-user/strace.list|  6 --
 4 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 77d750f66f..3ba697fd53 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -59,6 +59,9 @@ SYSCALL_DEF(futimesat, ARG_ATDIRFD, ARG_STR, ARG_PTR);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
+#ifdef TARGET_NR_gethostname
+SYSCALL_DEF(gethostname, ARG_PTR, ARG_DEC);
+#endif
 SYSCALL_DEF(getpgid, ARG_DEC);
 #ifdef TARGET_NR_getpgrp
 SYSCALL_DEF(getpgrp);
@@ -207,6 +210,7 @@ SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semget)
 SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
+SYSCALL_DEF(sethostname, ARG_STR);
 SYSCALL_DEF(setpgid, ARG_DEC, ARG_DEC);
 SYSCALL_DEF(setsid);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop)
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 567df54581..b1a801fb62 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -438,6 +438,21 @@ SYSCALL_IMPL(fork)
 }
 #endif
 
+#ifdef TARGET_NR_gethostname
+SYSCALL_IMPL(gethostname)
+{
+char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
+abi_long ret;
+
+if (!name) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(gethostname(name, arg2));
+unlock_user(name, arg1, arg2);
+return ret;
+}
+#endif
+
 SYSCALL_IMPL(getpgid)
 {
 return get_errno(getpgid(arg1));
@@ -485,6 +500,19 @@ SYSCALL_IMPL(nice)
 }
 #endif
 
+SYSCALL_IMPL(sethostname)
+{
+void *p = lock_user_string(arg1);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(sethostname(p, arg2));
+unlock_user(p, arg1, 0);
+return ret;
+}
+
 SYSCALL_IMPL(setpgid)
 {
 return get_errno(setpgid(arg1, arg2));
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b8b18ac1de..6dd4196647 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4240,12 +4240,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_sethostname:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(sethostname(p, arg2));
-unlock_user(p, arg1, 0);
-return ret;
 #ifdef TARGET_NR_setrlimit
 case TARGET_NR_setrlimit:
 {
@@ -7078,19 +7072,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return ret;
 }
 #endif
-#ifdef TARGET_NR_gethostname
-case TARGET_NR_gethostname:
-{
-char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
-if (name) {
-ret = get_errno(gethostname(name, arg2));
-unlock_user(name, arg1, arg2);
-} else {
-ret = -TARGET_EFAULT;
-}
-return ret;
-}
-#endif
 #ifdef TARGET_NR_atomic_cmpxchg_32
 case TARGET_NR_atomic_cmpxchg_32:
 {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index b1c2f7851e..361ceec853 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -244,9 +244,6 @@
 #ifdef TARGET_NR_getgroups32
 { TARGET_NR_getgroups32, "getgroups32" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_gethostname
-{ TARGET_NR_gethostname, "gethostname" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getitimer
 { TARGET_NR_getitimer, "getitimer" , NULL, NULL, NULL },
 #endif
@@ -1025,9 +1022,6 @@
 #ifdef TARGET_NR_sethae
 { TARGET_NR_sethae, "sethae" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_sethostname
-{ TARGET_NR_sethostname, "sethostname" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setitimer
 { TARGET_NR_setitimer, "setitimer" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 58/74] linux-user: Split out sigprocmask, rt_sigprocmask

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|   6 ++
 linux-user/syscall.h |   1 +
 linux-user/strace.c  |  44 +++--
 linux-user/syscall-sig.inc.c | 123 +++
 linux-user/syscall.c | 109 ---
 linux-user/strace.list   |   6 --
 6 files changed, 154 insertions(+), 135 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 99532f75b2..ef77f60524 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -194,6 +194,7 @@ SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, 
ARG_PTR, ARG_DEC);
 #else
 SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_DEC);
 #endif
+SYSCALL_DEF(rt_sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR, ARG_DEC);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
@@ -222,6 +223,11 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #ifdef TARGET_NR_sigaction
 SYSCALL_DEF(sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR);
 #endif
+#if defined(TARGET_ALPHA)
+SYSCALL_DEF(sigprocmask, ARG_SIGPROCMASKHOW, ARG_HEX);
+#elif defined(TARGET_NR_sigprocmask)
+SYSCALL_DEF(sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR);
+#endif
 #ifdef TARGET_NR_sgetmask
 SYSCALL_DEF(sgetmask);
 #endif
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 7b197840f5..cf9f3e5e55 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -59,6 +59,7 @@ typedef enum {
 ARG_ATDIRFD,
 ARG_SIGNAL,
 ARG_LSEEKWHENCE,
+ARG_SIGPROCMASKHOW,
 
 /* These print as sets of flags.  */
 ARG_ACCESSFLAG,
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 83dd755c73..886663af2e 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -102,6 +102,27 @@ add_signal(char *buf, int size, int sig)
 }
 }
 
+static int
+add_sigprocmaskhow(char *buf, int size, int how)
+{
+const char *str;
+
+switch (how) {
+case TARGET_SIG_BLOCK:
+str = "SIG_BLOCK";
+break;
+case TARGET_SIG_UNBLOCK:
+str = "SIG_UNBLOCK";
+break;
+case TARGET_SIG_SETMASK:
+str = "SIG_SETMASK";
+break;
+default:
+return snprintf(buf, size, "%d", how);
+}
+return snprintf(buf, size, "%s", str);
+}
+
 static void
 print_signal(abi_ulong arg, int last)
 {
@@ -1564,26 +1585,6 @@ print_fstat(const struct syscallname *name,
 #define print_fstat64 print_fstat
 #endif
 
-#ifdef TARGET_NR_rt_sigprocmask
-static void
-print_rt_sigprocmask(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-const char *how = "UNKNOWN";
-print_syscall_prologue(name);
-switch(arg0) {
-case TARGET_SIG_BLOCK: how = "SIG_BLOCK"; break;
-case TARGET_SIG_UNBLOCK: how = "SIG_UNBLOCK"; break;
-case TARGET_SIG_SETMASK: how = "SIG_SETMASK"; break;
-}
-gemu_log("%s,",how);
-print_pointer(arg1, 0);
-print_pointer(arg2, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_rt_sigqueueinfo
 static void
 print_rt_sigqueueinfo(const struct syscallname *name,
@@ -2015,6 +2016,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_SIGNAL:
 len = add_signal(b, rest, arg);
 break;
+case ARG_SIGPROCMASKHOW:
+len = add_sigprocmaskhow(b, rest, arg);
+break;
 case ARG_ACCESSFLAG:
 len = add_flags(b, rest, access_flags, arg, false);
 break;
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index f50ed16b74..8a6518bdaa 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -117,6 +117,53 @@ SYSCALL_IMPL(rt_sigaction)
 return ret;
 }
 
+SYSCALL_IMPL(rt_sigprocmask)
+{
+int how = 0;
+sigset_t set, oldset, *set_ptr = NULL;
+abi_long ret;
+void *p;
+
+if (arg4 != sizeof(target_sigset_t)) {
+return -TARGET_EINVAL;
+}
+
+if (arg2) {
+switch (arg1) {
+case TARGET_SIG_BLOCK:
+how = SIG_BLOCK;
+break;
+case TARGET_SIG_UNBLOCK:
+how = SIG_UNBLOCK;
+break;
+case TARGET_SIG_SETMASK:
+how = SIG_SETMASK;
+break;
+default:
+return -TARGET_EINVAL;
+}
+p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1);
+if (!p) {
+return -TARGET_EFAULT;
+}
+target_to_host_sigset(, p);
+unlock_user(p, arg2, 0);
+set_ptr = 
+}
+
+ret = do_sigprocmask(how, set_ptr, );
+
+if (!is_error(ret) && arg3) {
+p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0);
+if (!p) {
+return -TARGET_EFAULT;
+}
+host_to_target_sigset(p, );
+unlock_user(p, arg3, 

[Qemu-devel] [PATCH v7 71/74] linux-user: Split out swapon, swapoff

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  2 ++
 linux-user/syscall-file.inc.c | 26 ++
 linux-user/syscall.c  | 16 
 linux-user/strace.list|  6 --
 4 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 5625c268c3..34e799d206 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -279,6 +279,8 @@ SYSCALL_DEF(ssetmask, ARG_HEX);
 #ifdef TARGET_NR_stime
 SYSCALL_DEF(stime, ARG_PTR);
 #endif
+SYSCALL_DEF(swapoff, ARG_STR);
+SYSCALL_DEF(swapon, ARG_STR, ARG_HEX);
 #ifdef TARGET_NR_symlink
 SYSCALL_DEF(symlink, ARG_STR, ARG_STR);
 #endif
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index e3749f0fb4..bdf42ad437 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -1254,6 +1254,32 @@ SYSCALL_IMPL(select)
 }
 #endif
 
+SYSCALL_IMPL(swapoff)
+{
+char *p = lock_user_string(arg1);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(swapoff(p));
+unlock_user(p, arg1, 0);
+return ret;
+}
+
+SYSCALL_IMPL(swapon)
+{
+char *p = lock_user_string(arg1);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(swapon(p, arg2));
+unlock_user(p, arg1, 0);
+return ret;
+}
+
 static abi_long do_symlinkat(abi_ulong guest_target, int dirfd,
  abi_ulong guest_path)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fccf9ee184..ead2e5c2b8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4158,14 +4158,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_swapon
-case TARGET_NR_swapon:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(swapon(p, arg2));
-unlock_user(p, arg1, 0);
-return ret;
-#endif
 case TARGET_NR_reboot:
 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
/* arg4 must be ignored in all other cases */
@@ -4503,14 +4495,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 case TARGET_NR_syscall:
 return do_syscall(cpu_env, arg1 & 0x, arg2, arg3, arg4, arg5,
   arg6, arg7, arg8, 0);
-#endif
-#ifdef TARGET_NR_swapoff
-case TARGET_NR_swapoff:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(swapoff(p));
-unlock_user(p, arg1, 0);
-return ret;
 #endif
 case TARGET_NR_sysinfo:
 {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d9db80335d..3d2e398439 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1116,12 +1116,6 @@
 #ifdef TARGET_NR_swapcontext
 { TARGET_NR_swapcontext, "swapcontext" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_swapoff
-{ TARGET_NR_swapoff, "swapoff" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_swapon
-{ TARGET_NR_swapon, "swapon" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_syscall
 { TARGET_NR_syscall, "syscall" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 63/74] linux-user: Split out sigreturn, rt_sigreturn

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  4 
 linux-user/syscall-sig.inc.c | 18 ++
 linux-user/syscall.c | 12 
 linux-user/strace.list   |  6 --
 4 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 11851535e1..77d750f66f 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -197,6 +197,7 @@ SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, 
ARG_DEC);
 SYSCALL_DEF(rt_sigpending, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigqueueinfo, ARG_DEC, ARG_SIGNAL, ARG_PTR);
+SYSCALL_DEF(rt_sigreturn);
 SYSCALL_DEF(rt_sigsuspend, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigtimedwait, ARG_PTR, ARG_PTR, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_tgsigqueueinfo, ARG_DEC, ARG_DEC, ARG_SIGNAL, ARG_PTR);
@@ -236,6 +237,9 @@ SYSCALL_DEF(sigprocmask, ARG_SIGPROCMASKHOW, ARG_HEX);
 #elif defined(TARGET_NR_sigprocmask)
 SYSCALL_DEF(sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR);
 #endif
+#ifdef TARGET_NR_sigreturn
+SYSCALL_DEF(sigreturn);
+#endif
 #if defined(TARGET_ALPHA)
 SYSCALL_DEF(sigsuspend, ARG_HEX);
 #elif defined(TARGET_NR_sigsuspend)
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index 774346838b..d5c0ccdcc3 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -206,6 +206,14 @@ SYSCALL_IMPL(rt_sigqueueinfo)
 return get_errno(sys_rt_sigqueueinfo(arg1, arg2, ));
 }
 
+SYSCALL_IMPL(rt_sigreturn)
+{
+if (block_signals()) {
+return -TARGET_ERESTARTSYS;
+}
+return do_rt_sigreturn(cpu_env);
+}
+
 SYSCALL_IMPL(rt_sigsuspend)
 {
 CPUState *cpu = ENV_GET_CPU(cpu_env);
@@ -471,6 +479,16 @@ SYSCALL_IMPL(sigprocmask)
 }
 #endif
 
+#ifdef TARGET_NR_sigreturn
+SYSCALL_IMPL(sigreturn)
+{
+if (block_signals()) {
+return -TARGET_ERESTARTSYS;
+}
+return do_sigreturn(cpu_env);
+}
+#endif
+
 #ifdef TARGET_NR_sigsuspend
 SYSCALL_IMPL(sigsuspend)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e489d12103..b8b18ac1de 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4240,18 +4240,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_sigreturn
-case TARGET_NR_sigreturn:
-if (block_signals()) {
-return -TARGET_ERESTARTSYS;
-}
-return do_sigreturn(cpu_env);
-#endif
-case TARGET_NR_rt_sigreturn:
-if (block_signals()) {
-return -TARGET_ERESTARTSYS;
-}
-return do_rt_sigreturn(cpu_env);
 case TARGET_NR_sethostname:
 if (!(p = lock_user_string(arg1)))
 return -TARGET_EFAULT;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 57445a8d81..b1c2f7851e 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -926,9 +926,6 @@
 #ifdef TARGET_NR_rmdir
 { TARGET_NR_rmdir, "rmdir" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_rt_sigreturn
-{ TARGET_NR_rt_sigreturn, "rt_sigreturn" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_sched_getaffinity
 { TARGET_NR_sched_getaffinity, "sched_getaffinity" , NULL, NULL, NULL },
 #endif
@@ -1113,9 +1110,6 @@
 #ifdef TARGET_NR_signalfd4
 { TARGET_NR_signalfd4, "signalfd4" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_sigreturn
-{ TARGET_NR_sigreturn, "sigreturn" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_socket
 { TARGET_NR_socket, "socket" , NULL, print_socket, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 51/74] linux-user: Split out setpgid

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h | 1 +
 linux-user/syscall-proc.inc.c | 5 +
 linux-user/syscall.c  | 2 --
 linux-user/strace.list| 3 ---
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 5cf39f2bb9..6de7b84351 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -187,6 +187,7 @@ SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semget)
 SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
+SYSCALL_DEF(setpgid, ARG_DEC, ARG_DEC);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop)
 SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 517f84e139..5bd27d1d4b 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -468,6 +468,11 @@ SYSCALL_IMPL(nice)
 }
 #endif
 
+SYSCALL_IMPL(setpgid)
+{
+return get_errno(setpgid(arg1, arg2));
+}
+
 SYSCALL_IMPL(times)
 {
 abi_ulong target_buf = arg1;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 45fe05ac78..dcb35e1228 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,8 +4241,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_setpgid:
-return get_errno(setpgid(arg1, arg2));
 case TARGET_NR_umask:
 return get_errno(umask(arg1));
 case TARGET_NR_chroot:
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 68e202ca15..4a527b0c65 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1073,9 +1073,6 @@
 #ifdef TARGET_NR_setns
 { TARGET_NR_setns, "setns" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setpgid
-{ TARGET_NR_setpgid, "setpgid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setpgrp
 { TARGET_NR_setpgrp, "setpgrp" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 48/74] linux-user: Fix types in ioctl logging

2019-05-19 Thread Richard Henderson
There is no need to cast "int" to "long"; just use the
correct format in the first place.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-ioctl.inc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/linux-user/syscall-ioctl.inc.c b/linux-user/syscall-ioctl.inc.c
index be3f0b4b92..15d87b9663 100644
--- a/linux-user/syscall-ioctl.inc.c
+++ b/linux-user/syscall-ioctl.inc.c
@@ -791,7 +791,7 @@ SYSCALL_IMPL(ioctl)
 
 for (ie = ioctl_entries; ; ie++) {
 if (ie->target_cmd == 0) {
-gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
+gemu_log("Unsupported ioctl: cmd=0x%04x\n", cmd);
 return -TARGET_ENOSYS;
 }
 if (ie->target_cmd == cmd) {
@@ -864,8 +864,8 @@ SYSCALL_IMPL(ioctl)
 }
 break;
 default:
-gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
- (long)cmd, arg_type[0]);
+gemu_log("Unsupported ioctl type: cmd=0x%04x type=%d\n",
+ cmd, arg_type[0]);
 ret = -TARGET_ENOSYS;
 break;
 }
-- 
2.17.1




[Qemu-devel] [PATCH v7 67/74] linux-user: Split out gettimeofday, settimeofday

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  2 ++
 linux-user/syscall-time.inc.c | 33 +
 linux-user/syscall.c  | 31 ---
 linux-user/strace.list|  6 --
 4 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 446175af84..d109754c5f 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -77,6 +77,7 @@ SYSCALL_DEF(getrlimit, ARG_DEC, ARG_PTR);
 #endif
 SYSCALL_DEF(getrusage, ARG_DEC, ARG_PTR);
 SYSCALL_DEF(getsid, ARG_DEC);
+SYSCALL_DEF(gettimeofday, ARG_PTR);
 #ifdef TARGET_NR_getxpid
 SYSCALL_DEF(getxpid);
 #endif
@@ -220,6 +221,7 @@ SYSCALL_DEF(setpgid, ARG_DEC, ARG_DEC);
 SYSCALL_DEF(setrlimit, ARG_DEC, ARG_PTR);
 #endif
 SYSCALL_DEF(setsid);
+SYSCALL_DEF(settimeofday, ARG_PTR, ARG_PTR);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop)
 SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC);
 #endif
diff --git a/linux-user/syscall-time.inc.c b/linux-user/syscall-time.inc.c
index d1fb72bde0..1308af64ac 100644
--- a/linux-user/syscall-time.inc.c
+++ b/linux-user/syscall-time.inc.c
@@ -16,6 +16,39 @@
  *  along with this program; if not, see .
  */
 
+SYSCALL_IMPL(gettimeofday)
+{
+struct timeval tv;
+abi_long ret = get_errno(gettimeofday(, NULL));
+
+if (!is_error(ret) && copy_to_user_timeval(arg1, )) {
+return -TARGET_EFAULT;
+}
+return ret;
+}
+
+SYSCALL_IMPL(settimeofday)
+{
+struct timeval tv, *ptv = NULL;
+struct timezone tz, *ptz = NULL;
+
+if (arg1) {
+if (copy_from_user_timeval(, arg1)) {
+return -TARGET_EFAULT;
+}
+ptv = 
+}
+
+if (arg2) {
+if (copy_from_user_timezone(, arg2)) {
+return -TARGET_EFAULT;
+}
+ptz = 
+}
+
+return get_errno(settimeofday(ptv, ptz));
+}
+
 #ifdef TARGET_NR_stime
 SYSCALL_IMPL(stime)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5fe52c775d..b8bc44364d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4240,37 +4240,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_gettimeofday:
-{
-struct timeval tv;
-ret = get_errno(gettimeofday(, NULL));
-if (!is_error(ret)) {
-if (copy_to_user_timeval(arg1, ))
-return -TARGET_EFAULT;
-}
-}
-return ret;
-case TARGET_NR_settimeofday:
-{
-struct timeval tv, *ptv = NULL;
-struct timezone tz, *ptz = NULL;
-
-if (arg1) {
-if (copy_from_user_timeval(, arg1)) {
-return -TARGET_EFAULT;
-}
-ptv = 
-}
-
-if (arg2) {
-if (copy_from_user_timezone(, arg2)) {
-return -TARGET_EFAULT;
-}
-ptz = 
-}
-
-return get_errno(settimeofday(ptv, ptz));
-}
 #if defined(TARGET_NR_select)
 case TARGET_NR_select:
 #if defined(TARGET_WANT_NI_OLD_SELECT)
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 00a32bc616..635b952d2f 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -296,9 +296,6 @@
 #ifdef TARGET_NR_gettid
 { TARGET_NR_gettid, "gettid" , "%s()", NULL, NULL },
 #endif
-#ifdef TARGET_NR_gettimeofday
-{ TARGET_NR_gettimeofday, "gettimeofday" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getuid
 { TARGET_NR_getuid, "getuid" , "%s()", NULL, NULL },
 #endif
@@ -1068,9 +1065,6 @@
 #ifdef TARGET_NR_set_tid_address
 { TARGET_NR_set_tid_address, "set_tid_address" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_settimeofday
-{ TARGET_NR_settimeofday, "settimeofday" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setuid
 { TARGET_NR_setuid, "setuid" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 70/74] linux-user: Split out symlink, symlinkat

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/strace.c   | 27 ---
 linux-user/syscall-file.inc.c | 28 
 linux-user/syscall.c  | 30 --
 linux-user/strace.list|  6 --
 5 files changed, 32 insertions(+), 63 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index c179f69d9f..5625c268c3 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -279,6 +279,10 @@ SYSCALL_DEF(ssetmask, ARG_HEX);
 #ifdef TARGET_NR_stime
 SYSCALL_DEF(stime, ARG_PTR);
 #endif
+#ifdef TARGET_NR_symlink
+SYSCALL_DEF(symlink, ARG_STR, ARG_STR);
+#endif
+SYSCALL_DEF(symlinkat, ARG_STR, ARG_ATDIRFD, ARG_STR);
 SYSCALL_DEF(sync);
 SYSCALL_DEF(syncfs, ARG_DEC);
 #ifdef TARGET_NR_time
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 669eca7fa6..97755458d3 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1563,33 +1563,6 @@ print_statfs64(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_symlink
-static void
-print_symlink(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_string(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_symlinkat
-static void
-print_symlinkat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_at_dirfd(arg1, 0);
-print_string(arg2, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_utimensat
 static void
 print_utimensat(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 0a25d39d28..e3749f0fb4 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -1254,6 +1254,34 @@ SYSCALL_IMPL(select)
 }
 #endif
 
+static abi_long do_symlinkat(abi_ulong guest_target, int dirfd,
+ abi_ulong guest_path)
+{
+char *target = lock_user_string(guest_target);
+char *path = lock_user_string(guest_path);
+abi_long ret = -TARGET_EFAULT;
+
+if (target && path) {
+ret = get_errno(symlinkat(target, dirfd, path));
+}
+unlock_user(path, guest_path, 0);
+unlock_user(target, guest_target, 0);
+
+return ret;
+}
+
+#ifdef TARGET_NR_symlink
+SYSCALL_IMPL(symlink)
+{
+return do_symlinkat(arg1, AT_FDCWD, arg2);
+}
+#endif
+
+SYSCALL_IMPL(symlinkat)
+{
+return do_symlinkat(arg1, arg2, arg3);
+}
+
 SYSCALL_IMPL(sync)
 {
 sync();
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6355fd62d8..fccf9ee184 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4158,36 +4158,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_symlink
-case TARGET_NR_symlink:
-{
-void *p2;
-p = lock_user_string(arg1);
-p2 = lock_user_string(arg2);
-if (!p || !p2)
-ret = -TARGET_EFAULT;
-else
-ret = get_errno(symlink(p, p2));
-unlock_user(p2, arg2, 0);
-unlock_user(p, arg1, 0);
-}
-return ret;
-#endif
-#if defined(TARGET_NR_symlinkat)
-case TARGET_NR_symlinkat:
-{
-void *p2;
-p  = lock_user_string(arg1);
-p2 = lock_user_string(arg3);
-if (!p || !p2)
-ret = -TARGET_EFAULT;
-else
-ret = get_errno(symlinkat(p, arg2, p2));
-unlock_user(p2, arg3, 0);
-unlock_user(p, arg1, 0);
-}
-return ret;
-#endif
 #ifdef TARGET_NR_swapon
 case TARGET_NR_swapon:
 if (!(p = lock_user_string(arg1)))
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 1bb9224b5e..d9db80335d 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1122,12 +1122,6 @@
 #ifdef TARGET_NR_swapon
 { TARGET_NR_swapon, "swapon" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_symlink
-{ TARGET_NR_symlink, "symlink" , NULL, print_symlink, NULL },
-#endif
-#ifdef TARGET_NR_symlinkat
-{ TARGET_NR_symlinkat, "symlinkat", NULL, print_symlinkat, NULL },
-#endif
 #ifdef TARGET_NR_syscall
 { TARGET_NR_syscall, "syscall" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 62/74] linux-user: Split out rt_sigqueueinfo, rt_tgsigqueueinfo

2019-05-19 Thread Richard Henderson
This does drop the (questionable) siginfo_t printing.
But since we already do not handle more important things
in this area like sigset_t, this does not feel a loss.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|   2 +
 linux-user/strace.c  | 138 ---
 linux-user/syscall-sig.inc.c |  30 
 linux-user/syscall.c |  26 ---
 linux-user/strace.list   |   6 --
 5 files changed, 32 insertions(+), 170 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 24289ed413..11851535e1 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -196,8 +196,10 @@ SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, 
ARG_DEC);
 #endif
 SYSCALL_DEF(rt_sigpending, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR, ARG_DEC);
+SYSCALL_DEF(rt_sigqueueinfo, ARG_DEC, ARG_SIGNAL, ARG_PTR);
 SYSCALL_DEF(rt_sigsuspend, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigtimedwait, ARG_PTR, ARG_PTR, ARG_PTR, ARG_DEC);
+SYSCALL_DEF(rt_tgsigqueueinfo, ARG_DEC, ARG_DEC, ARG_SIGNAL, ARG_PTR);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 886663af2e..2e70a3910c 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -167,93 +167,6 @@ static void print_si_code(int arg)
 gemu_log("%s", codename);
 }
 
-static void get_target_siginfo(target_siginfo_t *tinfo,
-const target_siginfo_t *info)
-{
-abi_ulong sival_ptr;
-
-int sig;
-int si_errno;
-int si_code;
-int si_type;
-
-__get_user(sig, >si_signo);
-__get_user(si_errno, >si_errno);
-__get_user(si_code, >si_code);
-
-tinfo->si_signo = sig;
-tinfo->si_errno = si_errno;
-tinfo->si_code = si_code;
-
-/* Ensure we don't leak random junk to the guest later */
-memset(tinfo->_sifields._pad, 0, sizeof(tinfo->_sifields._pad));
-
-/* This is awkward, because we have to use a combination of
- * the si_code and si_signo to figure out which of the union's
- * members are valid. (Within the host kernel it is always possible
- * to tell, but the kernel carefully avoids giving userspace the
- * high 16 bits of si_code, so we don't have the information to
- * do this the easy way...) We therefore make our best guess,
- * bearing in mind that a guest can spoof most of the si_codes
- * via rt_sigqueueinfo() if it likes.
- *
- * Once we have made our guess, we record it in the top 16 bits of
- * the si_code, so that print_siginfo() later can use it.
- * print_siginfo() will strip these top bits out before printing
- * the si_code.
- */
-
-switch (si_code) {
-case SI_USER:
-case SI_TKILL:
-case SI_KERNEL:
-/* Sent via kill(), tkill() or tgkill(), or direct from the kernel.
- * These are the only unspoofable si_code values.
- */
-__get_user(tinfo->_sifields._kill._pid, >_sifields._kill._pid);
-__get_user(tinfo->_sifields._kill._uid, >_sifields._kill._uid);
-si_type = QEMU_SI_KILL;
-break;
-default:
-/* Everything else is spoofable. Make best guess based on signal */
-switch (sig) {
-case TARGET_SIGCHLD:
-__get_user(tinfo->_sifields._sigchld._pid,
-   >_sifields._sigchld._pid);
-__get_user(tinfo->_sifields._sigchld._uid,
-   >_sifields._sigchld._uid);
-__get_user(tinfo->_sifields._sigchld._status,
-   >_sifields._sigchld._status);
-__get_user(tinfo->_sifields._sigchld._utime,
-   >_sifields._sigchld._utime);
-__get_user(tinfo->_sifields._sigchld._stime,
-   >_sifields._sigchld._stime);
-si_type = QEMU_SI_CHLD;
-break;
-case TARGET_SIGIO:
-__get_user(tinfo->_sifields._sigpoll._band,
-   >_sifields._sigpoll._band);
-__get_user(tinfo->_sifields._sigpoll._fd,
-   >_sifields._sigpoll._fd);
-si_type = QEMU_SI_POLL;
-break;
-default:
-/* Assume a sigqueue()/mq_notify()/rt_sigqueueinfo() source. */
-__get_user(tinfo->_sifields._rt._pid, >_sifields._rt._pid);
-__get_user(tinfo->_sifields._rt._uid, >_sifields._rt._uid);
-/* XXX: potential problem if 64 bit */
-__get_user(sival_ptr, >_sifields._rt._sigval.sival_ptr);
-tinfo->_sifields._rt._sigval.sival_ptr = sival_ptr;
-
-si_type = QEMU_SI_RT;
-break;
-}
-break;
-}
-
-tinfo->si_code = deposit32(si_code, 16, 16, si_type);
-}
-
 static void print_siginfo(const target_siginfo_t *tinfo)
 {
 /* Print a target_siginfo_t in the format desired 

[Qemu-devel] [PATCH v7 66/74] linux-user: Split out getrusage

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/syscall-proc.inc.c | 12 
 linux-user/syscall.c  |  9 -
 linux-user/strace.list|  3 ---
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 34426a2e23..446175af84 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -75,6 +75,7 @@ SYSCALL_DEF(getppid);
 #ifdef TARGET_NR_getrlimit
 SYSCALL_DEF(getrlimit, ARG_DEC, ARG_PTR);
 #endif
+SYSCALL_DEF(getrusage, ARG_DEC, ARG_PTR);
 SYSCALL_DEF(getsid, ARG_DEC);
 #ifdef TARGET_NR_getxpid
 SYSCALL_DEF(getxpid);
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 1238b08191..bf9e278bf0 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -499,6 +499,18 @@ SYSCALL_IMPL(getrlimit)
 return ret;
 }
 #endif
+
+SYSCALL_IMPL(getrusage)
+{
+struct rusage rusage;
+abi_long ret = get_errno(getrusage(arg1, ));
+
+if (!is_error(ret)) {
+ret = host_to_target_rusage(arg2, );
+}
+return ret;
+}
+
 SYSCALL_IMPL(getsid)
 {
 return get_errno(getsid(arg1));
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 401450b0e3..5fe52c775d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4240,15 +4240,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_getrusage:
-{
-struct rusage rusage;
-ret = get_errno(getrusage(arg1, ));
-if (!is_error(ret)) {
-ret = host_to_target_rusage(arg2, );
-}
-}
-return ret;
 case TARGET_NR_gettimeofday:
 {
 struct timeval tv;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 711ad9c0aa..00a32bc616 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -283,9 +283,6 @@
 #ifdef TARGET_NR_get_robust_list
 { TARGET_NR_get_robust_list, "get_robust_list" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getrusage
-{ TARGET_NR_getrusage, "getrusage" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getsockname
 { TARGET_NR_getsockname, "getsockname" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 61/74] linux-user: Split out rt_sigtimedwait

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  1 +
 linux-user/syscall-sig.inc.c | 37 
 linux-user/syscall.c | 36 ---
 linux-user/strace.list   |  3 ---
 4 files changed, 38 insertions(+), 39 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 2b930f5599..24289ed413 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -197,6 +197,7 @@ SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, 
ARG_DEC);
 SYSCALL_DEF(rt_sigpending, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigsuspend, ARG_PTR, ARG_DEC);
+SYSCALL_DEF(rt_sigtimedwait, ARG_PTR, ARG_PTR, ARG_PTR, ARG_DEC);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index 23ea14e2a6..5f2c0ba499 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -215,6 +215,43 @@ SYSCALL_IMPL(rt_sigsuspend)
 return ret;
 }
 
+SYSCALL_IMPL(rt_sigtimedwait)
+{
+sigset_t set;
+struct timespec uts, *puts = NULL;
+siginfo_t uinfo;
+abi_long ret;
+void *p;
+
+if (arg4 != sizeof(target_sigset_t)) {
+return -TARGET_EINVAL;
+}
+p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
+if (!p) {
+return -TARGET_EFAULT;
+}
+target_to_host_sigset(, p);
+unlock_user(p, arg1, 0);
+if (arg3) {
+puts = 
+target_to_host_timespec(puts, arg3);
+}
+
+ret = get_errno(safe_rt_sigtimedwait(, , puts, SIGSET_T_SIZE));
+if (!is_error(ret)) {
+if (arg2) {
+p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0);
+if (!p) {
+return -TARGET_EFAULT;
+}
+host_to_target_siginfo(p, );
+unlock_user(p, arg2, sizeof(target_siginfo_t));
+}
+ret = host_to_target_signal(ret);
+}
+return ret;
+}
+
 #ifdef TARGET_NR_sigaction
 SYSCALL_IMPL(sigaction)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 00f4ba8753..8a05d3e32a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4240,42 +4240,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_rt_sigtimedwait:
-{
-sigset_t set;
-struct timespec uts, *puts;
-siginfo_t uinfo;
-
-if (arg4 != sizeof(target_sigset_t)) {
-return -TARGET_EINVAL;
-}
-
-if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 
1)))
-return -TARGET_EFAULT;
-target_to_host_sigset(, p);
-unlock_user(p, arg1, 0);
-if (arg3) {
-puts = 
-target_to_host_timespec(puts, arg3);
-} else {
-puts = NULL;
-}
-ret = get_errno(safe_rt_sigtimedwait(, , puts,
- SIGSET_T_SIZE));
-if (!is_error(ret)) {
-if (arg2) {
-p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
-  0);
-if (!p) {
-return -TARGET_EFAULT;
-}
-host_to_target_siginfo(p, );
-unlock_user(p, arg2, sizeof(target_siginfo_t));
-}
-ret = host_to_target_signal(ret);
-}
-}
-return ret;
 case TARGET_NR_rt_sigqueueinfo:
 {
 siginfo_t uinfo;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 26df8b25cd..0b2c057673 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -932,9 +932,6 @@
 #ifdef TARGET_NR_rt_sigreturn
 { TARGET_NR_rt_sigreturn, "rt_sigreturn" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_rt_sigtimedwait
-{ TARGET_NR_rt_sigtimedwait, "rt_sigtimedwait" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_rt_tgsigqueueinfo
 { TARGET_NR_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" , NULL, 
print_rt_tgsigqueueinfo, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 60/74] linux-user: Split out sigsuspend, rt_sigsuspend

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  6 +
 linux-user/syscall-sig.inc.c | 51 
 linux-user/syscall.c | 42 ++---
 linux-user/strace.list   |  6 -
 4 files changed, 59 insertions(+), 46 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 83a69246d0..2b930f5599 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -196,6 +196,7 @@ SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, 
ARG_DEC);
 #endif
 SYSCALL_DEF(rt_sigpending, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR, ARG_DEC);
+SYSCALL_DEF(rt_sigsuspend, ARG_PTR, ARG_DEC);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
@@ -232,6 +233,11 @@ SYSCALL_DEF(sigprocmask, ARG_SIGPROCMASKHOW, ARG_HEX);
 #elif defined(TARGET_NR_sigprocmask)
 SYSCALL_DEF(sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR);
 #endif
+#if defined(TARGET_ALPHA)
+SYSCALL_DEF(sigsuspend, ARG_HEX);
+#elif defined(TARGET_NR_sigsuspend)
+SYSCALL_DEF(sigsuspend, ARG_PTR);
+#endif
 #ifdef TARGET_NR_sgetmask
 SYSCALL_DEF(sgetmask);
 #endif
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index fe717a5121..23ea14e2a6 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -191,6 +191,30 @@ SYSCALL_IMPL(rt_sigprocmask)
 return ret;
 }
 
+SYSCALL_IMPL(rt_sigsuspend)
+{
+CPUState *cpu = ENV_GET_CPU(cpu_env);
+TaskState *ts = cpu->opaque;
+abi_long ret;
+void *p;
+
+if (arg2 != sizeof(target_sigset_t)) {
+return -TARGET_EINVAL;
+}
+p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
+if (!p) {
+return -TARGET_EFAULT;
+}
+target_to_host_sigset(>sigsuspend_mask, p);
+unlock_user(p, arg1, 0);
+
+ret = get_errno(safe_rt_sigsuspend(>sigsuspend_mask, SIGSET_T_SIZE));
+if (ret != -TARGET_ERESTARTSYS) {
+ts->in_sigsuspend = 1;
+}
+return ret;
+}
+
 #ifdef TARGET_NR_sigaction
 SYSCALL_IMPL(sigaction)
 {
@@ -380,6 +404,33 @@ SYSCALL_IMPL(sigprocmask)
 }
 #endif
 
+#ifdef TARGET_NR_sigsuspend
+SYSCALL_IMPL(sigsuspend)
+{
+CPUState *cpu = ENV_GET_CPU(cpu_env);
+TaskState *ts = cpu->opaque;
+abi_long ret;
+
+#if defined(TARGET_ALPHA)
+abi_ulong mask = arg1;
+target_to_host_old_sigset(>sigsuspend_mask, );
+#else
+void *p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
+if (!p) {
+return -TARGET_EFAULT;
+}
+target_to_host_old_sigset(>sigsuspend_mask, p);
+unlock_user(p, arg1, 0);
+#endif
+
+ret = get_errno(safe_rt_sigsuspend(>sigsuspend_mask, SIGSET_T_SIZE));
+if (ret != -TARGET_ERESTARTSYS) {
+ts->in_sigsuspend = 1;
+}
+return ret;
+}
+#endif
+
 #ifdef TARGET_NR_sgetmask
 SYSCALL_IMPL(sgetmask)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7dda237c95..00f4ba8753 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4227,7 +4227,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 abi_long arg5, abi_long arg6, abi_long arg7,
 abi_long arg8)
 {
-CPUState *cpu = ENV_GET_CPU(cpu_env);
 abi_long ret;
 #if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
 || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
@@ -4241,45 +4240,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_sigsuspend
-case TARGET_NR_sigsuspend:
-{
-TaskState *ts = cpu->opaque;
-#if defined(TARGET_ALPHA)
-abi_ulong mask = arg1;
-target_to_host_old_sigset(>sigsuspend_mask, );
-#else
-if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 
1)))
-return -TARGET_EFAULT;
-target_to_host_old_sigset(>sigsuspend_mask, p);
-unlock_user(p, arg1, 0);
-#endif
-ret = get_errno(safe_rt_sigsuspend(>sigsuspend_mask,
-   SIGSET_T_SIZE));
-if (ret != -TARGET_ERESTARTSYS) {
-ts->in_sigsuspend = 1;
-}
-}
-return ret;
-#endif
-case TARGET_NR_rt_sigsuspend:
-{
-TaskState *ts = cpu->opaque;
-
-if (arg2 != sizeof(target_sigset_t)) {
-return -TARGET_EINVAL;
-}
-if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 
1)))
-return -TARGET_EFAULT;
-target_to_host_sigset(>sigsuspend_mask, p);
-unlock_user(p, arg1, 0);
-ret = get_errno(safe_rt_sigsuspend(>sigsuspend_mask,
-   SIGSET_T_SIZE));
-if (ret != -TARGET_ERESTARTSYS) {
-ts->in_sigsuspend 

[Qemu-devel] [PATCH v7 43/74] linux-user: Split out pipe, pipe2

2019-05-19 Thread Richard Henderson
Note that pipe2 is universally available for guests.
Implement host support with syscall when !CONFIG_PIPE2.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h | 10 ++
 linux-user/syscall-file.inc.c | 51 +++
 linux-user/syscall.c  | 65 +++
 linux-user/strace.list|  6 
 4 files changed, 74 insertions(+), 58 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 062a75..bd3301a72f 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -132,6 +132,16 @@ SYSCALL_DEF(open_by_handle_at, ARG_DEC, ARG_PTR, 
ARG_OPENFLAG);
 #ifdef TARGET_NR_pause
 SYSCALL_DEF(pause);
 #endif
+#ifdef TARGET_NR_pipe
+# if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || \
+ defined(TARGET_SH4) || defined(TARGET_SPARC)
+/* ??? We have no way for strace to display the second returned fd.  */
+SYSCALL_DEF(pipe);
+# else
+SYSCALL_DEF(pipe, ARG_PTR);
+# endif
+#endif
+SYSCALL_DEF(pipe2, ARG_PTR, ARG_OPENFLAG);
 SYSCALL_DEF_FULL(pread64, .impl = impl_pread64,
  .args = args_pread64_pwrite64,
  .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 });
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 7d97dd1ec1..5bd9eaa002 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -726,6 +726,57 @@ SYSCALL_IMPL(open_by_handle_at)
 return ret;
 }
 
+static abi_long do_pipe(CPUArchState *cpu_env, abi_ulong target_fds,
+int target_flags, bool is_pipe2)
+{
+int host_flags = target_to_host_bitmask(target_flags, fcntl_flags_tbl);
+int host_fds[2];
+abi_long ret;
+
+ret = pipe2(host_fds, host_flags);
+if (is_error(ret)) {
+return get_errno(ret);
+}
+
+/*
+ * Several targets have special calling conventions for the original
+ * pipe syscall, but didn't replicate this into the pipe2 syscall.
+ */
+if (!is_pipe2) {
+#if defined(TARGET_ALPHA)
+cpu_env->ir[IR_A4] = host_fds[1];
+return host_fds[0];
+#elif defined(TARGET_MIPS)
+cpu_env->active_tc.gpr[3] = host_fds[1];
+return host_fds[0];
+#elif defined(TARGET_SH4)
+cpu_env->gregs[1] = host_fds[1];
+return host_fds[0];
+#elif defined(TARGET_SPARC)
+cpu_env->regwptr[1] = host_fds[1];
+return host_fds[0];
+#endif
+}
+
+if (put_user_s32(host_fds[0], target_fds)
+|| put_user_s32(host_fds[1], target_fds + 4)) {
+return -TARGET_EFAULT;
+}
+return 0;
+}
+
+#ifdef TARGET_NR_pipe
+SYSCALL_IMPL(pipe)
+{
+return do_pipe(cpu_env, arg1, 0, false);
+}
+#endif
+
+SYSCALL_IMPL(pipe2)
+{
+return do_pipe(cpu_env, arg1, arg2, true);
+}
+
 /*
  * Both pread64 and pwrite64 merge args into a 64-bit offset,
  * but the input registers and ordering are target specific.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bab9a57ee0..cda1f8a205 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -207,6 +207,9 @@ _syscall0(int, sys_gettid)
 #ifndef __NR_dup3
 #define __NR_dup3  -1
 #endif
+#ifndef __NR_pipe2
+#define __NR_pipe2  -1
+#endif
 #ifndef __NR_syncfs
 #define __NR_syncfs  -1
 #endif
@@ -273,6 +276,16 @@ _syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type,
 #ifndef CONFIG_SYNCFS
 _syscall1(int, syncfs, int, fd)
 #endif
+#ifndef CONFIG_PIPE2
+static int pipe2(int *fds, int flags)
+{
+if (flags) {
+return syscall(__NR_pipe2, fds, flags);
+} else {
+return pipe(fds);
+}
+}
+#endif
 
 static bitmask_transtbl fcntl_flags_tbl[] = {
   { TARGET_O_ACCMODE,   TARGET_O_WRONLY,O_ACCMODE,   O_WRONLY,},
@@ -1124,49 +1137,6 @@ static abi_long do_old_select(abi_ulong arg1)
 #endif
 #endif
 
-static abi_long do_pipe2(int host_pipe[], int flags)
-{
-#ifdef CONFIG_PIPE2
-return pipe2(host_pipe, flags);
-#else
-return -ENOSYS;
-#endif
-}
-
-static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
-int flags, int is_pipe2)
-{
-int host_pipe[2];
-abi_long ret;
-ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
-
-if (is_error(ret))
-return get_errno(ret);
-
-/* Several targets have special calling conventions for the original
-   pipe syscall, but didn't replicate this into the pipe2 syscall.  */
-if (!is_pipe2) {
-#if defined(TARGET_ALPHA)
-((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
-return host_pipe[0];
-#elif defined(TARGET_MIPS)
-((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
-return host_pipe[0];
-#elif defined(TARGET_SH4)
-((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
-return host_pipe[0];
-#elif defined(TARGET_SPARC)
-((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
-return host_pipe[0];
-#endif
-}
-
-if (put_user_s32(host_pipe[0], pipedes)
-|| 

[Qemu-devel] [PATCH v7 65/74] linux-user: Split out getrlimit, setrlimit

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  6 
 linux-user/syscall-proc.inc.c | 52 +++
 linux-user/syscall.c  | 46 ---
 linux-user/strace.list|  6 
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 3ba697fd53..34426a2e23 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -72,6 +72,9 @@ SYSCALL_DEF(getpid);
 #ifdef TARGET_NR_getppid
 SYSCALL_DEF(getppid);
 #endif
+#ifdef TARGET_NR_getrlimit
+SYSCALL_DEF(getrlimit, ARG_DEC, ARG_PTR);
+#endif
 SYSCALL_DEF(getsid, ARG_DEC);
 #ifdef TARGET_NR_getxpid
 SYSCALL_DEF(getxpid);
@@ -212,6 +215,9 @@ SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
 SYSCALL_DEF(sethostname, ARG_STR);
 SYSCALL_DEF(setpgid, ARG_DEC, ARG_DEC);
+#ifdef TARGET_NR_setrlimit
+SYSCALL_DEF(setrlimit, ARG_DEC, ARG_PTR);
+#endif
 SYSCALL_DEF(setsid);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop)
 SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC);
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index b1a801fb62..1238b08191 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -479,6 +479,26 @@ SYSCALL_IMPL(getppid)
 }
 #endif
 
+#ifdef TARGET_NR_getrlimit
+SYSCALL_IMPL(getrlimit)
+{
+int resource = target_to_host_resource(arg1);
+struct target_rlimit *target_rlim;
+struct rlimit rlim;
+abi_long ret;
+
+ret = get_errno(getrlimit(resource, ));
+if (!is_error(ret)) {
+if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) {
+return -TARGET_EFAULT;
+}
+target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
+target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
+unlock_user_struct(target_rlim, arg2, 1);
+}
+return ret;
+}
+#endif
 SYSCALL_IMPL(getsid)
 {
 return get_errno(getsid(arg1));
@@ -518,6 +538,38 @@ SYSCALL_IMPL(setpgid)
 return get_errno(setpgid(arg1, arg2));
 }
 
+#ifdef TARGET_NR_setrlimit
+SYSCALL_IMPL(setrlimit)
+{
+int resource = target_to_host_resource(arg1);
+struct target_rlimit *target_rlim;
+struct rlimit rlim;
+
+if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) {
+return -TARGET_EFAULT;
+}
+rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
+rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
+unlock_user_struct(target_rlim, arg2, 0);
+
+/*
+ * If we just passed through resource limit settings for memory then
+ * they would also apply to QEMU's own allocations, and QEMU will
+ * crash or hang or die if its allocations fail. Ideally we would
+ * track the guest allocations in QEMU and apply the limits ourselves.
+ * For now, just tell the guest the call succeeded but don't actually
+ * limit anything.
+ */
+if (resource != RLIMIT_AS &&
+resource != RLIMIT_DATA &&
+resource != RLIMIT_STACK) {
+return get_errno(setrlimit(resource, ));
+} else {
+return 0;
+}
+}
+#endif
+
 SYSCALL_IMPL(setsid)
 {
 return get_errno(setsid());
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6dd4196647..401450b0e3 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4240,52 +4240,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_setrlimit
-case TARGET_NR_setrlimit:
-{
-int resource = target_to_host_resource(arg1);
-struct target_rlimit *target_rlim;
-struct rlimit rlim;
-if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
-return -TARGET_EFAULT;
-rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
-rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
-unlock_user_struct(target_rlim, arg2, 0);
-/*
- * If we just passed through resource limit settings for memory 
then
- * they would also apply to QEMU's own allocations, and QEMU will
- * crash or hang or die if its allocations fail. Ideally we would
- * track the guest allocations in QEMU and apply the limits 
ourselves.
- * For now, just tell the guest the call succeeded but don't 
actually
- * limit anything.
- */
-if (resource != RLIMIT_AS &&
-resource != RLIMIT_DATA &&
-resource != RLIMIT_STACK) {
-return get_errno(setrlimit(resource, ));
-} else {
-return 0;
-}
-}
-#endif
-#ifdef TARGET_NR_getrlimit
-case TARGET_NR_getrlimit:
-{
-int resource = target_to_host_resource(arg1);
-struct target_rlimit *target_rlim;
-struct rlimit rlim;
-
-ret = 

[Qemu-devel] [PATCH v7 39/74] linux-user: Split out kill

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  1 +
 linux-user/syscall.h |  7 +++-
 linux-user/strace.c  | 76 ++--
 linux-user/syscall-sig.inc.c |  5 +++
 linux-user/syscall.c |  2 -
 linux-user/strace.list   |  3 --
 6 files changed, 48 insertions(+), 46 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 497fbdba66..c672b5ad99 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -58,6 +58,7 @@ SYSCALL_DEF(getxpid);
 #ifdef TARGET_NR_ipc
 SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX);
 #endif
+SYSCALL_DEF(kill, ARG_DEC, ARG_SIGNAL);
 #ifdef TARGET_NR_link
 SYSCALL_DEF(link, ARG_STR, ARG_STR);
 #endif
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 84a52b2d9a..642fb6dccb 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -55,8 +55,12 @@ typedef enum {
 ARG_HEX,
 ARG_OCT,
 
-/* These print as sets of flags.  */
+/* These numbers are interpreted.  */
 ARG_ATDIRFD,
+ARG_SIGNAL,
+ARG_LSEEKWHENCE,
+
+/* These print as sets of flags.  */
 ARG_ACCESSFLAG,
 ARG_ATFLAG,
 ARG_CLONEFLAG,
@@ -67,7 +71,6 @@ typedef enum {
 ARG_OPENFLAG,
 ARG_UMOUNTFLAG,
 ARG_UNLINKATFLAG,
-ARG_LSEEKWHENCE,
 
 /* These are interpreted as pointers.  */
 ARG_PTR,
diff --git a/linux-user/strace.c b/linux-user/strace.c
index c42abc2f08..01a5c210fa 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -70,35 +70,43 @@ UNUSED static void print_socket_protocol(int domain, int 
type, int protocol);
 /*
  * Utility functions
  */
+static int
+add_signal(char *buf, int size, int sig)
+{
+static const char * const signals[] = {
+[TARGET_SIGHUP]  = "SIGHUP",
+[TARGET_SIGINT]  = "SIGINT",
+[TARGET_SIGQUIT] = "SIGQUIT",
+[TARGET_SIGILL]  = "SIGILL",
+[TARGET_SIGABRT] = "SIGABRT",
+[TARGET_SIGFPE]  = "SIGFPE",
+[TARGET_SIGKILL] = "SIGKILL",
+[TARGET_SIGSEGV] = "SIGSEGV",
+[TARGET_SIGPIPE] = "SIGPIPE",
+[TARGET_SIGALRM] = "SIGALRM",
+[TARGET_SIGTERM] = "SIGTERM",
+[TARGET_SIGUSR1] = "SIGUSR1",
+[TARGET_SIGUSR2] = "SIGUSR2",
+[TARGET_SIGCHLD] = "SIGCHLD",
+[TARGET_SIGCONT] = "SIGCONT",
+[TARGET_SIGSTOP] = "SIGSTOP",
+[TARGET_SIGTTIN] = "SIGTTIN",
+[TARGET_SIGTTOU] = "SIGTTOU",
+};
+
+if (sig >= 0 && sig < ARRAY_SIZE(signals) && signals[sig]) {
+return snprintf(buf, size, "%s", signals[sig]);
+} else {
+return snprintf(buf, size, "%d", sig);
+}
+}
+
 static void
 print_signal(abi_ulong arg, int last)
 {
-const char *signal_name = NULL;
-switch(arg) {
-case TARGET_SIGHUP: signal_name = "SIGHUP"; break;
-case TARGET_SIGINT: signal_name = "SIGINT"; break;
-case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break;
-case TARGET_SIGILL: signal_name = "SIGILL"; break;
-case TARGET_SIGABRT: signal_name = "SIGABRT"; break;
-case TARGET_SIGFPE: signal_name = "SIGFPE"; break;
-case TARGET_SIGKILL: signal_name = "SIGKILL"; break;
-case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break;
-case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break;
-case TARGET_SIGALRM: signal_name = "SIGALRM"; break;
-case TARGET_SIGTERM: signal_name = "SIGTERM"; break;
-case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break;
-case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break;
-case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break;
-case TARGET_SIGCONT: signal_name = "SIGCONT"; break;
-case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break;
-case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break;
-case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break;
-}
-if (signal_name == NULL) {
-print_raw_param("%ld", arg, last);
-return;
-}
-gemu_log("%s%s", signal_name, get_comma(last));
+char buf[16];
+add_signal(buf, sizeof(buf), arg);
+gemu_log("%s%s", buf, get_comma(last));
 }
 
 static void print_si_code(int arg)
@@ -2044,19 +2052,6 @@ print_futex(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_kill
-static void
-print_kill(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_raw_param("%d", arg0, 0);
-print_signal(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_tkill
 static void
 print_tkill(const struct syscallname *name,
@@ -2190,6 +2185,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_ATDIRFD:
 len = add_atdirfd(b, rest, arg);
 break;
+case ARG_SIGNAL:
+len = add_signal(b, rest, arg);
+break;
 case ARG_ACCESSFLAG:
 len = add_flags(b, rest, 

[Qemu-devel] [PATCH v7 57/74] linux-user: Split out sgetmask, ssetmask

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  6 ++
 linux-user/syscall-sig.inc.c | 32 
 linux-user/syscall.c | 27 ---
 linux-user/strace.list   |  6 --
 4 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index b62bffeb68..99532f75b2 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -222,6 +222,12 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #ifdef TARGET_NR_sigaction
 SYSCALL_DEF(sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR);
 #endif
+#ifdef TARGET_NR_sgetmask
+SYSCALL_DEF(sgetmask);
+#endif
+#ifdef TARGET_NR_ssetmask
+SYSCALL_DEF(ssetmask, ARG_HEX);
+#endif
 #ifdef TARGET_NR_stime
 SYSCALL_DEF(stime, ARG_PTR);
 #endif
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index 918d58878f..f50ed16b74 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -211,3 +211,35 @@ SYSCALL_IMPL(sigaction)
 return ret;
 }
 #endif
+
+#ifdef TARGET_NR_sgetmask
+SYSCALL_IMPL(sgetmask)
+{
+sigset_t cur_set;
+abi_ulong target_set;
+abi_long ret = do_sigprocmask(0, NULL, _set);
+
+if (!ret) {
+host_to_target_old_sigset(_set, _set);
+ret = target_set;
+}
+return ret;
+}
+#endif
+
+#ifdef TARGET_NR_ssetmask
+SYSCALL_IMPL(ssetmask)
+{
+sigset_t set, oset;
+abi_ulong target_set = arg1;
+abi_long ret;
+
+target_to_host_old_sigset(, _set);
+ret = do_sigprocmask(SIG_SETMASK, , );
+if (!ret) {
+host_to_target_old_sigset(_set, );
+ret = target_set;
+}
+return ret;
+}
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3ef1bfb4ec..7bd410bcf0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,33 +4241,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_sgetmask /* not on alpha */
-case TARGET_NR_sgetmask:
-{
-sigset_t cur_set;
-abi_ulong target_set;
-ret = do_sigprocmask(0, NULL, _set);
-if (!ret) {
-host_to_target_old_sigset(_set, _set);
-ret = target_set;
-}
-}
-return ret;
-#endif
-#ifdef TARGET_NR_ssetmask /* not on alpha */
-case TARGET_NR_ssetmask:
-{
-sigset_t set, oset;
-abi_ulong target_set = arg1;
-target_to_host_old_sigset(, _set);
-ret = do_sigprocmask(SIG_SETMASK, , );
-if (!ret) {
-host_to_target_old_sigset(_set, );
-ret = target_set;
-}
-}
-return ret;
-#endif
 #ifdef TARGET_NR_sigprocmask
 case TARGET_NR_sigprocmask:
 {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 20a71adc21..3cad68e081 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1116,9 +1116,6 @@
 #ifdef TARGET_NR_setxattr
 { TARGET_NR_setxattr, "setxattr" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_sgetmask
-{ TARGET_NR_sgetmask, "sgetmask" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_shutdown
 { TARGET_NR_shutdown, "shutdown" , NULL, NULL, NULL },
 #endif
@@ -1158,9 +1155,6 @@
 #ifdef TARGET_NR_splice
 { TARGET_NR_splice, "splice" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_ssetmask
-{ TARGET_NR_ssetmask, "ssetmask" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_stat
 { TARGET_NR_stat, "stat" , NULL, print_stat, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 56/74] linux-user: Split out sigaction, rt_sigaction

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  10 ++
 linux-user/strace.c  |  14 ---
 linux-user/syscall-sig.inc.c | 172 +++
 linux-user/syscall.c | 160 
 linux-user/strace.list   |   6 --
 5 files changed, 182 insertions(+), 180 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index cd2c127c41..b62bffeb68 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -187,6 +187,13 @@ SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC);
 #ifdef TARGET_NR_rmdir
 SYSCALL_DEF(rmdir, ARG_STR);
 #endif
+#if defined(TARGET_ALPHA)
+SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_DEC, ARG_PTR);
+#elif defined(TARGET_SPARC)
+SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_PTR, ARG_DEC);
+#else
+SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_DEC);
+#endif
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
@@ -212,6 +219,9 @@ SYSCALL_DEF(shmdt, ARG_PTR);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget)
 SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
+#ifdef TARGET_NR_sigaction
+SYSCALL_DEF(sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR);
+#endif
 #ifdef TARGET_NR_stime
 SYSCALL_DEF(stime, ARG_PTR);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 787bf41307..83dd755c73 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1564,20 +1564,6 @@ print_fstat(const struct syscallname *name,
 #define print_fstat64 print_fstat
 #endif
 
-#ifdef TARGET_NR_rt_sigaction
-static void
-print_rt_sigaction(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_signal(arg0, 0);
-print_pointer(arg1, 0);
-print_pointer(arg2, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_rt_sigprocmask
 static void
 print_rt_sigprocmask(const struct syscallname *name,
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index a4fbcc567d..918d58878f 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -39,3 +39,175 @@ SYSCALL_IMPL(pause)
 return -TARGET_EINTR;
 }
 #endif
+
+SYSCALL_IMPL(rt_sigaction)
+{
+abi_long ret;
+#if defined(TARGET_ALPHA)
+/*
+ * For Alpha and SPARC this is a 5 argument syscall, with
+ * a 'restorer' parameter which must be copied into the
+ * sa_restorer field of the sigaction struct.
+ * For Alpha that 'restorer' is arg5; for SPARC it is arg4,
+ * and arg5 is the sigsetsize.
+ * Alpha also has a separate rt_sigaction struct that it uses
+ * here; SPARC uses the usual sigaction struct.
+ */
+struct target_rt_sigaction *rt_act;
+struct target_sigaction act, oact, *pact = NULL;
+
+if (arg4 != sizeof(target_sigset_t)) {
+return -TARGET_EINVAL;
+}
+if (arg2) {
+if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1)) {
+return -TARGET_EFAULT;
+}
+act._sa_handler = rt_act->_sa_handler;
+act.sa_mask = rt_act->sa_mask;
+act.sa_flags = rt_act->sa_flags;
+act.sa_restorer = arg5;
+unlock_user_struct(rt_act, arg2, 0);
+pact = 
+}
+ret = get_errno(do_sigaction(arg1, pact, ));
+if (!is_error(ret) && arg3) {
+if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0)) {
+return -TARGET_EFAULT;
+}
+rt_act->_sa_handler = oact._sa_handler;
+rt_act->sa_mask = oact.sa_mask;
+rt_act->sa_flags = oact.sa_flags;
+unlock_user_struct(rt_act, arg3, 1);
+}
+#else
+# ifdef TARGET_SPARC
+target_ulong restorer = arg4;
+target_ulong sigsetsize = arg5;
+# else
+target_ulong sigsetsize = arg4;
+# endif
+struct target_sigaction act, oact, *pact = NULL;
+
+if (sigsetsize != sizeof(target_sigset_t)) {
+return -TARGET_EINVAL;
+}
+if (arg2) {
+if (!lock_user_struct(VERIFY_READ, pact, arg2, 1)) {
+return -TARGET_EFAULT;
+}
+act = *pact;
+unlock_user_struct(pact, arg2, 0);
+# ifdef TARGET_ARCH_HAS_KA_RESTORER
+act.ka_restorer = restorer;
+# endif
+pact = 
+}
+
+ret = get_errno(do_sigaction(arg1, pact, ));
+
+if (!is_error(ret) && arg3) {
+if (!lock_user_struct(VERIFY_WRITE, pact, arg3, 0)) {
+return -TARGET_EFAULT;
+}
+*pact = oact;
+unlock_user_struct(pact, arg3, 1);
+}
+#endif
+return ret;
+}
+
+#ifdef TARGET_NR_sigaction
+SYSCALL_IMPL(sigaction)
+{
+abi_long ret;
+#if defined(TARGET_ALPHA)
+struct target_sigaction act, oact, *pact = NULL;
+struct target_old_sigaction *old_act;
+
+if (arg2) {
+if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) {
+return 

[Qemu-devel] [PATCH v7 59/74] linux-user: Split out sigpending, rt_sigpending

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  4 
 linux-user/syscall-sig.inc.c | 45 
 linux-user/syscall.c | 36 -
 linux-user/strace.list   |  6 -
 4 files changed, 49 insertions(+), 42 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index ef77f60524..83a69246d0 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -194,6 +194,7 @@ SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, 
ARG_PTR, ARG_DEC);
 #else
 SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_DEC);
 #endif
+SYSCALL_DEF(rt_sigpending, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(rt_sigprocmask, ARG_SIGPROCMASKHOW, ARG_PTR, ARG_PTR, ARG_DEC);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
@@ -223,6 +224,9 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #ifdef TARGET_NR_sigaction
 SYSCALL_DEF(sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR);
 #endif
+#ifdef TARGET_NR_sigpending
+SYSCALL_DEF(sigpending, ARG_PTR);
+#endif
 #if defined(TARGET_ALPHA)
 SYSCALL_DEF(sigprocmask, ARG_SIGPROCMASKHOW, ARG_HEX);
 #elif defined(TARGET_NR_sigprocmask)
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index 8a6518bdaa..fe717a5121 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -117,6 +117,33 @@ SYSCALL_IMPL(rt_sigaction)
 return ret;
 }
 
+SYSCALL_IMPL(rt_sigpending)
+{
+sigset_t set;
+abi_long ret;
+
+/*
+ * Yes, this check is >, not != like most. We follow the kernel's
+ * logic and it does it like this because it implements
+ * NR_sigpending through the same code path, and in that case
+ * the old_sigset_t is smaller in size.
+ */
+if (arg2 > sizeof(target_sigset_t)) {
+return -TARGET_EINVAL;
+}
+
+ret = get_errno(sigpending());
+if (!is_error(ret)) {
+void *p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0);
+if (!p) {
+return -TARGET_EFAULT;
+}
+host_to_target_sigset(p, );
+unlock_user(p, arg1, sizeof(target_sigset_t));
+}
+return ret;
+}
+
 SYSCALL_IMPL(rt_sigprocmask)
 {
 int how = 0;
@@ -259,6 +286,24 @@ SYSCALL_IMPL(sigaction)
 }
 #endif
 
+#ifdef TARGET_NR_sigpending
+SYSCALL_IMPL(sigpending)
+{
+sigset_t set;
+abi_long ret = get_errno(sigpending());
+
+if (!is_error(ret)) {
+void *p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0);
+if (!p) {
+return -TARGET_EFAULT;
+}
+host_to_target_old_sigset(p, );
+unlock_user(p, arg1, sizeof(target_sigset_t));
+}
+return ret;
+}
+#endif
+
 #ifdef TARGET_NR_sigprocmask
 SYSCALL_IMPL(sigprocmask)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 11bbdfade4..7dda237c95 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,42 +4241,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_sigpending
-case TARGET_NR_sigpending:
-{
-sigset_t set;
-ret = get_errno(sigpending());
-if (!is_error(ret)) {
-if (!(p = lock_user(VERIFY_WRITE, arg1, 
sizeof(target_sigset_t), 0)))
-return -TARGET_EFAULT;
-host_to_target_old_sigset(p, );
-unlock_user(p, arg1, sizeof(target_sigset_t));
-}
-}
-return ret;
-#endif
-case TARGET_NR_rt_sigpending:
-{
-sigset_t set;
-
-/* Yes, this check is >, not != like most. We follow the kernel's
- * logic and it does it like this because it implements
- * NR_sigpending through the same code path, and in that case
- * the old_sigset_t is smaller in size.
- */
-if (arg2 > sizeof(target_sigset_t)) {
-return -TARGET_EINVAL;
-}
-
-ret = get_errno(sigpending());
-if (!is_error(ret)) {
-if (!(p = lock_user(VERIFY_WRITE, arg1, 
sizeof(target_sigset_t), 0)))
-return -TARGET_EFAULT;
-host_to_target_sigset(p, );
-unlock_user(p, arg1, sizeof(target_sigset_t));
-}
-}
-return ret;
 #ifdef TARGET_NR_sigsuspend
 case TARGET_NR_sigsuspend:
 {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 7157876302..978e47bf0e 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -926,9 +926,6 @@
 #ifdef TARGET_NR_rmdir
 { TARGET_NR_rmdir, "rmdir" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_rt_sigpending
-{ TARGET_NR_rt_sigpending, "rt_sigpending" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_rt_sigqueueinfo
 { TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, print_rt_sigqueueinfo, 
NULL },
 #endif

[Qemu-devel] [PATCH v7 53/74] linux-user: Split out chroot

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/strace.c   | 12 
 linux-user/syscall-file.inc.c | 13 +
 linux-user/syscall.c  |  6 --
 linux-user/strace.list|  3 ---
 5 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index b6538350a3..b93ca1f78a 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -30,6 +30,7 @@ SYSCALL_DEF(chdir, ARG_STR);
 #ifdef TARGET_NR_chmod
 SYSCALL_DEF(chmod, ARG_STR, ARG_MODEFLAG);
 #endif
+SYSCALL_DEF(chroot, ARG_STR);
 SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(close, ARG_DEC);
 #ifdef TARGET_NR_creat
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 560284b3c3..787bf41307 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1130,18 +1130,6 @@ print_accept(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_chroot
-static void
-print_chroot(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_clock_adjtime
 static void
 print_clock_adjtime(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index cbde6d906f..6e730e3152 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -88,6 +88,19 @@ SYSCALL_IMPL(chmod)
 }
 #endif
 
+SYSCALL_IMPL(chroot)
+{
+char *p = lock_user_string(arg1);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(chroot(p));
+unlock_user(p, arg1, 0);
+return ret;
+}
+
 SYSCALL_IMPL(close)
 {
 int fd = arg1;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 419edceab2..255765aaa7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,12 +4241,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_chroot:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(chroot(p));
-unlock_user(p, arg1, 0);
-return ret;
 #ifdef TARGET_NR_getpgrp
 case TARGET_NR_getpgrp:
 return get_errno(getpgrp());
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 61d22ad16b..7679e844b6 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -58,9 +58,6 @@
 #ifdef TARGET_NR_chown32
 { TARGET_NR_chown32, "chown32" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_chroot
-{ TARGET_NR_chroot, "chroot" , NULL, print_chroot, NULL },
-#endif
 #ifdef TARGET_NR_clock_adjtime
 { TARGET_NR_clock_adjtime, "clock_adjtime" , NULL, print_clock_adjtime, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 54/74] linux-user: Split out getpgid, getpgrp

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/syscall-proc.inc.c | 12 
 linux-user/syscall.c  |  6 --
 linux-user/strace.list|  6 --
 4 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index b93ca1f78a..2ade9ec749 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -59,6 +59,10 @@ SYSCALL_DEF(futimesat, ARG_ATDIRFD, ARG_STR, ARG_PTR);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
+SYSCALL_DEF(getpgid, ARG_DEC);
+#ifdef TARGET_NR_getpgrp
+SYSCALL_DEF(getpgrp);
+#endif
 #ifdef TARGET_NR_getpid
 SYSCALL_DEF(getpid);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 5bd27d1d4b..39de5b7863 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -438,6 +438,18 @@ SYSCALL_IMPL(fork)
 }
 #endif
 
+SYSCALL_IMPL(getpgid)
+{
+return get_errno(getpgid(arg1));
+}
+
+#ifdef TARGET_NR_getpgrp
+SYSCALL_IMPL(getpgrp)
+{
+return get_errno(getpgrp());
+}
+#endif
+
 #ifdef TARGET_NR_getpid
 SYSCALL_IMPL(getpid)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 255765aaa7..75989a01bf 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,10 +4241,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_getpgrp
-case TARGET_NR_getpgrp:
-return get_errno(getpgrp());
-#endif
 case TARGET_NR_setsid:
 return get_errno(setsid());
 #ifdef TARGET_NR_sigaction
@@ -5388,8 +5384,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 return ret;
 #endif
-case TARGET_NR_getpgid:
-return get_errno(getpgid(arg1));
 case TARGET_NR_fchdir:
 return get_errno(fchdir(arg1));
 case TARGET_NR_personality:
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 7679e844b6..d283c924a7 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -262,12 +262,6 @@
 #ifdef TARGET_NR_getpeername
 { TARGET_NR_getpeername, "getpeername" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getpgid
-{ TARGET_NR_getpgid, "getpgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getpgrp
-{ TARGET_NR_getpgrp, "getpgrp" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getpmsg
 { TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 42/74] linux-user: Split out dup, dup2, dup3

2019-05-19 Thread Richard Henderson
Note that dup3 is universally available for guests.
Implement host support with syscall when !CONFIG_DUP3.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  5 +
 linux-user/syscall-file.inc.c | 42 +++
 linux-user/syscall.c  | 33 +++
 linux-user/strace.list|  6 -
 4 files changed, 50 insertions(+), 36 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 8b6d8f75ff..062a75 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -34,6 +34,11 @@ SYSCALL_DEF(close, ARG_DEC);
 #ifdef TARGET_NR_creat
 SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG);
 #endif
+SYSCALL_DEF(dup, ARG_DEC);
+#ifdef TARGET_NR_dup2
+SYSCALL_DEF(dup2, ARG_DEC, ARG_DEC);
+#endif
+SYSCALL_DEF(dup3, ARG_DEC, ARG_DEC, ARG_OPENFLAG);
 SYSCALL_DEF(exit, ARG_DEC);
 SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 5ed8b78c79..7d97dd1ec1 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -94,6 +94,48 @@ SYSCALL_IMPL(creat)
 }
 #endif
 
+SYSCALL_IMPL(dup)
+{
+abi_long ret = get_errno(dup(arg1));
+if (ret >= 0) {
+fd_trans_dup(arg1, ret);
+}
+return ret;
+}
+
+#ifdef TARGET_NR_dup2
+SYSCALL_IMPL(dup2)
+{
+abi_long ret = get_errno(dup2(arg1, arg2));
+if (ret >= 0) {
+fd_trans_dup(arg1, arg2);
+}
+return ret;
+}
+#endif
+
+SYSCALL_IMPL(dup3)
+{
+int ofd = arg1;
+int nfd = arg2;
+int host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl);
+abi_long ret;
+
+#ifdef CONFIG_DUP3
+ret = dup3(ofd, nfd, host_flags);
+#else
+if (host_flags == 0) {
+if (ofd == nfd) {
+return -TARGET_EINVAL;
+}
+ret = dup2(ofd, nfd);
+} else {
+ret = syscall(__NR_dup3, ofd, nfd, host_flags);
+}
+#endif
+return get_errno(ret);
+}
+
 SYSCALL_IMPL(faccessat)
 {
 return do_faccessat(arg1, arg2, arg3);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0d6a9b7a6c..bab9a57ee0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -204,6 +204,9 @@ _syscall0(int, sys_gettid)
  * Performing a bogus syscall is easier than boilerplating
  * the replacement functions here in C.
  */
+#ifndef __NR_dup3
+#define __NR_dup3  -1
+#endif
 #ifndef __NR_syncfs
 #define __NR_syncfs  -1
 #endif
@@ -5373,12 +5376,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_dup:
-ret = get_errno(dup(arg1));
-if (ret >= 0) {
-fd_trans_dup(arg1, ret);
-}
-return ret;
 #ifdef TARGET_NR_pipe
 case TARGET_NR_pipe:
 return do_pipe(cpu_env, arg1, 0, 0);
@@ -5433,30 +5430,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 ret = get_errno(chroot(p));
 unlock_user(p, arg1, 0);
 return ret;
-#ifdef TARGET_NR_dup2
-case TARGET_NR_dup2:
-ret = get_errno(dup2(arg1, arg2));
-if (ret >= 0) {
-fd_trans_dup(arg1, arg2);
-}
-return ret;
-#endif
-#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
-case TARGET_NR_dup3:
-{
-int host_flags;
-
-if ((arg3 & ~TARGET_O_CLOEXEC) != 0) {
-return -EINVAL;
-}
-host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl);
-ret = get_errno(dup3(arg1, arg2, host_flags));
-if (ret >= 0) {
-fd_trans_dup(arg1, arg2);
-}
-return ret;
-}
-#endif
 #ifdef TARGET_NR_getpgrp
 case TARGET_NR_getpgrp:
 return get_errno(getpgrp());
diff --git a/linux-user/strace.list b/linux-user/strace.list
index cdbc59bffd..2f78f4685b 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -91,12 +91,6 @@
 #ifdef TARGET_NR_dipc
 { TARGET_NR_dipc, "dipc" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_dup
-{ TARGET_NR_dup, "dup" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_dup2
-{ TARGET_NR_dup2, "dup2" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_epoll_create
 { TARGET_NR_epoll_create, "epoll_create" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 47/74] linux-user: Split out ioctl

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
v7: Do not accidentally change type of "cmd".
---
 linux-user/syscall-defs.h  |   1 +
 linux-user/syscall-ioctl.inc.c | 873 +
 linux-user/syscall.c   | 852 +---
 linux-user/strace.list |   3 -
 4 files changed, 875 insertions(+), 854 deletions(-)
 create mode 100644 linux-user/syscall-ioctl.inc.c

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index f8f280f376..f58b9745a4 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -61,6 +61,7 @@ SYSCALL_DEF(getppid);
 #ifdef TARGET_NR_getxpid
 SYSCALL_DEF(getxpid);
 #endif
+SYSCALL_DEF(ioctl, ARG_DEC, ARG_HEX);
 #ifdef TARGET_NR_ipc
 SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX);
 #endif
diff --git a/linux-user/syscall-ioctl.inc.c b/linux-user/syscall-ioctl.inc.c
new file mode 100644
index 00..be3f0b4b92
--- /dev/null
+++ b/linux-user/syscall-ioctl.inc.c
@@ -0,0 +1,873 @@
+/*
+ *  Linux ioctl syscall implementation
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+typedef struct IOCTLEntry IOCTLEntry;
+
+typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg);
+
+struct IOCTLEntry {
+int target_cmd;
+unsigned int host_cmd;
+const char *name;
+int access;
+do_ioctl_fn *do_ioctl;
+const argtype arg_type[5];
+};
+
+#define IOC_R 0x0001
+#define IOC_W 0x0002
+#define IOC_RW (IOC_R | IOC_W)
+
+#define MAX_STRUCT_SIZE 4096
+
+#ifdef CONFIG_FIEMAP
+/*
+ * So fiemap access checks don't overflow on 32 bit systems.
+ * This is very slightly smaller than the limit imposed by
+ * the underlying kernel.
+ */
+#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
+/ sizeof(struct fiemap_extent))
+
+static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
+   int fd, int cmd, abi_long arg)
+{
+/*
+ * The parameter for this ioctl is a struct fiemap followed
+ * by an array of struct fiemap_extent whose size is set
+ * in fiemap->fm_extent_count. The array is filled in by the
+ * ioctl.
+ */
+int target_size_in, target_size_out;
+struct fiemap *fm;
+const argtype *arg_type = ie->arg_type;
+const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
+void *argptr, *p;
+abi_long ret;
+int i, extent_size = thunk_type_size(extent_arg_type, 0);
+uint32_t outbufsz;
+int free_fm = 0;
+
+assert(arg_type[0] == TYPE_PTR);
+assert(ie->access == IOC_RW);
+arg_type++;
+target_size_in = thunk_type_size(arg_type, 0);
+argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
+if (!argptr) {
+return -TARGET_EFAULT;
+}
+thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+unlock_user(argptr, arg, 0);
+fm = (struct fiemap *)buf_temp;
+if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
+return -TARGET_EINVAL;
+}
+
+outbufsz = sizeof(*fm) + sizeof(struct fiemap_extent) * 
fm->fm_extent_count;
+
+if (outbufsz > MAX_STRUCT_SIZE) {
+/*
+ * We can't fit all the extents into the fixed size buffer.
+ * Allocate one that is large enough and use it instead.
+ */
+fm = g_try_malloc(outbufsz);
+if (!fm) {
+return -TARGET_ENOMEM;
+}
+memcpy(fm, buf_temp, sizeof(struct fiemap));
+free_fm = 1;
+}
+ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm));
+if (!is_error(ret)) {
+target_size_out = target_size_in;
+/*
+ * An extent_count of 0 means we were only counting the extents
+ * so there are no structs to copy
+ */
+if (fm->fm_extent_count != 0) {
+target_size_out += fm->fm_mapped_extents * extent_size;
+}
+argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
+if (!argptr) {
+ret = -TARGET_EFAULT;
+} else {
+/* Convert the struct fiemap */
+thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
+if (fm->fm_extent_count != 0) {
+p = argptr + target_size_in;
+/* ...and 

[Qemu-devel] [PATCH v7 55/74] linux-user: Split out getsid, setsid

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  2 ++
 linux-user/syscall-proc.inc.c | 10 ++
 linux-user/syscall.c  |  4 
 linux-user/strace.list|  6 --
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 2ade9ec749..cd2c127c41 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -69,6 +69,7 @@ SYSCALL_DEF(getpid);
 #ifdef TARGET_NR_getppid
 SYSCALL_DEF(getppid);
 #endif
+SYSCALL_DEF(getsid, ARG_DEC);
 #ifdef TARGET_NR_getxpid
 SYSCALL_DEF(getxpid);
 #endif
@@ -193,6 +194,7 @@ SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
 SYSCALL_DEF(setpgid, ARG_DEC, ARG_DEC);
+SYSCALL_DEF(setsid);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop)
 SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 39de5b7863..567df54581 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -464,6 +464,11 @@ SYSCALL_IMPL(getppid)
 }
 #endif
 
+SYSCALL_IMPL(getsid)
+{
+return get_errno(getsid(arg1));
+}
+
 #ifdef TARGET_NR_getxpid
 SYSCALL_IMPL(getxpid)
 {
@@ -485,6 +490,11 @@ SYSCALL_IMPL(setpgid)
 return get_errno(setpgid(arg1, arg2));
 }
 
+SYSCALL_IMPL(setsid)
+{
+return get_errno(setsid());
+}
+
 SYSCALL_IMPL(times)
 {
 abi_ulong target_buf = arg1;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 75989a01bf..0e9f4fd5ae 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,8 +4241,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_setsid:
-return get_errno(setsid());
 #ifdef TARGET_NR_sigaction
 case TARGET_NR_sigaction:
 {
@@ -5664,8 +5662,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 /* NOTE: the flock constant seems to be the same for every
Linux platform */
 return get_errno(safe_flock(arg1, arg2));
-case TARGET_NR_getsid:
-return get_errno(getsid(arg1));
 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
 case TARGET_NR_fdatasync:
 return get_errno(fdatasync(arg1));
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d283c924a7..bf87a6d4cb 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -292,9 +292,6 @@
 #ifdef TARGET_NR_getrusage
 { TARGET_NR_getrusage, "getrusage" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getsid
-{ TARGET_NR_getsid, "getsid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getsockname
 { TARGET_NR_getsockname, "getsockname" , NULL, NULL, NULL },
 #endif
@@ -1100,9 +1097,6 @@
 #ifdef TARGET_NR_set_robust_list
 { TARGET_NR_set_robust_list, "set_robust_list" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setsid
-{ TARGET_NR_setsid, "setsid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setsockopt
 { TARGET_NR_setsockopt, "setsockopt" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 33/74] linux-user: Split out stime

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  3 +++
 linux-user/syscall-time.inc.c | 12 
 linux-user/syscall.c  |  9 -
 linux-user/strace.list|  3 ---
 4 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 0d8da0c6d6..6ca82af397 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -152,6 +152,9 @@ SYSCALL_DEF(shmdt, ARG_PTR);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget)
 SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
+#ifdef TARGET_NR_stime
+SYSCALL_DEF(stime, ARG_PTR);
+#endif
 #ifdef TARGET_NR_time
 SYSCALL_DEF(time, ARG_PTR);
 #endif
diff --git a/linux-user/syscall-time.inc.c b/linux-user/syscall-time.inc.c
index 14fec88e47..d1fb72bde0 100644
--- a/linux-user/syscall-time.inc.c
+++ b/linux-user/syscall-time.inc.c
@@ -16,6 +16,18 @@
  *  along with this program; if not, see .
  */
 
+#ifdef TARGET_NR_stime
+SYSCALL_IMPL(stime)
+{
+time_t host_time;
+
+if (get_user_sal(host_time, arg1)) {
+return -TARGET_EFAULT;
+}
+return get_errno(stime(_time));
+}
+#endif
+
 #ifdef TARGET_NR_time
 SYSCALL_IMPL(time)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f3e03f535d..ae56ecbbc7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5380,15 +5380,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_stime /* not on alpha */
-case TARGET_NR_stime:
-{
-time_t host_time;
-if (get_user_sal(host_time, arg1))
-return -TARGET_EFAULT;
-return get_errno(stime(_time));
-}
-#endif
 #ifdef TARGET_NR_alarm /* not on alpha */
 case TARGET_NR_alarm:
 return alarm(arg1);
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 973a4c9209..d0646b9424 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1254,9 +1254,6 @@
 #ifdef TARGET_NR_statfs64
 { TARGET_NR_statfs64, "statfs64" , NULL, print_statfs64, NULL },
 #endif
-#ifdef TARGET_NR_stime
-{ TARGET_NR_stime, "stime" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_streams1
 { TARGET_NR_streams1, "streams1" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 49/74] linux-user: Remove sentinel from ioctl_entries

2019-05-19 Thread Richard Henderson
Iterate based on the size of the array instead.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-ioctl.inc.c | 14 +++---
 linux-user/syscall.c   |  6 ++
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/linux-user/syscall-ioctl.inc.c b/linux-user/syscall-ioctl.inc.c
index 15d87b9663..fc7df62017 100644
--- a/linux-user/syscall-ioctl.inc.c
+++ b/linux-user/syscall-ioctl.inc.c
@@ -773,7 +773,6 @@ static IOCTLEntry ioctl_entries[] = {
 #define IOCTL_IGNORE(cmd)   \
 { TARGET_ ## cmd, 0, #cmd },
 #include "ioctls.h"
-{ 0, 0, },
 };
 
 /* ??? Implement proper locking for ioctls.  */
@@ -789,16 +788,17 @@ SYSCALL_IMPL(ioctl)
 int target_size;
 void *argptr;
 
-for (ie = ioctl_entries; ; ie++) {
-if (ie->target_cmd == 0) {
-gemu_log("Unsupported ioctl: cmd=0x%04x\n", cmd);
-return -TARGET_ENOSYS;
-}
+for (ie = ioctl_entries;
+ ie < ioctl_entries + ARRAY_SIZE(ioctl_entries);
+ ie++) {
 if (ie->target_cmd == cmd) {
-break;
+goto found;
 }
 }
+gemu_log("Unsupported ioctl: cmd=0x%04x\n", cmd);
+return -TARGET_ENOSYS;
 
+ found:
 arg_type = ie->arg_type;
 if (ie->do_ioctl) {
 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8f90affe2f..5871d3e711 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8173,7 +8173,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
 void syscall_init(void)
 {
-IOCTLEntry *ie;
 const argtype *arg_type;
 int size;
 int i;
@@ -8203,8 +8202,8 @@ void syscall_init(void)
  * We patch the ioctl size if necessary.  We rely on the fact that
  * no ioctl has all the bits at '1' in the size field.
  */
-ie = ioctl_entries;
-while (ie->target_cmd != 0) {
+for (i = 0; i < ARRAY_SIZE(ioctl_entries); i++) {
+IOCTLEntry *ie = _entries[i];
 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
 TARGET_IOC_SIZEMASK) {
 arg_type = ie->arg_type;
@@ -8228,6 +8227,5 @@ void syscall_init(void)
 ie->name, ie->target_cmd, ie->host_cmd);
 }
 #endif
-ie++;
 }
 }
-- 
2.17.1




[Qemu-devel] [PATCH v7 52/74] linux-user: Split out umask

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h | 1 +
 linux-user/syscall-file.inc.c | 5 +
 linux-user/syscall.c  | 2 --
 linux-user/strace.list| 3 ---
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 6de7b84351..b6538350a3 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -214,6 +214,7 @@ SYSCALL_DEF(syncfs, ARG_DEC);
 SYSCALL_DEF(time, ARG_PTR);
 #endif
 SYSCALL_DEF(times, ARG_PTR);
+SYSCALL_DEF(umask, ARG_OCT);
 #ifdef TARGET_NR_umount
 SYSCALL_DEF(umount, ARG_STR);
 #endif
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 4080ab250e..cbde6d906f 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -1117,6 +1117,11 @@ SYSCALL_IMPL(rmdir)
 }
 #endif
 
+SYSCALL_IMPL(umask)
+{
+return get_errno(umask(arg1));
+}
+
 SYSCALL_IMPL(unlinkat)
 {
 return do_unlinkat(arg1, arg2, arg3);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dcb35e1228..419edceab2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,8 +4241,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_umask:
-return get_errno(umask(arg1));
 case TARGET_NR_chroot:
 if (!(p = lock_user_string(arg1)))
 return -TARGET_EFAULT;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 4a527b0c65..61d22ad16b 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1293,9 +1293,6 @@
 #ifdef TARGET_NR_ulimit
 { TARGET_NR_ulimit, "ulimit" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_umask
-{ TARGET_NR_umask, "umask" , "%s(%#o)", NULL, NULL },
-#endif
 #ifdef TARGET_NR_uname
 { TARGET_NR_uname, "uname" , "%s(%p)", NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 45/74] linux-user: Split out acct

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/syscall-file.inc.c | 18 ++
 linux-user/syscall.c  | 11 ---
 linux-user/strace.list|  3 ---
 4 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 25d5aaccd1..f8f280f376 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -19,6 +19,7 @@
 #ifdef TARGET_NR_access
 SYSCALL_DEF(access, ARG_STR, ARG_ACCESSFLAG);
 #endif
+SYSCALL_DEF(acct, ARG_STR);
 #ifdef TARGET_NR_alarm
 SYSCALL_DEF(alarm, ARG_DEC);
 #endif
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 5bd9eaa002..4080ab250e 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -36,6 +36,24 @@ SYSCALL_IMPL(access)
 }
 #endif
 
+SYSCALL_IMPL(acct)
+{
+abi_ulong target_path = arg1;
+abi_long ret;
+
+if (target_path == 0) {
+ret = get_errno(acct(NULL));
+} else {
+char *p = lock_user_string(target_path);
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(acct(path(p)));
+unlock_user(p, target_path, 0);
+}
+return ret;
+}
+
 SYSCALL_IMPL(chdir)
 {
 abi_ulong target_path = arg1;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cdca0dbe4f..5343486a58 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5346,17 +5346,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_acct:
-if (arg1 == 0) {
-ret = get_errno(acct(NULL));
-} else {
-if (!(p = lock_user_string(arg1))) {
-return -TARGET_EFAULT;
-}
-ret = get_errno(acct(path(p)));
-unlock_user(p, arg1, 0);
-}
-return ret;
 case TARGET_NR_ioctl:
 return do_ioctl(arg1, arg2, arg3);
 #ifdef TARGET_NR_fcntl
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 85e3de87d8..ce5e02975b 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -9,9 +9,6 @@
 #ifdef TARGET_NR_accept4
 { TARGET_NR_accept4, "accept4" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_acct
-{ TARGET_NR_acct, "acct" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_add_key
 { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 50/74] linux-user: Split out fcntl, fcntl64

2019-05-19 Thread Richard Henderson
Preserving strace functionality is tricky with this one.
Rearrange to lookup structures that contain the data for
both execution and strace for each command.

Do not allow lookup of 64-bit fcntl commands from 32-bit fcntl.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h  |   6 +
 linux-user/strace.c| 100 --
 linux-user/syscall-fcntl.inc.c | 322 +
 linux-user/syscall.c   | 256 +-
 linux-user/strace.list |   6 -
 5 files changed, 329 insertions(+), 361 deletions(-)
 create mode 100644 linux-user/syscall-fcntl.inc.c

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index f58b9745a4..5cf39f2bb9 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -46,6 +46,12 @@ SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, 
ARG_PTR, ARG_ATFLAG);
 SYSCALL_DEF(faccessat, ARG_ATDIRFD, ARG_STR, ARG_ACCESSFLAG);
 SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG);
 SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG);
+#ifdef TARGET_NR_fcntl
+SYSCALL_DEF_FULL(fcntl, .impl = impl_fcntl, .print = print_fcntl);
+#endif
+#if TARGET_ABI_BITS == 32
+SYSCALL_DEF_FULL(fcntl64, .impl = impl_fcntl64, .print = print_fcntl64);
+#endif
 #ifdef TARGET_NR_futimesat
 SYSCALL_DEF(futimesat, ARG_ATDIRFD, ARG_STR, ARG_PTR);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 2b31998dbd..560284b3c3 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1184,106 +1184,6 @@ print_fchownat(const struct syscallname *name,
 }
 #endif
 
-#if defined(TARGET_NR_fcntl) || defined(TARGET_NR_fcntl64)
-static void
-print_fcntl(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_raw_param("%d", arg0, 0);
-switch(arg1) {
-case TARGET_F_DUPFD:
-gemu_log("F_DUPFD,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
-break;
-case TARGET_F_GETFD:
-gemu_log("F_GETFD");
-break;
-case TARGET_F_SETFD:
-gemu_log("F_SETFD,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
-break;
-case TARGET_F_GETFL:
-gemu_log("F_GETFL");
-break;
-case TARGET_F_SETFL:
-gemu_log("F_SETFL,");
-print_open_flags(arg2, 1);
-break;
-case TARGET_F_GETLK:
-gemu_log("F_GETLK,");
-print_pointer(arg2, 1);
-break;
-case TARGET_F_SETLK:
-gemu_log("F_SETLK,");
-print_pointer(arg2, 1);
-break;
-case TARGET_F_SETLKW:
-gemu_log("F_SETLKW,");
-print_pointer(arg2, 1);
-break;
-case TARGET_F_GETOWN:
-gemu_log("F_GETOWN");
-break;
-case TARGET_F_SETOWN:
-gemu_log("F_SETOWN,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
-break;
-case TARGET_F_GETSIG:
-gemu_log("F_GETSIG");
-break;
-case TARGET_F_SETSIG:
-gemu_log("F_SETSIG,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
-break;
-#if TARGET_ABI_BITS == 32
-case TARGET_F_GETLK64:
-gemu_log("F_GETLK64,");
-print_pointer(arg2, 1);
-break;
-case TARGET_F_SETLK64:
-gemu_log("F_SETLK64,");
-print_pointer(arg2, 1);
-break;
-case TARGET_F_SETLKW64:
-gemu_log("F_SETLKW64,");
-print_pointer(arg2, 1);
-break;
-#endif
-case TARGET_F_SETLEASE:
-gemu_log("F_SETLEASE,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
-break;
-case TARGET_F_GETLEASE:
-gemu_log("F_GETLEASE");
-break;
-case TARGET_F_SETPIPE_SZ:
-gemu_log("F_SETPIPE_SZ,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
-break;
-case TARGET_F_GETPIPE_SZ:
-gemu_log("F_GETPIPE_SZ");
-break;
-case TARGET_F_DUPFD_CLOEXEC:
-gemu_log("F_DUPFD_CLOEXEC,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
-break;
-case TARGET_F_NOTIFY:
-gemu_log("F_NOTIFY,");
-print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
-break;
-default:
-print_raw_param(TARGET_ABI_FMT_ld, arg1, 0);
-print_pointer(arg2, 1);
-break;
-}
-print_syscall_epilogue(name);
-}
-#define print_fcntl64   print_fcntl
-#endif
-
-
 #if defined(TARGET_NR_socket)
 static void
 print_socket(const struct syscallname *name,
diff --git a/linux-user/syscall-fcntl.inc.c b/linux-user/syscall-fcntl.inc.c
new file mode 100644
index 00..768682bd17
--- /dev/null
+++ b/linux-user/syscall-fcntl.inc.c
@@ -0,0 +1,322 @@
+/*
+ *  Linux fcntl syscall implementation
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the 

[Qemu-devel] [PATCH v7 29/74] linux-user: Split out lseek, llseek

2019-05-19 Thread Richard Henderson
Canonicalise the target syscall name on llseek (new kernels)
instead of _llseek (old kernels).  Always use host lseek(3)
rather than attempting to use the host llseek(2).

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  6 ++
 linux-user/syscall.h  |  1 +
 linux-user/strace.c   | 39 +++
 linux-user/syscall-file.inc.c | 36 
 linux-user/syscall.c  | 32 ++--
 linux-user/strace.list|  6 --
 6 files changed, 62 insertions(+), 58 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 3ddf8aa0e3..3453e7afdf 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -43,6 +43,12 @@ SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, 
ARG_PTR, ARG_HEX);
 SYSCALL_DEF(link, ARG_STR, ARG_STR);
 #endif
 SYSCALL_DEF(linkat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR, ARG_ATFLAG);
+#ifdef TARGET_NR_lseek
+SYSCALL_DEF(lseek, ARG_DEC, ARG_DEC, ARG_LSEEKWHENCE);
+#endif
+#ifdef TARGET_NR_llseek
+SYSCALL_DEF_ARGS(llseek, ARG_DEC, ARG_DEC, ARG_PTR, ARG_LSEEKWHENCE);
+#endif
 #ifdef TARGET_NR_mknod
 SYSCALL_DEF(mknod, ARG_STR, ARG_MODEFLAG, ARG_HEX);
 #endif
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index bdc4d653c4..c16c0a3f1e 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -64,6 +64,7 @@ typedef enum {
 ARG_MODEFLAG,
 ARG_OPENFLAG,
 ARG_UNLINKATFLAG,
+ARG_LSEEKWHENCE,
 
 /* These are interpreted as pointers.  */
 ARG_PTR,
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 4771badeb5..a4d7b397b4 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -934,6 +934,20 @@ print_open_flags(abi_long flags, int last)
 gemu_log("%s%s", buf, get_comma(last));
 }
 
+static int add_lseek_whence(char *buf, int size, int whence)
+{
+switch (whence) {
+case SEEK_SET:
+return snprintf(buf, size, "SEEK_SET");
+case SEEK_CUR:
+return snprintf(buf, size, "SEEK_CUR");
+case SEEK_END:
+return snprintf(buf, size, "SEEK_END");
+default:
+return snprintf(buf, size, "%#x", whence);
+}
+}
+
 static void
 print_syscall_prologue(const struct syscallname *sc)
 {
@@ -1297,28 +1311,6 @@ print_futimesat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR__llseek
-static void
-print__llseek(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-const char *whence = "UNKNOWN";
-print_syscall_prologue(name);
-print_raw_param("%d", arg0, 0);
-print_raw_param("%ld", arg1, 0);
-print_raw_param("%ld", arg2, 0);
-print_pointer(arg3, 0);
-switch(arg4) {
-case SEEK_SET: whence = "SEEK_SET"; break;
-case SEEK_CUR: whence = "SEEK_CUR"; break;
-case SEEK_END: whence = "SEEK_END"; break;
-}
-gemu_log("%s",whence);
-print_syscall_epilogue(name);
-}
-#endif
-
 #if defined(TARGET_NR_socket)
 static void
 print_socket(const struct syscallname *name,
@@ -2329,6 +2321,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_UNLINKATFLAG:
 len = add_flags(b, rest, unlinkat_flags, arg, true);
 break;
+case ARG_LSEEKWHENCE:
+len = add_lseek_whence(b, rest, arg);
+break;
 case ARG_PTR:
 len = add_pointer(b, rest, arg);
 break;
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index fb64d5bd1d..e267adec1e 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -112,6 +112,42 @@ SYSCALL_IMPL(linkat)
 return do_linkat(arg1, arg2, arg3, arg4, arg5);
 }
 
+#ifdef TARGET_NR_lseek
+SYSCALL_IMPL(lseek)
+{
+return get_errno(lseek(arg1, arg2, arg3));
+}
+#endif
+
+#ifdef TARGET_NR_llseek
+SYSCALL_ARGS(llseek)
+{
+/* The parts for offset are *always* in big-endian order.  */
+abi_ulong lo = in[2], hi = in[1];
+out[1] = (((uint64_t)hi << (TARGET_ABI_BITS - 1)) << 1) | lo;
+out[2] = in[3];
+out[3] = in[4];
+return def;
+}
+
+SYSCALL_IMPL(llseek)
+{
+int fd = arg1;
+int64_t offset = arg2;
+abi_ulong target_res = arg3;
+int whence = arg4;
+
+off_t res = lseek(fd, offset, whence);
+
+if (res == -1) {
+return get_errno(-1);
+} else if (put_user_s64(res, target_res)) {
+return -TARGET_EFAULT;
+}
+return 0;
+}
+#endif
+
 static abi_long do_mknodat(int dirfd, abi_ulong target_path,
mode_t mode, dev_t dev)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3c0de73aa4..9eff91d67e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -192,8 +192,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 
arg4,type5 arg5,   \
 #endif
 
 /* Newer kernel ports have llseek() instead of _llseek() */
-#if 

[Qemu-devel] [PATCH v7 36/74] linux-user: Split out access, faccessat

2019-05-19 Thread Richard Henderson
Note that faccessat is unconditionally available.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/syscall.h  |  1 +
 linux-user/strace.c   | 33 -
 linux-user/syscall-file.inc.c | 25 +
 linux-user/syscall.c  | 18 --
 linux-user/strace.list|  6 --
 6 files changed, 34 insertions(+), 53 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 2767e335d8..39e3ae3c21 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -16,6 +16,9 @@
  *  along with this program; if not, see .
  */
 
+#ifdef TARGET_NR_access
+SYSCALL_DEF(access, ARG_STR, ARG_ACCESSFLAG);
+#endif
 #ifdef TARGET_NR_alarm
 SYSCALL_DEF(alarm, ARG_DEC);
 #endif
@@ -34,6 +37,7 @@ SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG);
 SYSCALL_DEF(exit, ARG_DEC);
 SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
+SYSCALL_DEF(faccessat, ARG_ATDIRFD, ARG_STR, ARG_ACCESSFLAG);
 SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG);
 SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG);
 #ifdef TARGET_NR_futimesat
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 3c936b648a..84a52b2d9a 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -57,6 +57,7 @@ typedef enum {
 
 /* These print as sets of flags.  */
 ARG_ATDIRFD,
+ARG_ACCESSFLAG,
 ARG_ATFLAG,
 ARG_CLONEFLAG,
 ARG_MMAPFLAG,
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 3a7a5c30ec..c42abc2f08 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -634,7 +634,7 @@ print_syscall_ret_adjtimex(const struct syscallname *name, 
abi_long ret)
 gemu_log("\n");
 }
 
-UNUSED static struct flags access_flags[] = {
+static struct flags const access_flags[] = {
 FLAG_GENERIC(F_OK),
 FLAG_GENERIC(R_OK),
 FLAG_GENERIC(W_OK),
@@ -1114,19 +1114,6 @@ print_accept(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_access
-static void
-print_access(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_flags(access_flags, arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_chroot
 static void
 print_chroot(const struct syscallname *name,
@@ -1165,21 +1152,6 @@ print_execv(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_faccessat
-static void
-print_faccessat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_flags(access_flags, arg2, 0);
-print_flags(at_file_flags, arg3, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_fchownat
 static void
 print_fchownat(const struct syscallname *name,
@@ -2218,6 +2190,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_ATDIRFD:
 len = add_atdirfd(b, rest, arg);
 break;
+case ARG_ACCESSFLAG:
+len = add_flags(b, rest, access_flags, arg, false);
+break;
 case ARG_ATFLAG:
 len = add_flags(b, rest, at_file_flags, arg, false);
 break;
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 42e5cd2dc1..5e276d13bc 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -16,6 +16,26 @@
  *  along with this program; if not, see .
  */
 
+static abi_long do_faccessat(int dirfd, abi_ulong target_path, int mode)
+{
+char *p = lock_user_string(target_path);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(faccessat(dirfd, p, mode, 0));
+unlock_user(p, target_path, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_access
+SYSCALL_IMPL(access)
+{
+return do_faccessat(AT_FDCWD, arg1, arg2);
+}
+#endif
+
 SYSCALL_IMPL(chdir)
 {
 abi_ulong target_path = arg1;
@@ -74,6 +94,11 @@ SYSCALL_IMPL(creat)
 }
 #endif
 
+SYSCALL_IMPL(faccessat)
+{
+return do_faccessat(arg1, arg2, arg3);
+}
+
 SYSCALL_IMPL(fchmod)
 {
 return get_errno(fchmod(arg1, arg2));
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f66acbf27c..b5ade974a7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5380,24 +5380,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_access
-case TARGET_NR_access:
-if (!(p = lock_user_string(arg1))) {
-return -TARGET_EFAULT;
-}
-ret = get_errno(access(path(p), arg2));
-unlock_user(p, arg1, 0);
-

[Qemu-devel] [PATCH v7 46/74] linux-user: Move syscall_init to the end

2019-05-19 Thread Richard Henderson
No functional change.  This will aid moving everything
related to ioctls to a separate file.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 113 +++
 1 file changed, 61 insertions(+), 52 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5343486a58..d0e76c392e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4831,58 +4831,6 @@ _syscall1(int, sys_setgid, gid_t, gid)
 _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
 _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
 
-void syscall_init(void)
-{
-IOCTLEntry *ie;
-const argtype *arg_type;
-int size;
-int i;
-
-thunk_init(STRUCT_MAX);
-
-#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, 
struct_ ## name ## _def);
-#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, 
#name, _ ## name ## _def);
-#include "syscall_types.h"
-#undef STRUCT
-#undef STRUCT_SPECIAL
-
-/* Build target_to_host_errno_table[] table from
- * host_to_target_errno_table[]. */
-for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
-target_to_host_errno_table[host_to_target_errno_table[i]] = i;
-}
-
-/* we patch the ioctl size if necessary. We rely on the fact that
-   no ioctl has all the bits at '1' in the size field */
-ie = ioctl_entries;
-while (ie->target_cmd != 0) {
-if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
-TARGET_IOC_SIZEMASK) {
-arg_type = ie->arg_type;
-if (arg_type[0] != TYPE_PTR) {
-fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
-ie->target_cmd);
-exit(1);
-}
-arg_type++;
-size = thunk_type_size(arg_type, 0);
-ie->target_cmd = (ie->target_cmd &
-  ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
-(size << TARGET_IOC_SIZESHIFT);
-}
-
-/* automatic consistency check if same arch */
-#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
-(defined(__x86_64__) && defined(TARGET_X86_64))
-if (unlikely(ie->target_cmd != ie->host_cmd)) {
-fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
-ie->name, ie->target_cmd, ie->host_cmd);
-}
-#endif
-ie++;
-}
-}
-
 static inline uint64_t target_offset64(abi_ulong word0, abi_ulong word1)
 {
 #if TARGET_ABI_BITS == 64
@@ -9072,3 +9020,64 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
 }
+
+void syscall_init(void)
+{
+IOCTLEntry *ie;
+const argtype *arg_type;
+int size;
+int i;
+
+thunk_init(STRUCT_MAX);
+
+#define STRUCT(name, ...) \
+thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
+#define STRUCT_SPECIAL(name) \
+thunk_register_struct_direct(STRUCT_ ## name, #name, \
+ _ ## name ## _def);
+
+#include "syscall_types.h"
+
+#undef STRUCT
+#undef STRUCT_SPECIAL
+
+/*
+ * Build target_to_host_errno_table[] table from
+ * host_to_target_errno_table[].
+ */
+for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
+target_to_host_errno_table[host_to_target_errno_table[i]] = i;
+}
+
+/*
+ * We patch the ioctl size if necessary.  We rely on the fact that
+ * no ioctl has all the bits at '1' in the size field.
+ */
+ie = ioctl_entries;
+while (ie->target_cmd != 0) {
+if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
+TARGET_IOC_SIZEMASK) {
+arg_type = ie->arg_type;
+if (arg_type[0] != TYPE_PTR) {
+fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
+ie->target_cmd);
+exit(1);
+}
+arg_type++;
+size = thunk_type_size(arg_type, 0);
+ie->target_cmd = (ie->target_cmd &
+  ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
+(size << TARGET_IOC_SIZESHIFT);
+}
+
+/* automatic consistency check if same arch */
+#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
+(defined(__x86_64__) && defined(TARGET_X86_64))
+if (unlikely(ie->target_cmd != ie->host_cmd)) {
+fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
+ie->name, ie->target_cmd, ie->host_cmd);
+}
+#endif
+ie++;
+}
+}
-- 
2.17.1




[Qemu-devel] [PATCH v7 41/74] linux-user: Split out mkdir, mkdirat

2019-05-19 Thread Richard Henderson
Note that mkdirat is universally available.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/strace.c   | 27 ---
 linux-user/syscall-file.inc.c | 25 +
 linux-user/syscall.c  | 16 
 linux-user/strace.list|  6 --
 5 files changed, 29 insertions(+), 49 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 0ed01aa100..8b6d8f75ff 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -69,6 +69,10 @@ SYSCALL_DEF(lseek, ARG_DEC, ARG_DEC, ARG_LSEEKWHENCE);
 #ifdef TARGET_NR_llseek
 SYSCALL_DEF_ARGS(llseek, ARG_DEC, ARG_DEC, ARG_PTR, ARG_LSEEKWHENCE);
 #endif
+#ifdef TARGET_NR_mkdir
+SYSCALL_DEF(mkdir, ARG_STR, ARG_MODEFLAG);
+#endif
+SYSCALL_DEF(mkdirat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG);
 #ifdef TARGET_NR_mknod
 SYSCALL_DEF(mknod, ARG_STR, ARG_MODEFLAG, ARG_HEX);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 8f871b30ae..2b31998dbd 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1676,33 +1676,6 @@ print_fstat(const struct syscallname *name,
 #define print_fstat64 print_fstat
 #endif
 
-#ifdef TARGET_NR_mkdir
-static void
-print_mkdir(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_file_mode(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_mkdirat
-static void
-print_mkdirat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_file_mode(arg2, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_rt_sigaction
 static void
 print_rt_sigaction(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 18553f055e..5ed8b78c79 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -205,6 +205,31 @@ SYSCALL_IMPL(llseek)
 }
 #endif
 
+static abi_long do_mkdirat(int dirfd, abi_ulong target_path, mode_t mode)
+{
+char *p = lock_user_string(target_path);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(mkdirat(dirfd, p, mode));
+unlock_user(p, target_path, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_mkdir
+SYSCALL_IMPL(mkdir)
+{
+return do_mkdirat(AT_FDCWD, arg1, arg2);
+}
+#endif
+
+SYSCALL_IMPL(mkdirat)
+{
+return do_mkdirat(arg1, arg2, arg3);
+}
+
 static abi_long do_mknodat(int dirfd, abi_ulong target_path,
mode_t mode, dev_t dev)
 {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d8f6da63cc..0d6a9b7a6c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5373,22 +5373,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_mkdir
-case TARGET_NR_mkdir:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(mkdir(p, arg2));
-unlock_user(p, arg1, 0);
-return ret;
-#endif
-#if defined(TARGET_NR_mkdirat)
-case TARGET_NR_mkdirat:
-if (!(p = lock_user_string(arg2)))
-return -TARGET_EFAULT;
-ret = get_errno(mkdirat(arg1, p, arg3));
-unlock_user(p, arg2, 0);
-return ret;
-#endif
 case TARGET_NR_dup:
 ret = get_errno(dup(arg1));
 if (ret >= 0) {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 3b002a0500..cdbc59bffd 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -473,12 +473,6 @@
 #ifdef TARGET_NR_mincore
 { TARGET_NR_mincore, "mincore" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_mkdir
-{ TARGET_NR_mkdir, "mkdir" , NULL, print_mkdir, NULL },
-#endif
-#ifdef TARGET_NR_mkdirat
-{ TARGET_NR_mkdirat, "mkdirat" , NULL, print_mkdirat, NULL },
-#endif
 #ifdef TARGET_NR_modify_ldt
 { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 26/74] linux-user: Split out time

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  3 +++
 linux-user/syscall-time.inc.c | 32 
 linux-user/syscall.c  | 13 +
 linux-user/strace.list|  3 ---
 4 files changed, 36 insertions(+), 15 deletions(-)
 create mode 100644 linux-user/syscall-time.inc.c

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 3fad9d51f0..9950b73e76 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -127,6 +127,9 @@ SYSCALL_DEF(shmdt, ARG_PTR);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget)
 SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
+#ifdef TARGET_NR_time
+SYSCALL_DEF(time, ARG_PTR);
+#endif
 #ifdef TARGET_NR_unlink
 SYSCALL_DEF(unlink, ARG_STR);
 #endif
diff --git a/linux-user/syscall-time.inc.c b/linux-user/syscall-time.inc.c
new file mode 100644
index 00..14fec88e47
--- /dev/null
+++ b/linux-user/syscall-time.inc.c
@@ -0,0 +1,32 @@
+/*
+ *  Linux time related syscalls
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifdef TARGET_NR_time
+SYSCALL_IMPL(time)
+{
+time_t host_time;
+abi_long ret = get_errno(time(_time));
+
+if (!is_error(ret)
+&& arg1
+&& put_user_sal(host_time, arg1)) {
+return -TARGET_EFAULT;
+}
+return ret;
+}
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0bf5901014..ea89734706 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5384,18 +5384,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_time
-case TARGET_NR_time:
-{
-time_t host_time;
-ret = get_errno(time(_time));
-if (!is_error(ret)
-&& arg1
-&& put_user_sal(host_time, arg1))
-return -TARGET_EFAULT;
-}
-return ret;
-#endif
 #ifdef TARGET_NR_mknod
 case TARGET_NR_mknod:
 if (!(p = lock_user_string(arg1)))
@@ -9392,6 +9380,7 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 #include "syscall-ipc.inc.c"
 #include "syscall-mem.inc.c"
 #include "syscall-proc.inc.c"
+#include "syscall-time.inc.c"
 
 #undef SYSCALL_IMPL
 #undef SYSCALL_ARGS
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 3f79159b63..95706a696b 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1350,9 +1350,6 @@
 #ifdef TARGET_NR_tgkill
 { TARGET_NR_tgkill, "tgkill" , NULL, print_tgkill, NULL },
 #endif
-#ifdef TARGET_NR_time
-{ TARGET_NR_time, "time" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_timer_create
 { TARGET_NR_timer_create, "timer_create" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 34/74] linux-user: Split out alarm, pause

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|  6 ++
 linux-user/syscall-sig.inc.c | 36 
 linux-user/syscall.c | 12 +---
 linux-user/strace.list   |  6 --
 4 files changed, 43 insertions(+), 17 deletions(-)
 create mode 100644 linux-user/syscall-sig.inc.c

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 6ca82af397..9d0dd7457b 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -16,6 +16,9 @@
  *  along with this program; if not, see .
  */
 
+#ifdef TARGET_NR_alarm
+SYSCALL_DEF(alarm, ARG_DEC);
+#endif
 SYSCALL_DEF_FULL(brk, .impl = impl_brk,
  .print_ret = print_syscall_ptr_ret,
  .arg_type = { ARG_PTR });
@@ -106,6 +109,9 @@ SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 #endif
 SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 SYSCALL_DEF(open_by_handle_at, ARG_DEC, ARG_PTR, ARG_OPENFLAG);
+#ifdef TARGET_NR_pause
+SYSCALL_DEF(pause);
+#endif
 SYSCALL_DEF_FULL(pread64, .impl = impl_pread64,
  .args = args_pread64_pwrite64,
  .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 });
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
new file mode 100644
index 00..f4e43eb00e
--- /dev/null
+++ b/linux-user/syscall-sig.inc.c
@@ -0,0 +1,36 @@
+/*
+ *  Linux signal related syscalls
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifdef TARGET_NR_alarm
+SYSCALL_IMPL(alarm)
+{
+return alarm(arg1);
+}
+#endif
+
+#ifdef TARGET_NR_pause
+SYSCALL_IMPL(pause)
+{
+if (!block_signals()) {
+CPUState *cpu = ENV_GET_CPU(cpu_env);
+TaskState *ts = cpu->opaque;
+sigsuspend(>signal_mask);
+}
+return -TARGET_EINTR;
+}
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ae56ecbbc7..96e77ea38f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5380,17 +5380,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_alarm /* not on alpha */
-case TARGET_NR_alarm:
-return alarm(arg1);
-#endif
-#ifdef TARGET_NR_pause /* not on alpha */
-case TARGET_NR_pause:
-if (!block_signals()) {
-sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
-}
-return -TARGET_EINTR;
-#endif
 #ifdef TARGET_NR_utime
 case TARGET_NR_utime:
 {
@@ -9224,6 +9213,7 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 #include "syscall-ipc.inc.c"
 #include "syscall-mem.inc.c"
 #include "syscall-proc.inc.c"
+#include "syscall-sig.inc.c"
 #include "syscall-time.inc.c"
 
 #undef SYSCALL_IMPL
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d0646b9424..2a65457c76 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -25,9 +25,6 @@
 #ifdef TARGET_NR_afs_syscall
 { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_alarm
-{ TARGET_NR_alarm, "alarm" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_aplib
 { TARGET_NR_aplib, "aplib" , NULL, NULL, NULL },
 #endif
@@ -872,9 +869,6 @@
 #ifdef TARGET_NR_osf_waitid
 { TARGET_NR_osf_waitid, "osf_waitid" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_pause
-{ TARGET_NR_pause, "pause" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_pciconfig_iobase
 { TARGET_NR_pciconfig_iobase, "pciconfig_iobase" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 44/74] linux-user: Split out times

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/syscall-proc.inc.c | 25 +
 linux-user/syscall.c  | 18 --
 linux-user/strace.list|  3 ---
 4 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index bd3301a72f..25d5aaccd1 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -204,6 +204,7 @@ SYSCALL_DEF(syncfs, ARG_DEC);
 #ifdef TARGET_NR_time
 SYSCALL_DEF(time, ARG_PTR);
 #endif
+SYSCALL_DEF(times, ARG_PTR);
 #ifdef TARGET_NR_umount
 SYSCALL_DEF(umount, ARG_STR);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index e29c2ede25..517f84e139 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -468,6 +468,31 @@ SYSCALL_IMPL(nice)
 }
 #endif
 
+SYSCALL_IMPL(times)
+{
+abi_ulong target_buf = arg1;
+struct tms tms;
+abi_long ret;
+
+ret = get_errno(times());
+if (target_buf) {
+struct target_tms *tmsp = lock_user(VERIFY_WRITE, target_buf,
+sizeof(struct target_tms), 0);
+if (!tmsp) {
+return -TARGET_EFAULT;
+}
+tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
+tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
+tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
+tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
+unlock_user(tmsp, target_buf, sizeof(struct target_tms));
+}
+if (!is_error(ret)) {
+ret = host_to_target_clock_t(ret);
+}
+return ret;
+}
+
 /*
  * Map host to target signal numbers for the wait family of syscalls.
  * Assume all other status bits are the same.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cda1f8a205..cdca0dbe4f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5346,24 +5346,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_times:
-{
-struct target_tms *tmsp;
-struct tms tms;
-ret = get_errno(times());
-if (arg1) {
-tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct 
target_tms), 0);
-if (!tmsp)
-return -TARGET_EFAULT;
-tmsp->tms_utime = 
tswapal(host_to_target_clock_t(tms.tms_utime));
-tmsp->tms_stime = 
tswapal(host_to_target_clock_t(tms.tms_stime));
-tmsp->tms_cutime = 
tswapal(host_to_target_clock_t(tms.tms_cutime));
-tmsp->tms_cstime = 
tswapal(host_to_target_clock_t(tms.tms_cstime));
-}
-if (!is_error(ret))
-ret = host_to_target_clock_t(ret);
-}
-return ret;
 case TARGET_NR_acct:
 if (arg1 == 0) {
 ret = get_errno(acct(NULL));
diff --git a/linux-user/strace.list b/linux-user/strace.list
index a1c3dd98e0..85e3de87d8 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1290,9 +1290,6 @@
 #ifdef TARGET_NR_timerfd_settime
 { TARGET_NR_timerfd_settime, "timerfd_settime" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_times
-{ TARGET_NR_times, "times" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_tkill
 { TARGET_NR_tkill, "tkill" , NULL, print_tkill, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 37/74] linux-user: Split out nice

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h | 3 +++
 linux-user/syscall-proc.inc.c | 7 +++
 linux-user/syscall.c  | 4 
 linux-user/strace.list| 3 ---
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 39e3ae3c21..860754aaca 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -111,6 +111,9 @@ SYSCALL_DEF(munlockall);
 SYSCALL_DEF(munmap, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(name_to_handle_at,
 ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
+#ifdef TARGET_NR_nice
+SYSCALL_DEF(nice, ARG_DEC);
+#endif
 #ifdef TARGET_NR_open
 SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 4d8d385b38..e29c2ede25 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -461,6 +461,13 @@ SYSCALL_IMPL(getxpid)
 }
 #endif
 
+#ifdef TARGET_NR_nice
+SYSCALL_IMPL(nice)
+{
+return get_errno(nice(arg1));
+}
+#endif
+
 /*
  * Map host to target signal numbers for the wait family of syscalls.
  * Assume all other status bits are the same.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b5ade974a7..6d30e8ff2f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5380,10 +5380,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_nice /* not on alpha */
-case TARGET_NR_nice:
-return get_errno(nice(arg1));
-#endif
 case TARGET_NR_sync:
 sync();
 return 0;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 80b9220e89..3161546afc 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -527,9 +527,6 @@
 #ifdef TARGET_NR_nfsservctl
 { TARGET_NR_nfsservctl, "nfsservctl" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_nice
-{ TARGET_NR_nice, "nice" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_old_adjtimex
 { TARGET_NR_old_adjtimex, "old_adjtimex" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 22/74] linux-user: Split out unlink, unlinkat, rmdir

2019-05-19 Thread Richard Henderson
Note that unlinkat is universally provided.
Implement rmdir in terms of unlinkat.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  7 ++
 linux-user/syscall.h  |  1 +
 linux-user/strace.c   | 43 ---
 linux-user/syscall-file.inc.c | 32 ++
 linux-user/syscall.c  | 24 ---
 linux-user/strace.list|  9 
 6 files changed, 44 insertions(+), 72 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 41dd887dbc..78d3f600eb 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -98,6 +98,9 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
 #endif
 SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC);
+#ifdef TARGET_NR_rmdir
+SYSCALL_DEF(rmdir, ARG_STR);
+#endif
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
@@ -121,6 +124,10 @@ SYSCALL_DEF(shmdt, ARG_PTR);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget)
 SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
+#ifdef TARGET_NR_unlink
+SYSCALL_DEF(unlink, ARG_STR);
+#endif
+SYSCALL_DEF(unlinkat, ARG_ATDIRFD, ARG_STR, ARG_UNLINKATFLAG);
 #ifdef TARGET_NR_vfork
 /* Emulate vfork() with fork().  */
 SYSCALL_DEF_FULL(vfork, .impl = impl_fork);
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index f75cd3ddd0..bdc4d653c4 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -63,6 +63,7 @@ typedef enum {
 ARG_MMAPPROT,
 ARG_MODEFLAG,
 ARG_OPENFLAG,
+ARG_UNLINKATFLAG,
 
 /* These are interpreted as pointers.  */
 ARG_PTR,
diff --git a/linux-user/strace.c b/linux-user/strace.c
index feb8ec7c09..9ac0b859da 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -684,7 +684,7 @@ static struct flags const at_file_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags unlinkat_flags[] = {
+static struct flags const unlinkat_flags[] = {
 #ifdef AT_REMOVEDIR
 FLAG_GENERIC(AT_REMOVEDIR),
 #endif
@@ -1810,18 +1810,6 @@ print_mkdirat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_rmdir
-static void
-print_rmdir(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_rt_sigaction
 static void
 print_rt_sigaction(const struct syscallname *name,
@@ -2187,32 +2175,6 @@ print_umount2(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_unlink
-static void
-print_unlink(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_unlinkat
-static void
-print_unlinkat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_flags(unlinkat_flags, arg2, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_utime
 static void
 print_utime(const struct syscallname *name,
@@ -2475,6 +2437,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_OPENFLAG:
 len = add_open_flags(b, rest, arg);
 break;
+case ARG_UNLINKATFLAG:
+len = add_flags(b, rest, unlinkat_flags, arg, true);
+break;
 case ARG_PTR:
 len = add_pointer(b, rest, arg);
 break;
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 440ff5ed14..5acd8ecc10 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -662,6 +662,38 @@ SYSCALL_IMPL(readlinkat)
 }
 #endif
 
+static abi_long do_unlinkat(int dirfd, abi_ulong target_path, int flags)
+{
+char *p = lock_user_string(target_path);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(unlinkat(dirfd, p, flags));
+unlock_user(p, target_path, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_unlink
+SYSCALL_IMPL(unlink)
+{
+return do_unlinkat(AT_FDCWD, arg1, 0);
+}
+#endif
+
+#ifdef TARGET_NR_rmdir
+SYSCALL_IMPL(rmdir)
+{
+return do_unlinkat(AT_FDCWD, arg1, AT_REMOVEDIR);
+}
+#endif
+
+SYSCALL_IMPL(unlinkat)
+{
+return do_unlinkat(arg1, arg2, arg3);
+}
+
 SYSCALL_IMPL(write)
 {
 int fd = arg1;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 865129df9e..53e108b614 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5383,22 +5383,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 

[Qemu-devel] [PATCH v7 40/74] linux-user: Split out rename, renameat, renameat2

2019-05-19 Thread Richard Henderson
Note that renameat2 is universally available for guests.
Merge sys_renameat2 into the new do_renameat2 helper.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  8 +
 linux-user/syscall.h  |  1 +
 linux-user/strace.c   | 39 ++---
 linux-user/syscall-file.inc.c | 45 
 linux-user/syscall.c  | 64 ---
 linux-user/strace.list|  9 -
 6 files changed, 65 insertions(+), 101 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index c672b5ad99..0ed01aa100 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -142,6 +142,14 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
 #ifdef TARGET_NR_readlinkat
 SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
 #endif
+#ifdef TARGET_NR_rename
+SYSCALL_DEF(rename, ARG_STR, ARG_STR);
+#endif
+#ifdef TARGET_NR_renameat
+SYSCALL_DEF(renameat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR);
+#endif
+SYSCALL_DEF(renameat2, ARG_ATDIRFD, ARG_STR,
+ARG_ATDIRFD, ARG_STR, ARG_RENAMEFLAG);
 SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC);
 #ifdef TARGET_NR_rmdir
 SYSCALL_DEF(rmdir, ARG_STR);
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 642fb6dccb..7b197840f5 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -69,6 +69,7 @@ typedef enum {
 ARG_MODEFLAG,
 ARG_MOUNTFLAG,
 ARG_OPENFLAG,
+ARG_RENAMEFLAG,
 ARG_UMOUNTFLAG,
 ARG_UNLINKATFLAG,
 
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 01a5c210fa..8f871b30ae 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "qemu.h"
 #include "syscall.h"
@@ -741,6 +742,13 @@ static struct flags const mount_flags[] = {
 FLAG_END,
 };
 
+static struct flags const renameat2_flags[] = {
+FLAG_GENERIC(RENAME_EXCHANGE),
+FLAG_GENERIC(RENAME_NOREPLACE),
+FLAG_GENERIC(RENAME_WHITEOUT),
+FLAG_END,
+};
+
 static struct flags const umount2_flags[] = {
 #ifdef MNT_FORCE
 FLAG_GENERIC(MNT_FORCE),
@@ -1899,34 +1907,6 @@ print_fstatat64(const struct syscallname *name,
 #define print_newfstatatprint_fstatat64
 #endif
 
-#ifdef TARGET_NR_rename
-static void
-print_rename(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_string(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_renameat
-static void
-print_renameat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_at_dirfd(arg2, 0);
-print_string(arg3, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_statfs
 static void
 print_statfs(const struct syscallname *name,
@@ -2212,6 +2192,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_OPENFLAG:
 len = add_open_flags(b, rest, arg);
 break;
+case ARG_RENAMEFLAG:
+len = add_flags(b, rest, renameat2_flags, arg, false);
+break;
 case ARG_UMOUNTFLAG:
 len = add_flags(b, rest, umount2_flags, arg, false);
 break;
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 9f3cf7221a..18553f055e 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -873,6 +873,51 @@ SYSCALL_IMPL(readlinkat)
 }
 #endif
 
+static abi_long do_renameat2(int oldfd, abi_ulong target_oldpath,
+ int newfd, abi_ulong target_newpath,
+ unsigned int flags)
+{
+char *p_old = lock_user_string(target_oldpath);
+char *p_new = lock_user_string(target_newpath);
+abi_long ret = -TARGET_EFAULT;
+
+if (p_old && p_new) {
+if (flags == 0) {
+ret = renameat(oldfd, p_old, newfd, p_new);
+} else {
+#ifdef __NR_renameat2
+ret = syscall(__NR_renameat2, oldfd, p_old, newfd, p_new, flags);
+#else
+errno = ENOSYS;
+ret = -1;
+#endif
+}
+ret = get_errno(ret);
+}
+unlock_user(p_old, target_oldpath, 0);
+unlock_user(p_new, target_newpath, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_rename
+SYSCALL_IMPL(rename)
+{
+return do_renameat2(AT_FDCWD, arg1, AT_FDCWD, arg2, 0);
+}
+#endif
+
+#ifdef TARGET_NR_renameat
+SYSCALL_IMPL(renameat)
+{
+return do_renameat2(arg1, arg2, arg3, arg4, 0);
+}
+#endif
+
+SYSCALL_IMPL(renameat2)
+{
+return do_renameat2(arg1, arg2, arg3, arg4, arg5);
+}
+
 SYSCALL_IMPL(sync)
 {
 sync();
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3fe770890c..d8f6da63cc 100644

[Qemu-devel] [PATCH v7 27/74] linux-user: Split out mknod, mknodat

2019-05-19 Thread Richard Henderson
Note that mknodat is universally provided.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/strace.c   | 39 ---
 linux-user/syscall-file.inc.c | 26 +++
 linux-user/syscall.c  | 16 --
 linux-user/strace.list|  6 --
 5 files changed, 30 insertions(+), 61 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 9950b73e76..b5951e6911 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -38,6 +38,10 @@ SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, 
ARG_PTR, ARG_HEX);
 SYSCALL_DEF(link, ARG_STR, ARG_STR);
 #endif
 SYSCALL_DEF(linkat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR, ARG_ATFLAG);
+#ifdef TARGET_NR_mknod
+SYSCALL_DEF(mknod, ARG_STR, ARG_MODEFLAG, ARG_HEX);
+#endif
+SYSCALL_DEF(mknodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG, ARG_HEX);
 SYSCALL_DEF(mlock, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(mlockall, ARG_HEX);
 #ifdef TARGET_NR_mmap
diff --git a/linux-user/strace.c b/linux-user/strace.c
index b234274034..c70c06d965 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1923,45 +1923,6 @@ print_syslog(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_mknod
-static void
-print_mknod(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-int hasdev = (arg1 & (S_IFCHR|S_IFBLK));
-
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_file_mode(arg1, (hasdev == 0));
-if (hasdev) {
-print_raw_param("makedev(%d", major(arg2), 0);
-print_raw_param("%d)", minor(arg2), 1);
-}
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_mknodat
-static void
-print_mknodat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-int hasdev = (arg2 & (S_IFCHR|S_IFBLK));
-
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_file_mode(arg2, (hasdev == 0));
-if (hasdev) {
-print_raw_param("makedev(%d", major(arg3), 0);
-print_raw_param("%d)", minor(arg3), 1);
-}
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_mq_open
 static void
 print_mq_open(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 76637fe71b..3adb629124 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -82,6 +82,32 @@ SYSCALL_IMPL(linkat)
 return do_linkat(arg1, arg2, arg3, arg4, arg5);
 }
 
+static abi_long do_mknodat(int dirfd, abi_ulong target_path,
+   mode_t mode, dev_t dev)
+{
+char *p = lock_user_string(target_path);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(mknodat(dirfd, p, mode, dev));
+unlock_user(p, target_path, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_mknod
+SYSCALL_IMPL(mknod)
+{
+return do_mknodat(AT_FDCWD, arg1, arg2, arg3);
+}
+#endif
+
+SYSCALL_IMPL(mknodat)
+{
+return do_mknodat(arg1, arg2, arg3, arg4);
+}
+
 /*
  * Helpers for do_openat, manipulating /proc/self/foo.
  */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ea89734706..18163f558c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5384,22 +5384,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_mknod
-case TARGET_NR_mknod:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(mknod(p, arg2, arg3));
-unlock_user(p, arg1, 0);
-return ret;
-#endif
-#if defined(TARGET_NR_mknodat)
-case TARGET_NR_mknodat:
-if (!(p = lock_user_string(arg2)))
-return -TARGET_EFAULT;
-ret = get_errno(mknodat(arg1, p, arg3, arg4));
-unlock_user(p, arg2, 0);
-return ret;
-#endif
 #ifdef TARGET_NR_chmod
 case TARGET_NR_chmod:
 if (!(p = lock_user_string(arg1)))
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 95706a696b..f56d9acf76 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -518,12 +518,6 @@
 #ifdef TARGET_NR_mkdirat
 { TARGET_NR_mkdirat, "mkdirat" , NULL, print_mkdirat, NULL },
 #endif
-#ifdef TARGET_NR_mknod
-{ TARGET_NR_mknod, "mknod" , NULL, print_mknod, NULL },
-#endif
-#ifdef TARGET_NR_mknodat
-{ TARGET_NR_mknodat, "mknodat" , NULL, print_mknodat, NULL },
-#endif
 #ifdef TARGET_NR_modify_ldt
 { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 32/74] linux-user: Split out umount, umount2

2019-05-19 Thread Richard Henderson
Note that umount2 is unconditionally available.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/syscall.h  |  1 +
 linux-user/strace.c   | 30 --
 linux-user/syscall-file.inc.c | 25 +
 linux-user/syscall.c  | 16 
 linux-user/strace.list|  6 --
 6 files changed, 34 insertions(+), 48 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 2b331c6a6d..0d8da0c6d6 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -155,6 +155,10 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #ifdef TARGET_NR_time
 SYSCALL_DEF(time, ARG_PTR);
 #endif
+#ifdef TARGET_NR_umount
+SYSCALL_DEF(umount, ARG_STR);
+#endif
+SYSCALL_DEF(umount2, ARG_STR, ARG_UMOUNTFLAG);
 #ifdef TARGET_NR_unlink
 SYSCALL_DEF(unlink, ARG_STR);
 #endif
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 35dd3e5fa3..3c936b648a 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -64,6 +64,7 @@ typedef enum {
 ARG_MODEFLAG,
 ARG_MOUNTFLAG,
 ARG_OPENFLAG,
+ARG_UMOUNTFLAG,
 ARG_UNLINKATFLAG,
 ARG_LSEEKWHENCE,
 
diff --git a/linux-user/strace.c b/linux-user/strace.c
index a99ab46b97..278d235ae6 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -733,7 +733,7 @@ static struct flags const mount_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags umount2_flags[] = {
+static struct flags const umount2_flags[] = {
 #ifdef MNT_FORCE
 FLAG_GENERIC(MNT_FORCE),
 #endif
@@ -2015,31 +2015,6 @@ print_symlinkat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_umount
-static void
-print_umount(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_umount2
-static void
-print_umount2(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_flags(umount2_flags, arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_utime
 static void
 print_utime(const struct syscallname *name,
@@ -2305,6 +2280,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_OPENFLAG:
 len = add_open_flags(b, rest, arg);
 break;
+case ARG_UMOUNTFLAG:
+len = add_flags(b, rest, umount2_flags, arg, false);
+break;
 case ARG_UNLINKATFLAG:
 len = add_flags(b, rest, unlinkat_flags, arg, true);
 break;
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 4fc12512c2..345b4cb421 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -816,6 +816,31 @@ SYSCALL_IMPL(readlinkat)
 }
 #endif
 
+static abi_long do_umount2(abi_ulong target_path, int flags)
+{
+char *p = lock_user_string(target_path);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(umount2(p, flags));
+unlock_user(p, target_path, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_umount
+SYSCALL_IMPL(umount)
+{
+return do_umount2(arg1, 0);
+}
+#endif
+
+SYSCALL_IMPL(umount2)
+{
+return do_umount2(arg1, arg2);
+}
+
 static abi_long do_unlinkat(int dirfd, abi_ulong target_path, int flags)
 {
 char *p = lock_user_string(target_path);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c826c65317..f3e03f535d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5380,14 +5380,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_umount
-case TARGET_NR_umount:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(umount(p));
-unlock_user(p, arg1, 0);
-return ret;
-#endif
 #ifdef TARGET_NR_stime /* not on alpha */
 case TARGET_NR_stime:
 {
@@ -5608,14 +5600,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 unlock_user(p, arg1, 0);
 }
 return ret;
-#ifdef TARGET_NR_umount2
-case TARGET_NR_umount2:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(umount2(p, arg2));
-unlock_user(p, arg1, 0);
-return ret;
-#endif
 case TARGET_NR_ioctl:
 return do_ioctl(arg1, arg2, arg3);
 #ifdef TARGET_NR_fcntl
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 9b4024d94f..973a4c9209 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1368,12 +1368,6 @@
 #ifdef TARGET_NR_umask
 { TARGET_NR_umask, "umask" , "%s(%#o)", NULL, NULL },
 #endif

[Qemu-devel] [PATCH v7 13/74] linux-user: Split out ipc syscalls

2019-05-19 Thread Richard Henderson
Because of the ipc multiplex syscall, these must be done all at once.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h|   38 ++
 linux-user/strace.c  |   83 ---
 linux-user/syscall-ipc.inc.c | 1088 ++
 linux-user/syscall.c |  973 +-
 linux-user/strace.list   |   42 --
 5 files changed, 1129 insertions(+), 1095 deletions(-)
 create mode 100644 linux-user/syscall-ipc.inc.c

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 1fc89c1b08..6d6349da01 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -17,6 +17,21 @@
  */
 
 SYSCALL_DEF(close, ARG_DEC);
+#ifdef TARGET_NR_ipc
+SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgctl)
+SYSCALL_DEF(msgctl, ARG_DEC, ARG_DEC, ARG_PTR);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgget)
+SYSCALL_DEF(msgget, ARG_DEC, ARG_DEC);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgrcv)
+SYSCALL_DEF(msgrcv, ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC, ARG_HEX);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgsnd)
+SYSCALL_DEF(msgsnd, ARG_DEC, ARG_PTR, ARG_DEC, ARG_HEX);
+#endif
 SYSCALL_DEF(name_to_handle_at,
 ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
 #ifdef TARGET_NR_open
@@ -44,5 +59,28 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
 #endif
 SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC);
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
+SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semget)
+SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop)
+SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmat)
+SYSCALL_DEF_FULL(shmat, .impl = impl_shmat,
+ .print_ret = print_syscall_ptr_ret,
+ .arg_type = { ARG_DEC, ARG_PTR, ARG_HEX });
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmctl)
+SYSCALL_DEF(shmctl, ARG_DEC, ARG_DEC, ARG_PTR);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmdt)
+SYSCALL_DEF(shmdt, ARG_PTR);
+#endif
+#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget)
+SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
+#endif
 SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(writev, ARG_DEC, ARG_PTR, ARG_DEC);
diff --git a/linux-user/strace.c b/linux-user/strace.c
index e92b2c298e..e1c4859a95 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1,8 +1,4 @@
 #include "qemu/osdep.h"
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
 #include 
@@ -74,54 +70,6 @@ UNUSED static void print_socket_protocol(int domain, int 
type, int protocol);
 /*
  * Utility functions
  */
-static void
-print_ipc_cmd(int cmd)
-{
-#define output_cmd(val) \
-if( cmd == val ) { \
-gemu_log(#val); \
-return; \
-}
-
-cmd &= 0xff;
-
-/* General IPC commands */
-output_cmd( IPC_RMID );
-output_cmd( IPC_SET );
-output_cmd( IPC_STAT );
-output_cmd( IPC_INFO );
-/* msgctl() commands */
-output_cmd( MSG_STAT );
-output_cmd( MSG_INFO );
-/* shmctl() commands */
-output_cmd( SHM_LOCK );
-output_cmd( SHM_UNLOCK );
-output_cmd( SHM_STAT );
-output_cmd( SHM_INFO );
-/* semctl() commands */
-output_cmd( GETPID );
-output_cmd( GETVAL );
-output_cmd( GETALL );
-output_cmd( GETNCNT );
-output_cmd( GETZCNT );
-output_cmd( SETVAL );
-output_cmd( SETALL );
-output_cmd( SEM_STAT );
-output_cmd( SEM_INFO );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-output_cmd( IPC_RMID );
-
-/* Some value we don't recognize */
-gemu_log("%d",cmd);
-}
-
 static void
 print_signal(abi_ulong arg, int last)
 {
@@ -620,18 +568,6 @@ print_newselect(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_semctl
-static void
-print_semctl(const struct syscallname *name,
- abi_long arg1, abi_long arg2, abi_long arg3,
- abi_long arg4, abi_long arg5, abi_long arg6)
-{
-gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", name->name, 
arg1, arg2);
-print_ipc_cmd(arg3);
-gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
-}
-#endif
-
 static void
 print_execve(const struct syscallname *name,
  abi_long arg1, abi_long arg2, abi_long arg3,
@@ -664,25 +600,6 @@ print_execve(const struct syscallname *name,
 gemu_log("NULL})");
 }
 
-#ifdef TARGET_NR_ipc
-static void
-print_ipc(const struct syscallname *name,
-  abi_long arg1, abi_long arg2, abi_long 

[Qemu-devel] [PATCH v7 31/74] linux-user: Split out mount

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/syscall.h  |  1 +
 linux-user/strace.c   | 21 +++--
 linux-user/syscall-file.inc.c | 48 ++
 linux-user/syscall.c  | 55 ---
 linux-user/strace.list|  3 --
 6 files changed, 54 insertions(+), 75 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index d163bbf409..2b331c6a6d 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -78,6 +78,7 @@ SYSCALL_DEF_FULL(mmap2, .impl = impl_mmap,
  .arg_type = { ARG_PTR, ARG_DEC, ARG_MMAPPROT,
ARG_MMAPFLAG, ARG_DEC, ARG_DEC64 });
 #endif
+SYSCALL_DEF(mount, ARG_STR, ARG_STR, ARG_STR, ARG_MOUNTFLAG, ARG_PTR);
 SYSCALL_DEF(mprotect, ARG_PTR, ARG_DEC, ARG_MMAPPROT);
 SYSCALL_DEF_FULL(mremap, .impl = impl_mremap,
  .print_ret = print_syscall_ptr_ret,
diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index c16c0a3f1e..35dd3e5fa3 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -62,6 +62,7 @@ typedef enum {
 ARG_MMAPFLAG,
 ARG_MMAPPROT,
 ARG_MODEFLAG,
+ARG_MOUNTFLAG,
 ARG_OPENFLAG,
 ARG_UNLINKATFLAG,
 ARG_LSEEKWHENCE,
diff --git a/linux-user/strace.c b/linux-user/strace.c
index a4d7b397b4..a99ab46b97 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -708,7 +708,7 @@ static struct flags const open_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags mount_flags[] = {
+static struct flags const mount_flags[] = {
 #ifdef MS_BIND
 FLAG_GENERIC(MS_BIND),
 #endif
@@ -2015,22 +2015,6 @@ print_symlinkat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_mount
-static void
-print_mount(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_string(arg1, 0);
-print_string(arg2, 0);
-print_flags(mount_flags, arg3, 0);
-print_pointer(arg4, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_umount
 static void
 print_umount(const struct syscallname *name,
@@ -2315,6 +2299,9 @@ static void print_syscall_def1(const SyscallDef *def, 
int64_t args[6])
 case ARG_MODEFLAG:
 len = add_flags(b, rest, mode_flags, arg, true);
 break;
+case ARG_MOUNTFLAG:
+len = add_flags(b, rest, mount_flags, arg, true);
+break;
 case ARG_OPENFLAG:
 len = add_open_flags(b, rest, arg);
 break;
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index e267adec1e..4fc12512c2 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -174,6 +174,54 @@ SYSCALL_IMPL(mknodat)
 return do_mknodat(arg1, arg2, arg3, arg4);
 }
 
+SYSCALL_IMPL(mount)
+{
+abi_ulong target_src = arg1;
+abi_ulong target_tgt = arg2;
+abi_ulong target_fst = arg3;
+abi_ulong mountflags = arg4;
+abi_ulong target_data = arg5;
+char *p_src = NULL, *p_tgt = NULL, *p_fst = NULL, *p_data = NULL;
+abi_long ret = -TARGET_EFAULT;
+
+if (target_src) {
+p_src = lock_user_string(target_src);
+if (!p_src) {
+goto exit0;
+}
+}
+
+p_tgt = lock_user_string(target_tgt);
+if (!p_tgt) {
+goto exit1;
+}
+
+if (target_fst) {
+p_fst = lock_user_string(target_fst);
+if (!p_fst) {
+goto exit2;
+}
+}
+
+/*
+ * FIXME - arg5 should be locked, but it isn't clear how to
+ * do that since it's not guaranteed to be a NULL-terminated
+ * string.
+ */
+if (target_data) {
+p_data = g2h(target_data);
+}
+ret = get_errno(mount(p_src, p_tgt, p_fst, mountflags, p_data));
+
+unlock_user(p_fst, target_fst, 0);
+ exit2:
+unlock_user(p_tgt, target_tgt, 0);
+ exit1:
+unlock_user(p_src, target_src, 0);
+ exit0:
+return ret;
+}
+
 /*
  * Helpers for do_openat, manipulating /proc/self/foo.
  */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 29ea56deee..c826c65317 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5380,61 +5380,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_mount:
-{
-/* need to look at the data field */
-void *p2, *p3;
-
-if (arg1) {
-p = lock_user_string(arg1);
-if (!p) {
-return -TARGET_EFAULT;
-}
-} else {
-p = NULL;
-}
-
-p2 = lock_user_string(arg2);
-if (!p2) {
-if (arg1) {
-unlock_user(p, arg1, 0);
-}
-return -TARGET_EFAULT;
-   

[Qemu-devel] [PATCH v7 38/74] linux-user: Split out sync, syncfs

2019-05-19 Thread Richard Henderson
Note that syncfs is universally available.
If !CONFIG_SYNCFS, provide our own syscall replacement.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  2 ++
 linux-user/syscall-file.inc.c | 11 +++
 linux-user/syscall.c  | 20 
 linux-user/strace.list|  6 --
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 860754aaca..497fbdba66 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -171,6 +171,8 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #ifdef TARGET_NR_stime
 SYSCALL_DEF(stime, ARG_PTR);
 #endif
+SYSCALL_DEF(sync);
+SYSCALL_DEF(syncfs, ARG_DEC);
 #ifdef TARGET_NR_time
 SYSCALL_DEF(time, ARG_PTR);
 #endif
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 5e276d13bc..9f3cf7221a 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -873,6 +873,17 @@ SYSCALL_IMPL(readlinkat)
 }
 #endif
 
+SYSCALL_IMPL(sync)
+{
+sync();
+return 0;
+}
+
+SYSCALL_IMPL(syncfs)
+{
+return get_errno(syncfs(arg1));
+}
+
 static abi_long do_umount2(abi_ulong target_path, int flags)
 {
 char *p = lock_user_string(target_path);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6d30e8ff2f..d612dade23 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -199,6 +199,15 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 
arg4,type5 arg5,  \
 #define __NR_sys_gettid __NR_gettid
 _syscall0(int, sys_gettid)
 
+/*
+ * These definitions produce an ENOSYS from the host kernel.
+ * Performing a bogus syscall is easier than boilerplating
+ * the replacement functions here in C.
+ */
+#ifndef __NR_syncfs
+#define __NR_syncfs  -1
+#endif
+
 /* For the 64-bit guest on 32-bit host case we must emulate
  * getdents using getdents64, because otherwise the host
  * might hand us back more dirent records than we can fit
@@ -254,11 +263,13 @@ _syscall3(int, ioprio_set, int, which, int, who, int, 
ioprio)
 #if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
 _syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
 #endif
-
 #if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
 _syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type,
   unsigned long, idx1, unsigned long, idx2)
 #endif
+#ifndef CONFIG_SYNCFS
+_syscall1(int, syncfs, int, fd)
+#endif
 
 static bitmask_transtbl fcntl_flags_tbl[] = {
   { TARGET_O_ACCMODE,   TARGET_O_WRONLY,O_ACCMODE,   O_WRONLY,},
@@ -5380,13 +5391,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_sync:
-sync();
-return 0;
-#if defined(TARGET_NR_syncfs) && defined(CONFIG_SYNCFS)
-case TARGET_NR_syncfs:
-return get_errno(syncfs(arg1));
-#endif
 case TARGET_NR_kill:
 return get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
 #ifdef TARGET_NR_rename
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 3161546afc..749bdce638 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1260,12 +1260,6 @@
 #ifdef TARGET_NR_symlinkat
 { TARGET_NR_symlinkat, "symlinkat", NULL, print_symlinkat, NULL },
 #endif
-#ifdef TARGET_NR_sync
-{ TARGET_NR_sync, "sync" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_syncfs
-{ TARGET_NR_syncfs, "syncfs" , "%s(%d)", NULL, NULL },
-#endif
 #ifdef TARGET_NR_syscall
 { TARGET_NR_syscall, "syscall" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 25/74] linux-user: Split out chdir

2019-05-19 Thread Richard Henderson
Note that chdir is universally provided.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/strace.c   | 12 
 linux-user/syscall-file.inc.c | 14 ++
 linux-user/syscall.c  |  6 --
 linux-user/strace.list|  3 ---
 5 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 392bd1579c..3fad9d51f0 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -19,6 +19,7 @@
 SYSCALL_DEF_FULL(brk, .impl = impl_brk,
  .print_ret = print_syscall_ptr_ret,
  .arg_type = { ARG_PTR });
+SYSCALL_DEF(chdir, ARG_STR);
 SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(close, ARG_DEC);
 #ifdef TARGET_NR_creat
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 9d6c765715..b234274034 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1113,18 +1113,6 @@ print_access(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_chdir
-static void
-print_chdir(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_chroot
 static void
 print_chroot(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 5acd8ecc10..76637fe71b 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -16,6 +16,20 @@
  *  along with this program; if not, see .
  */
 
+SYSCALL_IMPL(chdir)
+{
+abi_ulong target_path = arg1;
+char *p = lock_user_string(target_path);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(chdir(p));
+unlock_user(p, target_path, 0);
+return ret;
+}
+
 SYSCALL_IMPL(close)
 {
 int fd = arg1;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index affcd81273..0bf5901014 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5384,12 +5384,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-case TARGET_NR_chdir:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(chdir(p));
-unlock_user(p, arg1, 0);
-return ret;
 #ifdef TARGET_NR_time
 case TARGET_NR_time:
 {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index c6bb475728..3f79159b63 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -61,9 +61,6 @@
 #ifdef TARGET_NR_capset
 { TARGET_NR_capset, "capset" , "%s(%p,%p)", NULL, NULL },
 #endif
-#ifdef TARGET_NR_chdir
-{ TARGET_NR_chdir, "chdir" , NULL, print_chdir, NULL },
-#endif
 #ifdef TARGET_NR_chmod
 { TARGET_NR_chmod, "chmod" , NULL, print_chmod, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 35/74] linux-user: Split out utime, utimes, futimesat

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  9 
 linux-user/strace.c   | 41 ---
 linux-user/syscall-file.inc.c | 95 +++
 linux-user/syscall.c  | 63 ---
 linux-user/strace.list|  9 
 5 files changed, 104 insertions(+), 113 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 9d0dd7457b..2767e335d8 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -36,6 +36,9 @@ SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
 SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG);
 SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG);
+#ifdef TARGET_NR_futimesat
+SYSCALL_DEF(futimesat, ARG_ATDIRFD, ARG_STR, ARG_PTR);
+#endif
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
@@ -172,6 +175,12 @@ SYSCALL_DEF(umount2, ARG_STR, ARG_UMOUNTFLAG);
 SYSCALL_DEF(unlink, ARG_STR);
 #endif
 SYSCALL_DEF(unlinkat, ARG_ATDIRFD, ARG_STR, ARG_UNLINKATFLAG);
+#ifdef TARGET_NR_utime
+SYSCALL_DEF(utime, ARG_STR, ARG_PTR);
+#endif
+#ifdef TARGET_NR_utimes
+SYSCALL_DEF(utimes, ARG_STR, ARG_PTR);
+#endif
 #ifdef TARGET_NR_vfork
 /* Emulate vfork() with fork().  */
 SYSCALL_DEF_FULL(vfork, .impl = impl_fork);
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 278d235ae6..3a7a5c30ec 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1296,21 +1296,6 @@ print_fcntl(const struct syscallname *name,
 #endif
 
 
-#ifdef TARGET_NR_futimesat
-static void
-print_futimesat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_timeval(arg2, 0);
-print_timeval(arg2 + sizeof (struct target_timeval), 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #if defined(TARGET_NR_socket)
 static void
 print_socket(const struct syscallname *name,
@@ -2015,32 +2000,6 @@ print_symlinkat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_utime
-static void
-print_utime(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_pointer(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_utimes
-static void
-print_utimes(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_pointer(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_utimensat
 static void
 print_utimensat(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 345b4cb421..42e5cd2dc1 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -84,6 +84,38 @@ SYSCALL_IMPL(fchmodat)
 return do_fchmodat(arg1, arg2, arg3);
 }
 
+#ifdef TARGET_NR_futimesat
+SYSCALL_IMPL(futimesat)
+{
+int dirfd = arg1;
+abi_ulong target_path = arg2;
+abi_ulong target_tv = arg3;
+struct timeval *tvp, tv[2];
+char *p;
+abi_long ret;
+
+if (target_tv) {
+if (copy_from_user_timeval([0], target_tv)
+|| copy_from_user_timeval([1],
+  target_tv +
+  sizeof(struct target_timeval))) {
+return -TARGET_EFAULT;
+}
+tvp = tv;
+} else {
+tvp = NULL;
+}
+
+p = lock_user_string(target_path);
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(futimesat(dirfd, path(p), tvp));
+unlock_user(p, target_path, 0);
+return ret;
+}
+#endif
+
 static abi_long do_linkat(int olddirfd, abi_ulong target_oldpath,
   int newdirfd, abi_ulong target_newpath,
   int flags)
@@ -873,6 +905,69 @@ SYSCALL_IMPL(unlinkat)
 return do_unlinkat(arg1, arg2, arg3);
 }
 
+#ifdef TARGET_NR_utime
+SYSCALL_IMPL(utime)
+{
+abi_ulong target_path = arg1;
+abi_ulong target_times = arg2;
+struct utimbuf tbuf, *host_tbuf;
+struct target_utimbuf *target_tbuf;
+char *p;
+abi_long ret;
+
+if (target_times) {
+if (!lock_user_struct(VERIFY_READ, target_tbuf, target_times, 1)) {
+return -TARGET_EFAULT;
+}
+tbuf.actime = tswapal(target_tbuf->actime);
+tbuf.modtime = tswapal(target_tbuf->modtime);
+unlock_user_struct(target_tbuf, arg2, 0);
+host_tbuf = 
+} else {
+host_tbuf = NULL;
+}
+
+p = lock_user_string(target_path);
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(utime(p, host_tbuf));
+unlock_user(p, 

[Qemu-devel] [PATCH v7 30/74] linux-user: Split out getpid, getppid, getxpid

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  9 +
 linux-user/syscall-proc.inc.c | 23 +++
 linux-user/syscall.c  | 14 --
 linux-user/strace.list|  9 -
 4 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 3453e7afdf..d163bbf409 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -36,6 +36,15 @@ SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
+#ifdef TARGET_NR_getpid
+SYSCALL_DEF(getpid);
+#endif
+#ifdef TARGET_NR_getppid
+SYSCALL_DEF(getppid);
+#endif
+#ifdef TARGET_NR_getxpid
+SYSCALL_DEF(getxpid);
+#endif
 #ifdef TARGET_NR_ipc
 SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index fd114d1f03..4d8d385b38 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -438,6 +438,29 @@ SYSCALL_IMPL(fork)
 }
 #endif
 
+#ifdef TARGET_NR_getpid
+SYSCALL_IMPL(getpid)
+{
+return getpid();
+}
+#endif
+
+#ifdef TARGET_NR_getppid
+SYSCALL_IMPL(getppid)
+{
+return getppid();
+}
+#endif
+
+#ifdef TARGET_NR_getxpid
+SYSCALL_IMPL(getxpid)
+{
+/* Alpha specific */
+cpu_env->ir[IR_A4] = getppid();
+return getpid();
+}
+#endif
+
 /*
  * Map host to target signal numbers for the wait family of syscalls.
  * Assume all other status bits are the same.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9eff91d67e..29ea56deee 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5380,16 +5380,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
-/* Alpha specific */
-case TARGET_NR_getxpid:
-((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
-return get_errno(getpid());
-#endif
-#ifdef TARGET_NR_getpid
-case TARGET_NR_getpid:
-return get_errno(getpid());
-#endif
 case TARGET_NR_mount:
 {
 /* need to look at the data field */
@@ -5721,10 +5711,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return ret;
 }
 #endif
-#ifdef TARGET_NR_getppid /* not on alpha */
-case TARGET_NR_getppid:
-return get_errno(getppid());
-#endif
 #ifdef TARGET_NR_getpgrp
 case TARGET_NR_getpgrp:
 return get_errno(getpgrp());
diff --git a/linux-user/strace.list b/linux-user/strace.list
index fb37c72a1f..3e898ea307 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -298,15 +298,9 @@
 #ifdef TARGET_NR_getpgrp
 { TARGET_NR_getpgrp, "getpgrp" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getpid
-{ TARGET_NR_getpid, "getpid" , "%s()", NULL, NULL },
-#endif
 #ifdef TARGET_NR_getpmsg
 { TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getppid
-{ TARGET_NR_getppid, "getppid" , "%s()", NULL, NULL },
-#endif
 #ifdef TARGET_NR_getpriority
 { TARGET_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL },
 #endif
@@ -365,9 +359,6 @@
 #ifdef TARGET_NR_getxgid
 { TARGET_NR_getxgid, "getxgid" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getxpid
-{ TARGET_NR_getxpid, "getxpid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getxuid
 { TARGET_NR_getxuid, "getxuid" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 21/74] linux-user: Split out link, linkat

2019-05-19 Thread Richard Henderson
Note that linkat is universally provided.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  4 
 linux-user/strace.c   | 29 -
 linux-user/syscall-file.inc.c | 28 
 linux-user/syscall.c  | 32 
 linux-user/strace.list|  6 --
 5 files changed, 32 insertions(+), 67 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index de7a99f0c6..41dd887dbc 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -31,6 +31,10 @@ SYSCALL_DEF(fork);
 #ifdef TARGET_NR_ipc
 SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX);
 #endif
+#ifdef TARGET_NR_link
+SYSCALL_DEF(link, ARG_STR, ARG_STR);
+#endif
+SYSCALL_DEF(linkat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR, ARG_ATFLAG);
 SYSCALL_DEF(mlock, ARG_PTR, ARG_DEC);
 SYSCALL_DEF(mlockall, ARG_HEX);
 #ifdef TARGET_NR_mmap
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 640a80f32b..feb8ec7c09 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1369,35 +1369,6 @@ print_futimesat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_link
-static void
-print_link(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_string(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_linkat
-static void
-print_linkat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_at_dirfd(arg2, 0);
-print_string(arg3, 0);
-print_flags(at_file_flags, arg4, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR__llseek
 static void
 print__llseek(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 9b966ad627..440ff5ed14 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -40,6 +40,34 @@ SYSCALL_IMPL(creat)
 }
 #endif
 
+static abi_long do_linkat(int olddirfd, abi_ulong target_oldpath,
+  int newdirfd, abi_ulong target_newpath,
+  int flags)
+{
+char *oldpath = lock_user_string(target_oldpath);
+char *newpath = lock_user_string(target_newpath);
+abi_long ret = -TARGET_EFAULT;
+
+if (oldpath && newpath) {
+ret = get_errno(linkat(olddirfd, oldpath, newdirfd, newpath, flags));
+}
+unlock_user(oldpath, target_oldpath, 0);
+unlock_user(newpath, target_newpath, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_link
+SYSCALL_IMPL(link)
+{
+return do_linkat(AT_FDCWD, arg1, AT_FDCWD, arg2, 0);
+}
+#endif
+
+SYSCALL_IMPL(linkat)
+{
+return do_linkat(arg1, arg2, arg3, arg4, arg5);
+}
+
 /*
  * Helpers for do_openat, manipulating /proc/self/foo.
  */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 491e1d7cfb..865129df9e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5383,38 +5383,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_link
-case TARGET_NR_link:
-{
-void * p2;
-p = lock_user_string(arg1);
-p2 = lock_user_string(arg2);
-if (!p || !p2)
-ret = -TARGET_EFAULT;
-else
-ret = get_errno(link(p, p2));
-unlock_user(p2, arg2, 0);
-unlock_user(p, arg1, 0);
-}
-return ret;
-#endif
-#if defined(TARGET_NR_linkat)
-case TARGET_NR_linkat:
-{
-void * p2 = NULL;
-if (!arg2 || !arg4)
-return -TARGET_EFAULT;
-p  = lock_user_string(arg2);
-p2 = lock_user_string(arg4);
-if (!p || !p2)
-ret = -TARGET_EFAULT;
-else
-ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
-unlock_user(p, arg2, 0);
-unlock_user(p2, arg4, 0);
-}
-return ret;
-#endif
 #ifdef TARGET_NR_unlink
 case TARGET_NR_unlink:
 if (!(p = lock_user_string(arg1)))
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 41f8f8d0d0..f3c54cec69 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -461,12 +461,6 @@
 #ifdef TARGET_NR_lgetxattr
 { TARGET_NR_lgetxattr, "lgetxattr" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_link
-{ TARGET_NR_link, "link" , NULL, print_link, NULL },
-#endif
-#ifdef TARGET_NR_linkat
-{ TARGET_NR_linkat, "linkat" , NULL, print_linkat, NULL },
-#endif
 #ifdef TARGET_NR_Linux
 { TARGET_NR_Linux, "Linux" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 23/74] linux-user: Split out execve

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |   1 +
 linux-user/strace.c   |  32 --
 linux-user/syscall-proc.inc.c | 110 ++
 linux-user/syscall.c  |  97 --
 linux-user/strace.list|   3 -
 5 files changed, 111 insertions(+), 132 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 78d3f600eb..58fef48666 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -25,6 +25,7 @@ SYSCALL_DEF(close, ARG_DEC);
 SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG);
 #endif
 SYSCALL_DEF(exit, ARG_DEC);
+SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 9ac0b859da..9d6c765715 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -568,38 +568,6 @@ print_newselect(const struct syscallname *name,
 }
 #endif
 
-static void
-print_execve(const struct syscallname *name,
- abi_long arg1, abi_long arg2, abi_long arg3,
- abi_long arg4, abi_long arg5, abi_long arg6)
-{
-abi_ulong arg_ptr_addr;
-char *s;
-
-if (!(s = lock_user_string(arg1)))
-return;
-gemu_log("%s(\"%s\",{", name->name, s);
-unlock_user(s, arg1, 0);
-
-for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
-abi_ulong *arg_ptr, arg_addr;
-
-arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
-if (!arg_ptr)
-return;
-arg_addr = tswapal(*arg_ptr);
-unlock_user(arg_ptr, arg_ptr_addr, 0);
-if (!arg_addr)
-break;
-if ((s = lock_user_string(arg_addr))) {
-gemu_log("\"%s\",", s);
-unlock_user(s, arg_addr, 0);
-}
-}
-
-gemu_log("NULL})");
-}
-
 /*
  * Variants for the return value output function
  */
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index b7304b7a42..66ad768551 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -269,6 +269,116 @@ SYSCALL_IMPL(clone)
 return do_clone(cpu_env, arg1, arg2, arg3, arg4, arg5);
 }
 
+SYSCALL_IMPL(execve)
+{
+char **argp, **envp;
+int argc, envc;
+abi_ulong gp;
+abi_ulong guest_path = arg1;
+abi_ulong guest_argp = arg2;
+abi_ulong guest_envp = arg3;
+abi_ulong addr;
+char **q, *p;
+int total_size = 0;
+abi_long ret = -TARGET_EFAULT;
+
+argc = 0;
+for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
+if (get_user_ual(addr, gp)) {
+goto execve_nofree;
+}
+if (!addr) {
+break;
+}
+argc++;
+}
+envc = 0;
+for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
+if (get_user_ual(addr, gp)) {
+goto execve_nofree;
+}
+if (!addr) {
+break;
+}
+envc++;
+}
+
+argp = g_new0(char *, argc + 1);
+envp = g_new0(char *, envc + 1);
+
+for (gp = guest_argp, q = argp; gp; gp += sizeof(abi_ulong), q++) {
+char *this_q;
+
+if (get_user_ual(addr, gp)) {
+goto execve_free;
+}
+if (!addr) {
+break;
+}
+this_q = lock_user_string(addr);
+if (!this_q) {
+goto execve_free;
+}
+*q = this_q;
+total_size += strlen(this_q) + 1;
+}
+
+for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) {
+char *this_q;
+
+if (get_user_ual(addr, gp)) {
+goto execve_free;
+}
+if (!addr) {
+break;
+}
+this_q = lock_user_string(addr);
+if (!this_q) {
+goto execve_free;
+}
+*q = this_q;
+total_size += strlen(this_q) + 1;
+}
+
+p = lock_user_string(guest_path);
+if (!p) {
+goto execve_free;
+}
+
+/*
+ * Although execve() is not an interruptible syscall it is
+ * a special case where we must use the safe_syscall wrapper:
+ * if we allow a signal to happen before we make the host
+ * syscall then we will 'lose' it, because at the point of
+ * execve the process leaves QEMU's control. So we use the
+ * safe syscall wrapper to ensure that we either take the
+ * signal as a guest signal, or else it does not happen
+ * before the execve completes and makes it the other
+ * program's problem.
+ */
+ret = get_errno(safe_execve(p, argp, envp));
+unlock_user(p, guest_path, 0);
+
+ execve_free:
+for (gp = guest_argp, q = argp; *q; gp += sizeof(abi_ulong), q++) {
+if (get_user_ual(addr, gp) || !addr) {
+break;
+}
+unlock_user(*q, addr, 0);
+}
+for (gp = guest_envp, q = envp; *q; gp += sizeof(abi_ulong), q++) {
+if (get_user_ual(addr, gp) || !addr) {
+break;
+}
+

[Qemu-devel] [PATCH v7 24/74] linux-user: Implement execveat

2019-05-19 Thread Richard Henderson
A trivial extension to our current execve implementation
to support the new(ish) syscall.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  1 +
 linux-user/syscall-proc.inc.c | 19 ++-
 linux-user/syscall.c  |  3 ++-
 linux-user/strace.list|  3 ---
 4 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 58fef48666..392bd1579c 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -26,6 +26,7 @@ SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG);
 #endif
 SYSCALL_DEF(exit, ARG_DEC);
 SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR);
+SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 66ad768551..fd114d1f03 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -269,14 +269,13 @@ SYSCALL_IMPL(clone)
 return do_clone(cpu_env, arg1, arg2, arg3, arg4, arg5);
 }
 
-SYSCALL_IMPL(execve)
+static abi_long do_execveat(int dirfd, abi_ulong guest_path,
+abi_ulong guest_argp, abi_ulong guest_envp,
+int flags)
 {
 char **argp, **envp;
 int argc, envc;
 abi_ulong gp;
-abi_ulong guest_path = arg1;
-abi_ulong guest_argp = arg2;
-abi_ulong guest_envp = arg3;
 abi_ulong addr;
 char **q, *p;
 int total_size = 0;
@@ -356,7 +355,7 @@ SYSCALL_IMPL(execve)
  * before the execve completes and makes it the other
  * program's problem.
  */
-ret = get_errno(safe_execve(p, argp, envp));
+ret = get_errno(safe_execveat(dirfd, p, argp, envp, flags));
 unlock_user(p, guest_path, 0);
 
  execve_free:
@@ -379,6 +378,16 @@ SYSCALL_IMPL(execve)
 return ret;
 }
 
+SYSCALL_IMPL(execve)
+{
+return do_execveat(AT_FDCWD, arg1, arg2, arg3, 0);
+}
+
+SYSCALL_IMPL(execveat)
+{
+return do_execveat(arg1, arg2, arg3, arg4, arg5);
+}
+
 SYSCALL_IMPL(exit)
 {
 CPUState *cpu = ENV_GET_CPU(cpu_env);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a00df1162f..affcd81273 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -672,7 +672,8 @@ safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, 
options, \
   struct rusage *, rusage)
 safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
   int, options, struct rusage *, rusage)
-safe_syscall3(int, execve, const char *, filename, char **, argv, char **, 
envp)
+safe_syscall5(int, execveat, int, dirfd, const char *, filename,
+  char **, argv, char **, envp, int, flags)
 safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, 
\
   fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
 safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 39e5c5b1aa..c6bb475728 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -139,9 +139,6 @@
 #ifdef TARGET_NR_execv
 { TARGET_NR_execv, "execv" , NULL, print_execv, NULL },
 #endif
-#ifdef TARGET_NR_execveat
-{ TARGET_NR_execveat, "execveat" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_exec_with_loader
 { TARGET_NR_exec_with_loader, "exec_with_loader" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v7 28/74] linux-user: Split out chmod, fchmod, fchmodat

2019-05-19 Thread Richard Henderson
Note that fchmodat is universally provided.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  5 +
 linux-user/strace.c   | 28 
 linux-user/syscall-file.inc.c | 30 ++
 linux-user/syscall.c  | 18 --
 linux-user/strace.list|  9 -
 5 files changed, 35 insertions(+), 55 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index b5951e6911..3ddf8aa0e3 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -20,6 +20,9 @@ SYSCALL_DEF_FULL(brk, .impl = impl_brk,
  .print_ret = print_syscall_ptr_ret,
  .arg_type = { ARG_PTR });
 SYSCALL_DEF(chdir, ARG_STR);
+#ifdef TARGET_NR_chmod
+SYSCALL_DEF(chmod, ARG_STR, ARG_MODEFLAG);
+#endif
 SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(close, ARG_DEC);
 #ifdef TARGET_NR_creat
@@ -28,6 +31,8 @@ SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG);
 SYSCALL_DEF(exit, ARG_DEC);
 SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
+SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG);
+SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index c70c06d965..4771badeb5 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1125,19 +1125,6 @@ print_chroot(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_chmod
-static void
-print_chmod(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_file_mode(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_clock_adjtime
 static void
 print_clock_adjtime(const struct syscallname *name,
@@ -1179,21 +1166,6 @@ print_faccessat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_fchmodat
-static void
-print_fchmodat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_at_dirfd(arg0, 0);
-print_string(arg1, 0);
-print_file_mode(arg2, 0);
-print_flags(at_file_flags, arg3, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_fchownat
 static void
 print_fchownat(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 3adb629124..fb64d5bd1d 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -30,6 +30,26 @@ SYSCALL_IMPL(chdir)
 return ret;
 }
 
+static abi_long do_fchmodat(int dirfd, abi_ulong target_path, mode_t mode)
+{
+char *p = lock_user_string(target_path);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(fchmodat(dirfd, p, mode, 0));
+unlock_user(p, target_path, 0);
+return ret;
+}
+
+#ifdef TARGET_NR_chmod
+SYSCALL_IMPL(chmod)
+{
+return do_fchmodat(AT_FDCWD, arg1, arg2);
+}
+#endif
+
 SYSCALL_IMPL(close)
 {
 int fd = arg1;
@@ -54,6 +74,16 @@ SYSCALL_IMPL(creat)
 }
 #endif
 
+SYSCALL_IMPL(fchmod)
+{
+return get_errno(fchmod(arg1, arg2));
+}
+
+SYSCALL_IMPL(fchmodat)
+{
+return do_fchmodat(arg1, arg2, arg3);
+}
+
 static abi_long do_linkat(int olddirfd, abi_ulong target_oldpath,
   int newdirfd, abi_ulong target_newpath,
   int flags)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 18163f558c..3c0de73aa4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5384,14 +5384,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_chmod
-case TARGET_NR_chmod:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(chmod(p, arg2));
-unlock_user(p, arg1, 0);
-return ret;
-#endif
 #ifdef TARGET_NR_lseek
 case TARGET_NR_lseek:
 return get_errno(lseek(arg1, arg2, arg3));
@@ -6463,16 +6455,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 #ifdef TARGET_NR_ftruncate
 case TARGET_NR_ftruncate:
 return get_errno(ftruncate(arg1, arg2));
-#endif
-case TARGET_NR_fchmod:
-return get_errno(fchmod(arg1, arg2));
-#if defined(TARGET_NR_fchmodat)
-case TARGET_NR_fchmodat:
-if (!(p = lock_user_string(arg2)))
-return -TARGET_EFAULT;
-ret = get_errno(fchmodat(arg1, p, arg3, 0));
-unlock_user(p, arg2, 0);
-return ret;
 #endif
 case TARGET_NR_getpriority:
 /* Note that negative values are valid for getpriority, so we must
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 

[Qemu-devel] [PATCH v7 19/74] linux-user: Implement rusage argument to waitid

2019-05-19 Thread Richard Henderson
The kernel interface, which we are supposed to be implementing,
takes a fifth argument: an rusage pointer akin to wait4.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  2 +-
 linux-user/syscall-proc.inc.c | 27 +++
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index a84050a318..f099d98fa3 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -119,7 +119,7 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 SYSCALL_DEF_FULL(vfork, .impl = impl_fork);
 #endif
 SYSCALL_DEF(wait4, ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR);
-SYSCALL_DEF(waitid, ARG_HEX, ARG_DEC, ARG_PTR, ARG_HEX);
+SYSCALL_DEF(waitid, ARG_HEX, ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR);
 #ifdef TARGET_NR_waitpid
 SYSCALL_DEF(waitpid, ARG_DEC, ARG_PTR, ARG_HEX);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
index 7c647f36d7..b7304b7a42 100644
--- a/linux-user/syscall-proc.inc.c
+++ b/linux-user/syscall-proc.inc.c
@@ -370,19 +370,30 @@ SYSCALL_IMPL(waitid)
 id_t id = arg2;
 abi_ulong target_info = arg3;
 int options = arg4;
+abi_ulong target_rusage = arg5;
 siginfo_t info, *info_ptr = target_info ?  : NULL;
+struct rusage rusage;
+struct rusage *rusage_ptr = target_rusage ?  : NULL;
 abi_long ret;
 
 info.si_pid = 0;
-ret = get_errno(safe_waitid(idtype, id, info_ptr, options, NULL));
-if (!is_error(ret) && target_info && info.si_pid != 0) {
-target_siginfo_t *p = lock_user(VERIFY_WRITE, target_info,
-sizeof(target_siginfo_t), 0);
-if (!p) {
-return -TARGET_EFAULT;
+ret = get_errno(safe_waitid(idtype, id, info_ptr, options, rusage_ptr));
+if (!is_error(ret)) {
+if (target_info && info.si_pid != 0) {
+target_siginfo_t *p = lock_user(VERIFY_WRITE, target_info,
+sizeof(target_siginfo_t), 0);
+if (!p) {
+return -TARGET_EFAULT;
+}
+host_to_target_siginfo(p, );
+unlock_user(p, target_info, sizeof(target_siginfo_t));
+}
+if (target_rusage) {
+abi_long err = host_to_target_rusage(target_rusage, );
+if (err) {
+ret = err;
+}
 }
-host_to_target_siginfo(p, );
-unlock_user(p, target_info, sizeof(target_siginfo_t));
 }
 return ret;
 }
-- 
2.17.1




[Qemu-devel] [PATCH v7 20/74] linux-user: Split out creat

2019-05-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall-defs.h |  3 +++
 linux-user/strace.c   | 13 -
 linux-user/syscall-file.inc.c | 16 
 linux-user/syscall.c  |  9 -
 linux-user/strace.list|  3 ---
 5 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index f099d98fa3..de7a99f0c6 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -21,6 +21,9 @@ SYSCALL_DEF_FULL(brk, .impl = impl_brk,
  .arg_type = { ARG_PTR });
 SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
 SYSCALL_DEF(close, ARG_DEC);
+#ifdef TARGET_NR_creat
+SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG);
+#endif
 SYSCALL_DEF(exit, ARG_DEC);
 #ifdef TARGET_NR_fork
 SYSCALL_DEF(fork);
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 842136e425..640a80f32b 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1195,19 +1195,6 @@ print_clock_adjtime(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_creat
-static void
-print_creat(const struct syscallname *name,
-abi_long arg0, abi_long arg1, abi_long arg2,
-abi_long arg3, abi_long arg4, abi_long arg5)
-{
-print_syscall_prologue(name);
-print_string(arg0, 0);
-print_file_mode(arg1, 1);
-print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_execv
 static void
 print_execv(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index dd44d5b804..9b966ad627 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -24,6 +24,22 @@ SYSCALL_IMPL(close)
 return get_errno(close(fd));
 }
 
+#ifdef TARGET_NR_creat
+SYSCALL_IMPL(creat)
+{
+char *p = lock_user_string(arg1);
+abi_long ret;
+
+if (!p) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(creat(p, arg2));
+fd_trans_unregister(ret);
+unlock_user(p, arg1, 0);
+return ret;
+}
+#endif
+
 /*
  * Helpers for do_openat, manipulating /proc/self/foo.
  */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bdb0d45d9a..491e1d7cfb 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5383,15 +5383,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 void *p;
 
 switch(num) {
-#ifdef TARGET_NR_creat /* not on alpha */
-case TARGET_NR_creat:
-if (!(p = lock_user_string(arg1)))
-return -TARGET_EFAULT;
-ret = get_errno(creat(p, arg2));
-fd_trans_unregister(ret);
-unlock_user(p, arg1, 0);
-return ret;
-#endif
 #ifdef TARGET_NR_link
 case TARGET_NR_link:
 {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 759b35458e..41f8f8d0d0 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -94,9 +94,6 @@
 #ifdef TARGET_NR_connect
 { TARGET_NR_connect, "connect" , "%s(%d,%#x,%d)", NULL, NULL },
 #endif
-#ifdef TARGET_NR_creat
-{ TARGET_NR_creat, "creat" , NULL, print_creat, NULL },
-#endif
 #ifdef TARGET_NR_create_module
 { TARGET_NR_create_module, "create_module" , NULL, NULL, NULL },
 #endif
-- 
2.17.1




  1   2   >