Re: QEMU's FreeBSD 13 CI job is failing

2022-09-21 Thread Daniel P . Berrangé
On Tue, Sep 20, 2022 at 02:21:46PM -0600, Warner Losh wrote:
> On Tue, Sep 20, 2022 at 2:57 AM Daniel P. Berrangé 
> wrote:
> 
> > On Tue, Sep 20, 2022 at 10:23:56AM +0200, Thomas Huth wrote:
> > > On 20/09/2022 10.21, Daniel P. Berrangé wrote:
> > > > On Tue, Sep 20, 2022 at 08:44:27AM +0200, Thomas Huth wrote:
> > > > >
> > > > > Seen here for example:
> > > > >
> > > > > https://gitlab.com/qemu-project/qemu/-/jobs/3050165356#L2543
> > > > >
> > > > > ld-elf.so.1: /lib/libc.so.7: version FBSD_1.7 required by
> > > > > /usr/local/lib/libpython3.9.so.1.0 not found
> > > > > ERROR: Cannot use '/usr/local/bin/python3', Python >= 3.6 is
> > required.
> > > > >
> > > > > ... looks like the Python binary is not working anymore? Does
> > anybody know
> > > > > what happened here?
> > > >
> > > > FreeBSD ports is only guaranteed to work with latest minor release
> > > > base image. The python binary recently started relying on symbols
> > > > in the 13.1 base image, and we're using 13.0.
> > > >
> > > > I updated lcitool last week to pick 13.1, so we just need a refresh
> > > > on the QEMU side to pick this up.
> > >
> > > OK ... Alex, IIRC you have a patch queued to update the files that are
> > > refreshed by lcitool ... does that already contain the update for
> > FreeBSD,
> > > too?
> >
> > Oh actually, I'm forgetting that QEMU doesn't use the 'lcitool manifest'
> > command for auto-generating the gitlab-ci.yml file. In QEMU's case just
> > manually edit .gitlab-ci.d/cirrus.yml to change
> >
> > CIRRUS_VM_IMAGE_NAME: freebsd-13-0
> >
> 
> FreeBSD's support policy is that we EOL minor dot releases a few months
> after
> the next minor release is final. Part of that process involves moving the
> build
> of packages to that new minor version (which is what's not guaranteed to
> work
> on older versions... only old binaries on new versions is guaranteed)...
> And that's
> the problem that was hit here.

It would be nice if something in the ports tool / packages was
able to report the incompatibility at time of install, rather
than leaving a later runtime failed.

> I'll try to submit changes after the next minor release in that 'few month'
> window
> to update this in the future. In general, doing so would be the best fit
> with FreeBSD's
> support model...  It's one of those things I didn't think of at the time,
> but is obvious in
> hindsight.

Note, we're reliant on Cirrus CI actually publishing the new images
for use. I've not previously checked before how quickly they publish
them after FreeBSD does the upstream release, but anyway I go by what
they list here:

  https://cirrus-ci.org/guide/FreeBSD/

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Claudio Fontana
On 9/20/22 18:50, Kevin Wolf wrote:
> Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
>> On 9/8/22 19:10, Claudio Fontana wrote:
>>> On 9/8/22 18:03, Richard Henderson wrote:
 On 9/8/22 15:53, Claudio Fontana wrote:
> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> *options, int flags,
>   return -EINVAL;
>   }
>   
> -block_module_load_one("dmg-bz2");
> -block_module_load_one("dmg-lzfse");
> +if (!block_module_load_one("dmg-bz2", &local_err) && local_err) {
> +error_report_err(local_err);
> +}
> +local_err = NULL;
> +if (!block_module_load_one("dmg-lzfse", &local_err) && local_err) {
> +error_report_err(local_err);
> +}
>   
>   s->n_chunks = 0;
>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;

 I wonder if these shouldn't fail hard if the modules don't exist?
 Or at least pass back the error.

 Kevin?
>>
>> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
>> image is not compressed, "dmg" can function even if the extra dmg-bz
>> module is not loaded right?
> 
> Indeed. The code seems to consider that the modules may not be present.
> The behaviour in these cases is questionable (it seems to silently leave
> the buffers as they are and return success), but the modules are clearly
> optional.
> 
>> I'd suspect we should then do:
>>
>> if (!block_module_load_one("dmg-bz2", &local_err)) {
>>   if (local_err) {
>>  error_report_err(local_err);
>>  return -EINVAL;
>>   }
>>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks */
>> }
>>
>> and same for dmg-lzfse...?
> 
> Actually, I think during initialisation, we should just pass NULL as
> errp and ignore any errors.

Hmm really? I'd think that if there is an actual error loading the module 
(module is installed, but the loading itself fails due to broken module, wrong 
permissions, I/O errors etc)
we would want to report that fact as it happens?

> 
> When a request would access a block that can't be uncompressed because
> of the missing module, that's where we can have a warn_report_once() and
> arguably should fail the I/O request.
> 
> Kevin
> 

That would mean, moving the

warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks")

to the uncompression code and change it to a warn_report_once() right?

Thanks,

Claudio



Re: [PATCH] ratelimit: restrict the delay time to a non-negative value

2022-09-21 Thread Alberto Garcia
On Wed 21 Sep 2022 09:47:32 AM +08, Wang Liang wrote:
>> > -return limit->slice_end_time - now;
>> > +return MAX(limit->slice_end_time - now, 0);
>> 
>> How can this be negative? slice_end_time is guaranteed to be larger
>> than
>> now:
>> 
>> if (limit->slice_end_time < now) {
>> /* Previous, possibly extended, time slice finished; reset
>> the
>>  * accounting. */
>> limit->slice_start_time = now;
>> limit->slice_end_time = now + limit->slice_ns;
>> limit->dispatched = 0;
>> }
>> 
> This is just a guarantee. 
>
> If slice_end_time is assigned later by
> limit->slice_end_time = limit->slice_start_time +
> (uint64_t)(delay_slices * limit->slice_ns);

Ok, on a closer look, if at the start of the function

   limit->slice_start_time < now, and
   limit->slice_end_time >= now

it seems that in principle what you say can happen.

If it's so, it would be good to know under what conditions this happens,
because this hasn't changed in years.

Berto



Re: [PATCH v4 1/2] x86: return modified setup_data only if read as memory, not as file

2022-09-21 Thread Paolo Bonzini
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index 050eedc0c8..933bbdd836 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -764,6 +764,18 @@ static bool load_elfboot(const char *kernel_filename,
>  return true;
>  }
>
> +struct setup_data_fixup {
> +void *pos;
> +hwaddr val;
> +uint32_t addr;
> +};

Just a small comment, addr should be little-endian (see
fw_cfg_add_i32).  It's not used outside x86_load_linux, so it is
possible to just use cpu_to_le32 there.

Also I think it's cleaner if a reset callback puts the value back to
zero. fw_cfg already has fw_cfg_machine_reset, so perhaps the easiest
way is to add a FWCfgCallback reset_cb argument to just
fw_cfg_add_bytes_callback. If I am missing something and it's not
necessary I can do the cpu_to_le32 change myself or wait for you; in
any case I'll wait for either your ack or a v5.

By the way, does this supersede v1..v3 that use the new protocol (I'd
guess so from the presence of the same 2/2 patch), or are the two
patches doing belts-and-suspenders?

Thanks,

Paolo

> +static void fixup_setup_data(void *opaque)
> +{
> +struct setup_data_fixup *fixup = opaque;
> +stq_p(fixup->pos, fixup->val);
> +}
> +
>  void x86_load_linux(X86MachineState *x86ms,
>  FWCfgState *fw_cfg,
>  int acpi_data_size,
> @@ -1088,8 +1100,11 @@ void x86_load_linux(X86MachineState *x86ms,
>  qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
>  }
>
> -/* Offset 0x250 is a pointer to the first setup_data link. */
> -stq_p(header + 0x250, first_setup_data);
> +fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
> +fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
> +fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
> +sev_load_ctx.kernel_data = (char *)kernel;
> +sev_load_ctx.kernel_size = kernel_size;
>
>  /*
>   * If we're starting an encrypted VM, it will be OVMF based, which uses 
> the
> @@ -1099,16 +1114,18 @@ void x86_load_linux(X86MachineState *x86ms,
>   * file the user passed in.
>   */
>  if (!sev_enabled()) {
> +struct setup_data_fixup *fixup = g_malloc(sizeof(*fixup));
> +
>  memcpy(setup, header, MIN(sizeof(header), setup_size));
> +/* Offset 0x250 is a pointer to the first setup_data link. */
> +fixup->pos = setup + 0x250;
> +fixup->val = first_setup_data;
> +fixup->addr = real_addr;
> +fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_SETUP_ADDR, 
> fixup_setup_data, NULL,
> +  fixup, &fixup->addr, sizeof(fixup->addr), 
> true);
> +} else {
> +fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
>  }
> -
> -fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
> -fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
> -fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
> -sev_load_ctx.kernel_data = (char *)kernel;
> -sev_load_ctx.kernel_size = kernel_size;
> -
> -fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
>  fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
>  fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
>  sev_load_ctx.setup_data = (char *)setup;
> diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
> index d605f3f45a..564bda3395 100644
> --- a/hw/nvram/fw_cfg.c
> +++ b/hw/nvram/fw_cfg.c
> @@ -692,12 +692,12 @@ static const VMStateDescription vmstate_fw_cfg = {
>  }
>  };
>
> -static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
> -  FWCfgCallback select_cb,
> -  FWCfgWriteCallback write_cb,
> -  void *callback_opaque,
> -  void *data, size_t len,
> -  bool read_only)
> +void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
> +   FWCfgCallback select_cb,
> +   FWCfgWriteCallback write_cb,
> +   void *callback_opaque,
> +   void *data, size_t len,
> +   bool read_only)
>  {
>  int arch = !!(key & FW_CFG_ARCH_LOCAL);
>
> diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
> index 0e7a8bc7af..e4fef393be 100644
> --- a/include/hw/nvram/fw_cfg.h
> +++ b/include/hw/nvram/fw_cfg.h
> @@ -117,6 +117,28 @@ struct FWCfgMemState {
>   */
>  void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
>
> +/**
> + * fw_cfg_add_bytes_callback:
> + * @s: fw_cfg device being modified
> + * @key: selector key value for new fw_cfg item
> + * @select_cb: callback function when selecting
> + * @write_cb: callback function after a write
> + * @callback_opaque: argument to be passed into callback function
> + * @data: pointer to start of item data
> + * @len: size of it

Re: [PATCH v4 1/2] x86: return modified setup_data only if read as memory, not as file

2022-09-21 Thread Jason A. Donenfeld
Hi Paolo,

On Wed, Sep 21, 2022 at 10:59 AM Paolo Bonzini  wrote:
> Just a small comment, addr should be little-endian (see
> fw_cfg_add_i32).  It's not used outside x86_load_linux, so it is
> possible to just use cpu_to_le32 there.

Oh, shucks: I thought about this and then forgot to do it. Thanks for
catching it.

> Also I think it's cleaner if a reset callback puts the value back to
> zero. fw_cfg already has fw_cfg_machine_reset, so perhaps the easiest
> way is to add a FWCfgCallback reset_cb argument to just
> fw_cfg_add_bytes_callback. If I am missing something and it's not
> necessary I can do the cpu_to_le32 change myself or wait for you; in
> any case I'll wait for either your ack or a v5.

Actually, the idea is for the change to be permanent, since that
represents how the system has actually been booted. Are there
substantial changes possible to the firmware configuration on
fw_cfg_machine_reset() that setting this back how it was would make a
difference? Or do we benefit from having some consistency?

> By the way, does this supersede v1..v3 that use the new protocol (I'd
> guess so from the presence of the same 2/2 patch), or are the two
> patches doing belts-and-suspenders?

This v4 supersedes everything else.

Jason



Re: [PATCH v9 3/7] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls

2022-09-21 Thread Klaus Jensen
On Sep 21 13:44, Damien Le Moal wrote:
> On 9/20/22 17:51, Klaus Jensen wrote:
> > On Sep 10 13:27, Sam Li wrote:
> > > Add a new zoned_host_device BlockDriver. The zoned_host_device option
> > > accepts only zoned host block devices. By adding zone management
> > > operations in this new BlockDriver, users can use the new block
> > > layer APIs including Report Zone and four zone management operations
> > > (open, close, finish, reset).
> > > 
> > > Qemu-io uses the new APIs to perform zoned storage commands of the device:
> > > zone_report(zrp), zone_open(zo), zone_close(zc), zone_reset(zrs),
> > > zone_finish(zf).
> > > 
> > > For example, to test zone_report, use following command:
> > > $ ./build/qemu-io --image-opts -n driver=zoned_host_device, 
> > > filename=/dev/nullb0
> > > -c "zrp offset nr_zones"
> > > 
> > > Signed-off-by: Sam Li 
> > > Reviewed-by: Hannes Reinecke 
> > > ---
> > >   block/block-backend.c | 145 ++
> > >   block/file-posix.c| 323 +-
> > >   block/io.c|  41 
> > >   include/block/block-io.h  |   7 +
> > >   include/block/block_int-common.h  |  21 ++
> > >   include/block/raw-aio.h   |   6 +-
> > >   include/sysemu/block-backend-io.h |  17 ++
> > >   meson.build   |   1 +
> > >   qapi/block-core.json  |   8 +-
> > >   qemu-io-cmds.c| 143 +
> > >   10 files changed, 708 insertions(+), 4 deletions(-)
> > > 
> > > +/*
> > > + * zone management operations - Execute an operation on a zone
> > > + */
> > > +static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, 
> > > BlockZoneOp op,
> > > +int64_t offset, int64_t len) {
> > > +#if defined(CONFIG_BLKZONED)
> > > +BDRVRawState *s = bs->opaque;
> > > +RawPosixAIOData acb;
> > > +int64_t zone_sector, zone_sector_mask;
> > > +const char *zone_op_name;
> > > +unsigned long zone_op;
> > > +bool is_all = false;
> > > +
> > > +zone_sector = bs->bl.zone_sectors;
> > > +zone_sector_mask = zone_sector - 1;
> > > +if (offset & zone_sector_mask) {
> > > +error_report("sector offset %" PRId64 " is not aligned to zone 
> > > size "
> > > + "%" PRId64 "", offset, zone_sector);
> > > +return -EINVAL;
> > > +}
> > > +
> > > +if (len & zone_sector_mask) {
> > > +error_report("number of sectors %" PRId64 " is not aligned to 
> > > zone size"
> > > +  " %" PRId64 "", len, zone_sector);
> > > +return -EINVAL;
> > > +}
> > 
> > These checks impose a power-of-two constraint on the zone size. Can they
> > be changed to divisions to lift that constraint? I don't see anything in
> > this patch set that relies on power of two zone sizes.
> 
> Given that Linux will only expose zoned devices that have a zone size that
> is a power of 2 number of LBAs, this will work as is and avoid divisions in
> the IO path. But given that zone management operations are not performance
> critical, generalizing the code should be fine.
> 

Aight. That's fine, we can relax the constraint later. But I don't see why.

> However, once we start adding the code for full zone emulation on top of a
> regular file or qcow image, sector-to-zone conversions requiring divisions
> will hurt. So I really would prefer the code be left as-is for now.
> 

Block driver based zone emulation would not hit the above code path
anyway (there would be no iotcl to call), so I don't think that is an
argument for keeping it as-is.

On the sector-to-zone convertions. Yes, they may potentially hurt, but
it would be emulation after all. Why would we care about optimizing
those conversions at the expense of not being able to emulate all valid
geometries? The performance option (which this series enables) is to use
an underlying zoned device through virtio (or, potentially, hw/nvme).
What would be the usecase for deploying a performance sensitive emulated
zoned device?


signature.asc
Description: PGP signature


Re: [PATCH v4 1/2] x86: return modified setup_data only if read as memory, not as file

2022-09-21 Thread Jason A. Donenfeld
On Wed, Sep 21, 2022 at 11:04:17AM +0200, Jason A. Donenfeld wrote:
> > Also I think it's cleaner if a reset callback puts the value back to
> > zero. fw_cfg already has fw_cfg_machine_reset, so perhaps the easiest
> > way is to add a FWCfgCallback reset_cb argument to just
> > fw_cfg_add_bytes_callback. If I am missing something and it's not
> > necessary I can do the cpu_to_le32 change myself or wait for you; in
> > any case I'll wait for either your ack or a v5.
> 
> Actually, the idea is for the change to be permanent, since that
> represents how the system has actually been booted. Are there
> substantial changes possible to the firmware configuration on
> fw_cfg_machine_reset() that setting this back how it was would make a
> difference? Or do we benefit from having some consistency?

Looking at this more, I think your suggestion makes sense. I also have a
very straight forward way of implementing it. I'll send a v5 in a
minute.

Jason




Re: [PATCH v4 1/2] x86: return modified setup_data only if read as memory, not as file

2022-09-21 Thread Michael S. Tsirkin
On Wed, Sep 14, 2022 at 12:41:34AM +0100, Jason A. Donenfeld wrote:
> If setup_data is being read into a specific memory location, then
> generally the setup_data address parameter is read first, so that the
> caller knows where to read it into. In that case, we should return
> setup_data containing the absolute addresses that are hard coded and
> determined a priori. This is the case when kernels are loaded by BIOS,
> for example. In contrast, when setup_data is read as a file, then we
> shouldn't modify setup_data, since the absolute address will be wrong by
> definition. This is the case when OVMF loads the image.
> 
> This allows setup_data to be used like normal, without crashing when EFI
> tries to use it.
> 
> (As a small development note, strangely, fw_cfg_add_file_callback() was
> exported but fw_cfg_add_bytes_callback() wasn't, so this makes that
> consistent.)
> 
> Cc: Gerd Hoffmann 
> Cc: Laurent Vivier 
> Cc: Michael S. Tsirkin 
> Cc: Paolo Bonzini 
> Cc: Peter Maydell 
> Cc: Philippe Mathieu-Daudé 
> Cc: Richard Henderson 
> Suggested-by: Ard Biesheuvel 
> Signed-off-by: Jason A. Donenfeld 
> ---
>  hw/i386/x86.c | 37 +++--
>  hw/nvram/fw_cfg.c | 12 ++--
>  include/hw/nvram/fw_cfg.h | 22 ++
>  3 files changed, 55 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index 050eedc0c8..933bbdd836 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -764,6 +764,18 @@ static bool load_elfboot(const char *kernel_filename,
>  return true;
>  }
>  
> +struct setup_data_fixup {
> +void *pos;
> +hwaddr val;
> +uint32_t addr;
> +};
> +

btw

typedef struct SetupDataFixup {
void *pos;
hwaddr val;
uint32_t addr;
} SetupDataFixup;


and use typedef everywhere.

Yes I know setup_data is like this but that probably should be
fixed too.

> +static void fixup_setup_data(void *opaque)
> +{
> +struct setup_data_fixup *fixup = opaque;
> +stq_p(fixup->pos, fixup->val);
> +}
> +
>  void x86_load_linux(X86MachineState *x86ms,
>  FWCfgState *fw_cfg,
>  int acpi_data_size,
> @@ -1088,8 +1100,11 @@ void x86_load_linux(X86MachineState *x86ms,
>  qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
>  }
>  
> -/* Offset 0x250 is a pointer to the first setup_data link. */
> -stq_p(header + 0x250, first_setup_data);
> +fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
> +fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
> +fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
> +sev_load_ctx.kernel_data = (char *)kernel;
> +sev_load_ctx.kernel_size = kernel_size;
>  
>  /*
>   * If we're starting an encrypted VM, it will be OVMF based, which uses 
> the
> @@ -1099,16 +1114,18 @@ void x86_load_linux(X86MachineState *x86ms,
>   * file the user passed in.
>   */
>  if (!sev_enabled()) {
> +struct setup_data_fixup *fixup = g_malloc(sizeof(*fixup));
> +
>  memcpy(setup, header, MIN(sizeof(header), setup_size));
> +/* Offset 0x250 is a pointer to the first setup_data link. */
> +fixup->pos = setup + 0x250;
> +fixup->val = first_setup_data;
> +fixup->addr = real_addr;
> +fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_SETUP_ADDR, 
> fixup_setup_data, NULL,
> +  fixup, &fixup->addr, sizeof(fixup->addr), 
> true);
> +} else {
> +fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
>  }
> -
> -fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
> -fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
> -fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
> -sev_load_ctx.kernel_data = (char *)kernel;
> -sev_load_ctx.kernel_size = kernel_size;
> -
> -fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
>  fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
>  fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
>  sev_load_ctx.setup_data = (char *)setup;
> diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
> index d605f3f45a..564bda3395 100644
> --- a/hw/nvram/fw_cfg.c
> +++ b/hw/nvram/fw_cfg.c
> @@ -692,12 +692,12 @@ static const VMStateDescription vmstate_fw_cfg = {
>  }
>  };
>  
> -static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
> -  FWCfgCallback select_cb,
> -  FWCfgWriteCallback write_cb,
> -  void *callback_opaque,
> -  void *data, size_t len,
> -  bool read_only)
> +void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
> +   FWCfgCallback select_cb,
> +   FWCfgWriteCallback write_cb

Re: [PATCH v4 1/2] x86: return modified setup_data only if read as memory, not as file

2022-09-21 Thread Jason A. Donenfeld
On Wed, Sep 21, 2022 at 11:15 AM Michael S. Tsirkin  wrote:
>
> On Wed, Sep 14, 2022 at 12:41:34AM +0100, Jason A. Donenfeld wrote:
> > If setup_data is being read into a specific memory location, then
> > generally the setup_data address parameter is read first, so that the
> > caller knows where to read it into. In that case, we should return
> > setup_data containing the absolute addresses that are hard coded and
> > determined a priori. This is the case when kernels are loaded by BIOS,
> > for example. In contrast, when setup_data is read as a file, then we
> > shouldn't modify setup_data, since the absolute address will be wrong by
> > definition. This is the case when OVMF loads the image.
> >
> > This allows setup_data to be used like normal, without crashing when EFI
> > tries to use it.
> >
> > (As a small development note, strangely, fw_cfg_add_file_callback() was
> > exported but fw_cfg_add_bytes_callback() wasn't, so this makes that
> > consistent.)
> >
> > Cc: Gerd Hoffmann 
> > Cc: Laurent Vivier 
> > Cc: Michael S. Tsirkin 
> > Cc: Paolo Bonzini 
> > Cc: Peter Maydell 
> > Cc: Philippe Mathieu-Daudé 
> > Cc: Richard Henderson 
> > Suggested-by: Ard Biesheuvel 
> > Signed-off-by: Jason A. Donenfeld 
> > ---
> >  hw/i386/x86.c | 37 +++--
> >  hw/nvram/fw_cfg.c | 12 ++--
> >  include/hw/nvram/fw_cfg.h | 22 ++
> >  3 files changed, 55 insertions(+), 16 deletions(-)
> >
> > diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> > index 050eedc0c8..933bbdd836 100644
> > --- a/hw/i386/x86.c
> > +++ b/hw/i386/x86.c
> > @@ -764,6 +764,18 @@ static bool load_elfboot(const char *kernel_filename,
> >  return true;
> >  }
> >
> > +struct setup_data_fixup {
> > +void *pos;
> > +hwaddr val;
> > +uint32_t addr;
> > +};
> > +
>
> btw
>
> typedef struct SetupDataFixup {
> void *pos;
> hwaddr val;
> uint32_t addr;
> } SetupDataFixup;
>
>
> and use typedef everywhere.

Okay no problem. Will do for v5.

Jason



[PATCH v5 2/4] x86: use typedef for SetupData struct

2022-09-21 Thread Jason A. Donenfeld
The preferred style is SetupData as a typedef, not setup_data as a plain
struct.

Cc: Paolo Bonzini 
Cc: Ard Biesheuvel 
Suggested-by: Michael S. Tsirkin 
Signed-off-by: Jason A. Donenfeld 
---
 hw/i386/x86.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 96d205927e..1ee0b1b413 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -653,12 +653,12 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state)
 return dev;
 }
 
-struct setup_data {
+typedef struct SetupData {
 uint64_t next;
 uint32_t type;
 uint32_t len;
 uint8_t data[];
-} __attribute__((packed));
+} __attribute__((packed)) SetupData;
 
 
 /*
@@ -799,7 +799,7 @@ void x86_load_linux(X86MachineState *x86ms,
 FILE *f;
 char *vmode;
 MachineState *machine = MACHINE(x86ms);
-struct setup_data *setup_data;
+SetupData *setup_data;
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 const char *dtb_filename = machine->dtb;
@@ -1082,11 +1082,11 @@ void x86_load_linux(X86MachineState *x86ms,
 }
 
 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
-kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size;
+kernel_size = setup_data_offset + sizeof(SetupData) + dtb_size;
 kernel = g_realloc(kernel, kernel_size);
 
 
-setup_data = (struct setup_data *)(kernel + setup_data_offset);
+setup_data = (SetupData *)(kernel + setup_data_offset);
 setup_data->next = cpu_to_le64(first_setup_data);
 first_setup_data = prot_addr + setup_data_offset;
 setup_data->type = cpu_to_le32(SETUP_DTB);
@@ -1097,9 +1097,9 @@ void x86_load_linux(X86MachineState *x86ms,
 
 if (!legacy_no_rng_seed) {
 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
-kernel_size = setup_data_offset + sizeof(struct setup_data) + 
RNG_SEED_LENGTH;
+kernel_size = setup_data_offset + sizeof(SetupData) + RNG_SEED_LENGTH;
 kernel = g_realloc(kernel, kernel_size);
-setup_data = (struct setup_data *)(kernel + setup_data_offset);
+setup_data = (SetupData *)(kernel + setup_data_offset);
 setup_data->next = cpu_to_le64(first_setup_data);
 first_setup_data = prot_addr + setup_data_offset;
 setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
-- 
2.37.3




[PATCH v5 3/4] x86: reinitialize RNG seed on system reboot

2022-09-21 Thread Jason A. Donenfeld
Since this is read from fw_cfg on each boot, the kernel zeroing it out
alone is insufficient to prevent it from being used twice. And indeed on
reboot we always want a new seed, not the old one. So re-fill it in this
circumstance.

Cc: Paolo Bonzini 
Signed-off-by: Jason A. Donenfeld 
---
 hw/i386/x86.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 1ee0b1b413..f9a4ddaa4a 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -783,6 +783,12 @@ static void reset_setup_data(void *opaque)
 stq_p(fixup->pos, fixup->orig_val);
 }
 
+static void reset_rng_seed(void *opaque)
+{
+SetupData *setup_data = opaque;
+qemu_guest_getrandom_nofail(setup_data->data, 
le32_to_cpu(setup_data->len));
+}
+
 void x86_load_linux(X86MachineState *x86ms,
 FWCfgState *fw_cfg,
 int acpi_data_size,
@@ -1105,6 +,7 @@ void x86_load_linux(X86MachineState *x86ms,
 setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
 setup_data->len = cpu_to_le32(RNG_SEED_LENGTH);
 qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
+qemu_register_reset(reset_rng_seed, setup_data);
 }
 
 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
-- 
2.37.3




[PATCH v5 1/4] x86: return modified setup_data only if read as memory, not as file

2022-09-21 Thread Jason A. Donenfeld
If setup_data is being read into a specific memory location, then
generally the setup_data address parameter is read first, so that the
caller knows where to read it into. In that case, we should return
setup_data containing the absolute addresses that are hard coded and
determined a priori. This is the case when kernels are loaded by BIOS,
for example. In contrast, when setup_data is read as a file, then we
shouldn't modify setup_data, since the absolute address will be wrong by
definition. This is the case when OVMF loads the image.

This allows setup_data to be used like normal, without crashing when EFI
tries to use it.

(As a small development note, strangely, fw_cfg_add_file_callback() was
exported but fw_cfg_add_bytes_callback() wasn't, so this makes that
consistent.)

Cc: Gerd Hoffmann 
Cc: Laurent Vivier 
Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Cc: Peter Maydell 
Cc: Philippe Mathieu-Daudé 
Cc: Richard Henderson 
Suggested-by: Ard Biesheuvel 
Reviewed-by: Ard Biesheuvel 
Signed-off-by: Jason A. Donenfeld 
---
 hw/i386/x86.c | 46 ++-
 hw/nvram/fw_cfg.c | 12 +-
 include/hw/nvram/fw_cfg.h | 22 +++
 3 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 050eedc0c8..96d205927e 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -37,6 +37,7 @@
 #include "sysemu/whpx.h"
 #include "sysemu/numa.h"
 #include "sysemu/replay.h"
+#include "sysemu/reset.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/cpu-timers.h"
 #include "sysemu/xen.h"
@@ -764,6 +765,24 @@ static bool load_elfboot(const char *kernel_filename,
 return true;
 }
 
+typedef struct SetupDataFixup {
+void *pos;
+hwaddr orig_val, new_val;
+uint32_t addr;
+} SetupDataFixup;
+
+static void fixup_setup_data(void *opaque)
+{
+SetupDataFixup *fixup = opaque;
+stq_p(fixup->pos, fixup->new_val);
+}
+
+static void reset_setup_data(void *opaque)
+{
+SetupDataFixup *fixup = opaque;
+stq_p(fixup->pos, fixup->orig_val);
+}
+
 void x86_load_linux(X86MachineState *x86ms,
 FWCfgState *fw_cfg,
 int acpi_data_size,
@@ -1088,8 +1107,11 @@ void x86_load_linux(X86MachineState *x86ms,
 qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
 }
 
-/* Offset 0x250 is a pointer to the first setup_data link. */
-stq_p(header + 0x250, first_setup_data);
+fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
+fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
+sev_load_ctx.kernel_data = (char *)kernel;
+sev_load_ctx.kernel_size = kernel_size;
 
 /*
  * If we're starting an encrypted VM, it will be OVMF based, which uses the
@@ -1099,16 +1121,20 @@ void x86_load_linux(X86MachineState *x86ms,
  * file the user passed in.
  */
 if (!sev_enabled()) {
+SetupDataFixup *fixup = g_malloc(sizeof(*fixup));
+
 memcpy(setup, header, MIN(sizeof(header), setup_size));
+/* Offset 0x250 is a pointer to the first setup_data link. */
+fixup->pos = setup + 0x250;
+fixup->orig_val = ldq_p(fixup->pos);
+fixup->new_val = first_setup_data;
+fixup->addr = cpu_to_le32(real_addr);
+fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_SETUP_ADDR, fixup_setup_data, 
NULL,
+  fixup, &fixup->addr, sizeof(fixup->addr), 
true);
+qemu_register_reset(reset_setup_data, fixup);
+} else {
+fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
 }
-
-fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
-fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
-fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
-sev_load_ctx.kernel_data = (char *)kernel;
-sev_load_ctx.kernel_size = kernel_size;
-
-fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
 fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
 fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
 sev_load_ctx.setup_data = (char *)setup;
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index d605f3f45a..564bda3395 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -692,12 +692,12 @@ static const VMStateDescription vmstate_fw_cfg = {
 }
 };
 
-static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
-  FWCfgCallback select_cb,
-  FWCfgWriteCallback write_cb,
-  void *callback_opaque,
-  void *data, size_t len,
-  bool read_only)
+void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
+   FWCfgCallback select_cb,
+   FWCfgWriteCallback write_cb,
+   void *callba

[PATCH v5 4/4] x86: re-enable rng seeding via SetupData

2022-09-21 Thread Jason A. Donenfeld
This reverts 3824e25db1 ("x86: disable rng seeding via setup_data"), but
for 7.2 rather than 7.1, now that modifying setup_data is safe to do.

Cc: Laurent Vivier 
Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Cc: Peter Maydell 
Cc: Philippe Mathieu-Daudé 
Cc: Richard Henderson 
Cc: Ard Biesheuvel 
Acked-by: Gerd Hoffmann 
Signed-off-by: Jason A. Donenfeld 
---
 hw/i386/microvm.c | 2 +-
 hw/i386/pc_piix.c | 3 ++-
 hw/i386/pc_q35.c  | 3 ++-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 52cafa003d..7fe8cce03e 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -332,7 +332,7 @@ static void microvm_memory_init(MicrovmMachineState *mms)
 rom_set_fw(fw_cfg);
 
 if (machine->kernel_filename != NULL) {
-x86_load_linux(x86ms, fw_cfg, 0, true, true);
+x86_load_linux(x86ms, fw_cfg, 0, true, false);
 }
 
 if (mms->option_roms) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 8043a250ad..0b1a79c0fa 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -439,7 +439,6 @@ static void pc_i440fx_7_2_machine_options(MachineClass *m)
 m->alias = "pc";
 m->is_default = true;
 pcmc->default_cpu_version = 1;
-pcmc->legacy_no_rng_seed = true;
 }
 
 DEFINE_I440FX_MACHINE(v7_2, "pc-i440fx-7.2", NULL,
@@ -447,9 +446,11 @@ DEFINE_I440FX_MACHINE(v7_2, "pc-i440fx-7.2", NULL,
 
 static void pc_i440fx_7_1_machine_options(MachineClass *m)
 {
+PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 pc_i440fx_7_2_machine_options(m);
 m->alias = NULL;
 m->is_default = false;
+pcmc->legacy_no_rng_seed = true;
 compat_props_add(m->compat_props, hw_compat_7_1, hw_compat_7_1_len);
 compat_props_add(m->compat_props, pc_compat_7_1, pc_compat_7_1_len);
 }
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 53eda50e81..a496bd6e74 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -376,7 +376,6 @@ static void pc_q35_7_2_machine_options(MachineClass *m)
 pc_q35_machine_options(m);
 m->alias = "q35";
 pcmc->default_cpu_version = 1;
-pcmc->legacy_no_rng_seed = true;
 }
 
 DEFINE_Q35_MACHINE(v7_2, "pc-q35-7.2", NULL,
@@ -384,8 +383,10 @@ DEFINE_Q35_MACHINE(v7_2, "pc-q35-7.2", NULL,
 
 static void pc_q35_7_1_machine_options(MachineClass *m)
 {
+PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 pc_q35_7_2_machine_options(m);
 m->alias = NULL;
+pcmc->legacy_no_rng_seed = true;
 compat_props_add(m->compat_props, hw_compat_7_1, hw_compat_7_1_len);
 compat_props_add(m->compat_props, pc_compat_7_1, pc_compat_7_1_len);
 }
-- 
2.37.3




Re: [PATCH v4 1/2] x86: return modified setup_data only if read as memory, not as file

2022-09-21 Thread Paolo Bonzini
On Wed, Sep 21, 2022 at 11:12 AM Jason A. Donenfeld  wrote:
> > Also I think it's cleaner if a reset callback puts the value back to
> > zero. fw_cfg already has fw_cfg_machine_reset, so perhaps the easiest
> > way is to add a FWCfgCallback reset_cb argument to just
> > fw_cfg_add_bytes_callback. If I am missing something and it's not
> > necessary I can do the cpu_to_le32 change myself or wait for you; in
> > any case I'll wait for either your ack or a v5.
>
> Actually, the idea is for the change to be permanent, since that
> represents how the system has actually been booted. Are there
> substantial changes possible to the firmware configuration on
> fw_cfg_machine_reset() that setting this back how it was would make a
> difference? Or do we benefit from having some consistency?

It's not a very practical thing to happen but I guess you could boot
UEFI twice, but the second time go to a CSM which could use the
setup_data. But really as you say it's just more consistent if reset
brings everything back to the pristine state, unless there's a good
reason to do so (which you agreed in the next message there isn't).

I'll queue v5, thanks!

Paolo




Re: [PATCH 0/9] Deprecate sysbus_get_default() and get_system_memory() et. al

2022-09-21 Thread Peter Maydell
On Tue, 20 Sept 2022 at 23:50, Bernhard Beschow  wrote:
>
> Am 20. September 2022 09:55:37 UTC schrieb Peter Maydell 
> :
> >On Tue, 20 Sept 2022 at 00:18, Bernhard Beschow  wrote:
> >>
> >> In address-spaces.h it can be read that get_system_memory() and
> >> get_system_io() are temporary interfaces which "should only be used 
> >> temporarily
> >> until a proper bus interface is available". This statement certainly 
> >> extends to
> >> the address_space_memory and address_space_io singletons.
> >
> >This is a long standing "we never really completed a cleanup"...
> >
> >> This series attempts
> >> to stop further proliferation of their use by turning TYPE_SYSTEM_BUS into 
> >> an
> >> object-oriented, "proper bus interface" inspired by PCIBus.
> >>
> >> While at it, also the main_system_bus singleton is turned into an 
> >> attribute of
> >> MachineState. Together, this resolves five singletons in total, making the
> >> ownership relations much more obvious which helps comprehension.
> >
> >...but I don't think this is the direction we want to go.
> >Overall the reason that the "system memory" and "system IO"
> >singletons are weird is that in theory they should not be necessary
> >at all -- board code should create devices and map them into an
> >entirely arbitrary MemoryRegion or set of MemoryRegions corresponding
> >to address space(s) for the CPU and for DMA-capable devices.
>
> My intention was to allow exactly that: By turning sytem memory and system IO 
> into non-singletons, one could have many of them, thus allowing boards to 
> create arbitrary mappings of memory and IO. Since QEMU currently assumes one 
> set (memory and IO) of addresses, I for now instantiated the SysBus once in 
> the machine class to preserve behavior.

You can already create arbitrary mappings of memory and IO
(look at the virt board for an example). The existence of the
legacy singleton system-memory and system-io doesn't prevent that,
and stuffing the singletons into the MachineState doesn't do
anything to change the code that is relying on the singletons.

> >Retaining the whole-system singleton but shoving it into MachineState
> >doesn't really change much, IMHO.
> >
> >More generally, sysbus is rather weird because it isn't really a
> >bus. Every device in the system of TYPE_SYS_BUS_DEVICE is "on"
> >the unique TYPE_SYSTEM_BUS bus, but that doesn't mean they're
> >all in the same address space or that in real hardware they'd
> >all be on the same bus.
>
> Again, having multiple SysBuses may solve that issue.

We definitely don't want multiple sysbuses.

thanks
-- PMM



guest Linux Kernel hangs and reports CPU lockup/stuck gitlab bug

2022-09-21 Thread Claudio Fontana
Hi,

I think this bug report warrants some attention,

can Gerd take a look here?

The GTK Clipboard commit seems involved:

https://gitlab.com/qemu-project/qemu/-/issues/1150

Thanks,

Claudio




[PATCH v8 2/2] target/s390x: support PRNO_TRNG instruction

2022-09-21 Thread Jason A. Donenfeld
In order for hosts running inside of TCG to initialize the kernel's
random number generator, we should support the PRNO_TRNG instruction,
backed in the usual way with the qemu_guest_getrandom helper. This is
confirmed working on Linux 5.19.

Cc: Thomas Huth 
Cc: David Hildenbrand 
Cc: Christian Borntraeger 
Cc: Richard Henderson 
Cc: Cornelia Huck 
Cc: Harald Freudenberger 
Cc: Holger Dengler 
Signed-off-by: Jason A. Donenfeld 
---
 target/s390x/gen-features.c  |  1 +
 target/s390x/tcg/crypto_helper.c | 30 ++
 2 files changed, 31 insertions(+)

diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 14a7f2ae90..aaade67574 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -754,6 +754,7 @@ static uint16_t qemu_MAX[] = {
 S390_FEAT_MSA_EXT_5,
 S390_FEAT_KIMD_SHA_512,
 S390_FEAT_KLMD_SHA_512,
+S390_FEAT_PRNO_TRNG,
 };
 
 /** END FEATURE DEFS **/
diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_helper.c
index 02073ec70b..0daa9a2dd9 100644
--- a/target/s390x/tcg/crypto_helper.c
+++ b/target/s390x/tcg/crypto_helper.c
@@ -14,6 +14,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/main-loop.h"
+#include "qemu/guest-random.h"
 #include "s390x-internal.h"
 #include "tcg_s390x.h"
 #include "exec/helper-proto.h"
@@ -173,6 +174,31 @@ static int klmd_sha512(CPUS390XState *env, uintptr_t ra, 
uint64_t parameter_bloc
 return 0;
 }
 
+static void fill_buf_random(CPUS390XState *env, uintptr_t ra,
+uint64_t *buf_reg, uint64_t *len_reg)
+{
+uint8_t tmp[256];
+uint64_t len = *len_reg;
+int buf_reg_len = 64;
+
+if (!(env->psw.mask & PSW_MASK_64)) {
+len = (uint32_t)len;
+buf_reg_len = (env->psw.mask & PSW_MASK_32) ? 32 : 24;
+}
+
+while (len) {
+size_t block = MIN(len, sizeof(tmp));
+
+qemu_guest_getrandom_nofail(tmp, block);
+for (size_t i = 0; i < block; ++i) {
+cpu_stb_data_ra(env, wrap_address(env, *buf_reg), tmp[i], ra);
+*buf_reg = deposit64(*buf_reg, 0, buf_reg_len, *buf_reg + 1);
+--*len_reg;
+}
+len -= block;
+}
+}
+
 uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
  uint32_t type)
 {
@@ -215,6 +241,10 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, 
uint32_t r2, uint32_t r3,
 return klmd_sha512(env, ra, env->regs[1], &env->regs[r2], 
&env->regs[r2 + 1]);
 }
 break;
+case 114: /* CPACF_PRNO_TRNG */
+fill_buf_random(env, ra, &env->regs[r1], &env->regs[r1 + 1]);
+fill_buf_random(env, ra, &env->regs[r2], &env->regs[r2 + 1]);
+break;
 default:
 /* we don't implement any other subfunction yet */
 g_assert_not_reached();
-- 
2.37.3




[PATCH v8 1/2] target/s390x: support SHA-512 extensions

2022-09-21 Thread Jason A. Donenfeld
In order to fully support MSA_EXT_5, we have to support the SHA-512
special instructions. So implement those.

The implementation began as something TweetNacl-like, and then was
adjusted to be useful here. It's not very beautiful, but it is quite
short and compact, which is what we're going for.

Cc: Thomas Huth 
Cc: David Hildenbrand 
Cc: Christian Borntraeger 
Cc: Richard Henderson 
Cc: Cornelia Huck 
Cc: Harald Freudenberger 
Cc: Holger Dengler 
Signed-off-by: Jason A. Donenfeld 
---
 target/s390x/gen-features.c  |   3 +
 target/s390x/tcg/crypto_helper.c | 163 +++
 2 files changed, 166 insertions(+)

diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 1558c52626..14a7f2ae90 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -751,6 +751,9 @@ static uint16_t qemu_V7_0[] = {
  */
 static uint16_t qemu_MAX[] = {
 S390_FEAT_VECTOR_ENH2,
+S390_FEAT_MSA_EXT_5,
+S390_FEAT_KIMD_SHA_512,
+S390_FEAT_KLMD_SHA_512,
 };
 
 /** END FEATURE DEFS **/
diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_helper.c
index 138d9e7ad9..02073ec70b 100644
--- a/target/s390x/tcg/crypto_helper.c
+++ b/target/s390x/tcg/crypto_helper.c
@@ -1,10 +1,12 @@
 /*
  *  s390x crypto helpers
  *
+ *  Copyright (C) 2022 Jason A. Donenfeld . All Rights 
Reserved.
  *  Copyright (c) 2017 Red Hat Inc
  *
  *  Authors:
  *   David Hildenbrand 
+ *   Jason A. Donenfeld 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -18,6 +20,159 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
+static uint64_t R(uint64_t x, int c) { return (x >> c) | (x << (64 - c)); }
+static uint64_t Ch(uint64_t x, uint64_t y, uint64_t z) { return (x & y) ^ (~x 
& z); }
+static uint64_t Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) ^ (x 
& z) ^ (y & z); }
+static uint64_t Sigma0(uint64_t x) { return R(x, 28) ^ R(x, 34) ^ R(x, 39); }
+static uint64_t Sigma1(uint64_t x) { return R(x, 14) ^ R(x, 18) ^ R(x, 41); }
+static uint64_t sigma0(uint64_t x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
+static uint64_t sigma1(uint64_t x) { return R(x, 19) ^ R(x, 61) ^ (x >> 6); }
+
+static const uint64_t K[80] = {
+0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+static int kimd_sha512(CPUS390XState *env, uintptr_t ra, uint64_t 
parameter_block,
+   uint64_t *message_reg, uint64_t *len_reg, uint8_t 
*stack_buffer)
+{
+enum { MAX_BLOCKS_PER_RUN = 64 }; /* This is arbitrary, just to keep 
interactivity. */
+uint64_t z[8], b[8], a[8], w[16], t;
+uint64_t message = message_reg ? *message_reg : 0;
+uint64_t len = *len_reg, processed = 0, addr;
+int i, j, message_reg_len = 64, blocks = 0, cc = 0;
+
+if (!(env->psw.mask & PSW_MASK_64)) {
+len = (uint32_t)len;
+message_reg_len = (env->psw.mask & PSW_MASK_32) ? 32 : 24;
+}
+
+for (i = 0; i < 8; ++i) {
+addr = wrap_address(env, parameter_block + 8 * 

Re: [PATCH v2 2/7] multifd: modifying 'migrate' qmp command to add multifd socket on particular src and dest pair

2022-09-21 Thread Het Gala


On 29/08/22 10:04 am, Het Gala wrote:



On 08/08/22 11:41 am, Het Gala wrote:



On 02/08/22 1:23 pm, Markus Armbruster wrote:

Het Gala  writes:


On 26/07/22 4:43 pm, Daniel P. Berrangé wrote:

On Thu, Jul 21, 2022 at 07:56:15PM +, Het Gala wrote:

i) Modified the format of the qemu monitor command : 'migrate' by adding a list,
 each element in the list consisting of multifd connection parameters: 
source
 uri, destination uri and of the number of multifd channels between each 
pair.

ii) Information of all multifd connection parameters' list and length of the
  list is stored in 'OutgoingMigrateParams' struct.

Suggested-by: Manish Mishra
Signed-off-by: Het Gala
---
   migration/migration.c | 52 +
   migration/socket.c| 60 ---
   migration/socket.h| 19 +-
   monitor/hmp-cmds.c|  1 +
   qapi/migration.json   | 47 +
   5 files changed, 160 insertions(+), 19 deletions(-)

diff --git a/qapi/migration.json b/qapi/migration.json
index 81185d4311..456247af8f 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1449,12 +1449,37 @@
   ##
   { 'command': 'migrate-continue', 'data': {'state': 'MigrationStatus'} }
   +##
+# @MigrateUriParameter:
+#
+# Information regarding which source interface is connected to which
+# destination interface and number of multifd channels over each interface.
+#
+# @source-uri: uri of the source VM. Default port number is 0.
+#
+# @destination-uri: uri of the destination VM
+#
+# @multifd-channels: number of parallel multifd channels used to migrate data
+#for specific source-uri and destination-uri. Default value
+#in this case is 2 (Since 7.1)
+#
+##
+{ 'struct' : 'MigrateUriParameter',
+  'data' : { 'source-uri' : 'str',
+ 'destination-uri' : 'str',
+ '*multifd-channels' : 'uint8'} }
+
   ##
   # @migrate:
   #
   # Migrates the current running guest to another Virtual Machine.
   #
   # @uri: the Uniform Resource Identifier of the destination VM
+#   for migration thread
+#
+# @multi-fd-uri-list: list of pair of source and destination VM Uniform
+# Resource Identifiers with number of multifd-channels
+# for each pair
   #
   # @blk: do block migration (full disk copy)
   #
@@ -1474,20 +1499,32 @@
   # 1. The 'query-migrate' command should be used to check migration's progress
   #and final result (this information is provided by the 'status' member)
   #
-# 2. All boolean arguments default to false
+# 2. The uri argument should have the Uniform Resource Identifier of default
+#destination VM. This connection will be bound to default network
   #
-# 3. The user Monitor's "detach" argument is invalid in QMP and should not
+# 3. All boolean arguments default to false
+#
+# 4. The user Monitor's "detach" argument is invalid in QMP and should not
   #be used
   #
   # Example:
   #
-# -> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } }
+# -> { "execute": "migrate",
+#  "arguments": {
+#  "uri": "tcp:0:4446",
+#  "multi-fd-uri-list": [ { "source-uri": "tcp::6900",
+#   "destination-uri": "tcp:0:4480",
+#   "multifd-channels": 4},
+# { "source-uri": "tcp:10.0.0.0: ",
+#   "destination-uri": "tcp:11.0.0.0:7789",
+#   "multifd-channels": 5} ] } }
   # <- { "return": {} }
   #
   ##
   { 'command': 'migrate',
-  'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool',
-   '*detach': 'bool', '*resume': 'bool' } }
+  'data': {'uri': 'str', '*multi-fd-uri-list': ['MigrateUriParameter'],
+   '*blk': 'bool', '*inc': 'bool', '*detach': 'bool',
+   '*resume': 'bool' } }

Considering the existing migrate API from a QAPI design POV, I
think there are several significant flaws with it

The use of URIs is the big red flag. It is basically a data encoding
scheme within a data encoding scheme.  QEMU code should be able to
directly work with the results from QAPI, without having todo a
second level of parsing.

Concur.


URIs made sense in the context of HMP or the QemuOpts CLI, but do not
make sense in QMP. We made a mistake in this respect when we first
introduced QMP and implemented 'migrate'.

If we going to extend the migrate API I think we should stop using URIs
for the new fields, and instead define a QAPI discriminated union for
the different data transport backends we offer.

   { 'enum': 'MigrateTransport',
 'data': ['socket', 'exec'] }

   { 'union': 'MigrateAddress',
 'base': { 'transport': 'MigrateTransport'},
 'discriminator': 'transport',
 'data': {
 'socket': 'SocketAddress',
   'exec': ['str'],
 }

NB, 'socket' should be able to c

Re: [PATCH RESEND] hw/microblaze: pass random seed to fdt

2022-09-21 Thread Jason A. Donenfeld
On Thu, Sep 8, 2022 at 11:40 AM Jason A. Donenfeld  wrote:
>
> If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to
> initialize early. Set this using the usual guest random number
> generation function. This FDT node is part of the DT specification.
>
> Reviewed-by: Edgar E. Iglesias 
> Signed-off-by: Jason A. Donenfeld 
> ---
>  hw/microblaze/boot.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
> index 8b92a9801a..25ad54754e 100644
> --- a/hw/microblaze/boot.c
> +++ b/hw/microblaze/boot.c
> @@ -30,6 +30,7 @@
>  #include "qemu/option.h"
>  #include "qemu/config-file.h"
>  #include "qemu/error-report.h"
> +#include "qemu/guest-random.h"
>  #include "sysemu/device_tree.h"
>  #include "sysemu/reset.h"
>  #include "hw/boards.h"
> @@ -75,6 +76,7 @@ static int microblaze_load_dtb(hwaddr addr,
>  int fdt_size;
>  void *fdt = NULL;
>  int r;
> +uint8_t rng_seed[32];
>
>  if (dtb_filename) {
>  fdt = load_device_tree(dtb_filename, &fdt_size);
> @@ -83,6 +85,9 @@ static int microblaze_load_dtb(hwaddr addr,
>  return 0;
>  }
>
> +qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
> +qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
> +
>  if (kernel_cmdline) {
>  r = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
>  kernel_cmdline);
> --
> 2.37.3
>

Bumping this patch. Could somebody queue this up?



Re: guest Linux Kernel hangs and reports CPU lockup/stuck gitlab bug

2022-09-21 Thread Gerd Hoffmann
On Wed, Sep 21, 2022 at 11:55:01AM +0200, Claudio Fontana wrote:
> Hi,
> 
> I think this bug report warrants some attention,
> 
> can Gerd take a look here?
> 
> The GTK Clipboard commit seems involved:
> 
> https://gitlab.com/qemu-project/qemu/-/issues/1150

Had a very quick look.  Seems gtk_clipboard_wait_is_text_available()
blocks forever for some reason.  Not sure why.  Possibly a gtk bug.

The options I see are:
  (a) go debug why it hangs.
  (b) rewrite clipboard support to avoid using the
  gtk_clipboard_wait*() functions.
  (c) add a config option to turn off gtk clipboard support.

Don't have the time to dig deeper right now, sorry.

take care,
  Gerd




Re: [PATCH v7 2/2] target/s390x: support PRNO_TRNG instruction

2022-09-21 Thread Thomas Huth

On 29/08/2022 18.29, Jason A. Donenfeld wrote:

On Fri, Aug 26, 2022 at 01:28:11PM +0200, Thomas Huth wrote:

+qemu_guest_getrandom_nofail(tmp, block);
+for (size_t i = 0; i < block; ++i) {
+cpu_stb_data_ra(env, wrap_address(env, *buf_reg), tmp[i], ra);
+*buf_reg = deposit64(*buf_reg, 0, message_reg_len, *buf_reg + 1);
+--*len_reg;


I know it's annoying, but technically, you must not touch the upper bits of
the len_reg if running in 31- or 24-bit addressing mode. The Principles of
Operations say:

"In either the 24- or 31-bit addressing mode, bits 32-63 of the odd-numbered
register are decremented by the number
of bytes processed for the respective operand, and
bits 0-31 of the register remain unchanged."



This is what I was trying to do with the use of deposit64, following
David's guidance. Did I mess something up?


Sorry for not following up earlier - I've been away from keyboard for a 
couple of weeks...


Anyway, that was likely a wrong comment from my side anyway - I thought that 
"--*len_reg" might alter the upper bits, too, when there is no masking here. 
But since "len" has been constrained earlier in the function already, I 
think this cannot happen, so please never mind.


I just saw that you also sent a v8 now, so I'll follow up on that version.

 Thomas




[PATCH] virtio-gpu: Resource UUID

2022-09-21 Thread Antonio Caggiano
Enable resource UUID feature and implement command resource assign UUID.
This is done by introducing a hash table to map resource IDs to their
UUIDs.

Signed-off-by: Antonio Caggiano 
---
 hw/display/trace-events|  1 +
 hw/display/virtio-gpu-base.c   |  2 ++
 hw/display/virtio-gpu-virgl.c  | 11 ++
 hw/display/virtio-gpu.c| 40 ++
 include/hw/virtio/virtio-gpu.h |  4 
 5 files changed, 58 insertions(+)

diff --git a/hw/display/trace-events b/hw/display/trace-events
index 0c0ffcbe42..6632344322 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -41,6 +41,7 @@ virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) 
"res 0x%x, size %" P
 virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_assign_uuid(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_xfer_toh_2d(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_xfer_toh_3d(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_xfer_fromh_3d(uint32_t res) "res 0x%x"
diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index a29f191aa8..157d280b14 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -216,6 +216,8 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t 
features,
 features |= (1 << VIRTIO_GPU_F_RESOURCE_BLOB);
 }
 
+features |= (1 << VIRTIO_GPU_F_RESOURCE_UUID);
+
 return features;
 }
 
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 73cb92c8d5..7adb6be993 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -43,6 +43,10 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
 args.nr_samples = 0;
 args.flags = VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP;
 virgl_renderer_resource_create(&args, NULL, 0);
+
+struct virtio_gpu_simple_resource *res = g_new0(struct 
virtio_gpu_simple_resource, 1);
+res->resource_id = c2d.resource_id;
+QTAILQ_INSERT_HEAD(&g->reslist, res, next);
 }
 
 static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
@@ -67,6 +71,10 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
 args.nr_samples = c3d.nr_samples;
 args.flags = c3d.flags;
 virgl_renderer_resource_create(&args, NULL, 0);
+
+struct virtio_gpu_simple_resource *res = g_new0(struct 
virtio_gpu_simple_resource, 1);
+res->resource_id = c3d.resource_id;
+QTAILQ_INSERT_HEAD(&g->reslist, res, next);
 }
 
 static void virgl_cmd_resource_unref(VirtIOGPU *g,
@@ -452,6 +460,9 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
 /* TODO add security */
 virgl_cmd_ctx_detach_resource(g, cmd);
 break;
+case VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID:
+virtio_gpu_resource_assign_uuid(g, cmd);
+break;
 case VIRTIO_GPU_CMD_GET_CAPSET_INFO:
 virgl_cmd_get_capset_info(g, cmd);
 break;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 20cc703dcc..67e39fa839 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -937,6 +937,37 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g,
 virtio_gpu_cleanup_mapping(g, res);
 }
 
+void virtio_gpu_resource_assign_uuid(VirtIOGPU *g,
+ struct virtio_gpu_ctrl_command *cmd)
+{
+struct virtio_gpu_simple_resource *res;
+struct virtio_gpu_resource_assign_uuid assign;
+struct virtio_gpu_resp_resource_uuid resp;
+QemuUUID *uuid = NULL;
+
+VIRTIO_GPU_FILL_CMD(assign);
+virtio_gpu_bswap_32(&assign, sizeof(assign));
+trace_virtio_gpu_cmd_res_assign_uuid(assign.resource_id);
+
+res = virtio_gpu_find_check_resource(g, assign.resource_id, false, 
__func__, &cmd->error);
+if (!res) {
+return;
+}
+
+memset(&resp, 0, sizeof(resp));
+resp.hdr.type = VIRTIO_GPU_RESP_OK_RESOURCE_UUID;
+
+uuid = g_hash_table_lookup(g->resource_uuids, 
GUINT_TO_POINTER(assign.resource_id));
+if (!uuid) {
+uuid = g_new(QemuUUID, 1);
+qemu_uuid_generate(uuid);
+g_hash_table_insert(g->resource_uuids, 
GUINT_TO_POINTER(assign.resource_id), uuid);
+}
+
+memcpy(resp.uuid, uuid, sizeof(QemuUUID));
+virtio_gpu_ctrl_response(g, cmd, &resp.hdr, sizeof(resp));
+}
+
 void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
 {
@@ -985,6 +1016,9 @@ void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
 case VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING:
 virtio_gpu_resource_detach_backing(g, cmd);
 break;
+case VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID:
+virtio_gpu_resource_assign_uuid(g, cmd);
+break;
 default:
 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
 break;
@@ -1343,6 +1377,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error 
**errp)
 QTAILQ_INIT(&g->reslist);
 QTAILQ_INIT(&g->cmdq

Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Kevin Wolf
Am 21.09.2022 um 06:45 hat Markus Armbruster geschrieben:
> Kevin Wolf  writes:
> 
> > Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
> >> On 9/8/22 19:10, Claudio Fontana wrote:
> >> > On 9/8/22 18:03, Richard Henderson wrote:
> >> >> On 9/8/22 15:53, Claudio Fontana wrote:
> >> >>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> >> >>> *options, int flags,
> >> >>>   return -EINVAL;
> >> >>>   }
> >> >>>   
> >> >>> -block_module_load_one("dmg-bz2");
> >> >>> -block_module_load_one("dmg-lzfse");
> >> >>> +if (!block_module_load_one("dmg-bz2", &local_err) && local_err) {
> >> >>> +error_report_err(local_err);
> >> >>> +}
> >> >>> +local_err = NULL;
> >> >>> +if (!block_module_load_one("dmg-lzfse", &local_err) && local_err) 
> >> >>> {
> >> >>> +error_report_err(local_err);
> >> >>> +}
> >> >>>   
> >> >>>   s->n_chunks = 0;
> >> >>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> >> >>
> >> >> I wonder if these shouldn't fail hard if the modules don't exist?
> >> >> Or at least pass back the error.
> >> >>
> >> >> Kevin?
> >> 
> >> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
> >> image is not compressed, "dmg" can function even if the extra dmg-bz
> >> module is not loaded right?
> >
> > Indeed. The code seems to consider that the modules may not be present.
> > The behaviour in these cases is questionable (it seems to silently leave
> > the buffers as they are and return success), but the modules are clearly
> > optional.
> >
> >> I'd suspect we should then do:
> >> 
> >> if (!block_module_load_one("dmg-bz2", &local_err)) {
> >>   if (local_err) {
> >>  error_report_err(local_err);
> >>  return -EINVAL;
> >>   }
> >>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks 
> >> */
> >> }
> >> 
> >> and same for dmg-lzfse...?
> >
> > Actually, I think during initialisation, we should just pass NULL as
> > errp and ignore any errors.
> >
> > When a request would access a block that can't be uncompressed because
> > of the missing module, that's where we can have a warn_report_once() and
> > arguably should fail the I/O request.
> 
> Seems like asking for data corruption.  To avoid it, the complete stack
> needs to handle I/O errors correctly.

If you have any component that doesn't handle I/O errors correctly, keep
it far away from your data because it _will_ cause corruption eventually.
The earlier it fails, the better for you.

I don't think we should put great effort into making fundamentally
broken software a little bit less broken in the corner case that you're
least likely to hit.

> Can we detect presence of compressed blocks on open?

We seem to read in the full metadata of the image in dmg_open(). So I
think it would be possible to detect it there.

dmg_read_mish_block() is what fills in s->types. However, it never fills
in types that it doesn't know (and it pretends it doesn't know the types
of compressed blocks whose module is not loaded). So instead of checking
it in dmg_open() after dmg_read_mish_block() has completed, you would
have to catch the situation already in dmg_read_mish_block() while
parsing the image file, which should be entirely doable if you want.

This is a change in dmg's behaviour, though, which is not the goal of
the proposed patch. So if we want to do that, it should be a separate
patch.

Kevin




Re: [PATCH v2 03/23] target/i386: Remove cur_eip argument to gen_exception

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 4:45 PM Philippe Mathieu-Daudé  wrote:
>
> On 6/9/22 12:09, Richard Henderson wrote:
> > All callers pass s->base.pc_next - s->cs_base, which we can just
> > as well compute within the function.  Note the special case of
> > EXCP_VSYSCALL in which s->cs_base didn't have the subtraction,
> > but cs_base is always zero in 64-bit mode, when vsyscall is used.
> >
> > Signed-off-by: Richard Henderson 
> > ---
> >   target/i386/tcg/translate.c | 26 +-
> >   1 file changed, 13 insertions(+), 13 deletions(-)

Reviewed-by: Paolo Bonzini 




Re: [PATCH v2 01/23] target/i386: Remove pc_start

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> The DisasContext member and the disas_insn local variable of
> the same name are identical to DisasContextBase.pc_next.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 


> ---
>  target/i386/tcg/translate.c | 114 +++-
>  1 file changed, 60 insertions(+), 54 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index d6420df31d..1e24bb2985 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -76,7 +76,6 @@ typedef struct DisasContext {
>  DisasContextBase base;
>
>  target_ulong pc;   /* pc = eip + cs_base */
> -target_ulong pc_start; /* pc at TB entry */
>  target_ulong cs_base;  /* base of CS segment */
>
>  MemOp aflag;
> @@ -1345,13 +1344,13 @@ static void gen_exception(DisasContext *s, int 
> trapno, target_ulong cur_eip)
> the instruction is known, but it isn't allowed in the current cpu mode.  
> */
>  static void gen_illegal_opcode(DisasContext *s)
>  {
> -gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
> +gen_exception(s, EXCP06_ILLOP, s->base.pc_next - s->cs_base);
>  }
>
>  /* Generate #GP for the current instruction. */
>  static void gen_exception_gpf(DisasContext *s)
>  {
> -gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base);
> +gen_exception(s, EXCP0D_GPF, s->base.pc_next - s->cs_base);
>  }
>
>  /* Check for cpl == 0; if not, raise #GP and return false. */
> @@ -2016,7 +2015,7 @@ static uint64_t advance_pc(CPUX86State *env, 
> DisasContext *s, int num_bytes)
>  }
>
>  s->pc += num_bytes;
> -if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) {
> +if (unlikely(s->pc - s->base.pc_next > X86_MAX_INSN_LENGTH)) {
>  /* If the instruction's 16th byte is on a different page than the 
> 1st, a
>   * page fault on the second page wins over the general protection 
> fault
>   * caused by the instruction being too long.
> @@ -2589,7 +2588,7 @@ static void gen_unknown_opcode(CPUX86State *env, 
> DisasContext *s)
>  if (qemu_loglevel_mask(LOG_UNIMP)) {
>  FILE *logfile = qemu_log_trylock();
>  if (logfile) {
> -target_ulong pc = s->pc_start, end = s->pc;
> +target_ulong pc = s->base.pc_next, end = s->pc;
>
>  fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
>  for (; pc < end; ++pc) {
> @@ -3199,8 +3198,7 @@ static const struct SSEOpHelper_table7 
> sse_op_table7[256] = {
>  goto illegal_op; \
>  } while (0)
>
> -static void gen_sse(CPUX86State *env, DisasContext *s, int b,
> -target_ulong pc_start)
> +static void gen_sse(CPUX86State *env, DisasContext *s, int b)
>  {
>  int b1, op1_offset, op2_offset, is_xmm, val;
>  int modrm, mod, rm, reg;
> @@ -3242,7 +3240,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>  }
>  /* simple MMX/SSE operation */
>  if (s->flags & HF_TS_MASK) {
> -gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> +gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
>  return;
>  }
>  if (s->flags & HF_EM_MASK) {
> @@ -4675,11 +4673,10 @@ static target_ulong disas_insn(DisasContext *s, 
> CPUState *cpu)
>  MemOp ot, aflag, dflag;
>  int modrm, reg, rm, mod, op, opreg, val;
>  target_ulong next_eip, tval;
> -target_ulong pc_start = s->base.pc_next;
>  bool orig_cc_op_dirty = s->cc_op_dirty;
>  CCOp orig_cc_op = s->cc_op;
>
> -s->pc_start = s->pc = pc_start;
> +s->pc = s->base.pc_next;
>  s->override = -1;
>  #ifdef TARGET_X86_64
>  s->rex_w = false;
> @@ -4703,7 +4700,7 @@ static target_ulong disas_insn(DisasContext *s, 
> CPUState *cpu)
>  s->base.num_insns--;
>  tcg_remove_ops_after(s->prev_insn_end);
>  s->base.is_jmp = DISAS_TOO_MANY;
> -return pc_start;
> +return s->base.pc_next;
>  default:
>  g_assert_not_reached();
>  }
> @@ -6044,7 +6041,7 @@ static target_ulong disas_insn(DisasContext *s, 
> CPUState *cpu)
>  if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
>  /* if CR0.EM or CR0.TS are set, generate an FPU exception */
>  /* XXX: what to do if illegal op ? */
> -gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> +gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
>  break;
>  }
>  modrm = x86_ldub_code(env, s);
> @@ -6585,7 +6582,7 @@ static target_ulong disas_insn(DisasContext *s, 
> CPUState *cpu)
> offsetof(CPUX86State, segs[R_CS].selector));
>  tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
>   offsetof(CPUX86State, fpcs));
> -tcg_gen_st_tl(tcg_constant_tl(pc_start - s->cs_base),
> +tcg_ge

Re: [PATCH v2 04/23] target/i386: Remove cur_eip, next_eip arguments to gen_interrupt

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 4:46 PM Philippe Mathieu-Daudé  wrote:
>
> On 6/9/22 12:09, Richard Henderson wrote:
> > All callers pass s->base.pc_next and s->pc, which we can just
> > as well compute within the function.
> >
> > Signed-off-by: Richard Henderson 
> > ---
> >   target/i386/tcg/translate.c | 13 ++---
> >   1 file changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> > index 58e74c3162..0210382f77 100644
> > --- a/target/i386/tcg/translate.c
> > +++ b/target/i386/tcg/translate.c
> > @@ -2602,13 +2602,12 @@ static void gen_unknown_opcode(CPUX86State *env, 
> > DisasContext *s)
> >
> >   /* an interrupt is different from an exception because of the
> >  privilege checks */
> > -static void gen_interrupt(DisasContext *s, int intno,
> > -  target_ulong cur_eip, target_ulong next_eip)
> > +static void gen_interrupt(DisasContext *s, int intno)
> >   {
> >   gen_update_cc_op(s);
> > -gen_jmp_im(s, cur_eip);
> > -gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
> > -   tcg_const_i32(next_eip - cur_eip));
> > +gen_jmp_im(s, s->base.pc_next - s->cs_base);
> > +gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
> > +   tcg_constant_i32(s->pc - s->base.pc_next));

Reviewed-by: Paolo Bonzini 




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 21.09.2022 um 06:45 hat Markus Armbruster geschrieben:
>> Kevin Wolf  writes:
>> 
>> > Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
>> >> On 9/8/22 19:10, Claudio Fontana wrote:
>> >> > On 9/8/22 18:03, Richard Henderson wrote:
>> >> >> On 9/8/22 15:53, Claudio Fontana wrote:
>> >> >>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
>> >> >>> *options, int flags,
>> >> >>>   return -EINVAL;
>> >> >>>   }
>> >> >>>   
>> >> >>> -block_module_load_one("dmg-bz2");
>> >> >>> -block_module_load_one("dmg-lzfse");
>> >> >>> +if (!block_module_load_one("dmg-bz2", &local_err) && local_err) {
>> >> >>> +error_report_err(local_err);
>> >> >>> +}
>> >> >>> +local_err = NULL;
>> >> >>> +if (!block_module_load_one("dmg-lzfse", &local_err) && 
>> >> >>> local_err) {
>> >> >>> +error_report_err(local_err);
>> >> >>> +}
>> >> >>>   
>> >> >>>   s->n_chunks = 0;
>> >> >>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
>> >> >>
>> >> >> I wonder if these shouldn't fail hard if the modules don't exist?
>> >> >> Or at least pass back the error.
>> >> >>
>> >> >> Kevin?
>> >> 
>> >> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
>> >> image is not compressed, "dmg" can function even if the extra dmg-bz
>> >> module is not loaded right?
>> >
>> > Indeed. The code seems to consider that the modules may not be present.
>> > The behaviour in these cases is questionable (it seems to silently leave
>> > the buffers as they are and return success), but the modules are clearly
>> > optional.
>> >
>> >> I'd suspect we should then do:
>> >> 
>> >> if (!block_module_load_one("dmg-bz2", &local_err)) {
>> >>   if (local_err) {
>> >>  error_report_err(local_err);
>> >>  return -EINVAL;
>> >>   }
>> >>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
>> >> chunks */
>> >> }
>> >> 
>> >> and same for dmg-lzfse...?
>> >
>> > Actually, I think during initialisation, we should just pass NULL as
>> > errp and ignore any errors.
>> >
>> > When a request would access a block that can't be uncompressed because
>> > of the missing module, that's where we can have a warn_report_once() and
>> > arguably should fail the I/O request.
>> 
>> Seems like asking for data corruption.  To avoid it, the complete stack
>> needs to handle I/O errors correctly.
>
> If you have any component that doesn't handle I/O errors correctly, keep
> it far away from your data because it _will_ cause corruption eventually.
> The earlier it fails, the better for you.

True for immortals.  Since we're not, it actually depends on
probabilities.

> I don't think we should put great effort into making fundamentally
> broken software a little bit less broken in the corner case that you're
> least likely to hit.

Fair point.

>> Can we detect presence of compressed blocks on open?
>
> We seem to read in the full metadata of the image in dmg_open(). So I
> think it would be possible to detect it there.
>
> dmg_read_mish_block() is what fills in s->types. However, it never fills
> in types that it doesn't know (and it pretends it doesn't know the types
> of compressed blocks whose module is not loaded). So instead of checking
> it in dmg_open() after dmg_read_mish_block() has completed, you would
> have to catch the situation already in dmg_read_mish_block() while
> parsing the image file, which should be entirely doable if you want.

In most cases, "open fails because some blocks are known to be
unreadable" is much better UX than "everything goes swimmingly until you
try to read one of the known-unreadable blocks".

Even when your software manages not to eat your data, surprise bad
blocks are still likely to result in a bad day.

> This is a change in dmg's behaviour, though, which is not the goal of
> the proposed patch. So if we want to do that, it should be a separate
> patch.

Makes sense.




Re: [PATCH v2 06/23] target/i386: Create gen_update_eip_next

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Sync EIP before exiting a translation block.
> Replace all gen_jmp_im that use s->pc.
>
> Signed-off-by: Richard Henderson 
> ---
>  target/i386/tcg/translate.c | 45 -
>  1 file changed, 25 insertions(+), 20 deletions(-)

Reviewed-by: Paolo Bonzini 

>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 83cb925571..6084c85609 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -521,6 +521,11 @@ static void gen_update_eip_cur(DisasContext *s)
>  gen_jmp_im(s, s->base.pc_next - s->cs_base);
>  }
>
> +static void gen_update_eip_next(DisasContext *s)
> +{
> +gen_jmp_im(s, s->pc - s->cs_base);
> +}
> +
>  /* Compute SEG:REG into A0.  SEG is selected from the override segment
> (OVR_SEG) and the default segment (DEF_SEG).  OVR_SEG may be -1 to
> indicate no override.  */
> @@ -5675,7 +5680,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_pop_update(s, ot);
>  /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
>  if (s->base.is_jmp) {
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  if (reg == R_SS) {
>  s->flags &= ~HF_TF_MASK;
>  gen_eob_inhibit_irq(s, true);
> @@ -5690,7 +5695,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_movl_seg_T0(s, (b >> 3) & 7);
>  gen_pop_update(s, ot);
>  if (s->base.is_jmp) {
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob(s);
>  }
>  break;
> @@ -5741,7 +5746,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_movl_seg_T0(s, reg);
>  /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
>  if (s->base.is_jmp) {
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  if (reg == R_SS) {
>  s->flags &= ~HF_TF_MASK;
>  gen_eob_inhibit_irq(s, true);
> @@ -5948,7 +5953,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  /* then put the data */
>  gen_op_mov_reg_v(s, ot, reg, s->T1);
>  if (s->base.is_jmp) {
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob(s);
>  }
>  break;
> @@ -7004,7 +7009,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_pop_update(s, ot);
>  set_cc_op(s, CC_OP_EFLAGS);
>  /* abort translation because TF/AC flag may change */
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob(s);
>  }
>  break;
> @@ -7340,7 +7345,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  if (check_iopl(s)) {
>  gen_helper_sti(cpu_env);
>  /* interruptions are enabled only the first insn after sti */
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob_inhibit_irq(s, true);
>  }
>  break;
> @@ -7416,7 +7421,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>
>  gen_set_label(l3);
> -gen_jmp_im(s, next_eip);
> +gen_update_eip_next(s);
>  tcg_gen_br(l2);
>
>  gen_set_label(l1);
> @@ -7434,7 +7439,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_helper_rdmsr(cpu_env);
>  } else {
>  gen_helper_wrmsr(cpu_env);
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob(s);
>  }
>  }
> @@ -7634,7 +7639,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  goto illegal_op;
>  }
>  gen_helper_clac(cpu_env);
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob(s);
>  break;
>
> @@ -7644,7 +7649,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  goto illegal_op;
>  }
>  gen_helper_stac(cpu_env);
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob(s);
>  break;
>
> @@ -7689,7 +7694,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
>  gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
>  /* End TB because translation flags may change.  */
> -gen_jmp_im(s, s->pc - s->cs_base);
> +gen_update_eip_next(s);
>  gen_eob(s);
>  break;
>
> @@ -7751,7 +7756,7 @@ static bool 

Re: [PATCH v2 08/23] target/i386: Use DISAS_EOB* in gen_movl_seg_T0

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Set is_jmp properly in gen_movl_seg_T0, so that the callers
> need to nothing special.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 

> ---
>  target/i386/tcg/translate.c | 36 +---
>  1 file changed, 5 insertions(+), 31 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 778ee4ed4c..ea35d3e9b4 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -2432,13 +2432,15 @@ static void gen_movl_seg_T0(DisasContext *s, X86Seg 
> seg_reg)
> because ss32 may change. For R_SS, translation must always
> stop as a special handling must be done to disable hardware
> interrupts for the next instruction */
> -if (seg_reg == R_SS || (CODE32(s) && seg_reg < R_FS)) {
> -s->base.is_jmp = DISAS_TOO_MANY;
> +if (seg_reg == R_SS) {
> +s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
> +} else if (CODE32(s) && seg_reg < R_FS) {
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  }
>  } else {
>  gen_op_movl_seg_T0_vm(s, seg_reg);
>  if (seg_reg == R_SS) {
> -s->base.is_jmp = DISAS_TOO_MANY;
> +s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
>  }
>  }
>  }
> @@ -5682,26 +5684,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  ot = gen_pop_T0(s);
>  gen_movl_seg_T0(s, reg);
>  gen_pop_update(s, ot);
> -/* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
> -if (s->base.is_jmp) {
> -gen_update_eip_next(s);
> -if (reg == R_SS) {
> -s->flags &= ~HF_TF_MASK;
> -gen_eob_inhibit_irq(s, true);
> -} else {
> -gen_eob(s);
> -}
> -}
>  break;
>  case 0x1a1: /* pop fs */
>  case 0x1a9: /* pop gs */
>  ot = gen_pop_T0(s);
>  gen_movl_seg_T0(s, (b >> 3) & 7);
>  gen_pop_update(s, ot);
> -if (s->base.is_jmp) {
> -gen_update_eip_next(s);
> -gen_eob(s);
> -}
>  break;
>
>  /**/
> @@ -5748,16 +5736,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  goto illegal_op;
>  gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
>  gen_movl_seg_T0(s, reg);
> -/* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
> -if (s->base.is_jmp) {
> -gen_update_eip_next(s);
> -if (reg == R_SS) {
> -s->flags &= ~HF_TF_MASK;
> -gen_eob_inhibit_irq(s, true);
> -} else {
> -gen_eob(s);
> -}
> -}
>  break;
>  case 0x8c: /* mov Gv, seg */
>  modrm = x86_ldub_code(env, s);
> @@ -5956,10 +5934,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_movl_seg_T0(s, op);
>  /* then put the data */
>  gen_op_mov_reg_v(s, ot, reg, s->T1);
> -if (s->base.is_jmp) {
> -gen_update_eip_next(s);
> -gen_eob(s);
> -}
>  break;
>
>  //
> --
> 2.34.1
>




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Kevin Wolf
Am 21.09.2022 um 09:50 hat Claudio Fontana geschrieben:
> On 9/20/22 18:50, Kevin Wolf wrote:
> > Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
> >> On 9/8/22 19:10, Claudio Fontana wrote:
> >>> On 9/8/22 18:03, Richard Henderson wrote:
>  On 9/8/22 15:53, Claudio Fontana wrote:
> > @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> > *options, int flags,
> >   return -EINVAL;
> >   }
> >   
> > -block_module_load_one("dmg-bz2");
> > -block_module_load_one("dmg-lzfse");
> > +if (!block_module_load_one("dmg-bz2", &local_err) && local_err) {
> > +error_report_err(local_err);
> > +}
> > +local_err = NULL;
> > +if (!block_module_load_one("dmg-lzfse", &local_err) && local_err) {
> > +error_report_err(local_err);
> > +}
> >   
> >   s->n_chunks = 0;
> >   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> 
>  I wonder if these shouldn't fail hard if the modules don't exist?
>  Or at least pass back the error.
> 
>  Kevin?
> >>
> >> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
> >> image is not compressed, "dmg" can function even if the extra dmg-bz
> >> module is not loaded right?
> > 
> > Indeed. The code seems to consider that the modules may not be present.
> > The behaviour in these cases is questionable (it seems to silently leave
> > the buffers as they are and return success)

I think I misunderstood the code here actually. dmg_read_mish_block()
skips chunks of unknown type, so later trying to find them fails and
dmg_co_preadv() returns -EIO. Which is a reasonable return value for
this.

> > , but the modules are clearly
> > optional.
> > 
> >> I'd suspect we should then do:
> >>
> >> if (!block_module_load_one("dmg-bz2", &local_err)) {
> >>   if (local_err) {
> >>  error_report_err(local_err);
> >>  return -EINVAL;
> >>   }
> >>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks 
> >> */
> >> }
> >>
> >> and same for dmg-lzfse...?
> > 
> > Actually, I think during initialisation, we should just pass NULL as
> > errp and ignore any errors.
> 
> Hmm really? I'd think that if there is an actual error loading the
> module (module is installed, but the loading itself fails due to
> broken module, wrong permissions, I/O errors etc) we would want to
> report that fact as it happens?

Can we distinguish the two error cases?

Oooh... Reading the code again carefully, are you returning false
without setting errp if the module just couldn't be found? This is a
surprising interface.

Yes, I guess then your proposed code is fine (modulo moving
warn_report() somewhere else so that it doesn't complain when the image
doesn't even contain compressed chunks).

> > When a request would access a block that can't be uncompressed because
> > of the missing module, that's where we can have a warn_report_once() and
> > arguably should fail the I/O request.
> > 
> > Kevin
> > 
> 
> That would mean, moving the
> 
> warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks")
> 
> to the uncompression code and change it to a warn_report_once() right?

Yeah, though I think this doesn't actually work because we never even
stored the metadata for chunks of unknown type (see above), so we never
reach the uncompression code.

What misled me initially is this code in dmg_read_chunk():

case UDBZ: /* bzip2 compressed */
if (!dmg_uncompress_bz2) {
break;
}

I believe this is dead code, it could actually be an assertion. So
if I'm not missing anything, adding the warning there would be useless.

The other option is moving it into dmg_is_known_block_type() or its
caller dmg_read_mish_block(), then we would detect it during open, which
is probably nicer anyway.

Kevin




Re: [PATCH 0/7] nsis: gitlab-ci: Improve QEMU Windows installer packaging

2022-09-21 Thread Thomas Huth

On 21/09/2022 14.18, Bin Meng wrote:

Hi,

On Thu, Sep 8, 2022 at 9:28 PM Bin Meng  wrote:


At present packaging the required DLLs of QEMU executables is a
manual process, and error prone.

Improve scripts/nsis.py by adding a logic to automatically package
required DLLs of QEMU executables.

'make installer' is tested in the cross-build on Linux in CI, but
not in the Windows native build. Update CI to test the installer
generation on Windows too.

During testing a 32-bit build issue was exposed in block/nfs.c and
the fix is included in this series.


Bin Meng (7):
   scripts/nsis.py: Drop the unnecessary path separator
   scripts/nsis.py: Fix destination directory name when invoked on
 Windows
   scripts/nsis.py: Automatically package required DLLs of QEMU
 executables
   .gitlab-ci.d/windows.yml: Drop the sed processing in the 64-bit build
   block/nfs: Fix 32-bit Windows build
   .gitlab-ci.d/windows.yml: Unify the prerequisite packages
   .gitlab-ci.d/windows.yml: Test 'make installer' in the CI

  meson.build  |  1 +
  block/nfs.c  |  8 ++
  .gitlab-ci.d/windows.yml | 40 ---
  scripts/nsis.py  | 60 +---
  4 files changed, 89 insertions(+), 20 deletions(-)



I see Thomas only queued patch #4 (".gitlab-ci.d/windows.yml: Drop the
sed processing in the 64-bit build")

What about other patches?


I hope that Stefan Weil (our W32 maintainer) could have a look at these first...

 Thomas





Re: [PATCH v2 10/23] target/i386: USe DISAS_EOB_ONLY

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Replace lone calls to gen_eob() with the new enumerator.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 

> ---
>  target/i386/tcg/translate.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index a7e5bcdec7..5b77414a0a 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -6800,7 +6800,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  /* add stack offset */
>  gen_stack_update(s, val + (2 << dflag));
>  }
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_ONLY;
>  break;
>  case 0xcb: /* lret */
>  val = 0;
> @@ -6818,7 +6818,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>tcg_const_i32(s->pc - s->cs_base));
>  }
>  set_cc_op(s, CC_OP_EFLAGS);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_ONLY;
>  break;
>  case 0xe8: /* call im */
>  {
> @@ -7404,7 +7404,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_set_label(l1);
>  gen_jmp_im(s, tval);
>  gen_set_label(l2);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_ONLY;
>  }
>  break;
>  case 0x130: /* wrmsr */
> @@ -7445,7 +7445,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_exception_gpf(s);
>  } else {
>  gen_helper_sysenter(cpu_env);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_ONLY;
>  }
>  break;
>  case 0x135: /* sysexit */
> @@ -7456,7 +7456,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_exception_gpf(s);
>  } else {
>  gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_ONLY;
>  }
>  break;
>  #ifdef TARGET_X86_64
> @@ -8539,7 +8539,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_update_eip_next(s);
>  gen_helper_rsm(cpu_env);
>  #endif /* CONFIG_USER_ONLY */
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_ONLY;
>  break;
>  case 0x1b8: /* SSE4.2 popcnt */
>  if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
> --
> 2.34.1
>




Re: [PATCH v2 09/23] target/i386: Use DISAS_EOB_NEXT

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Replace sequences of gen_update_cc_op, gen_update_eip_next,
> and gen_eob with the new is_jmp enumerator.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 

> ---
>  target/i386/tcg/translate.c | 40 -
>  1 file changed, 13 insertions(+), 27 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index ea35d3e9b4..a7e5bcdec7 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -6987,8 +6987,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_pop_update(s, ot);
>  set_cc_op(s, CC_OP_EFLAGS);
>  /* abort translation because TF/AC flag may change */
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  }
>  break;
>  case 0x9e: /* sahf */
> @@ -7417,8 +7416,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_helper_rdmsr(cpu_env);
>  } else {
>  gen_helper_wrmsr(cpu_env);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  }
>  }
>  break;
> @@ -7617,8 +7615,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  goto illegal_op;
>  }
>  gen_helper_clac(cpu_env);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  break;
>
>  case 0xcb: /* stac */
> @@ -7627,8 +7624,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  goto illegal_op;
>  }
>  gen_helper_stac(cpu_env);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  break;
>
>  CASE_MODRM_MEM_OP(1): /* sidt */
> @@ -7672,8 +7668,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
>  gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
>  /* End TB because translation flags may change.  */
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  break;
>
>  case 0xd8: /* VMRUN */
> @@ -7734,8 +7729,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  gen_update_cc_op(s);
>  gen_helper_stgi(cpu_env);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  break;
>
>  case 0xdd: /* CLGI */
> @@ -7773,8 +7767,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
>  }
>  gen_helper_flush_page(cpu_env, s->A0);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  break;
>
>  CASE_MODRM_MEM_OP(2): /* lgdt */
> @@ -7857,8 +7850,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
>  tcg_gen_or_tl(s->T0, s->T0, s->T1);
>  gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  break;
>
>  CASE_MODRM_MEM_OP(7): /* invlpg */
> @@ -7868,8 +7860,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
>  gen_lea_modrm(env, s, modrm);
>  gen_helper_flush_page(cpu_env, s->A0);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  break;
>
>  case 0xf8: /* swapgs */
> @@ -8268,8 +8259,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
>  gen_op_mov_v_reg(s, ot, s->T0, rm);
>  gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEXT;
>  } else {
>  gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
>  gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
> @@ -8303,8 +8293,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_op_mov_v_reg(s, ot, s->T0, rm);
>  tcg_gen_movi_i32(s->tmp2_i32, reg);
>  gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
> -gen_update_eip_next(s);
> -gen_eob(s);
> +s->base.is_jmp = DISAS_EOB_NEX

Re: [PATCH v2 05/23] target/i386: Create gen_update_eip_cur

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Like gen_update_cc_op, sync EIP before doing something
> that could raise an exception.  Replace all gen_jmp_im
> that use s->base.pc_next.

The commit message seems a bit off (it sounds like adding
stuff rather than refactoring), but anyway:

Reviewed-by: Paolo Bonzini 

Paolo

> ---
>  target/i386/tcg/translate.c | 52 -
>  1 file changed, 28 insertions(+), 24 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 0210382f77..83cb925571 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -511,10 +511,14 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, 
> int idx, int d)
>  }
>  }
>
> -static inline void gen_jmp_im(DisasContext *s, target_ulong pc)
> +static void gen_jmp_im(DisasContext *s, target_ulong pc)
>  {
> -tcg_gen_movi_tl(s->tmp0, pc);
> -gen_op_jmp_v(s->tmp0);
> +gen_op_jmp_v(tcg_constant_tl(pc));
> +}
> +
> +static void gen_update_eip_cur(DisasContext *s)
> +{
> +gen_jmp_im(s, s->base.pc_next - s->cs_base);
>  }
>
>  /* Compute SEG:REG into A0.  SEG is selected from the override segment
> @@ -703,7 +707,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, 
> TCGv_i32 port,
>  target_ulong next_eip = s->pc - s->cs_base;
>
>  gen_update_cc_op(s);
> -gen_jmp_im(s, cur_eip);
> +gen_update_eip_cur(s);
>  if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
>  svm_flags |= SVM_IOIO_REP_MASK;
>  }
> @@ -1335,7 +1339,7 @@ static void gen_helper_fp_arith_STN_ST0(int op, int 
> opreg)
>  static void gen_exception(DisasContext *s, int trapno)
>  {
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
>  s->base.is_jmp = DISAS_NORETURN;
>  }
> @@ -2605,7 +2609,7 @@ static void gen_unknown_opcode(CPUX86State *env, 
> DisasContext *s)
>  static void gen_interrupt(DisasContext *s, int intno)
>  {
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
> tcg_constant_i32(s->pc - s->base.pc_next));
>  s->base.is_jmp = DISAS_NORETURN;
> @@ -6796,7 +6800,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  do_lret:
>  if (PE(s) && !VM86(s)) {
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
>tcg_const_i32(val));
>  } else {
> @@ -7292,7 +7296,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (prefixes & PREFIX_REPZ) {
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  gen_helper_pause(cpu_env, tcg_const_i32(s->pc - 
> s->base.pc_next));
>  s->base.is_jmp = DISAS_NORETURN;
>  }
> @@ -7318,7 +7322,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  if (CODE64(s))
>  goto illegal_op;
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  gen_helper_into(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
>  break;
>  #ifdef WANT_ICEBP
> @@ -7425,7 +7429,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  case 0x132: /* rdmsr */
>  if (check_cpl0(s)) {
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  if (b & 2) {
>  gen_helper_rdmsr(cpu_env);
>  } else {
> @@ -7437,7 +7441,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  break;
>  case 0x131: /* rdtsc */
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
>  }
> @@ -7448,7 +7452,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  break;
>  case 0x133: /* rdpmc */
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  gen_helper_rdpmc(cpu_env);
>  s->base.is_jmp = DISAS_NORETURN;
>  break;
> @@ -7478,7 +7482,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  case 0x105: /* syscall */
>  /* XXX: is it usable in real mode ? */
>  gen_update_cc_op(s);
> -gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +gen_update_eip_cur(s);
>  gen_helper_sysc

Re: [PATCH v2 11/23] target/i386: Create cur_insn_len, cur_insn_len_i32

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 4:50 PM Philippe Mathieu-Daudé  wrote:
>
> On 6/9/22 12:09, Richard Henderson wrote:
> > Create common routines for computing the length of the insn.
> >
> > Signed-off-by: Richard Henderson 
> > ---
> >   target/i386/tcg/translate.c | 31 +++
> >   1 file changed, 19 insertions(+), 12 deletions(-)

Reviewed-by: Paolo Bonzini 

Paolo




RE: [PATCH 5/7] block/nfs: Fix 32-bit Windows build

2022-09-21 Thread Meng, Bin
-Original Message-
From: Philippe Mathieu-Daudé  On Behalf Of 
Philippe Mathieu-Daudé
Sent: Sunday, September 18, 2022 5:32 AM
To: Bin Meng ; qemu-devel@nongnu.org
Cc: Meng, Bin ; Hanna Reitz ; Kevin 
Wolf ; Peter Lieven ; qemu-bl...@nongnu.org
Subject: Re: [PATCH 5/7] block/nfs: Fix 32-bit Windows build

[Please note: This e-mail is from an EXTERNAL e-mail address]

On 8/9/22 15:28, Bin Meng wrote:
> From: Bin Meng 
>
> libnfs.h declares nfs_fstat() as the following for win32:
>
>int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh,
>  struct __stat64 *st);
>
> The 'st' parameter should be of type 'struct __stat64'. The codes 
> happen to build successfully for 64-bit Windows, but it does not build 
> for 32-bit Windows.
>
> Fixes: 6542aa9c75bc ("block: add native support for NFS")
> Fixes: 18a8056e0bc7 ("block/nfs: cache allocated filesize for 
> read-only files")
> Signed-off-by: Bin Meng 
> ---
>
>   block/nfs.c | 8 
>   1 file changed, 8 insertions(+)
>
> diff --git a/block/nfs.c b/block/nfs.c index 444c40b458..d5d67937dd 
> 100644
> --- a/block/nfs.c
> +++ b/block/nfs.c
> @@ -418,7 +418,11 @@ static int64_t nfs_client_open(NFSClient *client, 
> BlockdevOptionsNfs *opts,
>  int flags, int open_flags, Error **errp)
>   {
>   int64_t ret = -EINVAL;
> +#ifdef _WIN32
> +struct __stat64 st;
> +#else
>   struct stat st;
> +#endif
>   char *file = NULL, *strp = NULL;
>
>   qemu_mutex_init(&client->mutex); @@ -781,7 +785,11 @@ static int 
> nfs_reopen_prepare(BDRVReopenState *state,
> BlockReopenQueue *queue, Error **errp)
>   {
>   NFSClient *client = state->bs->opaque;
> +#ifdef _WIN32
> +struct __stat64 st;
> +#else
>   struct stat st;
> +#endif
>   int ret = 0;
>
>   if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) 
> {

What about the field in struct NFSRPC?

NFSRPC::struct stat is used in nfs_get_allocated_file_size_cb() and 
nfs_get_allocated_file_size() that are not built on win32, so there is no 
problem.

Regards,
Bin




Re: [PATCH v2 13/23] target/i386: Introduce DISAS_JUMP

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Drop the unused dest argument to gen_jr().
> Remove most of the calls to gen_jr, and use DISAS_JUMP.
> Remove some unused loads of eip for lcall and ljmp.

The only use outside i386_tr_tb_stop is here:

static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
{
target_ulong pc = s->cs_base + eip;

if (translator_use_goto_tb(&s->base, pc))  {
/* jump to same page: we can use a direct jump */
tcg_gen_goto_tb(tb_num);
gen_jmp_im(s, eip);
tcg_gen_exit_tb(s->base.tb, tb_num);
s->base.is_jmp = DISAS_NORETURN;
} else {
/* jump to another page */
gen_jmp_im(s, eip);
gen_jr(s);
}
}

Should it set s->base.is_jmp = DISAS_JUMP instead, so that gen_jr() can be
inlined into i386_tr_tb_stop() and removed completely? If not,

Reviewed-by: Paolo Bonzini 

Paolo




Re: [PATCH v2 07/23] target/i386: Introduce DISAS_EOB*

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Add a few DISAS_TARGET_* aliases to reduce the number of
> calls to gen_eob() and gen_eob_inhibit_irq().  So far,
> only update i386_tr_translate_insn for exiting the block
> because of single-step or previous inhibit irq.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 


> ---
>  target/i386/tcg/translate.c | 23 +--
>  1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 6084c85609..778ee4ed4c 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -132,6 +132,10 @@ typedef struct DisasContext {
>  TCGOp *prev_insn_end;
>  } DisasContext;
>
> +#define DISAS_EOB_ONLY DISAS_TARGET_0
> +#define DISAS_EOB_NEXT DISAS_TARGET_1
> +#define DISAS_EOB_INHIBIT_IRQ  DISAS_TARGET_2
> +
>  /* The environment in which user-only runs is constrained. */
>  #ifdef CONFIG_USER_ONLY
>  #define PE(S) true
> @@ -8814,7 +8818,7 @@ static void i386_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cpu)
>   * the flag and abort the translation to give the irqs a
>   * chance to happen.
>   */
> -dc->base.is_jmp = DISAS_TOO_MANY;
> +dc->base.is_jmp = DISAS_EOB_NEXT;
>  } else if (!is_same_page(&dc->base, pc_next)) {
>  dc->base.is_jmp = DISAS_TOO_MANY;
>  }
> @@ -8826,9 +8830,24 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, 
> CPUState *cpu)
>  {
>  DisasContext *dc = container_of(dcbase, DisasContext, base);
>
> -if (dc->base.is_jmp == DISAS_TOO_MANY) {
> +switch (dc->base.is_jmp) {
> +case DISAS_NORETURN:
> +break;
> +case DISAS_TOO_MANY:
> +case DISAS_EOB_NEXT:
> +gen_update_cc_op(dc);
>  gen_update_eip_cur(dc);
> +/* fall through */
> +case DISAS_EOB_ONLY:
>  gen_eob(dc);
> +break;
> +case DISAS_EOB_INHIBIT_IRQ:
> +gen_update_cc_op(dc);
> +gen_update_eip_cur(dc);
> +gen_eob_inhibit_irq(dc, true);
> +break;
> +default:
> +g_assert_not_reached();
>  }
>  }
>
> --
> 2.34.1
>




Re: [PATCH v2 12/23] target/i386: Remove cur_eip, next_eip arguments to gen_repz*

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> All callers pass s->base.pc_next and s->pc, which we can just
> as well compute within the functions.  Pull out common helpers
> and reduce the amount of code under macros.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 


> ---
>  target/i386/tcg/translate.c | 116 ++--
>  1 file changed, 57 insertions(+), 59 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 393a1c1075..f3c26a9956 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -736,7 +736,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, 
> TCGv_i32 port,
>  #endif
>  }
>
> -static inline void gen_movs(DisasContext *s, MemOp ot)
> +static void gen_movs(DisasContext *s, MemOp ot)
>  {
>  gen_string_movl_A0_ESI(s);
>  gen_op_ld_v(s, ot, s->T0, s->A0);
> @@ -1156,18 +1156,18 @@ static inline void gen_jcc1(DisasContext *s, int b, 
> TCGLabel *l1)
>
>  /* XXX: does not work with gdbstub "ice" single step - not a
> serious problem */
> -static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
> +static TCGLabel *gen_jz_ecx_string(DisasContext *s)
>  {
>  TCGLabel *l1 = gen_new_label();
>  TCGLabel *l2 = gen_new_label();
>  gen_op_jnz_ecx(s, s->aflag, l1);
>  gen_set_label(l2);
> -gen_jmp_tb(s, next_eip, 1);
> +gen_jmp_tb(s, s->pc - s->cs_base, 1);
>  gen_set_label(l1);
>  return l2;
>  }
>
> -static inline void gen_stos(DisasContext *s, MemOp ot)
> +static void gen_stos(DisasContext *s, MemOp ot)
>  {
>  gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
>  gen_string_movl_A0_EDI(s);
> @@ -1176,7 +1176,7 @@ static inline void gen_stos(DisasContext *s, MemOp ot)
>  gen_op_add_reg_T0(s, s->aflag, R_EDI);
>  }
>
> -static inline void gen_lods(DisasContext *s, MemOp ot)
> +static void gen_lods(DisasContext *s, MemOp ot)
>  {
>  gen_string_movl_A0_ESI(s);
>  gen_op_ld_v(s, ot, s->T0, s->A0);
> @@ -1185,7 +1185,7 @@ static inline void gen_lods(DisasContext *s, MemOp ot)
>  gen_op_add_reg_T0(s, s->aflag, R_ESI);
>  }
>
> -static inline void gen_scas(DisasContext *s, MemOp ot)
> +static void gen_scas(DisasContext *s, MemOp ot)
>  {
>  gen_string_movl_A0_EDI(s);
>  gen_op_ld_v(s, ot, s->T1, s->A0);
> @@ -1194,7 +1194,7 @@ static inline void gen_scas(DisasContext *s, MemOp ot)
>  gen_op_add_reg_T0(s, s->aflag, R_EDI);
>  }
>
> -static inline void gen_cmps(DisasContext *s, MemOp ot)
> +static void gen_cmps(DisasContext *s, MemOp ot)
>  {
>  gen_string_movl_A0_EDI(s);
>  gen_op_ld_v(s, ot, s->T1, s->A0);
> @@ -1222,7 +1222,7 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 
> t_port, int ot)
>  }
>  }
>
> -static inline void gen_ins(DisasContext *s, MemOp ot)
> +static void gen_ins(DisasContext *s, MemOp ot)
>  {
>  gen_string_movl_A0_EDI(s);
>  /* Note: we must do this dummy write first to be restartable in
> @@ -1238,7 +1238,7 @@ static inline void gen_ins(DisasContext *s, MemOp ot)
>  gen_bpt_io(s, s->tmp2_i32, ot);
>  }
>
> -static inline void gen_outs(DisasContext *s, MemOp ot)
> +static void gen_outs(DisasContext *s, MemOp ot)
>  {
>  gen_string_movl_A0_ESI(s);
>  gen_op_ld_v(s, ot, s->T0, s->A0);
> @@ -1252,42 +1252,49 @@ static inline void gen_outs(DisasContext *s, MemOp ot)
>  gen_bpt_io(s, s->tmp2_i32, ot);
>  }
>
> -/* same method as Valgrind : we generate jumps to current or next
> -   instruction */
> -#define GEN_REPZ(op) 
>  \
> -static inline void gen_repz_ ## op(DisasContext *s, MemOp ot,  \
> - target_ulong cur_eip, target_ulong 
> next_eip) \
> -{
>  \
> -TCGLabel *l2;
>  \
> -gen_update_cc_op(s); 
>  \
> -l2 = gen_jz_ecx_string(s, next_eip); 
>  \
> -gen_ ## op(s, ot);   
>  \
> -gen_op_add_reg_im(s, s->aflag, R_ECX, -1);   
>  \
> -/* a loop would cause two single step exceptions if ECX = 1  
>  \
> -   before rep string_insn */ 
>  \
> -if (s->repz_opt) 
>  \
> -gen_op_jz_ecx(s, s->aflag, l2);  
>  \
> -gen_jmp(s, cur_eip); 
>  \
> +/* Generate jumps to current or next instruction */
> +static void gen_repz(DisasContext *s, MemOp ot,
> + void (*fn)(DisasContext *s, MemOp ot))
> +{
> +TCGLabel *l2;
> +gen_update_cc_op(s);
> +l2 = gen_jz_ecx_string(s);
> +fn(

Re: [PATCH v2 1/4] scripts/ci/setup: ninja missing from build-environment

2022-09-21 Thread Lucas Mateus Martins Araujo e Castro



On 15/09/2022 12:54, Thomas Huth wrote:


On 14/09/2022 13.41, Lucas Mateus Castro(alqotel) wrote:

From: "Lucas Mateus Castro (alqotel)" 

ninja-build is missing from the RHEL environment, so a system prepared
with that script would still fail to compile QEMU.
Tested on a Fedora 36

Signed-off-by: Lucas Mateus Castro (alqotel) 


---
  scripts/ci/setup/build-environment.yml | 1 +
  1 file changed, 1 insertion(+)

diff --git a/scripts/ci/setup/build-environment.yml 
b/scripts/ci/setup/build-environment.yml

index 232525b91d..6df3e61d94 100644
--- a/scripts/ci/setup/build-environment.yml
+++ b/scripts/ci/setup/build-environment.yml
@@ -150,6 +150,7 @@
    - libepoxy-devel
    - libgcrypt-devel
    - lzo-devel
+  - ninja-build
    - make
    - mesa-libEGL-devel
    - nettle-devel


Looks like the list used to be sorted alphabetically, so maybe you should
sort it in some lines later?

D'oh, I'll send a v3 fixing that.


And I wonder why this hasn't been noticed before ... Cleber, was this in 
use

after all?

  Thomas



--
Lucas Mateus M. Araujo e Castro
Instituto de Pesquisas ELDORADO

Departamento Computação Embarcada
Analista de Software Junior
Aviso Legal - Disclaimer 


Re: [PATCH v2 14/23] target/i386: Truncate values for lcall_real to i32

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Use i32 not int or tl for eip and cs arguments.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 

> ---
>  target/i386/helper.h | 2 +-
>  target/i386/tcg/seg_helper.c | 6 ++
>  target/i386/tcg/translate.c  | 3 ++-
>  3 files changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/target/i386/helper.h b/target/i386/helper.h
> index ac3b4d1ee3..39a3c24182 100644
> --- a/target/i386/helper.h
> +++ b/target/i386/helper.h
> @@ -37,7 +37,7 @@ DEF_HELPER_2(lldt, void, env, int)
>  DEF_HELPER_2(ltr, void, env, int)
>  DEF_HELPER_3(load_seg, void, env, int, int)
>  DEF_HELPER_4(ljmp_protected, void, env, int, tl, tl)
> -DEF_HELPER_5(lcall_real, void, env, int, tl, int, int)
> +DEF_HELPER_5(lcall_real, void, env, i32, i32, int, i32)
>  DEF_HELPER_5(lcall_protected, void, env, int, tl, int, tl)
>  DEF_HELPER_2(iret_real, void, env, int)
>  DEF_HELPER_3(iret_protected, void, env, int, int)
> diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
> index bffd82923f..539189b4d1 100644
> --- a/target/i386/tcg/seg_helper.c
> +++ b/target/i386/tcg/seg_helper.c
> @@ -1504,14 +1504,12 @@ void helper_ljmp_protected(CPUX86State *env, int 
> new_cs, target_ulong new_eip,
>  }
>
>  /* real mode call */
> -void helper_lcall_real(CPUX86State *env, int new_cs, target_ulong new_eip1,
> -   int shift, int next_eip)
> +void helper_lcall_real(CPUX86State *env, uint32_t new_cs, uint32_t new_eip,
> +   int shift, uint32_t next_eip)
>  {
> -int new_eip;
>  uint32_t esp, esp_mask;
>  target_ulong ssp;
>
> -new_eip = new_eip1;
>  esp = env->regs[R_ESP];
>  esp_mask = get_sp_mask(env->segs[R_SS].flags);
>  ssp = env->segs[R_SS].base;
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 1997f8d291..427ee72442 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -5302,7 +5302,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_const_tl(s->pc - s->cs_base));
>  } else {
>  tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
> -gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->T1,
> +tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
> +gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
>tcg_const_i32(dflag - 1),
>tcg_const_i32(s->pc - s->cs_base));
>  }
> --
> 2.34.1
>




Re: [PATCH v2 15/23] target/i386: Create eip_next_*

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Create helpers for loading the address of the next insn.
> Use tcg_constant_* in adjacent code where convenient.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Paolo Bonzini 

> ---
>  target/i386/tcg/translate.c | 44 +++--
>  1 file changed, 23 insertions(+), 21 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 427ee72442..527fb79895 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -541,6 +541,16 @@ static TCGv_i32 cur_insn_len_i32(DisasContext *s)
>  return tcg_constant_i32(cur_insn_len(s));
>  }
>
> +static TCGv_i32 eip_next_i32(DisasContext *s)
> +{
> +return tcg_constant_i32(s->pc - s->cs_base);

Perhaps this should return 0xdeadbeef or 0x in 64-bit mode, so
that code goes in the weeds very quickly if it tries to use it?

Alternatively, just make iret_protected take a target_ulong for
next_eip, without too much worries about 64-on-32 emulation.

Paolo

> +}
> +
> +static TCGv eip_next_tl(DisasContext *s)
> +{
> +return tcg_constant_tl(s->pc - s->cs_base);
> +}
> +
>  /* Compute SEG:REG into A0.  SEG is selected from the override segment
> (OVR_SEG) and the default segment (DEF_SEG).  OVR_SEG may be -1 to
> indicate no override.  */
> @@ -1213,12 +1223,9 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 
> t_port, int ot)
>  /* user-mode cpu should not be in IOBPT mode */
>  g_assert_not_reached();
>  #else
> -TCGv_i32 t_size = tcg_const_i32(1 << ot);
> -TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
> -
> +TCGv_i32 t_size = tcg_constant_i32(1 << ot);
> +TCGv t_next = eip_next_tl(s);
>  gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
> -tcg_temp_free_i32(t_size);
> -tcg_temp_free(t_next);
>  #endif /* CONFIG_USER_ONLY */
>  }
>  }
> @@ -5280,9 +5287,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  if (dflag == MO_16) {
>  tcg_gen_ext16u_tl(s->T0, s->T0);
>  }
> -next_eip = s->pc - s->cs_base;
> -tcg_gen_movi_tl(s->T1, next_eip);
> -gen_push_v(s, s->T1);
> +gen_push_v(s, eip_next_tl(s));
>  gen_op_jmp_v(s->T0);
>  gen_bnd_jmp(s);
>  s->base.is_jmp = DISAS_JUMP;
> @@ -5298,14 +5303,14 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  if (PE(s) && !VM86(s)) {
>  tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
>  gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
> -   tcg_const_i32(dflag - 1),
> -   tcg_const_tl(s->pc - s->cs_base));
> +   tcg_constant_i32(dflag - 1),
> +   eip_next_tl(s));
>  } else {
>  tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
>  tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
>  gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
> -  tcg_const_i32(dflag - 1),
> -  tcg_const_i32(s->pc - s->cs_base));
> +  tcg_constant_i32(dflag - 1),
> +  eip_next_i32(s));
>  }
>  s->base.is_jmp = DISAS_JUMP;
>  break;
> @@ -5328,7 +5333,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  if (PE(s) && !VM86(s)) {
>  tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
>  gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
> -  tcg_const_tl(s->pc - s->cs_base));
> +  eip_next_tl(s));
>  } else {
>  gen_op_movl_seg_T0_vm(s, R_CS);
>  gen_op_jmp_v(s->T1);
> @@ -6819,8 +6824,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
>  } else {
> -gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
> -  tcg_const_i32(s->pc - s->cs_base));
> +gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1),
> +  eip_next_i32(s));
>  }
>  set_cc_op(s, CC_OP_EFLAGS);
>  s->base.is_jmp = DISAS_EOB_ONLY;
> @@ -6832,15 +6837,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  } else {
>  tval = (int16_t)insn_get(env, s, MO_16);
>  }
> -next_eip = s->pc - s->cs_base;
> -tval += next_eip;
> +tval += s->pc - s->cs_base;
>  if (dflag == MO_16) {
> 

[RFC PATCH 3/3] tests/tcg/mips: Add mips32 arithmatic instruction test cases

2022-09-21 Thread Jiaxun Yang
Those cases are delivered from MIPS internal architecture validation
tools.

Signed-off-by: Jiaxun Yang 
---
 tests/tcg/mips/include/test_utils_32.h|  75 +++
 .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 ++
 .../mips/user/isa/mips32/arithmatic/addi.c|  70 ++
 .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +
 .../mips/user/isa/mips32/arithmatic/addu.c| 125 ++
 .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 
 .../mips/user/isa/mips32/arithmatic/divu.c|  78 +++
 .../mips/user/isa/mips32/arithmatic/madd.c|  79 +++
 .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 +++
 .../mips/user/isa/mips32/arithmatic/msub.c|  78 +++
 .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 +++
 .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 +++
 .../mips/user/isa/mips32/arithmatic/mult.c|  78 +++
 .../mips/user/isa/mips32/arithmatic/multu.c   |  78 +++
 .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +
 .../mips/user/isa/mips32/arithmatic/slti.c|  48 +++
 .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++
 .../mips/user/isa/mips32/arithmatic/sltu.c|  61 +
 .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 +++
 .../mips/user/isa/mips32/arithmatic/subu.c| 108 +++
 20 files changed, 1595 insertions(+)
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c

diff --git a/tests/tcg/mips/include/test_utils_32.h 
b/tests/tcg/mips/include/test_utils_32.h
index c33990c0c5..00480e3283 100644
--- a/tests/tcg/mips/include/test_utils_32.h
+++ b/tests/tcg/mips/include/test_utils_32.h
@@ -29,6 +29,81 @@
 
 #define PRINT_RESULTS 0
 
+#define DO_MIPS32_r(mnemonic, id, input1, input2, expect)  \
+{  \
+uint32_t output;   \
+uint32_t expect_val = expect;  \
+__asm__ volatile ( \
+  "li $t1, " #input1 "\n\t"\
+  "li $t2, " #input2 "\n\t"\
+  #mnemonic " $t0, $t1, $t2\n\t"   \
+  "sw $t0, 0(%0)\n\t"  \
+  :\
+  : "r" (&output)  \
+  : "t0", "t1", "t2", "memory" \
+); \
+check_single_insn_32(id, &pass_count, &fail_count, 1, &expect_val, 
&output); \
+}
+
+#define DO_MIPS32_i(mnemonic, id, imm, input1, expect) \
+{  \
+uint32_t output;   \
+uint32_t expect_val = expect;  \
+__asm__ volatile ( \
+  "li $t1, " #input1 "\n\t"\
+  #mnemonic " $t0, $t1, " #imm "\n\t"  \
+  "sw $t0, 0(%0)\n\t"  \
+  :\
+  : "r" (&output)  \
+  : "t0", "t1", "memory"   \
+); \
+check_single_insn_3

Re: [PATCH v4 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> On 16/9/22 11:27, Markus Armbruster wrote:
>> Claudio Fontana  writes:
>> 
>>> improve error handling during module load, by changing:
>>>
>>> bool module_load_one(const char *prefix, const char *lib_name);
>>> void module_load_qom_one(const char *type);
>>>
>>> to:
>>>
>>> bool module_load_one(const char *prefix, const char *name, Error **errp);
>>> bool module_load_qom_one(const char *type, Error **errp);
>>>
>>> module_load_qom_one has been introduced in:
>>>
>>> commit 28457744c345 ("module: qom module support"), which built on top of
>>> module_load_one, but discarded the bool return value. Restore it.
>>>
>>> Adapt all callers to emit errors, or ignore them, or fail hard,
>>> as appropriate in each context.
>> 
>> How exactly does behavior change?  The commit message is mum on the
>> behavior before the patch, and vague on the behavior afterwards.
>> 
>>> Signed-off-by: Claudio Fontana 
>>> ---
>>>   audio/audio.c |   9 ++-
>>>   block.c   |  15 -
>>>   block/dmg.c   |  18 +-
>>>   hw/core/qdev.c|  10 ++-
>>>   include/qemu/module.h |  38 ++--
>>>   qom/object.c  |  18 +-
>>>   softmmu/qtest.c   |   6 +-
>>>   ui/console.c  |  18 +-
>>>   util/module.c | 140 --
>>>   9 files changed, 194 insertions(+), 78 deletions(-)
>
>>> diff --git a/include/qemu/module.h b/include/qemu/module.h
>>> index 8c012bbe03..78d4c4de96 100644
>>> --- a/include/qemu/module.h
>>> +++ b/include/qemu/module.h
>>> @@ -61,16 +61,44 @@ typedef enum {
>
>>>   
>>>   void module_call_init(module_init_type type);
>>> -bool module_load_one(const char *prefix, const char *lib_name);
>>> -void module_load_qom_one(const char *type);
>>> +
>>> +/*
>>> + * module_load_one: attempt to load a module from a set of directories
>>> + *
>>> + * directories searched are:
>>> + * - getenv("QEMU_MODULE_DIR")
>>> + * - get_relocated_path(CONFIG_QEMU_MODDIR);
>>> + * - /var/run/qemu/${version_dir}
>>> + *
>>> + * prefix: a subsystem prefix, or the empty string ("audio-", ..., 
>>> "")
>>> + * name:   name of the module
>>> + * errp:   error to set in case the module is found, but load 
>>> failed.
>>> + *
>>> + * Return value:   true on success (found and loaded);
>>> + * if module if found, but load failed, errp will be set.
>>> + * if module is not found, errp will not be set.
>> 
>> I understand you need to distingush two failure modes "found, but load
>> failed" and "not found".
>> 
>> Functions that set an error on some failures only tend to be awkward: in
>> addition to checking the return value for failure, you have to check
>> @errp for special failures.  This is particularly cumbersome when it
>> requires a @local_err and an error_propagate() just for that.  I
>> generally prefer to return an error code and always set an error.
>
> I notice the same issue, therefore would suggest this alternative
> prototype:
>
>bool module_load_one(const char *prefix, const char *name, 
>  bool ignore_if_missing, Error **errp);
> which always sets *errp when returning false:
>
>   * Return value:   if ignore_if_missing is true:
>   *   true on success (found or missing), false on
>   *   load failure.
>   * if ignore_if_missing is false:
>   *   true on success (found and loaded); false if
>   *   not found or load failed.
>   * errp will be set if the returned value is false.
>   */

I think this interface is less surprising.

If having to pass a flag turns out to to be a legibility issue, we can
have wrapper functions.




[RFC PATCH 1/3] target/mips: Introduce register access helper functions

2022-09-21 Thread Jiaxun Yang
Introduce register access functions with value extend capability
to prepare for decodetree based translation implmentation.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/translate.c | 143 +++-
 target/mips/tcg/translate.h |  54 ++
 2 files changed, 196 insertions(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index de1511baaf..b5d595ef34 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1196,6 +1196,17 @@ enum {
 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
 };
 
+/*
+ * If an operation is being performed on less than TARGET_LONG_BITS,
+ * it may require the inputs to be sign- or zero-extended; which will
+ * depend on the exact operation being performed.
+ */
+typedef enum {
+EXT_NONE,
+EXT_SIGN,
+EXT_ZERO
+} DisasExtend;
+
 /* global register indices */
 TCGv cpu_gpr[32], cpu_PC;
 /*
@@ -1221,6 +1232,18 @@ static const char regnames_LO[][4] = {
 "LO0", "LO1", "LO2", "LO3",
 };
 
+static TCGv ctx_temp_new(DisasContext *ctx)
+{
+assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
+return ctx->temp[ctx->ntemp++] = tcg_temp_new();
+}
+
+static TCGv_i64 ctx_temp_new_i64(DisasContext *ctx)
+{
+assert(ctx->ntemp64 < ARRAY_SIZE(ctx->temp64));
+return ctx->temp64[ctx->ntemp64++] = tcg_temp_new_i64();
+}
+
 /* General purpose registers moves. */
 void gen_load_gpr(TCGv t, int reg)
 {
@@ -1238,6 +1261,106 @@ void gen_store_gpr(TCGv t, int reg)
 }
 }
 
+void gen_extend(TCGv dst, TCGv src, DisasExtend src_ext)
+{
+switch (src_ext) {
+case EXT_NONE:
+tcg_gen_mov_tl(dst, src);
+return;
+case EXT_SIGN:
+tcg_gen_ext32s_tl(dst, src);
+return;
+case EXT_ZERO:
+tcg_gen_ext32u_tl(dst, src);
+return;
+}
+g_assert_not_reached();
+}
+
+TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend src_ext)
+{
+TCGv t;
+
+if (reg_num == 0) {
+return ctx->zero;
+}
+
+switch (src_ext) {
+case EXT_NONE:
+return cpu_gpr[reg_num];
+default:
+t = ctx_temp_new(ctx);
+gen_extend(t, cpu_gpr[reg_num], src_ext);
+return t;
+}
+}
+
+TCGv_i64 get_hilo(DisasContext *ctx, int acc)
+{
+TCGv_i64 t = ctx_temp_new_i64(ctx);
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+tcg_gen_concat_tl_i64(t, cpu_LO[acc], cpu_HI[acc]);
+
+return t;
+}
+
+TCGv dest_gpr(DisasContext *ctx, int reg_num)
+{
+if (reg_num == 0) {
+return ctx_temp_new(ctx);
+}
+return cpu_gpr[reg_num];
+}
+
+TCGv dest_lo(DisasContext *ctx, int acc)
+{
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+
+return cpu_LO[acc];
+}
+
+TCGv dest_hi(DisasContext *ctx, int acc)
+{
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+
+return cpu_HI[acc];
+}
+
+/* For 32 bit hilo pair */
+TCGv_i64 dest_hilo(DisasContext *ctx, int acc)
+{
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+return ctx_temp_new_i64(ctx);
+}
+
+void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext)
+{
+if (reg_num != 0) {
+gen_extend(cpu_gpr[reg_num], t, dst_ext);
+}
+}
+
+void gen_set_lo(int acc, TCGv t, DisasExtend dst_ext)
+{
+gen_extend(cpu_LO[acc], t, dst_ext);
+}
+
+void gen_set_hi(int acc, TCGv t, DisasExtend dst_ext)
+{
+gen_extend(cpu_HI[acc], t, dst_ext);
+}
+
+/* For 32 bit hilo pair */
+void gen_set_hilo(int acc, TCGv_i64 t)
+{
+gen_move_low32(cpu_LO[acc], t);
+gen_move_high32(cpu_HI[acc], t);
+}
+
 #if defined(TARGET_MIPS64)
 void gen_load_gpr_hi(TCGv_i64 t, int reg)
 {
@@ -2615,7 +2738,6 @@ static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
 tcg_temp_free(t0);
 }
 
-/* Arithmetic */
 static void gen_arith(DisasContext *ctx, uint32_t opc,
   int rd, int rs, int rt)
 {
@@ -16031,6 +16153,12 @@ static void 
mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 ctx->base.max_insns = 2;
 }
 
+ctx->ntemp = 0;
+ctx->ntemp64 = 0;
+memset(ctx->temp, 0, sizeof(ctx->temp));
+memset(ctx->temp64, 0, sizeof(ctx->temp));
+ctx->zero = tcg_constant_tl(0);
+
 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
   ctx->hflags);
 }
@@ -16053,6 +16181,7 @@ static void mips_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 int insn_bytes;
 int is_slot;
+int i;
 
 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
 if (ctx->insn_flags & ISA_NANOMIPS32) {
@@ -16074,6 +16203,18 @@ static void mips_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 return;
 }
 
+for (i = ctx->ntemp - 1; i >= 0; --i) {
+tcg_temp_fre

Re: [PATCH 0/7] nsis: gitlab-ci: Improve QEMU Windows installer packaging

2022-09-21 Thread Bin Meng
Hi,

On Thu, Sep 8, 2022 at 9:28 PM Bin Meng  wrote:
>
> At present packaging the required DLLs of QEMU executables is a
> manual process, and error prone.
>
> Improve scripts/nsis.py by adding a logic to automatically package
> required DLLs of QEMU executables.
>
> 'make installer' is tested in the cross-build on Linux in CI, but
> not in the Windows native build. Update CI to test the installer
> generation on Windows too.
>
> During testing a 32-bit build issue was exposed in block/nfs.c and
> the fix is included in this series.
>
>
> Bin Meng (7):
>   scripts/nsis.py: Drop the unnecessary path separator
>   scripts/nsis.py: Fix destination directory name when invoked on
> Windows
>   scripts/nsis.py: Automatically package required DLLs of QEMU
> executables
>   .gitlab-ci.d/windows.yml: Drop the sed processing in the 64-bit build
>   block/nfs: Fix 32-bit Windows build
>   .gitlab-ci.d/windows.yml: Unify the prerequisite packages
>   .gitlab-ci.d/windows.yml: Test 'make installer' in the CI
>
>  meson.build  |  1 +
>  block/nfs.c  |  8 ++
>  .gitlab-ci.d/windows.yml | 40 ---
>  scripts/nsis.py  | 60 +---
>  4 files changed, 89 insertions(+), 20 deletions(-)
>

I see Thomas only queued patch #4 (".gitlab-ci.d/windows.yml: Drop the
sed processing in the 64-bit build")

What about other patches?

Regards,
Bin



[RFC PATCH 2/3] target/mips: Convert legacy arithmatic instructions to decodetree

2022-09-21 Thread Jiaxun Yang
Mostly copy paste from translate.c, with some simplification
based on newly introduced register access functions.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/insn_trans/trans_arith.c.inc | 352 +++
 target/mips/tcg/legacy.decode|  62 
 target/mips/tcg/meson.build  |   1 +
 target/mips/tcg/translate.c  |  20 +-
 4 files changed, 425 insertions(+), 10 deletions(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode

diff --git a/target/mips/tcg/insn_trans/trans_arith.c.inc 
b/target/mips/tcg/insn_trans/trans_arith.c.inc
new file mode 100644
index 00..3de9722939
--- /dev/null
+++ b/target/mips/tcg/insn_trans/trans_arith.c.inc
@@ -0,0 +1,352 @@
+static bool gen_arith_notrap(DisasContext *ctx, arg_r *a,
+ DisasExtend ext, void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = dest_gpr(ctx, a->rd);
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+TCGv src2 = get_gpr(ctx, a->rt, ext);
+
+func(dest, src1, src2);
+gen_set_gpr(a->rd, dest, ext);
+
+return true;
+}
+
+static bool gen_add(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = get_gpr(ctx, a->rs, ext);
+TCGv t2 = get_gpr(ctx, a->rt, ext);
+TCGLabel *l1 = gen_new_label();
+
+tcg_gen_add_tl(t0, t1, t2);
+gen_extend(t0, t0, ext);
+tcg_gen_xor_tl(t1, t1, t2);
+tcg_gen_xor_tl(t2, t0, t2);
+tcg_gen_andc_tl(t1, t2, t1);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+/* operands of same sign, result different sign */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool gen_sub(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+TCGv src2 = get_gpr(ctx, a->rt, ext);
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = tcg_temp_local_new();
+TCGv t2 = tcg_temp_local_new();
+TCGLabel *l1 = gen_new_label();
+
+tcg_gen_sub_tl(t0, src1, src2);
+gen_extend(t0, t0, ext);
+tcg_gen_xor_tl(t2, src1, src2);
+tcg_gen_xor_tl(t1, t0, src1);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+tcg_temp_free(t1);
+/*
+ * operands of different sign, first operand and the result
+ * of different sign
+ */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool gen_arith_imm_notrap(DisasContext *ctx, arg_i *a, DisasExtend ext,
+ void (*func)(TCGv, TCGv, target_long))
+{
+TCGv dest = dest_gpr(ctx, a->rt);
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+
+func(dest, src1, a->imm);
+gen_set_gpr(a->rt, dest, ext);
+
+return true;
+}
+
+static bool gen_add_imm(DisasContext *ctx, arg_i *a, DisasExtend ext)
+{
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = get_gpr(ctx, a->rs, ext);
+TCGv t2 = tcg_temp_new();
+TCGLabel *l1 = gen_new_label();
+target_ulong uimm = (target_long)a->imm; /* Sign extend to 32/64 bits */
+
+gen_load_gpr(t1, a->rs);
+tcg_gen_addi_tl(t0, t1, uimm);
+tcg_gen_ext32s_tl(t0, t0);
+
+tcg_gen_xori_tl(t1, t1, ~uimm);
+tcg_gen_xori_tl(t2, t0, uimm);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+/* operands of same sign, result different sign */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+tcg_gen_ext32s_tl(t0, t0);
+gen_store_gpr(t0, a->rt);
+tcg_temp_free(t0);
+
+return true;
+}
+
+#define DECLEAR_GEN_CL(suffix, arg_type)\
+static bool gen_cl_##suffix(DisasContext *ctx, arg_type * a, bool zero) \
+{   \
+TCGv dest = dest_gpr(ctx, a->rd);   \
+TCGv src = get_gpr(ctx, a->rs, EXT_NONE);   \
+if (!zero) {\
+tcg_gen_not_tl(dest, src);  \
+}   \
+tcg_gen_ext32u_tl(dest, dest);  \
+tcg_gen_clzi_tl(dest, dest, TARGET_LONG_BITS);  \
+tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32); \
+gen_set_gpr(a->rd, dest, EXT_NONE); \
+return true;\
+}   \
+
+DECLEAR_GEN_CL(legacy, arg_r)
+#undef DECLEAR_GEN_CL
+
+#ifdef TARGET_MIPS64
+#define DECLEAR_GEN_DCL(suffix, arg_type

[RFC PATCH 0/3] MIPS decodetree conversion attempt

2022-09-21 Thread Jiaxun Yang
Hi,

This is my attempt of converting MIPS translation code into decodetree.

Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
Old decoding functions are perserved in codebase for now due to dependencies
from microMIPS/nanoMIPS translation code. Will remove them after dealing with
release 6.

Both instruction encoding and test cases are generated form MIPS's internal
architecture validation tools so they are gureented to be correct.

Thanks.

- Jiaxun

Jiaxun Yang (3):
  target/mips: Introduce register access helper functions
  target/mips: Convert legacy arithmatic instructions to decodetree
  tests/tcg/mips: Add mips32 arithmatic instruction test cases

 target/mips/tcg/insn_trans/trans_arith.c.inc  | 352 ++
 target/mips/tcg/legacy.decode |  62 +++
 target/mips/tcg/meson.build   |   1 +
 target/mips/tcg/translate.c   | 143 ++-
 target/mips/tcg/translate.h   |  54 +++
 tests/tcg/mips/include/test_utils_32.h|  75 
 .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 +
 .../mips/user/isa/mips32/arithmatic/addi.c|  70 
 .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +
 .../mips/user/isa/mips32/arithmatic/addu.c| 125 +++
 .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 
 .../mips/user/isa/mips32/arithmatic/divu.c|  78 
 .../mips/user/isa/mips32/arithmatic/madd.c|  79 
 .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 
 .../mips/user/isa/mips32/arithmatic/msub.c|  78 
 .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 
 .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 
 .../mips/user/isa/mips32/arithmatic/mult.c|  78 
 .../mips/user/isa/mips32/arithmatic/multu.c   |  78 
 .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +++
 .../mips/user/isa/mips32/arithmatic/slti.c|  48 +++
 .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++
 .../mips/user/isa/mips32/arithmatic/sltu.c|  61 +++
 .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 ++
 .../mips/user/isa/mips32/arithmatic/subu.c| 108 ++
 25 files changed, 2206 insertions(+), 1 deletion(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c

-- 
2.34.1




Re: [PATCH v2 22/23] target/i386: Create gen_eip_cur

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Signed-off-by: Richard Henderson 
> ---
>  target/i386/tcg/translate.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 97a5f7e432..39bcb7263b 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -516,6 +516,11 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, 
> int idx, int d)
>  }
>  }
>
> +static TCGv gen_eip_cur(DisasContext *s)
> +{
> +return tcg_constant_tl(s->base.pc_next - s->cs_base);
> +}

eip_cur_tl() for consistency with eip_next_tl()?

Paolo




Re: [PATCH] target/m68k: Implement atomic test-and-set

2022-09-21 Thread Laurent Vivier

Le 29/08/2022 à 07:17, Richard Henderson a écrit :

This is slightly more complicated than cas,
because tas is allowed on data registers.

Signed-off-by: Richard Henderson 
---
  target/m68k/translate.c | 40 ++--
  1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 8f3c298ad0..0aef827b38 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2825,19 +2825,39 @@ DISAS_INSN(illegal)
  gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
  }
  
-/* ??? This should be atomic.  */

  DISAS_INSN(tas)
  {
-TCGv dest;
-TCGv src1;
-TCGv addr;
+int mode = extract32(insn, 3, 3);
+int reg0 = REG(insn, 0);
  
-dest = tcg_temp_new();

-SRC_EA(env, src1, OS_BYTE, 1, &addr);
-gen_logic_cc(s, src1, OS_BYTE);
-tcg_gen_ori_i32(dest, src1, 0x80);
-DEST_EA(env, insn, OS_BYTE, dest, &addr);
-tcg_temp_free(dest);
+if (mode == 0) {
+/* data register direct */
+TCGv dest = cpu_dregs[reg0];
+gen_logic_cc(s, dest, OS_BYTE);
+tcg_gen_ori_tl(dest, dest, 0x80);
+} else {
+TCGv src1, addr;
+
+addr = gen_lea_mode(env, s, mode, reg0, OS_BYTE);
+if (IS_NULL_QREG(addr)) {
+gen_addr_fault(s);
+return;
+}
+src1 = tcg_temp_new();
+tcg_gen_atomic_fetch_or_tl(src1, addr, tcg_constant_tl(0x80),
+   IS_USER(s), MO_SB);
+gen_logic_cc(s, src1, OS_BYTE);
+tcg_temp_free(src1);
+
+switch (mode) {
+case 3: /* Indirect postincrement.  */
+tcg_gen_addi_i32(AREG(insn, 0), addr, 1);
+break;
+case 4: /* Indirect predecrememnt.  */
+tcg_gen_mov_i32(AREG(insn, 0), addr);
+break;
+}
+}
  }
  
  DISAS_INSN(mull)


Applied to my m68k-for-7.2 branch

Thanks,
Laurent




Re: [PATCH v2 16/23] target/i386: Use DISAS_TOO_MANY to exit after gen_io_start

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> We can set is_jmp early, using only one if, and let that
> be overwritten by gen_repz_* etc.

Perhaps "be overwritten by gen_rep*'s calls to gen_jmp_rel". Code-wise,

Reviewed-by: Paolo Bonzini 

Paolo

>
> Signed-off-by: Richard Henderson 
> ---
>  target/i386/tcg/translate.c | 42 +
>  1 file changed, 10 insertions(+), 32 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 527fb79895..cedc195837 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -5605,14 +5605,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
> +s->base.is_jmp = DISAS_TOO_MANY;
>  }
>  gen_helper_rdrand(s->T0, cpu_env);
>  rm = (modrm & 7) | REX_B(s);
>  gen_op_mov_reg_v(s, dflag, rm, s->T0);
>  set_cc_op(s, CC_OP_EFLAGS);
> -if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> -gen_jmp(s, s->pc - s->cs_base);
> -}
>  break;
>
>  default:
> @@ -6658,15 +6656,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
> +s->base.is_jmp = DISAS_TOO_MANY;
>  }
>  if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
>  gen_repz_ins(s, ot);
> -/* jump generated by gen_repz_ins */
>  } else {
>  gen_ins(s, ot);
> -if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> -gen_jmp(s, s->pc - s->cs_base);
> -}
>  }
>  break;
>  case 0x6e: /* outsS */
> @@ -6679,15 +6674,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
> +s->base.is_jmp = DISAS_TOO_MANY;
>  }
>  if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
>  gen_repz_outs(s, ot);
> -/* jump generated by gen_repz_outs */
>  } else {
>  gen_outs(s, ot);
> -if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> -gen_jmp(s, s->pc - s->cs_base);
> -}
>  }
>  break;
>
> @@ -6704,13 +6696,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
> +s->base.is_jmp = DISAS_TOO_MANY;
>  }
>  gen_helper_in_func(ot, s->T1, s->tmp2_i32);
>  gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
>  gen_bpt_io(s, s->tmp2_i32, ot);
> -if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> -gen_jmp(s, s->pc - s->cs_base);
> -}
>  break;
>  case 0xe6:
>  case 0xe7:
> @@ -6722,14 +6712,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
> +s->base.is_jmp = DISAS_TOO_MANY;
>  }
>  gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
>  tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
>  gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
>  gen_bpt_io(s, s->tmp2_i32, ot);
> -if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> -gen_jmp(s, s->pc - s->cs_base);
> -}
>  break;
>  case 0xec:
>  case 0xed:
> @@ -6741,13 +6729,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
> +s->base.is_jmp = DISAS_TOO_MANY;
>  }
>  gen_helper_in_func(ot, s->T1, s->tmp2_i32);
>  gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
>  gen_bpt_io(s, s->tmp2_i32, ot);
> -if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> -gen_jmp(s, s->pc - s->cs_base);
> -}
>  break;
>  case 0xee:
>  case 0xef:
> @@ -6759,14 +6745,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
>  gen_io_start();
> +s->base.is_jmp = DISAS_TOO_MANY;
>  }
>  gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
>  tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
>  gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
>  gen_bpt_io(s, s->tmp2_i32, ot);
> -if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> -gen_jmp(s, s->pc - s->cs_base);
> -}
>  break;
>
>  //
> @@ -7432,11 +7416,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  gen_update_eip_cur(s);
>  if (tb_cflags(s->base.tb) & CF_US

Re: [PATCH 1/4] target/m68k: rename M68K_FEATURE_M68000 to M68K_FEATURE_M68K

2022-09-21 Thread Laurent Vivier

Le 17/09/2022 à 13:25, Mark Cave-Ayland a écrit :

The M68K_FEATURE_M68000 feature is misleading in that its name suggests the 
feature
is defined just for Motorola 68000 CPUs, whilst in fact it is defined for all
Motorola 680X0 CPUs.

In order to avoid confusion with the other M68K_FEATURE_M680X0 constants which
define the features available for specific Motorola CPU models, rename
M68K_FEATURE_M68000 to M68K_FEATURE_M68K and add comments to clarify its usage.

Signed-off-by: Mark Cave-Ayland 
---
  target/m68k/cpu.c   |   2 +-
  target/m68k/cpu.h   |   5 +-
  target/m68k/helper.c|   2 +-
  target/m68k/op_helper.c |   2 +-
  target/m68k/translate.c | 138 
  5 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 5bbefda575..f681be3a2a 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -110,7 +110,7 @@ static void m68000_cpu_initfn(Object *obj)
  M68kCPU *cpu = M68K_CPU(obj);
  CPUM68KState *env = &cpu->env;
  
-m68k_set_feature(env, M68K_FEATURE_M68000);

+m68k_set_feature(env, M68K_FEATURE_M68K);
  m68k_set_feature(env, M68K_FEATURE_USP);
  m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
  m68k_set_feature(env, M68K_FEATURE_MOVEP);
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 4d8f48e8c7..67b6c12c28 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -480,8 +480,9 @@ void do_m68k_semihosting(CPUM68KState *env, int nr);
   */
  
  enum m68k_features {

-/* Base m68k instruction set */
-M68K_FEATURE_M68000,
+/* Base Motorola CPU set (not set for Coldfire CPUs) */
+M68K_FEATURE_M68K,
+/* Motorola CPU feature sets */
  M68K_FEATURE_M68010,
  M68K_FEATURE_M68020,
  M68K_FEATURE_M68030,
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 5728e48585..4621cf2402 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -460,7 +460,7 @@ void m68k_switch_sp(CPUM68KState *env)
  int new_sp;
  
  env->sp[env->current_sp] = env->aregs[7];

-if (m68k_feature(env, M68K_FEATURE_M68000)) {
+if (m68k_feature(env, M68K_FEATURE_M68K)) {
  if (env->sr & SR_S) {
  /* SR:Master-Mode bit unimplemented then ISP is not available */
  if (!m68k_feature(env, M68K_FEATURE_MSP) || env->sr & SR_M) {
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index d9937ca8dc..99dc994fcb 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -433,7 +433,7 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
  
  static void do_interrupt_all(CPUM68KState *env, int is_hw)

  {
-if (m68k_feature(env, M68K_FEATURE_M68000)) {
+if (m68k_feature(env, M68K_FEATURE_M68K)) {
  m68k_interrupt_all(env, is_hw);
  return;
  }
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 5098f7e570..fad8af8f83 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -471,7 +471,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext 
*s, TCGv base)
  if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
  return NULL_QREG;
  
-if (m68k_feature(s->env, M68K_FEATURE_M68000) &&

+if (m68k_feature(s->env, M68K_FEATURE_M68K) &&
  !m68k_feature(s->env, M68K_FEATURE_SCALED_INDEX)) {
  ext &= ~(3 << 9);
  }
@@ -804,7 +804,7 @@ static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
  reg = get_areg(s, reg0);
  tmp = mark_to_release(s, tcg_temp_new());
  if (reg0 == 7 && opsize == OS_BYTE &&
-m68k_feature(s->env, M68K_FEATURE_M68000)) {
+m68k_feature(s->env, M68K_FEATURE_M68K)) {
  tcg_gen_subi_i32(tmp, reg, 2);
  } else {
  tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize));
@@ -888,7 +888,7 @@ static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, 
int mode, int reg0,
  if (what == EA_STORE || !addrp) {
  TCGv tmp = tcg_temp_new();
  if (reg0 == 7 && opsize == OS_BYTE &&
-m68k_feature(s->env, M68K_FEATURE_M68000)) {
+m68k_feature(s->env, M68K_FEATURE_M68K)) {
  tcg_gen_addi_i32(tmp, reg, 2);
  } else {
  tcg_gen_addi_i32(tmp, reg, opsize_bytes(opsize));
@@ -2210,7 +2210,7 @@ DISAS_INSN(bitop_im)
  op = (insn >> 6) & 3;
  
  bitnum = read_im16(env, s);

-if (m68k_feature(s->env, M68K_FEATURE_M68000)) {
+if (m68k_feature(s->env, M68K_FEATURE_M68K)) {
  if (bitnum & 0xfe00) {
  disas_undef(env, s, insn);
  return;
@@ -2875,7 +2875,7 @@ DISAS_INSN(mull)
  return;
  }
  SRC_EA(env, src1, OS_LONG, 0, NULL);
-if (m68k_feature(s->env, M68K_FEATURE_M68000)) {
+if (m68k_feature(s->env, M68K_FEATURE_M68K)) {
  tcg_gen_movi_i32(QREG_CC_C, 0);
  if (sign) {
  tcg_gen_muls2_i32(QREG_CC_N

Re: [PATCH 2/2] target/m68k: Perform writback before modifying SR

2022-09-21 Thread Laurent Vivier

Le 13/09/2022 à 16:28, Richard Henderson a écrit :

Writes to SR may change security state, which may involve
a swap of %ssp with %usp as reflected in %a7.  Finish the
writeback of %sp@+ before swapping stack pointers.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1206
Signed-off-by: Richard Henderson 
---
  target/m68k/translate.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 87044382c3..8506da0a0b 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2285,9 +2285,9 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, 
int ccr_only)
  tcg_gen_movi_i32(QREG_CC_N, val & CCF_N ? -1 : 0);
  tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0);
  } else {
-TCGv sr = tcg_const_i32(val);
-gen_helper_set_sr(cpu_env, sr);
-tcg_temp_free(sr);
+/* Must writeback before changing security state. */
+do_writebacks(s);
+gen_helper_set_sr(cpu_env, tcg_constant_i32(val));
  }
  set_cc_op(s, CC_OP_FLAGS);
  }
@@ -2297,6 +2297,8 @@ static void gen_set_sr(DisasContext *s, TCGv val, int 
ccr_only)
  if (ccr_only) {
  gen_helper_set_ccr(cpu_env, val);
  } else {
+/* Must writeback before changing security state. */
+do_writebacks(s);
  gen_helper_set_sr(cpu_env, val);
  }
  set_cc_op(s, CC_OP_FLAGS);


Applied to my m68k-for-7.2 branch

Thanks,
Laurent





Re: [PATCH v2 21/23] target/i386: Use gen_jmp_rel for DISAS_TOO_MANY

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> With gen_jmp_rel, we may chain between two translation blocks
> which may only be separated because of TB size limits.
>
> Signed-off-by: Richard Henderson 
> ---
>  target/i386/tcg/translate.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 7a9e533c6e..97a5f7e432 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -8740,6 +8740,9 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, 
> CPUState *cpu)
>  case DISAS_NORETURN:
>  break;
>  case DISAS_TOO_MANY:
> +gen_update_cc_op(dc);
> +gen_jmp_rel(dc, MO_32, 0, 0);
> +break;
>  case DISAS_EOB_NEXT:
>  gen_update_cc_op(dc);
>  gen_update_eip_cur(dc);

Reviewed-by: Paolo Bonzini 




Re: [PATCH v4 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Markus Armbruster
Claudio Fontana  writes:

> Hi Markus, sorry for the harsh response last week, it comes from a position 
> of lack of time,
> and the expectation that Richard's review would be enough.

I gladly accept your apology.

We had the good fortune to meet in person (at KVM Forums before the
plague).  Makes it so much easier to react "good guy is having a bad
day, try to help" instead of "bad guy, avoid".

> I don't have (and I suspect no one that is not 100% working on qemu 
> "upstream" and cannot hang around IRC channels or such)
> good visibility of what happens to patches after they are reviewed like in 
> this case,
> so this makes the process in my view overall quite unpredictable and seems to 
> require a lot of time investment for even the smallest change.

I understand.  It's a common complaint.

> That is why I would generally prefer smaller chunks of work to be committed 
> incrementally, each series self-contained,
> rather than hundred-patch series that I expect to lose momentum or get lost.
>
> There are things we can fine tune here, but I see some of the changes you 
> propose as going beyond what a fix for the acute problem really requires,
> so if this series requires a lot of work in your view for even the minimal 
> fix to be done, I think we will need someone else to step in and expand on 
> the work,
>
> or we will have to keep the fix as downstream-only for now, and I'll try to 
> find more time to invest early next year.

That's fair.

We can accept patches that don't solve the entire problem.  I still like
to understand the entire problem to a useful degree, and have a rough
idea of how a solution of the entire problem could look like.

We may then conclude that such a solution isn't in the cards right now,
but a partial solution is, so we better take it.

Sometimes, the proposed patch turns out to be not even a partial
solution (but we recognize that only now we understand the entire
problem).  Then we better reject it.

Trouble is that developing such an understanding in patch review can
easily come over as non-negotiable demands.  This can be frustrating and
demoralizing for patch submitters.  I try to avoid this trap, but I
don't always succeed.  When understanding the patch and the problem
consumes 95% of my poor brain's capacity, I'm left with 5% for
communicating...  and when 5% aren't enough, I need to apologize for not
expressing myself clearly.




Re: [PATCH v2 17/23] target/i386: Create gen_jmp_rel

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Create a common helper for pc-relative branches.
> The jmp jb insn was missing a mask for CODE32.
>
> Signed-off-by: Richard Henderson 

(Oops, my remark the previous patch should still have pointed to gen_jmp_tb).

In gen_jz_ecx_string, in the translation for LOOPNZ/LOOPZ/LOOP/JECXZ
and in i386_tr_tb_stop there is:

> -gen_jmp_tb(s, s->pc - s->cs_base, 1);
> +gen_jmp_rel(s, MO_32, 0, 1);

What happens if the instruction's last byte is at 0x? Wraparound
in the middle of an instruction is generally undefined, but I think it
should work if the instruction does not cross the 64K/4G limit (and on
real hardware, which obeys segment limits unlike TCG, said limit must
be 64K/4G of course).

In other words, why MO_32 and not "CODE32(s) ? MO_32 : MO_16"?
Likewise, if you change that you need to change gen_repz/gen_repz2
too.

Paolo


>  gen_set_label(l1);
>  return l2;
>  }
> @@ -2756,6 +2757,18 @@ static void gen_jmp_tb(DisasContext *s, target_ulong 
> eip, int tb_num)
>  }
>  }
>
> +static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
> +{
> +target_ulong dest = s->pc - s->cs_base + diff;
> +
> +if (ot == MO_16) {
> +dest &= 0x;
> +} else if (!CODE64(s)) {
> +dest &= 0x;
> +}
> +gen_jmp_tb(s, dest, tb_num);
> +}
> +
>  static void gen_jmp(DisasContext *s, target_ulong eip)
>  {
>  gen_jmp_tb(s, eip, 0);
> @@ -6816,20 +6829,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  break;
>  case 0xe8: /* call im */
>  {
> -if (dflag != MO_16) {
> -tval = (int32_t)insn_get(env, s, MO_32);
> -} else {
> -tval = (int16_t)insn_get(env, s, MO_16);
> -}
> -tval += s->pc - s->cs_base;
> -if (dflag == MO_16) {
> -tval &= 0x;
> -} else if (!CODE64(s)) {
> -tval &= 0x;
> -}
> +int diff = (dflag != MO_16
> +? (int32_t)insn_get(env, s, MO_32)
> +: (int16_t)insn_get(env, s, MO_16));
>  gen_push_v(s, eip_next_tl(s));
>  gen_bnd_jmp(s);
> -gen_jmp(s, tval);
> +gen_jmp_rel(s, dflag, diff, 0);
>  }
>  break;
>  case 0x9a: /* lcall im */
> @@ -6847,19 +6852,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  goto do_lcall;
>  case 0xe9: /* jmp im */
> -if (dflag != MO_16) {
> -tval = (int32_t)insn_get(env, s, MO_32);
> -} else {
> -tval = (int16_t)insn_get(env, s, MO_16);
> +{
> +int diff = (dflag != MO_16
> +? (int32_t)insn_get(env, s, MO_32)
> +: (int16_t)insn_get(env, s, MO_16));
> +gen_bnd_jmp(s);
> +gen_jmp_rel(s, dflag, diff, 0);
>  }
> -tval += s->pc - s->cs_base;
> -if (dflag == MO_16) {
> -tval &= 0x;
> -} else if (!CODE64(s)) {
> -tval &= 0x;
> -}
> -gen_bnd_jmp(s);
> -gen_jmp(s, tval);
>  break;
>  case 0xea: /* ljmp im */
>  {
> @@ -6876,12 +6875,10 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  goto do_ljmp;
>  case 0xeb: /* jmp Jb */
> -tval = (int8_t)insn_get(env, s, MO_8);
> -tval += s->pc - s->cs_base;
> -if (dflag == MO_16) {
> -tval &= 0x;
> +{
> +int diff = (int8_t)insn_get(env, s, MO_8);
> +gen_jmp_rel(s, dflag, diff, 0);
>  }
> -gen_jmp(s, tval);
>  break;
>  case 0x70 ... 0x7f: /* jcc Jb */
>  tval = (int8_t)insn_get(env, s, MO_8);
> --
> 2.34.1
>




Re: [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
> -static inline void gen_jcc(DisasContext *s, int b,
> -   target_ulong val, target_ulong next_eip)
> +static void gen_jcc(DisasContext *s, MemOp ot, int b, int diff)
>  {
> -TCGLabel *l1, *l2;
> +TCGLabel *l1 = gen_new_label();
>
> -if (s->jmp_opt) {
> -l1 = gen_new_label();
> -gen_jcc1(s, b, l1);
> -
> -gen_goto_tb(s, 0, next_eip);
> -
> -gen_set_label(l1);
> -gen_goto_tb(s, 1, val);
> -} else {
> -l1 = gen_new_label();
> -l2 = gen_new_label();
> -gen_jcc1(s, b, l1);
> -
> -gen_jmp_im(s, next_eip);
> -tcg_gen_br(l2);
> -
> -gen_set_label(l1);
> -gen_jmp_im(s, val);
> -gen_set_label(l2);
> -gen_eob(s);
> -}
> +gen_jcc1(s, b, l1);
> +gen_jmp_rel(s, ot, 0, 1);
> +gen_set_label(l1);
> +gen_jmp_rel(s, ot, diff, 0);

Might be worth a comment that jumps with 16-bit operand size truncate
EIP even if the jump is not taken.

Otherwise,

Reviewed-by: Paolo Bonzini 

Paolo

>  }
>
>  static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b,
> @@ -4721,7 +4703,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  int shift;
>  MemOp ot, aflag, dflag;
>  int modrm, reg, rm, mod, op, opreg, val;
> -target_ulong next_eip, tval;
>  bool orig_cc_op_dirty = s->cc_op_dirty;
>  CCOp orig_cc_op = s->cc_op;
>
> @@ -6881,22 +6862,20 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  }
>  break;
>  case 0x70 ... 0x7f: /* jcc Jb */
> -tval = (int8_t)insn_get(env, s, MO_8);
> -goto do_jcc;
> +{
> +int diff = (int8_t)insn_get(env, s, MO_8);
> +gen_bnd_jmp(s);
> +gen_jcc(s, dflag, b, diff);
> +}
> +break;
>  case 0x180 ... 0x18f: /* jcc Jv */
> -if (dflag != MO_16) {
> -tval = (int32_t)insn_get(env, s, MO_32);
> -} else {
> -tval = (int16_t)insn_get(env, s, MO_16);
> +{
> +int diff = (dflag != MO_16
> +? (int32_t)insn_get(env, s, MO_32)
> +: (int16_t)insn_get(env, s, MO_16));
> +gen_bnd_jmp(s);
> +gen_jcc(s, dflag, b, diff);
>  }
> -do_jcc:
> -next_eip = s->pc - s->cs_base;
> -tval += next_eip;
> -if (dflag == MO_16) {
> -tval &= 0x;
> -}
> -gen_bnd_jmp(s);
> -gen_jcc(s, b, tval, next_eip);
>  break;
>
>  case 0x190 ... 0x19f: /* setcc Gv */
> --
> 2.34.1
>




Re: [PATCH 4/4] target/m68k: always call gen_exit_tb() after writes to SR

2022-09-21 Thread Laurent Vivier

Le 17/09/2022 à 13:25, Mark Cave-Ayland a écrit :

Any write to SR can change the security state so always call gen_exit_tb() when
this occurs. In particular MacOS makes use of andiw/oriw in a few places to
handle the switch between user and supervisor mode.

Signed-off-by: Mark Cave-Ayland 
---
  target/m68k/translate.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index be5561e1e9..892473d01f 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2373,6 +2373,7 @@ DISAS_INSN(arith_im)
  tcg_gen_or_i32(dest, src1, im);
  if (with_SR) {
  gen_set_sr(s, dest, opsize == OS_BYTE);
+gen_exit_tb(s);
  } else {
  DEST_EA(env, insn, opsize, dest, &addr);
  gen_logic_cc(s, dest, opsize);
@@ -2382,6 +2383,7 @@ DISAS_INSN(arith_im)
  tcg_gen_and_i32(dest, src1, im);
  if (with_SR) {
  gen_set_sr(s, dest, opsize == OS_BYTE);
+gen_exit_tb(s);
  } else {
  DEST_EA(env, insn, opsize, dest, &addr);
  gen_logic_cc(s, dest, opsize);
@@ -2405,6 +2407,7 @@ DISAS_INSN(arith_im)
  tcg_gen_xor_i32(dest, src1, im);
  if (with_SR) {
  gen_set_sr(s, dest, opsize == OS_BYTE);
+gen_exit_tb(s);
  } else {
  DEST_EA(env, insn, opsize, dest, &addr);
  gen_logic_cc(s, dest, opsize);
@@ -4592,6 +4595,7 @@ DISAS_INSN(strldsr)
  }
  gen_push(s, gen_get_sr(s));
  gen_set_sr_im(s, ext, 0);
+gen_exit_tb(s);
  }
  
  DISAS_INSN(move_from_sr)


Applied to my m68k-for-7.2 branch

Thanks,
Laurent




Re: [PATCH 1/2] target/m68k: Fix MACSR to CCR

2022-09-21 Thread Laurent Vivier

Le 13/09/2022 à 16:28, Richard Henderson a écrit :

First, we were writing to the entire SR register, instead
of only the flags portion.  Second, we were not clearing C
as per the documentation (X was cleared via the 0xf mask).

Signed-off-by: Richard Henderson 
---
  target/m68k/translate.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 5098f7e570..87044382c3 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -5892,8 +5892,10 @@ DISAS_INSN(from_mext)
  DISAS_INSN(macsr_to_ccr)
  {
  TCGv tmp = tcg_temp_new();
-tcg_gen_andi_i32(tmp, QREG_MACSR, 0xf);
-gen_helper_set_sr(cpu_env, tmp);
+
+/* Note that X and C are always cleared. */
+tcg_gen_andi_i32(tmp, QREG_MACSR, CCF_N | CCF_Z | CCF_V);
+gen_helper_set_ccr(cpu_env, tmp);
  tcg_temp_free(tmp);
  set_cc_op(s, CC_OP_FLAGS);
  }


Applied to my m68k-for-7.2 branch

Thanks,
Laurent




Re: [PATCH v2] hw/acpi: Add ospm_status hook implementation for acpi-ged

2022-09-21 Thread Igor Mammedov
On Tue, 20 Sep 2022 14:15:36 +0100
Peter Maydell  wrote:

> On Wed, 24 Aug 2022 at 16:04, Igor Mammedov  wrote:
> >
> > On Tue, 16 Aug 2022 17:49:57 +0800
> > Keqian Zhu  wrote:
> >  
> > > Setup an ARM virtual machine of machine virt and execute qmp 
> > > "query-acpi-ospm-status"
> > > causes segmentation fault with following dumpstack:
> > >  #1  0xab64235c in qmp_query_acpi_ospm_status 
> > > (errp=errp@entry=0xf030) at ../monitor/qmp-cmds.c:312
> > >  #2  0xabfc4e20 in qmp_marshal_query_acpi_ospm_status 
> > > (args=, ret=0xea4ffe90, errp=0xea4ffe88) at 
> > > qapi/qapi-commands-acpi.c:63
> > >  #3  0xabff8ba0 in do_qmp_dispatch_bh (opaque=0xea4ffe98) at 
> > > ../qapi/qmp-dispatch.c:128
> > >  #4  0xac02e594 in aio_bh_call (bh=0xe0004d80) at 
> > > ../util/async.c:150
> > >  #5  aio_bh_poll (ctx=ctx@entry=0xad0f6040) at ../util/async.c:178
> > >  #6  0xac00bd40 in aio_dispatch (ctx=ctx@entry=0xad0f6040) at 
> > > ../util/aio-posix.c:421
> > >  #7  0xac02e010 in aio_ctx_dispatch (source=0xad0f6040, 
> > > callback=, user_data=) at 
> > > ../util/async.c:320
> > >  #8  0xf76f6884 in g_main_context_dispatch () at 
> > > /usr/lib64/libglib-2.0.so.0
> > >  #9  0xac0452d4 in glib_pollfds_poll () at ../util/main-loop.c:297
> > >  #10 os_host_main_loop_wait (timeout=0) at ../util/main-loop.c:320
> > >  #11 main_loop_wait (nonblocking=nonblocking@entry=0) at 
> > > ../util/main-loop.c:596
> > >  #12 0xab5c9e50 in qemu_main_loop () at ../softmmu/runstate.c:734
> > >  #13 0xab185370 in qemu_main (argc=argc@entry=47, 
> > > argv=argv@entry=0xf518, envp=envp@entry=0x0) at 
> > > ../softmmu/main.c:38
> > >  #14 0xab16f99c in main (argc=47, argv=0xf518) at 
> > > ../softmmu/main.c:47
> > >
> > > Fixes: ebb62075021a ("hw/acpi: Add ACPI Generic Event Device Support")
> > > Signed-off-by: Keqian Zhu   
> >
> > Reviewed-by: Igor Mammedov   
> 
> I notice this doesn't seem to have gone in yet -- whose tree is it
> going to go via?

I'd guess ARM tree (due to almost sole user virt-arm).
(there are toy users like microvm and new loongarch)

> 
> thanks
> -- PMM
> 




Re: [PATCH 13/14] migration: Remove old preempt code around state maintainance

2022-09-21 Thread Peter Xu
On Tue, Sep 20, 2022 at 08:47:20PM -0400, Peter Xu wrote:
> On Tue, Sep 20, 2022 at 06:52:27PM -0400, Peter Xu wrote:
> > With the new code to send pages in rp-return thread, there's little help to
> > keep lots of the old code on maintaining the preempt state in migration
> > thread, because the new way should always be faster..
> > 
> > Then if we'll always send pages in the rp-return thread anyway, we don't
> > need those logic to maintain preempt state anymore because now we serialize
> > things using the mutex directly instead of using those fields.
> > 
> > It's very unfortunate to have those code for a short period, but that's
> > still one intermediate step that we noticed the next bottleneck on the
> > migration thread.  Now what we can do best is to drop unnecessary code as
> > long as the new code is stable to reduce the burden.  It's actually a good
> > thing because the new "sending page in rp-return thread" model is (IMHO)
> > even cleaner and with better performance.
> > 
> > Remove the old code that was responsible for maintaining preempt states, at
> > the meantime also remove x-postcopy-preempt-break-huge parameter because
> > with concurrent sender threads we don't really need to break-huge anymore.
> > 
> > Signed-off-by: Peter Xu 
> > ---
> >  migration/migration.c |   2 -
> >  migration/ram.c   | 258 +-
> >  2 files changed, 3 insertions(+), 257 deletions(-)
> > 
> > diff --git a/migration/migration.c b/migration/migration.c
> > index fae8fd378b..698fd94591 100644
> > --- a/migration/migration.c
> > +++ b/migration/migration.c
> > @@ -4399,8 +4399,6 @@ static Property migration_properties[] = {
> >  DEFINE_PROP_SIZE("announce-step", MigrationState,
> >parameters.announce_step,
> >DEFAULT_MIGRATE_ANNOUNCE_STEP),
> > -DEFINE_PROP_BOOL("x-postcopy-preempt-break-huge", MigrationState,
> > -  postcopy_preempt_break_huge, true),
> 
> Forgot to drop the variable altogether:
> 
> diff --git a/migration/migration.h b/migration/migration.h
> index cdad8aceaa..ae4ffd3454 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -340,13 +340,6 @@ struct MigrationState {
>  bool send_configuration;
>  /* Whether we send section footer during migration */
>  bool send_section_footer;
> -/*
> - * Whether we allow break sending huge pages when postcopy preempt is
> - * enabled.  When disabled, we won't interrupt precopy within sending a
> - * host huge page, which is the old behavior of vanilla postcopy.
> - * NOTE: this parameter is ignored if postcopy preempt is not enabled.
> - */
> -bool postcopy_preempt_break_huge;
>  
>  /* Needed by postcopy-pause state */
>  QemuSemaphore postcopy_pause_sem;
> 
> Will squash this in in next version.

Two more varialbes to drop, as attached..


-- 
Peter Xu
>From b3308e34398e21c19bd36ec21aae9c7f9f623d75 Mon Sep 17 00:00:00 2001
From: Peter Xu 
Date: Wed, 21 Sep 2022 09:51:55 -0400
Subject: [PATCH] fixup! migration: Remove old preempt code around state
 maintainance
Content-type: text/plain

Signed-off-by: Peter Xu 
---
 migration/ram.c | 33 -
 1 file changed, 33 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 03bf2324ab..2599eee070 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -97,28 +97,6 @@ struct PageSearchStatus {
 unsigned long page;
 /* Set once we wrap around */
 bool complete_round;
-/*
- * [POSTCOPY-ONLY] Whether current page is explicitly requested by
- * postcopy.  When set, the request is "urgent" because the dest QEMU
- * threads are waiting for us.
- */
-bool postcopy_requested;
-/*
- * [POSTCOPY-ONLY] The target channel to use to send current page.
- *
- * Note: This may _not_ match with the value in postcopy_requested
- * above. Let's imagine the case where the postcopy request is exactly
- * the page that we're sending in progress during precopy. In this case
- * we'll have postcopy_requested set to true but the target channel
- * will be the precopy channel (so that we don't split brain on that
- * specific page since the precopy channel already contains partial of
- * that page data).
- *
- * Besides that specific use case, postcopy_target_channel should
- * always be equal to postcopy_requested, because by default we send
- * postcopy pages via postcopy preempt channel.
- */
-bool postcopy_target_channel;
 /* Whether we're sending a host page */
 bool  host_page_sending;
 /* The start/end of current host page.  Invalid if 
host_page_sending==false */
@@ -1573,13 +1551,6 @@ retry:
  */
 static bool find_dirty_block(RAMState *rs, PageSearchStatus *pss, bool *again)
 {
-/*
- * This is not a postcopy requested page, mark it "not urgent", and use
- * preco

Re: [PATCH v2 18/23] target/i386: Use gen_jmp_rel for loop and jecxz insns

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> With gen_jmp_rel, we may chain to the next tb
> instead of merely writing to eip and exiting.
>
> Signed-off-by: Richard Henderson 

See comment on the previous patch.

Paolo

> ---
>  target/i386/tcg/translate.c | 21 ++---
>  1 file changed, 6 insertions(+), 15 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 07c7764649..fdd17c3cf3 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -7355,24 +7355,18 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  case 0xe2: /* loop */
>  case 0xe3: /* jecxz */
>  {
> -TCGLabel *l1, *l2, *l3;
> -
> -tval = (int8_t)insn_get(env, s, MO_8);
> -tval += s->pc - s->cs_base;
> -if (dflag == MO_16) {
> -tval &= 0x;
> -}
> +TCGLabel *l1, *l2;
> +int diff = (int8_t)insn_get(env, s, MO_8);
>
>  l1 = gen_new_label();
>  l2 = gen_new_label();
> -l3 = gen_new_label();
>  gen_update_cc_op(s);
>  b &= 3;
>  switch(b) {
>  case 0: /* loopnz */
>  case 1: /* loopz */
>  gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
> -gen_op_jz_ecx(s, s->aflag, l3);
> +gen_op_jz_ecx(s, s->aflag, l2);
>  gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
>  break;
>  case 2: /* loop */
> @@ -7385,14 +7379,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>  break;
>  }
>
> -gen_set_label(l3);
> -gen_update_eip_next(s);
> -tcg_gen_br(l2);
> +gen_set_label(l2);
> +gen_jmp_rel(s, MO_32, 0, 1);
>
>  gen_set_label(l1);
> -gen_jmp_im(s, tval);
> -gen_set_label(l2);
> -s->base.is_jmp = DISAS_EOB_ONLY;
> +gen_jmp_rel(s, dflag, diff, 0);
>  }
>  break;
>  case 0x130: /* wrmsr */
> --
> 2.34.1
>




Re: [PATCH v3 4/5] acpi/nvdimm: Implement ACPI NVDIMM Label Methods

2022-09-21 Thread Igor Mammedov
On Tue, 20 Sep 2022 20:28:31 +0800
Robert Hoo  wrote:

> On Tue, 2022-09-20 at 11:13 +0200, Igor Mammedov wrote:
> > On Fri, 16 Sep 2022 21:15:35 +0800
> > Robert Hoo  wrote:
> >   
> > > On Fri, 2022-09-16 at 09:37 +0200, Igor Mammedov wrote:
> > >   
> > > > > Fine, get your point now.
> > > > > In ASL it will look like this:
> > > > > Local1 = Package (0x3) {STTS, SLSA, MAXT}
> > > > > Return (Local1)
> > > > 
> > > > 
> > > > > 
> > > > > But as for 
> > > > > CreateDWordField (Local0, Zero, STTS)  //
> > > > > Status
> > > > > CreateDWordField (Local0, 0x04, SLSA)  //
> > > > > SizeofLSA
> > > > > CreateDWordField (Local0, 0x08, MAXT)  //
> > > > > Max
> > > > > Trans
> > > > > 
> > > > > I cannot figure out how to substitute with LocalX. Can you shed
> > > > > more
> > > > > light?
> > > > 
> > > > Leave this as is, there is no way to make it anonymous/local with
> > > > FooField.
> > > > 
> > > > (well one might try to use Index and copy field's bytes into a
> > > > buffer
> > > > and
> > > > then explicitly convert to Integer, but that's a rather
> > > > convoluted
> > > > way
> > > > around limitation so I'd not go this route)
> > > > 
> > > 
> > > OK, pls. take a look, how about this?
> > > 
> > > Method (_LSI, 0, Serialized)  // _LSI: Label Storage Information
> > > {   
> > > Local0 = NCAL (ToUUID("4309ac30-0d11-11e4-9191-0800200c9a66"),
> > > 0x02, 0x04, Zero, One)// Buffer
> > > CreateDWordField (Local0, Zero, STTS)  // Status
> > > CreateDWordField (Local0, 0x04, SLSA)  // Size of LSA
> > > CreateDWordField (Local0, 0x08, MAXT)  // Max Transfer Size
> > > Local1 = Package (0x3) {STTS, SLSA, MAXT}
> > > Return (Local1)
> > > }
> > > 
> > > Method (_LSR, 2, Serialized)  // _LSR: Label Storage Read
> > > {
> > > Name (INPT, Buffer(8) {})
> > > CreateDWordField (INPT, Zero, OFST);
> > > CreateDWordField (INPT, 4, LEN);  
> > 
> > why do you have to create and use INPT, wouldn't local be enough to
> > keep the buffer?  
> 
> If substitute INPT with LocalX, then later
> Local0 = Package (0x01) {LocalX} isn't accepted.
> 
> PackageElement :=
> DataObject | NameString

ok, then respin series and lets get it some testing.

BTW:
it looks like Windows Server starting from v2019 has support for
NVDIMM-P devices which came with 'Optane DC Persistent Memory Modules'
but it fails to recognize NVDIMMs in QEMU (complaining something about
wrong target). Perhaps you can reach someone with Optane/ACPI
expertise within your org and try to fix QEMU side.

> >   
> > > OFST = Arg0
> > > LEN = Arg1
> > > Local0 = Package (0x01) {INPT}
> > > Local3 = NCAL (ToUUID("4309ac30-0d11-11e4-9191-0800200c9a66"),
> > > 0x02, 0x05, Local0, One)
> > > CreateDWordField (Local3, Zero, STTS)
> > > CreateField (Local3, 32, LEN << 3, LDAT)
> > > Local1 = Package (0x2) {STTS, toBuffer(LDAT)}
> > > Return (Local1)
> > > }
> > > 
> > > Method (_LSW, 3, Serialized)  // _LSW: Label Storage Write
> > > {
> > > Local2 = Arg2
> > > Name (INPT, Buffer(8) {})  
> > 
> > ditto
> >   
> > > CreateDWordField (INPT, Zero, OFST);
> > > CreateDWordField (INPT, 4, TLEN);
> > > OFST = Arg0
> > > TLEN = Arg1
> > > Concatenate(INPT, Local2, INPT)
> > > Local0 = Package (0x01)
> > > {
> > > INPT
> > > }
> > > Local3 = NCAL (ToUUID ("4309ac30-0d11-11e4-9191-0800200c9a66"),
> > > 0x02, 0x06, Local0, One)
> > > CreateDWordField (Local3, 0, STTS)
> > > Return (STTS)
> > > }  
> 
> 




Re: [RFC 1/4] docs/tcg-plugins: describe QPP API

2022-09-21 Thread Alex Bennée


Andrew Fasano  writes:

> Describe how multiple TCG plugins can interact using the QEMU
> Plugin-to-Plugin API (QPP) with both callbacks and direct
> function calls.

Looks ok at first glance. I suspect it is quickly coming to the point we
need to split the examples and the API apart in the docs to stop things
getting too messy.

>
> Signed-off-by: Andrew Fasano 
> ---
>  docs/devel/tcg-plugins.rst | 76 ++
>  1 file changed, 76 insertions(+)
>
> diff --git a/docs/devel/tcg-plugins.rst b/docs/devel/tcg-plugins.rst
> index a7cc44aa20..7985572027 100644
> --- a/docs/devel/tcg-plugins.rst
> +++ b/docs/devel/tcg-plugins.rst
> @@ -441,3 +441,79 @@ The plugin has a number of arguments, all of them are 
> optional:
>associativity of the L2 cache, respectively. Setting any of the L2
>configuration arguments implies ``l2=on``.
>(default: N = 2097152 (2MB), B = 64, A = 16)
> +
> +Plugin-to-Plugin Interactions
> +-
> +
> +Plugins may interact with other plugins through the QEMU Plugin-to-Plugin
> +("QPP") API by including ``qemu/plugin-qpp.h``. This API supports direct
> +function calls between plugins as well as an inter-plugin callback system.
> +This API allows for composition of plugins: plugins can make use of logic in
> +other plugins without the need for code duplication.
> +
> +Plugin names
> +
> +Plugins are automatically given a name by removing the suffix from their
> +filename.  These plugin names will be used during QPP interactions as
> +described below.  A plugin can access its own name through the preprocessor
> +variable ``CURRENT_PLUGIN``.
> +
> +QPP function calls
> +~~
> +When a plugin (e.g. ``plugin_a``) wishes to make some of its functions (e.g.
> +``func_1``) available to other plugins, it must:
> +
> +1. Mark the function definition with the ``QEMU_PLUGIN_EXPORT`` macro. For
> +example : ``QEMU_PLUGIN_EXPORT int func_1(int x) {...}``.
> +2. Provide prototypes for exported functions in a header file (e.g.
> +``plugin_a.h``) using the macro ``QPP_FUN_PROTOTYPE`` with arguments of the
> +plugin's name, the function's return type, the function's name, and any
> +arguments the function takes. For example:
> +``QPP_FUN_PROTOTYPE(plugin_a, int, func_1, int);``.
> +3. Import this header from the plugin.
> +
> +When other plugins wish to use the functions exported by ``plugin_a``, they
> +must:
> +
> +1. Import the header file (e.g. ``plugin_a.h``) with the function 
> prototype(s).
> +2. Call the function when desired by combining the target plugin name, an
> +   underscore, and the target function name, e.g. ``plugin_a_func_1()``.
> +
> +QPP callbacks
> +~
> +
> +The QPP API also allows a plugin to define callback events and for other 
> plugins
> +to request to be notified whenever these events happens. The plugin that 
> defines
> +the callback is responsible for triggering the callback when it so wishes. 
> Other
> +plugins that wish to be notified on these events must define a function of an
> +appropriate type and register it to run on this event.
> +
> +When a plugin (e.g. ``plugin_a``) wishes to define a callback (an event that
> +other plugins can request to be notified about), it must:
> +
> +1. Define the callback using the ``QPP_CREATE_CB`` macro with a single 
> argument
> +   of the callback's name. For example: ``QPP_CREATE_CB(on_some_event);``.
> +2. In a header file (e.g. ``plugin_a.h``) create a prototype for the callback
> +   type with ``QPP_CB_PROTOTYPE`` with arguments of the callback's return 
> type
> +   (only ``void`` is currently supported), the name of the callback, and any
> +   arguments the callback function will be called with. For example with a
> +   callback named ``on_some_event`` that returns a void and takes an int and
> +   a bool as an argument, you would use: ``QPP_CB_PROTOTYPE(void,
> +   on_some_event, int, bool)``.
> +3. Import this header from the plugin.
> +4. When the plugin wishes to run any registered callback functions, it should
> +   use the macro ``QPP_RUN_CB`` with the first argument set to the callback
> +   name followed by the arguments as specified in the header. For example:
> +   ``QPP_RUN_CB(on_some_event, 2, true);``.
> +
> +When other plugins wish to register a function to run on such an event, they
> +must:
> +
> +1. Import the header file with the callback prototype(s) (e.g. 
> ``plugin_a.h``)
> +2. Define a function that matches the callback signature. For example:
> +   ``void plugin_b_callback(int, bool) {...}``.
> +3. Register this function to be run on the callback using the ``QPP_REG_CB``
> +   macro with the first argument being the name of the plugin that provides 
> the
> +   callback (as a string), the second being the callback name, and the third 
> as
> +   the function that should be run. For example: ``QPP_REG_CB("plugin_a",
> +   on_some_event, plugin_b_callback);``


-- 
Alex Bennée



Re: [PATCH v2 20/23] target/i386: Use gen_jmp_rel for gen_repz*

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> Subtract cur_insn_len to restart the current insn.
>
> Signed-off-by: Richard Henderson 

I wouldn't mind squashing this with the jecxz/loop patch (and the
review comments there apply here too).

Paolo

> ---
>  target/i386/tcg/translate.c | 10 ++
>  1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index e27f36e4e9..7a9e533c6e 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -224,7 +224,6 @@ STUB_HELPER(wrmsr, TCGv_env env)
>
>  static void gen_eob(DisasContext *s);
>  static void gen_jr(DisasContext *s);
> -static void gen_jmp(DisasContext *s, target_ulong eip);
>  static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
>  static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
>  static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
> @@ -1277,7 +1276,7 @@ static void gen_repz(DisasContext *s, MemOp ot,
>  if (s->repz_opt) {
>  gen_op_jz_ecx(s, s->aflag, l2);
>  }
> -gen_jmp(s, s->base.pc_next - s->cs_base);
> +gen_jmp_rel(s, MO_32, -cur_insn_len(s), 0);
>  }
>
>  #define GEN_REPZ(op) \
> @@ -1297,7 +1296,7 @@ static void gen_repz2(DisasContext *s, MemOp ot, int nz,
>  if (s->repz_opt) {
>  gen_op_jz_ecx(s, s->aflag, l2);
>  }
> -gen_jmp(s, s->base.pc_next - s->cs_base);
> +gen_jmp_rel(s, MO_32, -cur_insn_len(s), 0);
>  }
>
>  #define GEN_REPZ2(op) \
> @@ -2751,11 +2750,6 @@ static void gen_jmp_rel(DisasContext *s, MemOp ot, int 
> diff, int tb_num)
>  gen_jmp_tb(s, dest, tb_num);
>  }
>
> -static void gen_jmp(DisasContext *s, target_ulong eip)
> -{
> -gen_jmp_tb(s, eip, 0);
> -}
> -
>  static inline void gen_ldq_env_A0(DisasContext *s, int offset)
>  {
>  tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
> --
> 2.34.1
>




Re: [PATCH 2/4] target/m68k: increase size of m68k CPU features from uint32_t to uint64_t

2022-09-21 Thread Laurent Vivier

Le 20/09/2022 à 18:30, Mark Cave-Ayland a écrit :

On 17/09/2022 23:27, Philippe Mathieu-Daudé via wrote:


On 17/9/22 14:09, BALATON Zoltan wrote:

On Sat, 17 Sep 2022, Mark Cave-Ayland wrote:

There are already 32 feature bits in use, so change the size of the m68k
CPU features to uint64_t (allong with the associated m68k_feature()
functions) to allow up to 64 feature bits to be used.

Signed-off-by: Mark Cave-Ayland 
---
target/m68k/cpu.c | 4 ++--
target/m68k/cpu.h | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index f681be3a2a..7b4797e2f1 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -38,12 +38,12 @@ static bool m68k_cpu_has_work(CPUState *cs)

static void m68k_set_feature(CPUM68KState *env, int feature)
{
-    env->features |= (1u << feature);
+    env->features |= (1ul << feature);


 env->features = deposit64(env->features, feature, 1, 1);


}

static void m68k_unset_feature(CPUM68KState *env, int feature)
{
-    env->features &= (-1u - (1u << feature));
+    env->features &= (-1ul - (1ul << feature));


 env->features = deposit64(env->features, feature, 1, 0);


Should these be ull instead of ul?


Yes. Not needed if using the  extract/deposit API.


I must admit I find the deposit64() variants not particularly easy to read: if we're considering 
alterations rather than changing the constant suffix then I'd much rather go for:


     env->features |= (1ULL << feature);

and:

     env->features &= ~(1ULL << feature);

Laurent, what would be your preference?


I have no preference, do as you prefer.




}

static void m68k_cpu_reset(DeviceState *dev)
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 67b6c12c28..d3384e5d98 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -154,7 +154,7 @@ typedef struct CPUArchState {
    struct {} end_reset_fields;

    /* Fields from here on are preserved across CPU reset. */
-    uint32_t features;
+    uint64_t features;
} CPUM68KState;

/*
@@ -539,9 +539,9 @@ enum m68k_features {
    M68K_FEATURE_TRAPCC,
};

-static inline int m68k_feature(CPUM68KState *env, int feature)
+static inline uint64_t m68k_feature(CPUM68KState *env, int feature)


Why uint64_t? Can we simplify using a boolean?


I don't really feel strongly either way here. Again I'm happy to go with whatever Laurent would 
prefer as maintainer.


A boolean seems more logic, I think.

Thanks,
Laurent



Re: [RFC 0/4] Support interactions between TCG plugins

2022-09-21 Thread Alex Bennée


Andrew Fasano  writes:

> Hello,
>
> I'm requesting comments on the following series of patches expanding the
> TCG plugin system to add the "QEMU Plugin-to-Plugin (QPP)" interface
> that allows for interactions between TCG plugins. The goal of this
> interface is to enable plugins to expand on other plugins and reduce
> code duplication. This patch series includes documentation and
> significant comments, but a high-level summary is below along with a
> discussion of the current implementation as well as the benefits and
> drawbacks of these changes.

Thanks for a very detailed cover letter. My initial thoughts are if we
are trying to reduce code duplication what about simply using a library
and linking it to the final plugin. I guess it depends on how
computational effort has been spent in calculating a particular piece of
state and if that is avoided by having this IPC mechanism instead of
just repeating the calculation.

> **Summary**
>
> The QPP interface allows two types of interactions between plugins:
>
> 1) Exported functions: A plugin may wish to allow other plugins to call
> one of the functions it has defined. To do this, the plugin must mark
> the function definition as publicly visible with the QEMU_PLUGIN_EXPORT
> macro and place a definition in an included header file using the
> QPP_FUN_PROTOTYPE macro. Other plugins can then include this header and
> call the exported function by combining the name of the target plugin
> with the name of the exported function.
>
> For example, consider a hypothetical plugin that collects a list of
> cache misses. This plugin could export two functions using the QPP
> interface: one to allow another plugin to query this list and another
> to empty the list. This would enable the development of another plugin
> that examines guest CPU state to identify process changes and reports
> the cache misses per process. With the QPP interface, this second plugin
> would not need to duplicate any logic from the first.

Thinking of this concrete example I guess the process change detection
is a fairly expensive operation that might be tuned to a particular
architecture? Is this something Panda currently derives from plugins
instead of the core QEMU code?

> 2) Callbacks: Multiple plugins may wish to take some action when some
> event of interest occurs inside a running guest. To support modularity
> and reduce code duplication, the QPP callback system allows this logic
> to be contained in single plugin that detects whenever a given event
> occurs and exposes a callback with a given name. Another plugin can then
> request to have one of its own functions run whenever this event occurs.
> Additional plugins could also use this same callback to run additional
> logic whenever this event occurs.
>
> For example, consider (again) a hypothetical plugin that detects when
> the current guest process changes by analyzing the guest CPU state. This
> plugin could define a callback named "on_process_change" and trigger
> this callback event whenever it detects a process change. Other plugins
> could then be developed that take various actions on process changes by
> registering internal functions to run on this event.
>
> These patches and examples are inspired by the PANDA project
> (https://panda.re and https://github.com/panda-re/panda), a fork of QEMU
> modified to support dynamic program analysis and reverse engineering.
> PANDA also includes a large plugin system with a similar interface for
> interactions between plugins. I'm one of the maintainers of PANDA
> and have seen how the ability for plugins to interact with
> other plugins reduces code duplication and enables the creation of many
> useful plugins.

Would another use-case be to export the PANDA APIs so you could use the
existing plugins on an upstream QEMU?

> **Implementation Overview**
>
> These patches modify the TCG plugin build system to define the 
> preprocessor variable CURRENT_PLUGIN to the name of the current plugin
> based off its filename. This can be useful for plugin developers in
> general and is used internally in the QPP implementation to determine
> if an exported plugin function is defined in the current plugin or
> in another.
>
> These patches also add the function qemu_plugin_name_to_handle to the 
> core plugin API which uses the new internal function is_plugin_named.
> The ability for plugins to get a handle to another plugin is necessary
> for the inter-plugin interactions described below.
>
> The QPP implementation is contained inside a header file plugin-qpp.h
> that adds the macros QPP_CREATE_CB, QPP_RUN_CB, QPP_REG_CB,
> QPP_REMOVE_CB, and QPP_FUN_PROTOTYPE. The first 4 of these are related
> to the callback system and the last one is for exported functions.
>
> The QPP_CREATE_CB macro is used by a plugin that wishes to create a
> callback with a given name. The macro will create an array of function
> pointers for every function that has been registered to run on this
> callback ev

Re: [RFC 2/4] tcg/plugins: Automatically define CURRENT_PLUGIN

2022-09-21 Thread Alex Bennée


Andrew Fasano  writes:

> Use plugin filenames to set the preprocessor variable CURRENT_PLUGIN
> as a string during plugin compilation.
>
> Signed-off-by: Andrew Fasano 
> ---
>  contrib/plugins/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile
> index df3499f4f2..b7720fea0f 100644
> --- a/contrib/plugins/Makefile
> +++ b/contrib/plugins/Makefile
> @@ -34,7 +34,7 @@ CFLAGS += -I$(SRC_PATH)/include/qemu
>  all: $(SONAMES)
>  
>  %.o: %.c
> - $(CC) $(CFLAGS) -c -o $@ $<
> + $(CC) $(CFLAGS) -DCURRENT_PLUGIN=\"$(basename $@)\" -c -o $@ $<

While all plugins are currently single files this seems a little clumsy.

We can already check exported plugin symbols in loader.c (see
qemu_plugin_version) so maybe it would be better to declare an API
update and mandate any plugin object also needs to define a
qemu_plugin_name with a null terminated string?

>  
>  lib%.so: %.o
>   $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDLIBS)


-- 
Alex Bennée



Re: [PATCH v2 23/23] target/i386: Enable TARGET_TB_PCREL

2022-09-21 Thread Paolo Bonzini
On Tue, Sep 6, 2022 at 12:10 PM Richard Henderson
 wrote:
>  static void gen_update_eip_cur(DisasContext *s)
>  {
>  gen_jmp_im(s, s->base.pc_next - s->cs_base);
> +s->pc_save = s->base.pc_next;

s->pc_save is not valid after all gen_jmp_im() calls. Is it worth
noting after each call to gen_jmp_im() why this is not a problem?

>  }
>
>  static void gen_update_eip_next(DisasContext *s)
>  {
>  gen_jmp_im(s, s->pc - s->cs_base);
> +s->pc_save = s->pc;
> +}
> +
> +static TCGv gen_eip_cur(DisasContext *s)
> +{
> +if (TARGET_TB_PCREL) {
> +gen_update_eip_cur(s);
> +return cpu_eip;
> +} else {
> +return tcg_constant_tl(s->base.pc_next - s->cs_base);
> +}

Ok, now I see why you called it gen_eip_cur(), but it's still a bit
disconcerting to see the difference in behavior between the
TARGET_TB_PCREL and !TARGET_TB_PCREL cases, one of them updating
cpu_eip and other not.

Perhaps gen_jmp_im() and gen_update_eip_cur() could be rewritten to
return the destination instead:

static TCGv gen_jmp_im(DisasContext *s, target_ulong eip)
{
if (TARGET_TB_PCREL) {
target_ulong eip_save = s->pc_save - s->cs_base;
tcg_gen_addi_tl(cpu_eip, cpu_eip, eip - eip_save);
return cpu_eip;
} else {
TCGv dest = tcg_constant_tl(eip);
tcg_gen_mov_tl(cpu_eip, dest);
return dest;
}
}

static TCGv gen_update_eip_cur(DisasContext *s)
{
TCGv dest = gen_jmp_im(s, s->base.pc_next - s->cs_base);
s->pc_save = s->base.pc_next;
return dest;
}

and the "if (update_ip)" case would use the return value?

This change would basically replace the previous patch, with just the
"if (TARGET_TB_PCREL)" added here.

Paolo




[PATCH] qga: fix possible memory leak

2022-09-21 Thread luzhipeng
From: lu zhipeng 

Signed-off-by: lu zhipeng 
---
 qga/main.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/qga/main.c b/qga/main.c
index 5f1efa2333..73ea1aae65 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1287,7 +1287,7 @@ static GAState *initialize_agent(GAConfig *config, int 
socket_activation)
 if (g_mkdir_with_parents(config->state_dir, S_IRWXU) == -1) {
 g_critical("unable to create (an ancestor of) the state directory"
" '%s': %s", config->state_dir, strerror(errno));
-return NULL;
+goto failed;
 }
 #endif
 
@@ -1312,7 +1312,7 @@ static GAState *initialize_agent(GAConfig *config, int 
socket_activation)
 if (!log_file) {
 g_critical("unable to open specified log file: %s",
strerror(errno));
-return NULL;
+goto failed;
 }
 s->log_file = log_file;
 }
@@ -1323,7 +1323,7 @@ static GAState *initialize_agent(GAConfig *config, int 
socket_activation)
s->pstate_filepath,
ga_is_frozen(s))) {
 g_critical("failed to load persistent state");
-return NULL;
+goto failed;
 }
 
 config->blacklist = ga_command_blacklist_init(config->blacklist);
@@ -1344,7 +1344,7 @@ static GAState *initialize_agent(GAConfig *config, int 
socket_activation)
 #ifndef _WIN32
 if (!register_signal_handlers()) {
 g_critical("failed to register signal handlers");
-return NULL;
+goto failed;
 }
 #endif
 
@@ -1357,12 +1357,21 @@ static GAState *initialize_agent(GAConfig *config, int 
socket_activation)
 s->wakeup_event = CreateEvent(NULL, TRUE, FALSE, TEXT("WakeUp"));
 if (s->wakeup_event == NULL) {
 g_critical("CreateEvent failed");
-return NULL;
+goto failed;
 }
 #endif
 
 ga_state = s;
 return s;
+
+failed:
+g_free(s->pstate_filepath);
+g_free(s->state_filepath_isfrozen);
+if (s->log_file && s->log_file != stderr) {
+fclose(s->log_file);
+}
+g_free(s);
+return NULL;
 }
 
 static void cleanup_agent(GAState *s)
-- 
2.31.1






Re: [PATCH v2 00/23] target/i386: pc-relative translation blocks

2022-09-21 Thread Paolo Bonzini
Looks good! Just a couple weird parts of the architecture where I need
some more explanation.

Paolo

On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
 wrote:
>
> This is the x86 specific changes required to reduce the
> amount of translation for address space randomization.
> This is a re-base, with no other significant changes over v1.
>
>
> r~
>
>
> Based-on: 20220906091126.298041-1-richard.hender...@linaro.org
> ("[PATCH v4 0/7] tcg: pc-relative translation blocks")
>
> branch: https://gitlab.com/rth7680/qemu/-/tree/tgt-x86-pcrel
>
>
> Richard Henderson (23):
>   target/i386: Remove pc_start
>   target/i386: Return bool from disas_insn
>   target/i386: Remove cur_eip argument to gen_exception
>   target/i386: Remove cur_eip, next_eip arguments to gen_interrupt
>   target/i386: Create gen_update_eip_cur
>   target/i386: Create gen_update_eip_next
>   target/i386: Introduce DISAS_EOB*
>   target/i386: Use DISAS_EOB* in gen_movl_seg_T0
>   target/i386: Use DISAS_EOB_NEXT
>   target/i386: USe DISAS_EOB_ONLY
>   target/i386: Create cur_insn_len, cur_insn_len_i32
>   target/i386: Remove cur_eip, next_eip arguments to gen_repz*
>   target/i386: Introduce DISAS_JUMP
>   target/i386: Truncate values for lcall_real to i32
>   target/i386: Create eip_next_*
>   target/i386: Use DISAS_TOO_MANY to exit after gen_io_start
>   target/i386: Create gen_jmp_rel
>   target/i386: Use gen_jmp_rel for loop and jecxz insns
>   target/i386: Use gen_jmp_rel for gen_jcc
>   target/i386: Use gen_jmp_rel for gen_repz*
>   target/i386: Use gen_jmp_rel for DISAS_TOO_MANY
>   target/i386: Create gen_eip_cur
>   target/i386: Enable TARGET_TB_PCREL
>
>  target/i386/cpu-param.h  |   1 +
>  target/i386/helper.h |   2 +-
>  target/i386/tcg/seg_helper.c |   6 +-
>  target/i386/tcg/tcg-cpu.c|   8 +-
>  target/i386/tcg/translate.c  | 712 ++-
>  5 files changed, 369 insertions(+), 360 deletions(-)
>
> --
> 2.34.1
>




[PATCH] try to find out which cluster allocated in qcow2

2022-09-21 Thread songlinfeng
In our project,we want to full backup a disk only allocated area,but qmp 
block-dity-block-add can create a bitmap with all zero,so we can't find out 
which cluster is allocated.in qcow2,I think l2_table can help me find out which 
cluster should be backup.

Signed-off-by: songlinfeng 
---
 block/qcow2.c | 49 +
 block/qcow2.h |  1 +
 2 files changed, 50 insertions(+)

diff --git a/block/qcow2.c b/block/qcow2.c
index c6c6692..944cf4f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -4194,6 +4194,55 @@ fail:
 return ret;
 }
 
+void qcow2_get_cluster(BlockDriverState *bs, uint64_t size)
+{
+BDRVQcow2State *s = bs->opaque;
+int l1_size = s->l1_size;
+int cluster_size = s->cluster_size;
+int i;
+int j;
+uint64_t *l2_table = (uint64_t *)malloc(cluster_size);
+int l2_entries = cluster_size / sizeof(uint64_t);
+int total = (size + cluster_size + 1) / cluster_size;
+for (i = 0; i < l1_size; i++) {
+uint64_t l1_entry = s->l1_table[i];
+uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;
+if (l2_offset == 0) {
+if (l2_entries < total) {
+char *buf = (char *)malloc(l2_entries * sizeof(char));
+memset(buf, '0', l2_entries);
+printf("%s", buf);
+free(buf);
+total -= l2_entries;
+} else {
+char *buf = (char *)malloc(total * sizeof(char));
+memset(buf, '0', total);
+printf("%s", buf);
+free(buf);
+total -= total;
+}
+continue;
+}
+int ret = bdrv_pread(bs->file, l2_offset, l2_table, cluster_size);
+if (ret < 0) {
+error_report("can't get l2_table");
+abort();
+}
+for (j = 0; j < l2_entries; j++) {
+if (total) {
+if (l2_table[j] == 0) {
+printf("0");
+} else {
+printf("1");
+}
+total--;
+}
+}
+}
+free(l2_table);
+printf("\n");
+}
+
 static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
   bool exact, PreallocMode prealloc,
   BdrvRequestFlags flags, Error **errp)
diff --git a/block/qcow2.h b/block/qcow2.h
index ba436a8..7079916 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -998,6 +998,7 @@ int 
qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
 const char *name,
 Error **errp);
 bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
+void qcow2_get_cluster(BlockDriverState *bs, uint64_t size);
 uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
 uint32_t cluster_size);
 
-- 
1.8.3.1




Re: [PATCH v1 3/3] ui/gtk: Add a new parameter to assign connectors/monitors to GFX VCs

2022-09-21 Thread Markus Armbruster
Vivek Kasireddy  writes:

> The new parameter named "connector" can be used to assign physical
> monitors/connectors to individual GFX VCs such that when the monitor
> is connected or hotplugged, the associated GTK window would be
> fullscreened on it. If the monitor is disconnected or unplugged,
> the associated GTK window would be destroyed and a relevant
> disconnect event would be sent to the Guest.
>
> Usage: -device virtio-gpu-pci,max_outputs=2,blob=true,xres=1920,yres=1080...
>-display gtk,gl=on,connector.0=eDP-1,connector.1=DP-1.
>
> Cc: Dongwon Kim 
> Cc: Gerd Hoffmann 
> Cc: Daniel P. Berrangé 
> Cc: Markus Armbruster 
> Cc: Philippe Mathieu-Daudé 
> Cc: Marc-André Lureau 
> Cc: Thomas Huth 
> Signed-off-by: Vivek Kasireddy 
> ---
>  qapi/ui.json|   9 ++-
>  qemu-options.hx |   1 +
>  ui/gtk.c| 168 
>  3 files changed, 177 insertions(+), 1 deletion(-)
>
> diff --git a/qapi/ui.json b/qapi/ui.json
> index 286c5731d1..86787a4c95 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -1199,13 +1199,20 @@
>  #   interfaces (e.g. VGA and virtual console character devices)
>  #   by default.
>  #   Since 7.1
> +# @connector:   List of physical monitor/connector names where the GTK 
> windows
> +#   containing the respective graphics virtual consoles (VCs) are
> +#   to be placed. If a mapping exists for a VC, it will be
> +#   fullscreened on that specific monitor or else it would not be
> +#   displayed anywhere and would appear disconnected to the 
> guest.

Let's see whether I understand this...  We have VCs numbered 0, 1, ...
VC #i is mapped to the i-th element of @connector, counting from zero.
Correct?

Ignorant question: what's a "physical monitor/connector name"?

Would you mind breaking the lines a bit earlier, between column 70 and
75?

> +#   Since 7.2
>  #
>  # Since: 2.12
>  ##
>  { 'struct'  : 'DisplayGTK',
>'data': { '*grab-on-hover' : 'bool',
>  '*zoom-to-fit'   : 'bool',
> -'*show-tabs' : 'bool'  } }
> +'*show-tabs' : 'bool',
> +'*connector' : ['str']  } }
>  
>  ##
>  # @DisplayEGLHeadless:
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 31c04f7eea..576b65ef9f 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1945,6 +1945,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
>  #if defined(CONFIG_GTK)
>  "-display gtk[,full-screen=on|off][,gl=on|off][,grab-on-hover=on|off]\n"
>  "
> [,show-tabs=on|off][,show-cursor=on|off][,window-close=on|off]\n"
> +"[,connector.=]\n"

Is "" a VC number?

>  #endif
>  #if defined(CONFIG_VNC)
>  "-display vnc=[,]\n"

Remainder of my review is on style only.  Style suggestions are not
demands :)

> diff --git a/ui/gtk.c b/ui/gtk.c
> index 945c550909..651aaaf174 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -37,6 +37,7 @@
>  #include "qapi/qapi-commands-misc.h"
>  #include "qemu/cutils.h"
>  #include "qemu/main-loop.h"
> +#include "qemu/option.h"
>  
>  #include "ui/console.h"
>  #include "ui/gtk.h"
> @@ -115,6 +116,7 @@
>  #endif
>  
>  #define HOTKEY_MODIFIERS(GDK_CONTROL_MASK | GDK_MOD1_MASK)
> +#define MAX_NUM_ATTEMPTS 5

Could use a comment, and maybe a more telling name (this one doesn't
tell me what is being attempted).

>  
>  static const guint16 *keycode_map;
>  static size_t keycode_maplen;
> @@ -126,6 +128,15 @@ struct VCChardev {
>  };
>  typedef struct VCChardev VCChardev;
>  
> +struct gd_monitor_data {
> +GtkDisplayState *s;
> +GdkDisplay *dpy;
> +GdkMonitor *monitor;
> +QEMUTimer *hp_timer;
> +int attempt;
> +};
> +typedef struct gd_monitor_data gd_monitor_data;

We usually contract these like

   typedef struct gd_monitor_data {
   ...
   } gd_monitor_data;

> +
>  #define TYPE_CHARDEV_VC "chardev-vc"
>  DECLARE_INSTANCE_CHECKER(VCChardev, VC_CHARDEV,
>   TYPE_CHARDEV_VC)
> @@ -1385,6 +1396,147 @@ static void gd_menu_untabify(GtkMenuItem *item, void 
> *opaque)
>  }
>  }
>  
> +static void gd_monitor_fullscreen(GdkDisplay *dpy, VirtualConsole *vc,
> +  gint monitor_num)
> +{
> +GtkDisplayState *s = vc->s;
> +
> +if (!vc->window) {
> +gd_tab_window_create(vc);
> +}
> +gtk_window_fullscreen_on_monitor(GTK_WINDOW(vc->window),
> + gdk_display_get_default_screen(dpy),
> + monitor_num);
> +s->full_screen = TRUE;
> +gd_update_cursor(vc);
> +}
> +
> +static int gd_monitor_lookup(GdkDisplay *dpy, char *label)
> +{
> +GdkMonitor *monitor;
> +const char *monitor_name;
> +int i, total_monitors;
> +
> +total_monitors = gdk_display_get_n_monitors(dpy);
> +for (i = 0; i < total_monitors; i++) {

Suggest to format like this:

   int to

Re: [PATCH v2] virtio-scsi: Send "REPORTED LUNS CHANGED" sense data upon disk hotplug events.

2022-09-21 Thread Paolo Bonzini
On Fri, Sep 16, 2022 at 3:44 AM Venu Busireddy
 wrote:
> diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> index 41f2a5630173..69194c7ae23c 100644
> --- a/hw/scsi/virtio-scsi.c
> +++ b/hw/scsi/virtio-scsi.c
> @@ -608,7 +608,19 @@ static void virtio_scsi_command_complete(SCSIRequest *r, 
> size_t resid)
>
>  req->resp.cmd.response = VIRTIO_SCSI_S_OK;
>  req->resp.cmd.status = r->status;
> -if (req->resp.cmd.status == GOOD) {
> +if (req->dev->reported_luns_changed &&
> +(req->req.cmd.cdb[0] != INQUIRY) &&
> +(req->req.cmd.cdb[0] != REPORT_LUNS) &&
> +(req->req.cmd.cdb[0] != REQUEST_SENSE)) {
> +req->dev->reported_luns_changed = false;
> +req->resp.cmd.resid = 0;
> +req->resp.cmd.status_qualifier = 0;
> +req->resp.cmd.status = CHECK_CONDITION;
> +sense_len = scsi_build_sense(sense, 
> SENSE_CODE(REPORTED_LUNS_CHANGED));
> +qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd),
> +sense, sense_len);
> +req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len);
> +} else if (req->resp.cmd.status == GOOD) {
>  req->resp.cmd.resid = virtio_tswap32(vdev, resid);
>  } else {
>  req->resp.cmd.resid = 0;

Hi,

a unit attention sense must be sent _instead_ of executing the command.

QEMU already has a function scsi_device_set_ua() that handles
everything; you have to call it, if reported_luns_changed is true,
from virtio_scsi_handle_cmd_req_prepare() before scsi_req_new().

It will also skip GET_CONFIGURATION and GET_EVENT_STATUS_NOTIFICATION
commands which are further special-cased in 4.1.6.1 of the MMC
specification.

Thanks,

Paolo


> @@ -956,6 +968,7 @@ static void virtio_scsi_hotplug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  virtio_scsi_push_event(s, sd,
> VIRTIO_SCSI_T_TRANSPORT_RESET,
> VIRTIO_SCSI_EVT_RESET_RESCAN);
> +s->reported_luns_changed = true;
>  virtio_scsi_release(s);
>  }
>  }
> @@ -973,6 +986,7 @@ static void virtio_scsi_hotunplug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  virtio_scsi_push_event(s, sd,
> VIRTIO_SCSI_T_TRANSPORT_RESET,
> VIRTIO_SCSI_EVT_RESET_REMOVED);
> +s->reported_luns_changed = true;
>  virtio_scsi_release(s);
>  }
>
> diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
> index a36aad9c8695..efbcf9ba069a 100644
> --- a/include/hw/virtio/virtio-scsi.h
> +++ b/include/hw/virtio/virtio-scsi.h
> @@ -81,6 +81,7 @@ struct VirtIOSCSI {
>  SCSIBus bus;
>  int resetting;
>  bool events_dropped;
> +bool reported_luns_changed;
>
>  /* Fields for dataplane below */
>  AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
>




Re: [PATCH v2] virtio-scsi: Send "REPORTED LUNS CHANGED" sense data upon disk hotplug events.

2022-09-21 Thread Venu Busireddy
On 2022-09-21 16:33:35 +0200, Paolo Bonzini wrote:
> On Fri, Sep 16, 2022 at 3:44 AM Venu Busireddy
>  wrote:
> > diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> > index 41f2a5630173..69194c7ae23c 100644
> > --- a/hw/scsi/virtio-scsi.c
> > +++ b/hw/scsi/virtio-scsi.c
> > @@ -608,7 +608,19 @@ static void virtio_scsi_command_complete(SCSIRequest 
> > *r, size_t resid)
> >
> >  req->resp.cmd.response = VIRTIO_SCSI_S_OK;
> >  req->resp.cmd.status = r->status;
> > -if (req->resp.cmd.status == GOOD) {
> > +if (req->dev->reported_luns_changed &&
> > +(req->req.cmd.cdb[0] != INQUIRY) &&
> > +(req->req.cmd.cdb[0] != REPORT_LUNS) &&
> > +(req->req.cmd.cdb[0] != REQUEST_SENSE)) {
> > +req->dev->reported_luns_changed = false;
> > +req->resp.cmd.resid = 0;
> > +req->resp.cmd.status_qualifier = 0;
> > +req->resp.cmd.status = CHECK_CONDITION;
> > +sense_len = scsi_build_sense(sense, 
> > SENSE_CODE(REPORTED_LUNS_CHANGED));
> > +qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd),
> > +sense, sense_len);
> > +req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len);
> > +} else if (req->resp.cmd.status == GOOD) {
> >  req->resp.cmd.resid = virtio_tswap32(vdev, resid);
> >  } else {
> >  req->resp.cmd.resid = 0;
> 
> Hi,
> 
> a unit attention sense must be sent _instead_ of executing the command.
> 
> QEMU already has a function scsi_device_set_ua() that handles
> everything; you have to call it, if reported_luns_changed is true,
> from virtio_scsi_handle_cmd_req_prepare() before scsi_req_new().
> 
> It will also skip GET_CONFIGURATION and GET_EVENT_STATUS_NOTIFICATION
> commands which are further special-cased in 4.1.6.1 of the MMC
> specification.

Thanks, Paolo. I will test your suggestion (as soon as I finish what I
am working currently), and get back with either more questions, or with
a v3 post.

Venu

> > @@ -956,6 +968,7 @@ static void virtio_scsi_hotplug(HotplugHandler 
> > *hotplug_dev, DeviceState *dev,
> >  virtio_scsi_push_event(s, sd,
> > VIRTIO_SCSI_T_TRANSPORT_RESET,
> > VIRTIO_SCSI_EVT_RESET_RESCAN);
> > +s->reported_luns_changed = true;
> >  virtio_scsi_release(s);
> >  }
> >  }
> > @@ -973,6 +986,7 @@ static void virtio_scsi_hotunplug(HotplugHandler 
> > *hotplug_dev, DeviceState *dev,
> >  virtio_scsi_push_event(s, sd,
> > VIRTIO_SCSI_T_TRANSPORT_RESET,
> > VIRTIO_SCSI_EVT_RESET_REMOVED);
> > +s->reported_luns_changed = true;
> >  virtio_scsi_release(s);
> >  }
> >
> > diff --git a/include/hw/virtio/virtio-scsi.h 
> > b/include/hw/virtio/virtio-scsi.h
> > index a36aad9c8695..efbcf9ba069a 100644
> > --- a/include/hw/virtio/virtio-scsi.h
> > +++ b/include/hw/virtio/virtio-scsi.h
> > @@ -81,6 +81,7 @@ struct VirtIOSCSI {
> >  SCSIBus bus;
> >  int resetting;
> >  bool events_dropped;
> > +bool reported_luns_changed;
> >
> >  /* Fields for dataplane below */
> >  AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
> >
> 



[PATCH] add keepalive for qemu-nbd

2022-09-21 Thread songlinfeng
From: songlinfeng 

we want to export a image with qemu-nbd as server, in client we use libnbd to 
connect qemu-nbd,but when client power down,the server is still working.
qemu-nbd will exit when last client exit.so,we still want server exit when 
client power down.maybe qmp can handle it,but i don't know how to do .
Signed-off-by: songlinfeng 
---
 qemu-nbd.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 0cd5aa6..115ef2b 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -20,7 +20,8 @@
 #include 
 #include 
 #include 
-
+#include 
+#include 
 #include "qemu/help-texts.h"
 #include "qapi/error.h"
 #include "qemu/cutils.h"
@@ -365,6 +366,26 @@ static void nbd_accept(QIONetListener *listener, 
QIOChannelSocket *cioc,
 nb_fds++;
 nbd_update_server_watch();
 nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed);
+int tcp_keepalive_intvl = 5;
+int tcp_keepalive_probes = 5;
+int tcp_keepalive_time = 60;
+int tcp_keepalive_on = 1;
+if (setsockopt(cioc->fd, SOL_TCP, TCP_KEEPINTVL,
+   &tcp_keepalive_intvl, sizeof(tcp_keepalive_intvl)) < 0) {
+perror("setsockopt failed\n");
+}
+if (setsockopt(cioc->fd, SOL_TCP, TCP_KEEPCNT,
+   &tcp_keepalive_probes, sizeof(tcp_keepalive_probes)) < 0) {
+perror("setsockopt failed\n");
+}
+if (setsockopt(cioc->fd, SOL_TCP, TCP_KEEPIDLE,
+   &tcp_keepalive_time, sizeof(tcp_keepalive_time)) < 0) {
+perror("setsockopt failed\n");
+}
+if (setsockopt(cios->fd, SOL_SOCKET, SO_KEEPALIVE,
+   &tcp_keepalive_on, sizeof(tcp_keepalive_on)) < 0) {
+perror("setsockopt failed\n");
+}
 }
 
 static void nbd_update_server_watch(void)
-- 
1.8.3.1




Re: [PATCH RFC 0/7] hostmem: NUMA-aware memory preallocation using ThreadContext

2022-09-21 Thread Michal Prívozník
On 7/21/22 14:07, David Hildenbrand wrote:
>

Ping? Is there any plan how to move forward? I have libvirt patches
ready to consume this and I'd like to prune my old local branches :-)

Michal




Re: [PATCH] i386: Add new CPU model SapphireRapids

2022-09-21 Thread Dr. David Alan Gilbert
* Wang, Lei (lei4.w...@intel.com) wrote:
> The new CPU model mostly inherits features from Icelake-Server, while
> adding new features:
>  - AMX (Advance Matrix eXtensions)
>  - Bus Lock Debug Exception
> and new instructions:
>  - AVX VNNI (Vector Neural Network Instruction):
> - VPDPBUS: Multiply and Add Unsigned and Signed Bytes
> - VPDPBUSDS: Multiply and Add Unsigned and Signed Bytes with Saturation
> - VPDPWSSD: Multiply and Add Signed Word Integers
> - VPDPWSSDS: Multiply and Add Signed Integers with Saturation
>  - FP16: Replicates existing AVX512 computational SP (FP32) instructions
>using FP16 instead of FP32 for ~2X performance gain
>  - SERIALIZE: Provide software with a simple way to force the processor to
>complete all modifications, faster, allowed in all privilege levels and
>not causing an unconditional VM exit
>  - TSX Suspend Load Address Tracking: Allows programmers to choose which
>memory accesses do not need to be tracked in the TSX read set
>  - AVX512_BF16: Vector Neural Network Instructions supporting BFLOAT16
>inputs and conversion instructions from IEEE single precision
> 
> Features may be added in future versions:
>  - CET (virtualization support hasn't been merged)
> Instructions may be added in future versions:
>  - fast zero-length MOVSB (KVM doesn't support yet)
>  - fast short STOSB (KVM doesn't support yet)
>  - fast short CMPSB, SCASB (KVM doesn't support yet)
> 
> Signed-off-by: Wang, Lei 
> Reviewed-by: Robert Hoo 

Hi,
   What fills in the AMX tile and tmul information leafs
(0x1D, 0x1E)?
  In particular, how would we make sure when we migrate between two
generations of AMX/Tile/Tmul capable devices with different
register/palette/tmul limits that the migration is tied to the CPU type
correctly?
  Would you expect all devices called a 'SappireRapids' to have the same
sizes?

Dave
 
> ---
>  target/i386/cpu.c | 128 ++
>  target/i386/cpu.h |   4 ++
>  2 files changed, 132 insertions(+)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 1db1278a59..abb43853d4 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -3467,6 +3467,134 @@ static const X86CPUDefinition builtin_x86_defs[] = {
>  { /* end of list */ }
>  }
>  },
> +{
> +.name = "SapphireRapids",
> +.level = 0x20,
> +.vendor = CPUID_VENDOR_INTEL,
> +.family = 6,
> +.model = 143,
> +.stepping = 4,
> +/*
> + * please keep the ascending order so that we can have a clear view 
> of
> + * bit position of each feature.
> + */
> +.features[FEAT_1_EDX] =
> +CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
> +CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
> +CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
> +CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR 
> |
> +CPUID_SSE | CPUID_SSE2,
> +.features[FEAT_1_ECX] =
> +CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
> +CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | 
> CPUID_EXT_SSE41 |
> +CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE |
> +CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES |
> +CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | 
> CPUID_EXT_RDRAND,
> +.features[FEAT_8000_0001_EDX] =
> +CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB |
> +CPUID_EXT2_RDTSCP | CPUID_EXT2_LM,
> +.features[FEAT_8000_0001_ECX] =
> +CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH,
> +.features[FEAT_8000_0008_EBX] =
> +CPUID_8000_0008_EBX_WBNOINVD,
> +.features[FEAT_7_0_EBX] =
> +CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE |
> +CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 |
> +CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM |
> +CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
> +CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP |
> +CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT |
> +CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | 
> CPUID_7_0_EBX_SHA_NI |
> +CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL,
> +.features[FEAT_7_0_ECX] =
> +CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | 
> CPUID_7_0_ECX_PKU |
> +CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI |
> +CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
> +CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
> +CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 |
> +CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT,
> +.features[FEAT_7_0_EDX] =
> 

[PATCH] qcow2: fix memory leak in qcow2_read_extensions

2022-09-21 Thread luzhipeng
From: lu zhipeng 

Free feature_table if it is failed in bdrv_pread.

Signed-off-by: lu zhipeng 
---
 block/qcow2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/qcow2.c b/block/qcow2.c
index c6c6692fb7..c8fc3a6160 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -275,6 +275,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, 
uint64_t start_offset,
 if (ret < 0) {
 error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "
  "Could not read table");
+g_free(feature_table);
 return ret;
 }
 
-- 
2.31.1






Re: [PATCH RFC 0/7] hostmem: NUMA-aware memory preallocation using ThreadContext

2022-09-21 Thread David Hildenbrand

On 21.09.22 16:44, Michal Prívozník wrote:

On 7/21/22 14:07, David Hildenbrand wrote:




Ping? Is there any plan how to move forward? I have libvirt patches
ready to consume this and I'd like to prune my old local branches :-)


Heh, I was thinking about this series just today. I was distracted with 
all other kind of stuff.


I'll move forward with this series later this week/early next week.

Thanks!

--
Thanks,

David / dhildenb




Re: [PATCH] qga: fix possible memory leak

2022-09-21 Thread Markus Armbruster
luzhipeng  writes:

> From: lu zhipeng 
>
> Signed-off-by: lu zhipeng 
> ---
>  qga/main.c | 19 ++-
>  1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/qga/main.c b/qga/main.c
> index 5f1efa2333..73ea1aae65 100644
> --- a/qga/main.c
> +++ b/qga/main.c
> @@ -1287,7 +1287,7 @@ static GAState *initialize_agent(GAConfig *config, int 
> socket_activation)
>  if (g_mkdir_with_parents(config->state_dir, S_IRWXU) == -1) {
>  g_critical("unable to create (an ancestor of) the state directory"
> " '%s': %s", config->state_dir, strerror(errno));
> -return NULL;
> +goto failed;
>  }
>  #endif
>  
> @@ -1312,7 +1312,7 @@ static GAState *initialize_agent(GAConfig *config, int 
> socket_activation)
>  if (!log_file) {
>  g_critical("unable to open specified log file: %s",
> strerror(errno));
> -return NULL;
> +goto failed;
>  }
>  s->log_file = log_file;
>  }
> @@ -1323,7 +1323,7 @@ static GAState *initialize_agent(GAConfig *config, int 
> socket_activation)
> s->pstate_filepath,
> ga_is_frozen(s))) {
>  g_critical("failed to load persistent state");
> -return NULL;
> +goto failed;
>  }
>  
>  config->blacklist = ga_command_blacklist_init(config->blacklist);
> @@ -1344,7 +1344,7 @@ static GAState *initialize_agent(GAConfig *config, int 
> socket_activation)
>  #ifndef _WIN32
>  if (!register_signal_handlers()) {
>  g_critical("failed to register signal handlers");
> -return NULL;
> +goto failed;
>  }
>  #endif
>  
> @@ -1357,12 +1357,21 @@ static GAState *initialize_agent(GAConfig *config, 
> int socket_activation)
>  s->wakeup_event = CreateEvent(NULL, TRUE, FALSE, TEXT("WakeUp"));
>  if (s->wakeup_event == NULL) {
>  g_critical("CreateEvent failed");
> -return NULL;
> +goto failed;
>  }
>  #endif
>  
>  ga_state = s;
>  return s;
> +
> +failed:
> +g_free(s->pstate_filepath);
> +g_free(s->state_filepath_isfrozen);
> +if (s->log_file && s->log_file != stderr) {
> +fclose(s->log_file);
> +}
> +g_free(s);
> +return NULL;
>  }
>  
>  static void cleanup_agent(GAState *s)

The function's only caller is main():

   int main(int argc, char **argv)
   {
   int ret = EXIT_SUCCESS;

   ...

   s = initialize_agent(config, socket_activation);
   if (!s) {
   g_critical("error initializing guest agent");
   goto end;
   }

   ...

   end:
   if (config->daemonize) {
   unlink(config->pid_filepath);
   }

   config_free(config);

   return ret;
   }

When initialize_agent() fails, the process terminates immediately.
There is no memory leak.

We might want to free in initialize_agent() anyway.  Up to the
maintainer.

Bug (not related to this patch): when initialize_agent() fails, we still
terminate successfully.  We should ret = EXIT_FAILURE before goto end,
like we do elsewhere in main().




Re: [PATCH] i386: Add new CPU model SapphireRapids

2022-09-21 Thread Daniel P . Berrangé
On Wed, Sep 21, 2022 at 03:51:42PM +0100, Dr. David Alan Gilbert wrote:
> * Wang, Lei (lei4.w...@intel.com) wrote:
> > The new CPU model mostly inherits features from Icelake-Server, while
> > adding new features:
> >  - AMX (Advance Matrix eXtensions)
> >  - Bus Lock Debug Exception
> > and new instructions:
> >  - AVX VNNI (Vector Neural Network Instruction):
> > - VPDPBUS: Multiply and Add Unsigned and Signed Bytes
> > - VPDPBUSDS: Multiply and Add Unsigned and Signed Bytes with Saturation
> > - VPDPWSSD: Multiply and Add Signed Word Integers
> > - VPDPWSSDS: Multiply and Add Signed Integers with Saturation
> >  - FP16: Replicates existing AVX512 computational SP (FP32) instructions
> >using FP16 instead of FP32 for ~2X performance gain
> >  - SERIALIZE: Provide software with a simple way to force the processor to
> >complete all modifications, faster, allowed in all privilege levels and
> >not causing an unconditional VM exit
> >  - TSX Suspend Load Address Tracking: Allows programmers to choose which
> >memory accesses do not need to be tracked in the TSX read set
> >  - AVX512_BF16: Vector Neural Network Instructions supporting BFLOAT16
> >inputs and conversion instructions from IEEE single precision
> > 
> > Features may be added in future versions:
> >  - CET (virtualization support hasn't been merged)
> > Instructions may be added in future versions:
> >  - fast zero-length MOVSB (KVM doesn't support yet)
> >  - fast short STOSB (KVM doesn't support yet)
> >  - fast short CMPSB, SCASB (KVM doesn't support yet)
> > 
> > Signed-off-by: Wang, Lei 
> > Reviewed-by: Robert Hoo 
> 
> Hi,
>What fills in the AMX tile and tmul information leafs
> (0x1D, 0x1E)?
>   In particular, how would we make sure when we migrate between two
> generations of AMX/Tile/Tmul capable devices with different
> register/palette/tmul limits that the migration is tied to the CPU type
> correctly?
>   Would you expect all devices called a 'SappireRapids' to have the same
> sizes?

We shouldn't assume this will only be used on 'SappireRapids' host
silicon. Thi named CPU model is likely to be used by a guest running
on any host silicon generations that follow SappireRapids too.

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH] i386: Add new CPU model SapphireRapids

2022-09-21 Thread Dr. David Alan Gilbert
* Daniel P. Berrangé (berra...@redhat.com) wrote:
> On Wed, Sep 21, 2022 at 03:51:42PM +0100, Dr. David Alan Gilbert wrote:
> > * Wang, Lei (lei4.w...@intel.com) wrote:
> > > The new CPU model mostly inherits features from Icelake-Server, while
> > > adding new features:
> > >  - AMX (Advance Matrix eXtensions)
> > >  - Bus Lock Debug Exception
> > > and new instructions:
> > >  - AVX VNNI (Vector Neural Network Instruction):
> > > - VPDPBUS: Multiply and Add Unsigned and Signed Bytes
> > > - VPDPBUSDS: Multiply and Add Unsigned and Signed Bytes with 
> > > Saturation
> > > - VPDPWSSD: Multiply and Add Signed Word Integers
> > > - VPDPWSSDS: Multiply and Add Signed Integers with Saturation
> > >  - FP16: Replicates existing AVX512 computational SP (FP32) instructions
> > >using FP16 instead of FP32 for ~2X performance gain
> > >  - SERIALIZE: Provide software with a simple way to force the processor to
> > >complete all modifications, faster, allowed in all privilege levels and
> > >not causing an unconditional VM exit
> > >  - TSX Suspend Load Address Tracking: Allows programmers to choose which
> > >memory accesses do not need to be tracked in the TSX read set
> > >  - AVX512_BF16: Vector Neural Network Instructions supporting BFLOAT16
> > >inputs and conversion instructions from IEEE single precision
> > > 
> > > Features may be added in future versions:
> > >  - CET (virtualization support hasn't been merged)
> > > Instructions may be added in future versions:
> > >  - fast zero-length MOVSB (KVM doesn't support yet)
> > >  - fast short STOSB (KVM doesn't support yet)
> > >  - fast short CMPSB, SCASB (KVM doesn't support yet)
> > > 
> > > Signed-off-by: Wang, Lei 
> > > Reviewed-by: Robert Hoo 
> > 
> > Hi,
> >What fills in the AMX tile and tmul information leafs
> > (0x1D, 0x1E)?
> >   In particular, how would we make sure when we migrate between two
> > generations of AMX/Tile/Tmul capable devices with different
> > register/palette/tmul limits that the migration is tied to the CPU type
> > correctly?
> >   Would you expect all devices called a 'SappireRapids' to have the same
> > sizes?
> 
> We shouldn't assume this will only be used on 'SappireRapids' host
> silicon. Thi named CPU model is likely to be used by a guest running
> on any host silicon generations that follow SappireRapids too.

Indeed, but I wanted to check the opposite question first; whether
all SappireRapids had the same sizes; I think you're asking the opposite
question.

Dave

> With regards,
> Daniel
> -- 
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v3 1/1] monitor/hmp: print trace as option in help for log command

2022-09-21 Thread Markus Armbruster
Dongli Zhang  writes:

> Hi Markus,
>
> On 9/17/22 2:44 PM, Philippe Mathieu-Daudé via wrote:
>> Hi Markus,
>> 
>> On 2/9/22 14:24, Markus Armbruster wrote:
>>> Dongli Zhang  writes:
>>>
 The below is printed when printing help information in qemu-system-x86_64
 command line, and when CONFIG_TRACE_LOG is enabled:

 
 $ qemu-system-x86_64 -d help
 ... ...
 trace:PATTERN   enable trace events

 Use "-d trace:help" to get a list of trace events.
 

 However, the options of "trace:PATTERN" are only printed by
 "qemu-system-x86_64 -d help", but missing in hmp "help log" command.

 Fixes: c84ea00dc2 ("log: add "-d trace:PATTERN"")
 Cc: Joe Jin 
 Signed-off-by: Dongli Zhang 
 ---
 Changed since v1:
 - change format for "none" as well.
 Changed since v2:
 - use "log trace:help" in help message.
 - add more clarification in commit message.
 - add 'Fixes' tag.
 ---
   monitor/hmp.c | 9 +++--
   1 file changed, 7 insertions(+), 2 deletions(-)
>> 
>>> Not this patch's fault:
>>>
>>> 1. "-d help" terminates with exit status 1, "-d trace:help" with 0.  The
>>>     former is wrong.
>
> May I assume it is expected to have exit status 1 when "-d help"?

Non-zero exit status means error.  Asking for and receiving help is not
an error.  Therefore, "-d help" should exit with status 0, just like
"-help", "-device help", "-machine help", ...

> According to the output of "-d", there is even not a "help" option, but only a
> "-d trace:help" option. That is, "-d help" is not officially supported.

It *is* documented:

$ qemu-system-x86_64 -help | grep -- '^-d '
-d item1,...enable logging of specified items (use '-d help' for a list 
of log items)

> The below example use "-d hellworld" but not "help".
>
> # qemu-system-x86_64 -d helloworld
> Log items (comma separated):
> out_asm show generated host assembly code for each compiled TB
> in_asm  show target assembly code for each compiled TB
> op  show micro ops for each compiled TB
> op_opt  show micro ops after optimization
> op_ind  show micro ops before indirect lowering
> int show interrupts/exceptions in short format
> execshow trace before each executed TB (lots of logs)
> cpu show CPU registers before entering a TB (lots of logs)
> fpu include FPU registers in the 'cpu' logging
> mmu log MMU-related activities
> pcall   x86 only: show protected mode far calls/returns/exceptions
> cpu_reset   show CPU state before CPU resets
> unimp   log unimplemented functionality
> guest_errorslog when the guest OS does something invalid (eg accessing a
> non-existent register)
> pagedump pages at beginning of user mode emulation
> nochain do not chain compiled TBs so that "exec" and "cpu" show
> complete traces
> plugin  output from TCG plugins
>
> strace  log every user-mode syscall, its input, and its result
> tid open a separate log file per thread; filename must contain 
> '%d'
> trace:PATTERN   enable trace events
>
> Use "-d trace:help" to get a list of trace events.
>
>
> According to the source code, the qemu_str_to_log_mask() expects either log
> items or "trace". For any other inputs (e.g., "help" or "helloworld"),
> qemu_str_to_log_mask() returns 0 (no bit set in the mask).

You're right.

>That indicates the
> input (e.g., "help") is not an expected input.

No, it indicates laziness :)

> Therefore, can I assume this is not a bug? I do not think something like below
> is very helpful.
>
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 263f029a8e..54c8e624bf 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -2389,6 +2389,8 @@ static void qemu_process_early_options(void)
>  mask = qemu_str_to_log_mask(log_mask);
>  if (!mask) {
>  qemu_print_log_usage(stdout);
> +if (g_str_equal(log_mask, "help"))
> +exit(0)
>  exit(1);
>  }
>  }

Let's make "-d help" print help to stdout and terminate successfully,
and "-d crap" report an error and terminate unsuccessfully.  Just like
other options, such as -device and -machine.

> Thank you very much!

You're welcome!




Re: QEMU's FreeBSD 13 CI job is failing

2022-09-21 Thread Warner Losh
On Wed, Sep 21, 2022 at 1:13 AM Daniel P. Berrangé 
wrote:

> On Tue, Sep 20, 2022 at 02:21:46PM -0600, Warner Losh wrote:
> > On Tue, Sep 20, 2022 at 2:57 AM Daniel P. Berrangé 
> > wrote:
> >
> > > On Tue, Sep 20, 2022 at 10:23:56AM +0200, Thomas Huth wrote:
> > > > On 20/09/2022 10.21, Daniel P. Berrangé wrote:
> > > > > On Tue, Sep 20, 2022 at 08:44:27AM +0200, Thomas Huth wrote:
> > > > > >
> > > > > > Seen here for example:
> > > > > >
> > > > > > https://gitlab.com/qemu-project/qemu/-/jobs/3050165356#L2543
> > > > > >
> > > > > > ld-elf.so.1: /lib/libc.so.7: version FBSD_1.7 required by
> > > > > > /usr/local/lib/libpython3.9.so.1.0 not found
> > > > > > ERROR: Cannot use '/usr/local/bin/python3', Python >= 3.6 is
> > > required.
> > > > > >
> > > > > > ... looks like the Python binary is not working anymore? Does
> > > anybody know
> > > > > > what happened here?
> > > > >
> > > > > FreeBSD ports is only guaranteed to work with latest minor release
> > > > > base image. The python binary recently started relying on symbols
> > > > > in the 13.1 base image, and we're using 13.0.
> > > > >
> > > > > I updated lcitool last week to pick 13.1, so we just need a refresh
> > > > > on the QEMU side to pick this up.
> > > >
> > > > OK ... Alex, IIRC you have a patch queued to update the files that
> are
> > > > refreshed by lcitool ... does that already contain the update for
> > > FreeBSD,
> > > > too?
> > >
> > > Oh actually, I'm forgetting that QEMU doesn't use the 'lcitool
> manifest'
> > > command for auto-generating the gitlab-ci.yml file. In QEMU's case just
> > > manually edit .gitlab-ci.d/cirrus.yml to change
> > >
> > > CIRRUS_VM_IMAGE_NAME: freebsd-13-0
> > >
> >
> > FreeBSD's support policy is that we EOL minor dot releases a few months
> > after
> > the next minor release is final. Part of that process involves moving the
> > build
> > of packages to that new minor version (which is what's not guaranteed to
> > work
> > on older versions... only old binaries on new versions is guaranteed)...
> > And that's
> > the problem that was hit here.
>
> It would be nice if something in the ports tool / packages was
> able to report the incompatibility at time of install, rather
> than leaving a later runtime failed.
>

Indeed. I've suggested it to the authors...  There's some technical issues
around this and the package format they need to work out.


> > I'll try to submit changes after the next minor release in that 'few
> month'
> > window
> > to update this in the future. In general, doing so would be the best fit
> > with FreeBSD's
> > support model...  It's one of those things I didn't think of at the time,
> > but is obvious in
> > hindsight.
>
> Note, we're reliant on Cirrus CI actually publishing the new images
> for use. I've not previously checked before how quickly they publish
> them after FreeBSD does the upstream release, but anyway I go by what
> they list here:
>
>   https://cirrus-ci.org/guide/FreeBSD/


 Yea. They have been pretty good in the past about getting new images up
quickly after the release.

Warner


Re: [RFC 3/4] tcg/plugins: Support for inter-plugin interactions

2022-09-21 Thread Alex Bennée


Andrew Fasano  writes:

> Expand tcg-plugin system to allow for plugins to export functions
> and callbacks that can be used by other plugins. Exported functions
> can be called at runtime by other loaded plugins. Loaded plugins
> can register functions with exported callbacks and have these
> functions run whenever the callback is triggered.

Could you please split the callback and function handling in future
patches to aid review.

>
> Signed-off-by: Andrew Fasano 
> ---
>  include/qemu/plugin-qpp.h| 252 +++
>  plugins/core.c   |  11 ++
>  plugins/loader.c |  24 
>  plugins/plugin.h |   5 +
>  plugins/qemu-plugins.symbols |   1 +
>  5 files changed, 293 insertions(+)
>  create mode 100644 include/qemu/plugin-qpp.h
>
> diff --git a/include/qemu/plugin-qpp.h b/include/qemu/plugin-qpp.h
> new file mode 100644
> index 00..befa4f9b8b
> --- /dev/null
> +++ b/include/qemu/plugin-qpp.h
> @@ -0,0 +1,252 @@
> +#ifndef PLUGIN_QPP_H
> +#define PLUGIN_QPP_H
> +
> +/*
> + * Facilities for "QEMU plugin to plugin" (QPP) interactions between tcg
> + * plugins.  These allow for an inter-plugin callback system as well
> + * as direct function calls between loaded plugins. For more details see
> + * docs/devel/plugin.rst.
> + */
> +
> +#include 
> +#include 
> +#include 
> +extern GModule * qemu_plugin_name_to_handle(const char *);

Plugin API functions should have /** */ kernel-doc annotations for the
benefit of the autogenerated API docs. Moreover handles to plugins are
usually anonymous pointer types to discourage them fishing about in the
contents.

The fact we expose GModule to the plugin to do the linking makes me
think that maybe the linking should be pushed into loader and be done on
behalf of the plugin.

> +
> +#define PLUGIN_CONCAT(x, y) _PLUGIN_CONCAT(x, y)
> +#define _PLUGIN_CONCAT(x, y) x##y
> +#define QPP_NAME(plugin, fn) PLUGIN_CONCAT(plugin, PLUGIN_CONCAT(_, fn))
> +#define QPP_MAX_CB 256
> +#define _QPP_SETUP_NAME(plugin, fn) PLUGIN_CONCAT(_qpp_setup_, \
> +QPP_NAME(plugin, fn))
> +
> +/*
> + **
> + * The QPP_CREATE_CB and QPP_RUN_CB macros are to be used by a plugin that
> + * wishs to create and later trigger QPP-based callback events. These are
> + * events that the plugin can detect (i.e., through analysis of guest state)
> + * that may be of interest to other plugins.
> + **
> + */
> +
> +/*
> + * QPP_CREATE_CB(name) will create a callback by defining necessary internal
> + * functions and variables based off the provided name. It must be run before
> + * triggering the callback event (with QPP_RUN_CB). This macro will create 
> the
> + * following variables and functions, based off the provided name:
> + *
> + * 1) qpp_[name]_cb is an array of function pointers storing the
> + *registered callbacks.
> + * 2) qpp_[name]_num_cb stores the number of functions stored with this
> + *callback.
> + * 3) qpp_add_cb_[name] is a function to add a pointer into the qpp_[name]_cb
> + *array and increment qpp_[name]_num_cb.
> + * 4) qpp_remove_cb_[name] finds a registered callback, deletes it, 
> decrements
> + *_num_cb and shifts the _cb array appropriately to fill the gap.
> + *
> + * Important notes:
> + *
> + * 1) Multiple callbacks can be registered for the same event, however 
> consumers
> + *can not control the order in which they are called and this order may
> + *change in the future.
> + *
> + * 2) If this macro is incorrectly used multiple times in the same plugin 
> with
> + *the same callback name set, it will raise a compilation error since
> + *these variables would then be defined multiple times. The same callback
> + *name can, however, be created in distrinct plugins without issue.
> + */
> +#define QPP_CREATE_CB(cb_name)  \
> +void qpp_add_cb_##cb_name(cb_name##_t fptr);\
> +bool qpp_remove_cb_##cb_name(cb_name##_t fptr); \
> +cb_name##_t * qpp_##cb_name##_cb[QPP_MAX_CB];   \
> +int qpp_##cb_name##_num_cb; \
> +\
> +void qpp_add_cb_##cb_name(cb_name##_t fptr) \
> +{   \
> +  assert(qpp_##cb_name##_num_cb < QPP_MAX_CB);  \
> +  qpp_##cb_name##_cb[qpp_##cb_name##_num_cb] = fptr;\
> +  qpp_##cb_name##_num_cb += 1;  \
> +}   \
> +\
> +bool qpp_remove_cb_##cb_name(cb_name##_t fptr)  \
> +{   \
> +  int i = 0;

Re: [PATCH v8 13/14] net: stream: move to QIO

2022-09-21 Thread Markus Armbruster
Laurent Vivier  writes:

> Use QIOChannel, QIOChannelSocket and QIONetListener.
>
> Signed-off-by: Laurent Vivier 
> ---

[...]

> diff --git a/qemu-options.hx b/qemu-options.hx
> index ee2436ae14a7..a0b5b70c80cb 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2732,8 +2732,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
>  "-netdev socket,id=str[,fd=h][,udp=host:port][,localaddr=host:port]\n"
>  "configure a network backend to connect to another 
> network\n"
>  "using an UDP tunnel\n"
> -"-netdev 
> stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port\n"
> -"-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path\n"
> +"-netdev 
> stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port[,to=maxport][,numeric=on|off][,keep-alive=on|off][,mptcp=on|off][,addr.ipv4=on|off][,addr.ipv6=on|off]\n"
> +"-netdev 
> stream,id=str[,server=on|off],addr.type=unix,addr.path=path[,abstract=on|off][,tight=on|off]\n"
>  "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=h\n"
>  "configure a network backend to connect to another 
> network\n"
>  "using a socket connection in stream mode.\n"

The commit message didn't prepare me for this change.  Could you
explain?




Re: [PATCH v8 12/14] qemu-sockets: update socket_uri() and socket_parse() to be consistent

2022-09-21 Thread Markus Armbruster
Laurent Vivier  writes:

> To be consistent with socket_uri(), add 'tcp:' prefix for inet type in
> socket_parse(), by default socket_parse() use tcp when no prefix is
> provided (format is host:port).
>
> In socket_uri(), use 'vsock:' prefix for vsock type rather than 'tcp:'
> because it makes a vsock address look like an inet address with CID
> misinterpreted as host.
> Goes back to commit 9aca82ba31 "migration: Create socket-address parameter"
>
> Signed-off-by: Laurent Vivier 
> ---
>  util/qemu-sockets.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> index 9f6f655fd526..a9926af714c4 100644
> --- a/util/qemu-sockets.c
> +++ b/util/qemu-sockets.c
> @@ -1090,7 +1090,7 @@ char *socket_uri(SocketAddress *addr)
>  case SOCKET_ADDRESS_TYPE_FD:
>  return g_strdup_printf("fd:%s", addr->u.fd.str);
>  case SOCKET_ADDRESS_TYPE_VSOCK:
> -return g_strdup_printf("tcp:%s:%s",
> +return g_strdup_printf("vsock:%s:%s",
> addr->u.vsock.cid,
> addr->u.vsock.port);
>  default:
> @@ -1124,6 +1124,11 @@ SocketAddress *socket_parse(const char *str, Error 
> **errp)
>  if (vsock_parse(&addr->u.vsock, str + strlen("vsock:"), errp)) {
>  goto fail;
>  }
> +} else if (strstart(str, "tcp:", NULL)) {
> +addr->type = SOCKET_ADDRESS_TYPE_INET;
> +if (inet_parse(&addr->u.inet, str + strlen("tcp:"), errp)) {
> +goto fail;
> +}
>  } else {
>  addr->type = SOCKET_ADDRESS_TYPE_INET;
>  if (inet_parse(&addr->u.inet, str, errp)) {

I'd be tempted to split this patch, but I'm a compulsive patch splitter
;)

Reviewed-by: Markus Armbruster 




Re: [RFC 4/4] tcg/plugins: Add example pair of QPP plugins

2022-09-21 Thread Alex Bennée


Andrew Fasano  writes:

> The first plugin, qpp_srv exposes two functions and one callback that other
> plugins can leverage. These functions are described in the corresponding
> header file.
>
> The second plugin, qpp_client, imports this header file, registers its
> own function to run on a qpp_srv-provided callback, and directly calls
> into the two exposed functions in qpp_srv.

I'll just sketch out how I would change the API in this example plugin:

>
> Signed-off-by: Andrew Fasano 
> ---
>  contrib/plugins/Makefile |  2 ++
>  contrib/plugins/qpp_client.c | 42 
>  contrib/plugins/qpp_client.h |  1 +
>  contrib/plugins/qpp_srv.c| 33 
>  contrib/plugins/qpp_srv.h| 17 +++
>  5 files changed, 95 insertions(+)
>  create mode 100644 contrib/plugins/qpp_client.c
>  create mode 100644 contrib/plugins/qpp_client.h
>  create mode 100644 contrib/plugins/qpp_srv.c
>  create mode 100644 contrib/plugins/qpp_srv.h
>
> diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile
> index b7720fea0f..b7510de89c 100644
> --- a/contrib/plugins/Makefile
> +++ b/contrib/plugins/Makefile
> @@ -21,6 +21,8 @@ NAMES += lockstep
>  NAMES += hwprofile
>  NAMES += cache
>  NAMES += drcov
> +NAMES += qpp_srv
> +NAMES += qpp_client
>  
>  SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
>  
> diff --git a/contrib/plugins/qpp_client.c b/contrib/plugins/qpp_client.c
> new file mode 100644
> index 00..de3335e167
> --- /dev/null
> +++ b/contrib/plugins/qpp_client.c
> @@ -0,0 +1,42 @@
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "qpp_srv.h"
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;

QEMU_PLUGIN_EXPORT const char *qemu_plugin_name = "qpp_client";
QEMU_PLUGIN_EXPORT const char *qemu_plugin_uses = "qpp_server";

> +
> +void my_on_exit(int x, bool b)

void my_on_exit(gpointer evdata, gpointer udata)
{
  struct qpp_exit_event *info = (struct qpp_exit_event *) evdata;
  x = info->x;
  b = info->b;

> +{
> +  g_autoptr(GString) report = g_string_new("Client: on_exit runs with args: 
> ");
> +  g_string_append_printf(report, "%d, %d\n", x, b);
> +  qemu_plugin_outs(report->str);
> +
> +  g_string_printf(report, "Client: calls qpp_srv's do_add(1): %d\n",
> +  qpp_srv_do_add(1));
> +  qemu_plugin_outs(report->str);
> +
> +  g_string_printf(report, "Client: calls qpp_srv's do_sub(1): %d\n",
> +   qpp_srv_do_sub(1));
> +  qemu_plugin_outs(report->str);
> +}
> +
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
> +   const qemu_info_t *info, int argc, char **argv) {
> +
> +/*
> + * Register our "my_on_exit" function to run on the on_exit QPP-callback
> + * exported by qpp_srv
> + */
> +QPP_REG_CB("qpp_srv", on_exit, my_on_exit);

   qemu_plugin_register_event_listener("qpp_server", "exit", my_on_exit);

> +
> +g_autoptr(GString) report = g_string_new(CURRENT_PLUGIN ": Call "
> + "qpp_srv's do_add(0) => ");
> +g_string_append_printf(report, "%d\n", qpp_srv_do_add(0));
> +qemu_plugin_outs(report->str);
> +
> +g_string_printf(report, "Client: registered on_exit callback\n");
> +return 0;
> +}
> +
> diff --git a/contrib/plugins/qpp_client.h b/contrib/plugins/qpp_client.h
> new file mode 100644
> index 00..573923f580
> --- /dev/null
> +++ b/contrib/plugins/qpp_client.h
> @@ -0,0 +1 @@
> +void my_on_exit(int, bool);
> diff --git a/contrib/plugins/qpp_srv.c b/contrib/plugins/qpp_srv.c
> new file mode 100644
> index 00..61a6ab38ed
> --- /dev/null
> +++ b/contrib/plugins/qpp_srv.c
> @@ -0,0 +1,33 @@
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "qpp_srv.h"
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;

QEMU_PLUGIN_EXPORT const char *qemu_plugin_name = "qpp_server";

> +
> +QPP_CREATE_CB(on_exit);

void *on_exit;

> +
> +static void plugin_exit(qemu_plugin_id_t id, void *p)
> +{
> +  qemu_plugin_outs(CURRENT_PLUGIN "exit triggered, running all registered"
> +  " QPP callbacks\n");
> +  QPP_RUN_CB(on_exit, 0, true);

 struct qpp_exit_event *info = g_new0(qpp_exit_event, 1);
 info->x = 0;
 info->b = true;
 qemu_plugin_trigger_event(on_exit, info);

> +}
> +
> +QEMU_PLUGIN_EXPORT int do_add(int x)

QEMU_PLUGIN_EXPORT int qpp_srv_do_add(int x)

> +{
> +  return x + 1;
> +}
> +
> +QEMU_PLUGIN_EXPORT int do_sub(int x)

QEMU_PLUGIN_EXPORT int qpp_srv_do_sub(int x)

> +{
> +  return x - 1;
> +}
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
> +   const qemu_info_t *info, int argc, char **argv) {
> +qemu_plugin_outs("qpp_srv loaded\n");
> +qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
> +return 0;
> +}
> diff --git a/contrib/plugins/qpp_srv.h b/contrib/plugins/qpp_srv.h
> new file mode 100644
> in

Re: [PATCH] add keepalive for qemu-nbd

2022-09-21 Thread Denis V. Lunev

On 9/21/22 10:36, songlinfeng wrote:

From: songlinfeng 

we want to export a image with qemu-nbd as server, in client we use libnbd to 
connect qemu-nbd,but when client power down,the server is still working.
qemu-nbd will exit when last client exit.so,we still want server exit when 
client power down.maybe qmp can handle it,but i don't know how to do .
Signed-off-by: songlinfeng 
---
  qemu-nbd.c | 23 ++-
  1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 0cd5aa6..115ef2b 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -20,7 +20,8 @@
  #include 
  #include 
  #include 
-
+#include 
+#include 
  #include "qemu/help-texts.h"
  #include "qapi/error.h"
  #include "qemu/cutils.h"
@@ -365,6 +366,26 @@ static void nbd_accept(QIONetListener *listener, 
QIOChannelSocket *cioc,
  nb_fds++;
  nbd_update_server_watch();
  nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed);
+int tcp_keepalive_intvl = 5;
+int tcp_keepalive_probes = 5;
+int tcp_keepalive_time = 60;
+int tcp_keepalive_on = 1;
+if (setsockopt(cioc->fd, SOL_TCP, TCP_KEEPINTVL,
+   &tcp_keepalive_intvl, sizeof(tcp_keepalive_intvl)) < 0) {
+perror("setsockopt failed\n");
+}
+if (setsockopt(cioc->fd, SOL_TCP, TCP_KEEPCNT,
+   &tcp_keepalive_probes, sizeof(tcp_keepalive_probes)) < 0) {
+perror("setsockopt failed\n");
+}
+if (setsockopt(cioc->fd, SOL_TCP, TCP_KEEPIDLE,
+   &tcp_keepalive_time, sizeof(tcp_keepalive_time)) < 0) {
+perror("setsockopt failed\n");
+}
+if (setsockopt(cios->fd, SOL_SOCKET, SO_KEEPALIVE,
+   &tcp_keepalive_on, sizeof(tcp_keepalive_on)) < 0) {
+perror("setsockopt failed\n");
+}
  }
  
  static void nbd_update_server_watch(void)

I tend to so no. Not in this exact form.

In general we have NBD server which could be created and configured
in several different ways. Through qemu-nbd and through QMP.

At the moment we do set KEEP_ALIVE for outgoing connections
only and that is configurable, please refer to

int inet_parse(InetSocketAddress *addr, const char *str, Error **errp)

which I believe should be called for the any real configuration
setting with an IP address specified. This option will get
InetSocketAddress->keep_alive/has_keep_alive set.

Though this option has no effect for the listen socket and
this is wrong for you case. You are absolutely right,
as specified in
static int inet_listen_saddr(InetSocketAddress *saddr,
 int port_offset,
 int num,
 Error **errp)
{
    struct addrinfo ai,*res,*e;
    char port[33];
    char uaddr[INET6_ADDRSTRLEN+1];
    char uport[33];
    int rc, port_min, port_max, p;
    int slisten = -1;
    int saved_errno = 0;
    bool socket_created = false;
    Error *err = NULL;

    if (saddr->keep_alive) {
    error_setg(errp, "keep-alive option is not supported for passive "
   "sockets");
    return -1;
    }

thus you should technically remove this pitfall and set keep_alive
in the generic accept code if you have it specified for the listen
socket.

This seems consistent to me. Adding Vladimir to the loop as
the submitter of the original keep-alive code (if my memory
does not fail me :).

Den



Re: [RFC 4/4] tcg/plugins: Add example pair of QPP plugins

2022-09-21 Thread Alex Bennée


Andrew Fasano  writes:

> The first plugin, qpp_srv exposes two functions and one callback that other
> plugins can leverage. These functions are described in the corresponding
> header file.
>
> The second plugin, qpp_client, imports this header file, registers its
> own function to run on a qpp_srv-provided callback, and directly calls
> into the two exposed functions in qpp_srv.
>
> Signed-off-by: Andrew Fasano 
> ---
>  contrib/plugins/Makefile |  2 ++
>  contrib/plugins/qpp_client.c | 42 
>  contrib/plugins/qpp_client.h |  1 +
>  contrib/plugins/qpp_srv.c| 33 
>  contrib/plugins/qpp_srv.h| 17 +++

Oh and I forgot this toy case should probably be in test/plugins/qpp with an
explicit test in tests/tcg/multiarch/Makefile to exercise it during
"make check-tcg". This should hopefully avoid having to mess with
PLUGINS in tests/tcg/Makefile.target.



-- 
Alex Bennée



[PULL 1/5] target/m68k: Implement atomic test-and-set

2022-09-21 Thread Laurent Vivier
From: Richard Henderson 

This is slightly more complicated than cas,
because tas is allowed on data registers.

Signed-off-by: Richard Henderson 
Reviewed-by: Laurent Vivier 
Message-Id: <20220829051746.227094-1-richard.hender...@linaro.org>
Signed-off-by: Laurent Vivier 
---
 target/m68k/translate.c | 40 ++--
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 5098f7e570e0..ffcc761d6011 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2825,19 +2825,39 @@ DISAS_INSN(illegal)
 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
 }
 
-/* ??? This should be atomic.  */
 DISAS_INSN(tas)
 {
-TCGv dest;
-TCGv src1;
-TCGv addr;
+int mode = extract32(insn, 3, 3);
+int reg0 = REG(insn, 0);
 
-dest = tcg_temp_new();
-SRC_EA(env, src1, OS_BYTE, 1, &addr);
-gen_logic_cc(s, src1, OS_BYTE);
-tcg_gen_ori_i32(dest, src1, 0x80);
-DEST_EA(env, insn, OS_BYTE, dest, &addr);
-tcg_temp_free(dest);
+if (mode == 0) {
+/* data register direct */
+TCGv dest = cpu_dregs[reg0];
+gen_logic_cc(s, dest, OS_BYTE);
+tcg_gen_ori_tl(dest, dest, 0x80);
+} else {
+TCGv src1, addr;
+
+addr = gen_lea_mode(env, s, mode, reg0, OS_BYTE);
+if (IS_NULL_QREG(addr)) {
+gen_addr_fault(s);
+return;
+}
+src1 = tcg_temp_new();
+tcg_gen_atomic_fetch_or_tl(src1, addr, tcg_constant_tl(0x80),
+   IS_USER(s), MO_SB);
+gen_logic_cc(s, src1, OS_BYTE);
+tcg_temp_free(src1);
+
+switch (mode) {
+case 3: /* Indirect postincrement.  */
+tcg_gen_addi_i32(AREG(insn, 0), addr, 1);
+break;
+case 4: /* Indirect predecrememnt.  */
+tcg_gen_mov_i32(AREG(insn, 0), addr);
+break;
+}
+}
 }
 
 DISAS_INSN(mull)
-- 
2.37.3




[PULL 2/5] target/m68k: Fix MACSR to CCR

2022-09-21 Thread Laurent Vivier
From: Richard Henderson 

First, we were writing to the entire SR register, instead
of only the flags portion.  Second, we were not clearing C
as per the documentation (X was cleared via the 0xf mask).

Signed-off-by: Richard Henderson 
Reviewed-by: Laurent Vivier 
Message-Id: <20220913142818.7802-2-richard.hender...@linaro.org>
Signed-off-by: Laurent Vivier 
---
 target/m68k/translate.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index ffcc761d6011..c9bb05380323 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -5912,8 +5912,10 @@ DISAS_INSN(from_mext)
 DISAS_INSN(macsr_to_ccr)
 {
 TCGv tmp = tcg_temp_new();
-tcg_gen_andi_i32(tmp, QREG_MACSR, 0xf);
-gen_helper_set_sr(cpu_env, tmp);
+
+/* Note that X and C are always cleared. */
+tcg_gen_andi_i32(tmp, QREG_MACSR, CCF_N | CCF_Z | CCF_V);
+gen_helper_set_ccr(cpu_env, tmp);
 tcg_temp_free(tmp);
 set_cc_op(s, CC_OP_FLAGS);
 }
-- 
2.37.3




[PULL 3/5] target/m68k: Perform writback before modifying SR

2022-09-21 Thread Laurent Vivier
From: Richard Henderson 

Writes to SR may change security state, which may involve
a swap of %ssp with %usp as reflected in %a7.  Finish the
writeback of %sp@+ before swapping stack pointers.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1206
Signed-off-by: Richard Henderson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Mark Cave-Ayland 
Message-Id: <20220913142818.7802-3-richard.hender...@linaro.org>
Signed-off-by: Laurent Vivier 
---
 target/m68k/translate.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index c9bb05380323..4640eadf78e1 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2285,9 +2285,9 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, 
int ccr_only)
 tcg_gen_movi_i32(QREG_CC_N, val & CCF_N ? -1 : 0);
 tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0);
 } else {
-TCGv sr = tcg_const_i32(val);
-gen_helper_set_sr(cpu_env, sr);
-tcg_temp_free(sr);
+/* Must writeback before changing security state. */
+do_writebacks(s);
+gen_helper_set_sr(cpu_env, tcg_constant_i32(val));
 }
 set_cc_op(s, CC_OP_FLAGS);
 }
@@ -2297,6 +2297,8 @@ static void gen_set_sr(DisasContext *s, TCGv val, int 
ccr_only)
 if (ccr_only) {
 gen_helper_set_ccr(cpu_env, val);
 } else {
+/* Must writeback before changing security state. */
+do_writebacks(s);
 gen_helper_set_sr(cpu_env, val);
 }
 set_cc_op(s, CC_OP_FLAGS);
-- 
2.37.3




[PULL 0/5] M68k for 7.2 patches

2022-09-21 Thread Laurent Vivier
The following changes since commit 832e9e33bc51f52fc3ea667d48912e95af3e28f3:

  Merge tag 'pull-loongarch-20220920' of https://gitlab.com/gaosong/qemu into 
staging (2022-09-20 14:17:03 -0400)

are available in the Git repository at:

  https://github.com/vivier/qemu-m68k.git tags/m68k-for-7.2-pull-request

for you to fetch changes up to c7546abfaa1b1c2729eaddd41c6268a73cdae14f:

  target/m68k: always call gen_exit_tb() after writes to SR (2022-09-21 
15:10:57 +0200)


m68k pull request 20220921

- several fixes for SR
- implement TAS
- feature cleanup



Mark Cave-Ayland (2):
  target/m68k: rename M68K_FEATURE_M68000 to M68K_FEATURE_M68K
  target/m68k: always call gen_exit_tb() after writes to SR

Richard Henderson (3):
  target/m68k: Implement atomic test-and-set
  target/m68k: Fix MACSR to CCR
  target/m68k: Perform writback before modifying SR

 target/m68k/cpu.h   |   5 +-
 target/m68k/cpu.c   |   2 +-
 target/m68k/helper.c|   2 +-
 target/m68k/op_helper.c |   2 +-
 target/m68k/translate.c | 196 +++-
 5 files changed, 118 insertions(+), 89 deletions(-)

-- 
2.37.3




[PULL 5/5] target/m68k: always call gen_exit_tb() after writes to SR

2022-09-21 Thread Laurent Vivier
From: Mark Cave-Ayland 

Any write to SR can change the security state so always call gen_exit_tb() when
this occurs. In particular MacOS makes use of andiw/oriw in a few places to
handle the switch between user and supervisor mode.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220917112515.83905-5-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 target/m68k/translate.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 0b618e8eb2bd..233b9d8e5783 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2375,6 +2375,7 @@ DISAS_INSN(arith_im)
 tcg_gen_or_i32(dest, src1, im);
 if (with_SR) {
 gen_set_sr(s, dest, opsize == OS_BYTE);
+gen_exit_tb(s);
 } else {
 DEST_EA(env, insn, opsize, dest, &addr);
 gen_logic_cc(s, dest, opsize);
@@ -2384,6 +2385,7 @@ DISAS_INSN(arith_im)
 tcg_gen_and_i32(dest, src1, im);
 if (with_SR) {
 gen_set_sr(s, dest, opsize == OS_BYTE);
+gen_exit_tb(s);
 } else {
 DEST_EA(env, insn, opsize, dest, &addr);
 gen_logic_cc(s, dest, opsize);
@@ -2407,6 +2409,7 @@ DISAS_INSN(arith_im)
 tcg_gen_xor_i32(dest, src1, im);
 if (with_SR) {
 gen_set_sr(s, dest, opsize == OS_BYTE);
+gen_exit_tb(s);
 } else {
 DEST_EA(env, insn, opsize, dest, &addr);
 gen_logic_cc(s, dest, opsize);
@@ -4614,6 +4617,7 @@ DISAS_INSN(strldsr)
 }
 gen_push(s, gen_get_sr(s));
 gen_set_sr_im(s, ext, 0);
+gen_exit_tb(s);
 }
 
 DISAS_INSN(move_from_sr)
-- 
2.37.3




[PULL 4/5] target/m68k: rename M68K_FEATURE_M68000 to M68K_FEATURE_M68K

2022-09-21 Thread Laurent Vivier
From: Mark Cave-Ayland 

The M68K_FEATURE_M68000 feature is misleading in that its name suggests the 
feature
is defined just for Motorola 68000 CPUs, whilst in fact it is defined for all
Motorola 680X0 CPUs.

In order to avoid confusion with the other M68K_FEATURE_M680X0 constants which
define the features available for specific Motorola CPU models, rename
M68K_FEATURE_M68000 to M68K_FEATURE_M68K and add comments to clarify its usage.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220917112515.83905-2-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 target/m68k/cpu.h   |   5 +-
 target/m68k/cpu.c   |   2 +-
 target/m68k/helper.c|   2 +-
 target/m68k/op_helper.c |   2 +-
 target/m68k/translate.c | 138 
 5 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 4d8f48e8c747..67b6c12c2892 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -480,8 +480,9 @@ void do_m68k_semihosting(CPUM68KState *env, int nr);
  */
 
 enum m68k_features {
-/* Base m68k instruction set */
-M68K_FEATURE_M68000,
+/* Base Motorola CPU set (not set for Coldfire CPUs) */
+M68K_FEATURE_M68K,
+/* Motorola CPU feature sets */
 M68K_FEATURE_M68010,
 M68K_FEATURE_M68020,
 M68K_FEATURE_M68030,
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 5bbefda5752d..f681be3a2a58 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -110,7 +110,7 @@ static void m68000_cpu_initfn(Object *obj)
 M68kCPU *cpu = M68K_CPU(obj);
 CPUM68KState *env = &cpu->env;
 
-m68k_set_feature(env, M68K_FEATURE_M68000);
+m68k_set_feature(env, M68K_FEATURE_M68K);
 m68k_set_feature(env, M68K_FEATURE_USP);
 m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
 m68k_set_feature(env, M68K_FEATURE_MOVEP);
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 5728e48585fc..4621cf24027e 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -460,7 +460,7 @@ void m68k_switch_sp(CPUM68KState *env)
 int new_sp;
 
 env->sp[env->current_sp] = env->aregs[7];
-if (m68k_feature(env, M68K_FEATURE_M68000)) {
+if (m68k_feature(env, M68K_FEATURE_M68K)) {
 if (env->sr & SR_S) {
 /* SR:Master-Mode bit unimplemented then ISP is not available */
 if (!m68k_feature(env, M68K_FEATURE_MSP) || env->sr & SR_M) {
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index a96a03405060..5da176d6425a 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -432,7 +432,7 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
 
 static void do_interrupt_all(CPUM68KState *env, int is_hw)
 {
-if (m68k_feature(env, M68K_FEATURE_M68000)) {
+if (m68k_feature(env, M68K_FEATURE_M68K)) {
 m68k_interrupt_all(env, is_hw);
 return;
 }
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 4640eadf78e1..0b618e8eb2bd 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -471,7 +471,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext 
*s, TCGv base)
 if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
 return NULL_QREG;
 
-if (m68k_feature(s->env, M68K_FEATURE_M68000) &&
+if (m68k_feature(s->env, M68K_FEATURE_M68K) &&
 !m68k_feature(s->env, M68K_FEATURE_SCALED_INDEX)) {
 ext &= ~(3 << 9);
 }
@@ -804,7 +804,7 @@ static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
 reg = get_areg(s, reg0);
 tmp = mark_to_release(s, tcg_temp_new());
 if (reg0 == 7 && opsize == OS_BYTE &&
-m68k_feature(s->env, M68K_FEATURE_M68000)) {
+m68k_feature(s->env, M68K_FEATURE_M68K)) {
 tcg_gen_subi_i32(tmp, reg, 2);
 } else {
 tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize));
@@ -888,7 +888,7 @@ static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, 
int mode, int reg0,
 if (what == EA_STORE || !addrp) {
 TCGv tmp = tcg_temp_new();
 if (reg0 == 7 && opsize == OS_BYTE &&
-m68k_feature(s->env, M68K_FEATURE_M68000)) {
+m68k_feature(s->env, M68K_FEATURE_M68K)) {
 tcg_gen_addi_i32(tmp, reg, 2);
 } else {
 tcg_gen_addi_i32(tmp, reg, opsize_bytes(opsize));
@@ -2210,7 +2210,7 @@ DISAS_INSN(bitop_im)
 op = (insn >> 6) & 3;
 
 bitnum = read_im16(env, s);
-if (m68k_feature(s->env, M68K_FEATURE_M68000)) {
+if (m68k_feature(s->env, M68K_FEATURE_M68K)) {
 if (bitnum & 0xfe00) {
 disas_undef(env, s, insn);
 return;
@@ -2897,7 +2897,7 @@ DISAS_INSN(mull)
 return;
 }
 SRC_EA(env, src1, OS_LONG, 0, NULL);
-if (m68k_feature(s->env, M68K_FEATURE_M68000)) {
+if (m68k_feature(s->env, M68K_FEATURE_M68K)) {

[PATCH v1 01/10] monitor: expose monitor_puts to rest of code

2022-09-21 Thread Alex Bennée
This helps us construct strings elsewhere before echoing to the
monitor. It avoids having to jump through hoops like:

  monitor_printf(mon, "%s", s->str);

It will be useful in following patches but for now convert all
existing plain "%s" printfs to use the _puts api.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 

---
v2
  - s/monitor_printf(mon, "%s"/monitor_puts(mon, /
---
 docs/devel/writing-monitor-commands.rst |  2 +-
 include/monitor/monitor.h   |  1 +
 monitor/monitor-internal.h  |  1 -
 block/monitor/block-hmp-cmds.c  | 10 +-
 hw/misc/mos6522.c   |  2 +-
 monitor/hmp-cmds.c  |  8 
 monitor/hmp.c   |  2 +-
 target/i386/helper.c|  2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/docs/devel/writing-monitor-commands.rst 
b/docs/devel/writing-monitor-commands.rst
index 4aa2bb904d..2fefedcd98 100644
--- a/docs/devel/writing-monitor-commands.rst
+++ b/docs/devel/writing-monitor-commands.rst
@@ -716,7 +716,7 @@ message. Here's the implementation of the "info roms" HMP 
command::
  if (hmp_handle_error(mon, err)) {
  return;
  }
- monitor_printf(mon, "%s", info->human_readable_text);
+ monitor_puts(mon, info->human_readable_text);
  }
 
 Also, you have to add the function's prototype to the hmp.h file.
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index a4b40e8391..737e750670 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -31,6 +31,7 @@ void monitor_resume(Monitor *mon);
 int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
 int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
 
+int monitor_puts(Monitor *mon, const char *str);
 int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
 G_GNUC_PRINTF(2, 0);
 int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index caa2e90ef2..a2cdbbf646 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -174,7 +174,6 @@ extern int mon_refcount;
 
 extern HMPCommand hmp_cmds[];
 
-int monitor_puts(Monitor *mon, const char *str);
 void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush,
bool use_io_thread);
 void monitor_data_destroy(Monitor *mon);
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index bfb3c043a0..939a520d17 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -638,16 +638,16 @@ static void print_block_info(Monitor *mon, BlockInfo 
*info,
 assert(!info || !info->has_inserted || info->inserted == inserted);
 
 if (info && *info->device) {
-monitor_printf(mon, "%s", info->device);
+monitor_puts(mon, info->device);
 if (inserted && inserted->has_node_name) {
 monitor_printf(mon, " (%s)", inserted->node_name);
 }
 } else {
 assert(info || inserted);
-monitor_printf(mon, "%s",
-   inserted && inserted->has_node_name ? 
inserted->node_name
-   : info && info->has_qdev ? info->qdev
-   : "");
+monitor_puts(mon,
+ inserted && inserted->has_node_name ? inserted->node_name
+ : info && info->has_qdev ? info->qdev
+ : "");
 }
 
 if (inserted) {
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index f9e646350e..fe38c44426 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -595,7 +595,7 @@ void hmp_info_via(Monitor *mon, const QDict *qdict)
 if (hmp_handle_error(mon, err)) {
 return;
 }
-monitor_printf(mon, "%s", info->human_readable_text);
+monitor_puts(mon, info->human_readable_text);
 }
 
 static const MemoryRegionOps mos6522_ops = {
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index c6cd6f91dd..f90eea8d01 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -730,7 +730,7 @@ static void hmp_info_pci_device(Monitor *mon, const 
PciDeviceInfo *dev)
 monitor_printf(mon, "");
 
 if (dev->class_info->has_desc) {
-monitor_printf(mon, "%s", dev->class_info->desc);
+monitor_puts(mon, dev->class_info->desc);
 } else {
 monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class);
 }
@@ -2258,12 +2258,12 @@ static void print_stats_schema_value(Monitor *mon, 
StatsSchemaValue *value)
 if (unit && value->base == 10 &&
 value->exponent >= -18 && value->exponent <= 18 &&
 value->exponent % 3 == 0) {
-monitor_printf(mon, "%s", si_prefix(value->exponent));
+monitor_puts(mon, si_prefix(value->exponent));
 } else if (unit && value->base == 2 &&
value->exponent >= 0 && value->exponent <= 60 &&
value->exponent % 10 == 0) {
 
-

[PATCH v1 00/10] plugins/next (disas, monitor, docs, execlog)

2022-09-21 Thread Alex Bennée
Hi,

It has been a while since I last posted the state of my plugins queue.
These are mostly small cleanups and documentation tweaks. I also did a
little bit of tidying up in the disas interface.

The following still need review:

 - docs/devel: document the test plugins
 - contrib/plugins: reset skip when matching in execlog
 - docs/devel: move API to end of tcg-plugins.rst
 - docs/devel: clean-up qemu invocations in tcg-plugins
 - tests/tcg: add memory-sve test for aarch64

Alex Bennée (9):
  monitor: expose monitor_puts to rest of code
  disas: generalise plugin_printf and use for monitor_disas
  disas: use result of ->read_memory_func
  tests/tcg: add memory-sve test for aarch64
  plugins: extend execlog to filter matches
  docs/devel: clean-up qemu invocations in tcg-plugins
  docs/devel: move API to end of tcg-plugins.rst
  contrib/plugins: reset skip when matching in execlog
  docs/devel: document the test plugins

Richard Henderson (1):
  plugins: Assert mmu_idx in range before use in qemu_plugin_get_hwaddr

 docs/devel/tcg-plugins.rst| 175 +++---
 docs/devel/writing-monitor-commands.rst   |   2 +-
 include/monitor/monitor.h |   1 +
 monitor/monitor-internal.h|   1 -
 block/monitor/block-hmp-cmds.c|  10 +-
 contrib/plugins/execlog.c |  99 ++--
 disas.c   |  43 +++---
 disas/capstone.c  |  73 +
 hw/misc/mos6522.c |   2 +-
 monitor/hmp-cmds.c|   8 +-
 monitor/hmp.c |   2 +-
 plugins/api.c |   2 +
 target/i386/helper.c  |   2 +-
 tests/tcg/aarch64/Makefile.softmmu-target |   7 +
 tests/tcg/aarch64/system/boot.S   |   3 +-
 15 files changed, 336 insertions(+), 94 deletions(-)

-- 
2.34.1




  1   2   >