Re: [PATCH v2 for-8.0 0/5] scripts/make-release: Decrease size of the release tarballs

2022-12-09 Thread Thomas Huth

On 30/11/2022 13.09, Daniel P. Berrangé wrote:

On Wed, Nov 30, 2022 at 11:49:50AM +0100, Thomas Huth wrote:

On 28/11/2022 18.04, Daniel P. Berrangé wrote:

On Mon, Nov 28, 2022 at 10:25:50AM +0100, Thomas Huth wrote:

Our release tarballs are huge - qemu-7.2.0-rc2.tar.xz has a size of 116
MiB. If you look at the contents, approx. 80% of the size is used for the
firmware sources that we ship along to provide the sources for the ROM
binaries. This feels very wrong, why do we urge users to download such
huge tarballs while 99.9% of them never will rebuilt the firmware sources?
We were also struggeling a bit in the past already with server load and
costs, so we should really try to decrease the size of our release tarballs
to a saner level.


The main reason for shipping the source in the tarball was to
guarantee license compliance for anyone who is distributing
qemu release tarballs, including ourselves.

Splitting off the firmware source, but not the firmware binaries,
means people are now at risk of not complying with the license
but failing to provide complete and corresponding source.

Technically the license requirement is only critical for GPL
licenses ROMs, but as good practice we do it for all our ROMs.


So let's split the firmware sources into a separate tarball to decrease
the size of the main QEMU sources tarball a lot (which should help us
to safe a lot of traffic on the server).


With my distro maintainer hat I would rather QEMU ship neither the
ROM source, nor the ROM binaries.

Still the binaries are convenient for people doing their own QEMU
builds from source.

How about shipping two distinct options:

qemu-x.y.z.tar.xz  (QEMU source only)
qemu-bundled-x.y.z.tar.xz  (QEMU source + bundled ROM binaries + ROM 
sources)

though I'm not sure how much of an impact that will have on the download
traffic - depends what is causing the traffic.

Another option is

qemu-x.y.z.tar.xz(QEMU source only)
qemu-roms-x.y.z.tar.xz   (bundled ROM binaries + ROM sources)

though this is slightly more inconvenient for users, and there's the
risk they'll use new QEMU with old ROMs.


Maybe that would work for distros, but I don't think that these are good
options for the average users who just want to download and recompile the
latest version of QEMU on their own.
I assume that most users don't have an environment with cross-compilers or
for running things in a container, so I think they still want to use the
pre-built binaries. Thus, if you bundle the binaries along with their
sources, people will still continue to download the big tarball and we
haven't gained anything.

So do you really really think shipping the binaries in the main tarball is a
problem? Honestly, it's not a problem for us as long as we publish both
tarballs together - and if someone wants to mirror the main tarball to their
webserver and fails to mirror the rom-sources tarball, too, it's their
fault, not ours.


I think we would be contributing to mistakes by providing a tarball
that contains a mixture of sources and binaries, but not all the
sources for all the binaries.


Anyway, what about splitting the binaries into a separate tarball, so we
would have three tarballs:

 qemu-x.y.z.tar.xz   (QEMU source only)
 qemu-roms-x.y.z.tar.xz  (ROM binaries)
 qemu-roms-sources-x.y.z.tar.xz  (ROM sources)

That should make it hopefully obvious that the two qemu-roms* tarballs
belong together. Would that be OK for you?


Yes, I think that's better, as it is cleanly separating the
binaries and sources.


I pondered about this idea quite a while now, but I think that will 
definitely be a decrease in the user's experience, e.g. "make install" won't 
work by default anymore if the user did not download the binaries before. 
Sure, we can instruct the users to download and uncompress the roms tarball 
here or there ... but still, it's getting more cumbersome for the users this 
way. Thus I think I'd rather would like to avoid packaging the binaries in 
an extra tarball.



The downside is that there's the risk of ROMS not matching
the QEMU version, if people updates to latest qemu tarball
but forgot the corresponding ROMs tarball. Most of the time
a mismatch would not matter, but we should think about if
there is a way to make it easier to diagnose such a
mismatch if only for easier bug triage.


Yes, that's another disadvantage which will lead to very subtle bug reports 
if we don't prevent it from happening somehow.



Perhaps the ROMs should install into a versioned subdir
of /usr/share/qemu, instead of the root of it, and the
QEMU binary preferentially look at the versioned subdir
Maybe that's overthinking things though, and we would
suffic to have a /usr/share/qemu/ROM-VERSION.txt file


I don't think that a text file will be sufficient to prevent people running 
into the problem. Having versioned subdirs might help, but it has the 
disadvantage that it might cause lots of old files l

Re: [PATCH v3 1/8] util: Add interval-tree.c

2022-12-09 Thread Philippe Mathieu-Daudé

On 9/12/22 06:19, Richard Henderson wrote:

Copy and simplify the Linux kernel's interval_tree_generic.h,
instantiating for uint64_t.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
  include/qemu/interval-tree.h|  99 
  tests/unit/test-interval-tree.c | 209 
  util/interval-tree.c| 882 
  tests/unit/meson.build  |   1 +
  util/meson.build|   1 +
  5 files changed, 1192 insertions(+)
  create mode 100644 include/qemu/interval-tree.h
  create mode 100644 tests/unit/test-interval-tree.c
  create mode 100644 util/interval-tree.c

diff --git a/include/qemu/interval-tree.h b/include/qemu/interval-tree.h
new file mode 100644
index 00..25006debe8
--- /dev/null
+++ b/include/qemu/interval-tree.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Interval trees.
+ *
+ * Derived from include/linux/interval_tree.h and its dependencies.
+ */
+
+#ifndef QEMU_INTERVAL_TREE_H
+#define QEMU_INTERVAL_TREE_H



+
+#endif /* QEMU_INTERVAL_TREE_H */
diff --git a/tests/unit/test-interval-tree.c b/tests/unit/test-interval-tree.c
new file mode 100644
index 00..119817a019
--- /dev/null
+++ b/tests/unit/test-interval-tree.c





+/* Occasionally useful for calling from within the debugger. */
+#if 0
+static void debug_interval_tree_int(IntervalTreeNode *node,
+const char *dir, int level)
+{
+printf("%4d %*s %s [%" PRIu64 ",%" PRIu64 "] subtree_last:%" PRIu64 "\n",
+   level, level + 1, dir, rb_is_red(&node->rb) ? "r" : "b",
+   node->start, node->last, node->subtree_last);
+
+if (node->rb.rb_left) {
+debug_interval_tree_int(rb_to_itree(node->rb.rb_left), "<", level + 1);
+}
+if (node->rb.rb_right) {
+debug_interval_tree_int(rb_to_itree(node->rb.rb_right), ">", level + 
1);
+}
+}
+
+void debug_interval_tree(IntervalTreeNode *node);


If you think this function is helpful, shouldn't we declare it in the
header within CONFIG_DEBUG_TCG guards?


+void debug_interval_tree(IntervalTreeNode *node)
+{
+if (node) {
+debug_interval_tree_int(node, "*", 0);
+} else {
+printf("null\n");
+}
+}
+#endif




Re: Target-dependent include path, why?

2022-12-09 Thread Markus Armbruster
Richard Henderson  writes:

> On 12/8/22 23:12, Markus Armbruster wrote:
>> I stumbled over this:
>>  ../include/ui/qemu-pixman.h:12:10: fatal error: pixman.h: No such file 
>> or directory
>> 12 | #include 
>>|  ^~
>> Works when included into target-dependent code.
>> Running make -V=1 shows we're passing a number of -I only when compiling
>> target-dependent code, i.e. together with -DNEED_CPU_H:
>>  -I/usr/include/pixman-1 -I/usr/include/capstone 
>> -I/usr/include/spice-server -I/usr/include/spice-1
>>  -I/usr/include/cacard -I/usr/include/nss3 -I/usr/include/nspr4 
>> -I/usr/include/PCSC
>>  -isystem../linux-headers -isystemlinux-headers
>> Why?
>
> Because of where [pixman] is added as a dependency in meson.build.

Is it added where it is for a reason, or is it accidental?

> If you want to use it somewhere new, you've got to move the dependency.




Re: [PATCH v15 1/6] qmp: add QMP command x-query-virtio

2022-12-09 Thread Jonah Palmer


On 12/7/22 08:22, Markus Armbruster wrote:

Jonah Palmer  writes:


On 12/2/22 10:21, Markus Armbruster wrote:

Philippe Mathieu-Daudé   writes:


On 2/12/22 13:23, Jonah Palmer wrote:

On 11/30/22 11:16, Philippe Mathieu-Daudé wrote:

Hi,

On 11/8/22 14:24, Jonah Palmer wrote:

From: Laurent Vivier

This new command lists all the instances of VirtIODevices with
their canonical QOM path and name.

[Jonah: @virtio_list duplicates information that already exists in
    the QOM composition tree. However, extracting necessary information
    from this tree seems to be a bit convoluted.

    Instead, we still create our own list of realized virtio devices
    but use @qmp_qom_get with the device's canonical QOM path to confirm
    that the device exists and is realized. If the device exists but
    is actually not realized, then we remove it from our list (for
    synchronicity to the QOM composition tree).

How could this happen?


    Also, the QMP command @x-query-virtio is redundant as @qom-list
    and @qom-get are sufficient to search '/machine/' for realized
    virtio devices. However, @x-query-virtio is much more convenient
    in listing realized virtio devices.]

Signed-off-by: Laurent Vivier
Signed-off-by: Jonah Palmer
---
    hw/virtio/meson.build  |  2 ++
    hw/virtio/virtio-stub.c    | 14 
    hw/virtio/virtio.c | 44 
    include/hw/virtio/virtio.h |  1 +
    qapi/meson.build   |  1 +
    qapi/qapi-schema.json  |  1 +
    qapi/virtio.json   | 68 ++
    tests/qtest/qmp-cmd-test.c |  1 +
    8 files changed, 132 insertions(+)
    create mode 100644 hw/virtio/virtio-stub.c
    create mode 100644 qapi/virtio.json
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 5d607aeaa0..bdfa82e9c0 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -13,12 +13,18 @@
      #include "qemu/osdep.h"
    #include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qapi-commands-virtio.h"
+#include "qapi/qapi-commands-qom.h"
+#include "qapi/qapi-visit-virtio.h"
+#include "qapi/qmp/qjson.h"
    #include "cpu.h"
    #include "trace.h"
    #include "qemu/error-report.h"
    #include "qemu/log.h"
    #include "qemu/main-loop.h"
    #include "qemu/module.h"
+#include "qom/object_interfaces.h"
    #include "hw/virtio/virtio.h"
    #include "migration/qemu-file-types.h"
    #include "qemu/atomic.h"
@@ -29,6 +35,9 @@
    #include "sysemu/runstate.h"
    #include "standard-headers/linux/virtio_ids.h"
    +/* QAPI list of realized VirtIODevices */
+static QTAILQ_HEAD(, VirtIODevice) virtio_list;
+
    /*
     * The alignment to use between consumer and producer parts of vring.
     * x86 pagesize again. This is the default, used by transports like PCI
@@ -3698,6 +3707,7 @@ static void virtio_device_realize(DeviceState *dev, Error 
**errp)
    vdev->listener.commit = virtio_memory_listener_commit;
    vdev->listener.name = "virtio";
    memory_listener_register(&vdev->listener, vdev->dma_as);
+    QTAILQ_INSERT_TAIL(&virtio_list, vdev, next);
    }
      static void virtio_device_unrealize(DeviceState *dev)
@@ -3712,6 +3722,7 @@ static void virtio_device_unrealize(DeviceState *dev)
    vdc->unrealize(dev);
    }
    +    QTAILQ_REMOVE(&virtio_list, vdev, next);
    g_free(vdev->bus_name);
    vdev->bus_name = NULL;
    }
@@ -3885,6 +3896,8 @@ static void virtio_device_class_init(ObjectClass *klass, 
void *data)
    vdc->stop_ioeventfd = virtio_device_stop_ioeventfd_impl;
      vdc->legacy_features |= VIRTIO_LEGACY_FEATURES;
+
+    QTAILQ_INIT(&virtio_list);
    }
      bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev)
@@ -3895,6 +3908,37 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev)
    return virtio_bus_ioeventfd_enabled(vbus);
    }
    +VirtioInfoList *qmp_x_query_virtio(Error **errp)
+{
+    VirtioInfoList *list = NULL;
+    VirtioInfoList *node;
+    VirtIODevice *vdev;
+
+    QTAILQ_FOREACH(vdev, &virtio_list, next) {
+    DeviceState *dev = DEVICE(vdev);
+    Error *err = NULL;
+    QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err);
+
+    if (err == NULL) {
+    GString *is_realized = qobject_to_json_pretty(obj, true);
+    /* virtio device is NOT realized, remove it from list */

Why not check dev->realized instead of calling qmp_qom_get() & 
qobject_to_json_pretty()?

This check queries the QOM composition tree to check that the device actually 
exists and is
realized. In other words, we just want to confirm with the QOM composition tree 
for the device.

Again, how could this happen?

If @virtio_list isn't reliable, why have it in the first place?

Honestly, I'm not sure how this even could happen, since the @virtio_list is 
managed at the realization
and unrealization of a virtio device. Given this, I do feel as though the list 
is reliable, although
this might just benaïve of me to

Re: [PATCH] blockdev: add 'media=cdrom' argument to support usb cdrom emulated as cdrom

2022-12-09 Thread Paolo Bonzini

On 12/9/22 03:28, Zhipeng Lu wrote:

Thanks.

  -device usb-bot,id=bot0
  -device scsi-{cd,hd},bus=bot0.0,drive=drive0

Qemu implements virtio scsi to emulate scsi controller, but if the 
virtual machine(for example windows guest os) don't install the virtio 
scsi driver, it don't work
i need the function: emulate cdrom in guest, support hotplug and unplug, 
not  depend on virtio driver


usb-bot *is* a SCSI controller and it does not require drivers in the 
guest.  It is not very high-performance, but as you say it has hotplug 
functionality via USB.


Paolo




Re: [PATCH v10 6/9] KVM: Unmap existing mappings when change the memory attributes

2022-12-09 Thread Fuad Tabba
Hi,

On Thu, Dec 8, 2022 at 11:18 AM Chao Peng  wrote:
>
> On Wed, Dec 07, 2022 at 05:16:34PM +, Fuad Tabba wrote:
> > Hi,
> >
> > On Fri, Dec 2, 2022 at 6:19 AM Chao Peng  
> > wrote:
> > >
> > > Unmap the existing guest mappings when memory attribute is changed
> > > between shared and private. This is needed because shared pages and
> > > private pages are from different backends, unmapping existing ones
> > > gives a chance for page fault handler to re-populate the mappings
> > > according to the new attribute.
> > >
> > > Only architecture has private memory support needs this and the
> > > supported architecture is expected to rewrite the weak
> > > kvm_arch_has_private_mem().
> >
> > This kind of ties into the discussion of being able to share memory in
> > place. For pKVM for example, shared and private memory would have the
> > same backend, and the unmapping wouldn't be needed.
> >
> > So I guess that, instead of kvm_arch_has_private_mem(), can the check
> > be done differently, e.g., with a different function, say
> > kvm_arch_private_notify_attribute_change() (but maybe with a more
> > friendly name than what I suggested :) )?
>
> Besides controlling the unmapping here, kvm_arch_has_private_mem() is
> also used to gate the memslot KVM_MEM_PRIVATE flag in patch09. I know
> unmapping is confirmed unnecessary for pKVM, but how about
> KVM_MEM_PRIVATE? Will pKVM add its own flag or reuse KVM_MEM_PRIVATE?
> If the answer is the latter, then yes we should use a different check
> which only works for confidential usages here.

I think it makes sense for pKVM to use the same flag (KVM_MEM_PRIVATE)
and not to add another one.

Thank you,
/fuad



>
> Thanks,
> Chao
> >
> > Thanks,
> > /fuad
> >
> > >
> > > Also, during memory attribute changing and the unmapping time frame,
> > > page fault handler may happen in the same memory range and can cause
> > > incorrect page state, invoke kvm_mmu_invalidate_* helpers to let the
> > > page fault handler retry during this time frame.
> > >
> > > Signed-off-by: Chao Peng 
> > > ---
> > >  include/linux/kvm_host.h |   7 +-
> > >  virt/kvm/kvm_main.c  | 168 ++-
> > >  2 files changed, 116 insertions(+), 59 deletions(-)
> > >
> > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > > index 3d69484d2704..3331c0c92838 100644
> > > --- a/include/linux/kvm_host.h
> > > +++ b/include/linux/kvm_host.h
> > > @@ -255,7 +255,6 @@ bool kvm_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t 
> > > cr2_or_gpa,
> > >  int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu);
> > >  #endif
> > >
> > > -#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
> > >  struct kvm_gfn_range {
> > > struct kvm_memory_slot *slot;
> > > gfn_t start;
> > > @@ -264,6 +263,8 @@ struct kvm_gfn_range {
> > > bool may_block;
> > >  };
> > >  bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range);
> > > +
> > > +#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
> > >  bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
> > >  bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
> > >  bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
> > > @@ -785,11 +786,12 @@ struct kvm {
> > >
> > >  #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
> > > struct mmu_notifier mmu_notifier;
> > > +#endif
> > > unsigned long mmu_invalidate_seq;
> > > long mmu_invalidate_in_progress;
> > > gfn_t mmu_invalidate_range_start;
> > > gfn_t mmu_invalidate_range_end;
> > > -#endif
> > > +
> > > struct list_head devices;
> > > u64 manual_dirty_log_protect;
> > > struct dentry *debugfs_dentry;
> > > @@ -1480,6 +1482,7 @@ bool kvm_arch_dy_has_pending_interrupt(struct 
> > > kvm_vcpu *vcpu);
> > >  int kvm_arch_post_init_vm(struct kvm *kvm);
> > >  void kvm_arch_pre_destroy_vm(struct kvm *kvm);
> > >  int kvm_arch_create_vm_debugfs(struct kvm *kvm);
> > > +bool kvm_arch_has_private_mem(struct kvm *kvm);
> > >
> > >  #ifndef __KVM_HAVE_ARCH_VM_ALLOC
> > >  /*
> > > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > > index ad55dfbc75d7..4e1e1e113bf0 100644
> > > --- a/virt/kvm/kvm_main.c
> > > +++ b/virt/kvm/kvm_main.c
> > > @@ -520,6 +520,62 @@ void kvm_destroy_vcpus(struct kvm *kvm)
> > >  }
> > >  EXPORT_SYMBOL_GPL(kvm_destroy_vcpus);
> > >
> > > +void kvm_mmu_invalidate_begin(struct kvm *kvm)
> > > +{
> > > +   /*
> > > +* The count increase must become visible at unlock time as no
> > > +* spte can be established without taking the mmu_lock and
> > > +* count is also read inside the mmu_lock critical section.
> > > +*/
> > > +   kvm->mmu_invalidate_in_progress++;
> > > +
> > > +   if (likely(kvm->mmu_invalidate_in_progress == 1)) {
> > > +   kvm->mmu_invalidate_range_start = INVALID_GPA;
> > > +   kvm->mmu_invalidate_range_end = INVALID_GPA;
> > > +   }
> > > +

Re: [PATCH for-8.0] hw/rtc/mc146818rtc: Make this rtc device target independent

2022-12-09 Thread Thomas Huth

On 07/12/2022 15.47, Bernhard Beschow wrote:



Am 6. Dezember 2022 20:06:41 UTC schrieb Thomas Huth :

The only code that is really, really target dependent is the apic-related
code in rtc_policy_slew_deliver_irq(). By moving this code into the hw/i386/
folder (renamed to rtc_apic_policy_slew_deliver_irq()) and passing this
function as parameter to mc146818_rtc_init(), we can make the RTC completely
target-independent.

Signed-off-by: Thomas Huth 
---
include/hw/rtc/mc146818rtc.h |  7 +--
hw/alpha/dp264.c |  2 +-
hw/hppa/machine.c|  2 +-
hw/i386/microvm.c|  3 ++-
hw/i386/pc.c | 10 +-
hw/mips/jazz.c   |  2 +-
hw/ppc/pnv.c |  2 +-
hw/rtc/mc146818rtc.c | 34 +++---
hw/rtc/meson.build   |  3 +--
9 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h
index 1db0fcee92..c687953cc4 100644
--- a/include/hw/rtc/mc146818rtc.h
+++ b/include/hw/rtc/mc146818rtc.h
@@ -46,14 +46,17 @@ struct RTCState {
 Notifier clock_reset_notifier;
 LostTickPolicy lost_tick_policy;


This lost_tick_policy attribute along with its enum is now redundant and can be 
removed. Removing it avoids an error condition (see below).


lost_tick_policy is used for a property of the device which gets set from 
softmmu/rtc.c, so I would not say that it is unused ... or do I miss something?


 Thomas




Re: [PATCH v10 8/9] KVM: Handle page fault for private memory

2022-12-09 Thread Fuad Tabba
Hi,

On Fri, Dec 2, 2022 at 6:19 AM Chao Peng  wrote:
>
> A KVM_MEM_PRIVATE memslot can include both fd-based private memory and
> hva-based shared memory. Architecture code (like TDX code) can tell
> whether the on-going fault is private or not. This patch adds a
> 'is_private' field to kvm_page_fault to indicate this and architecture
> code is expected to set it.
>
> To handle page fault for such memslot, the handling logic is different
> depending on whether the fault is private or shared. KVM checks if
> 'is_private' matches the host's view of the page (maintained in
> mem_attr_array).
>   - For a successful match, private pfn is obtained with
> restrictedmem_get_page() and shared pfn is obtained with existing
> get_user_pages().
>   - For a failed match, KVM causes a KVM_EXIT_MEMORY_FAULT exit to
> userspace. Userspace then can convert memory between private/shared
> in host's view and retry the fault.
>
> Co-developed-by: Yu Zhang 
> Signed-off-by: Yu Zhang 
> Signed-off-by: Chao Peng 
> ---
>  arch/x86/kvm/mmu/mmu.c  | 63 +++--
>  arch/x86/kvm/mmu/mmu_internal.h | 14 +++-
>  arch/x86/kvm/mmu/mmutrace.h |  1 +
>  arch/x86/kvm/mmu/tdp_mmu.c  |  2 +-
>  include/linux/kvm_host.h| 30 
>  5 files changed, 105 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 2190fd8c95c0..b1953ebc012e 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -3058,7 +3058,7 @@ static int host_pfn_mapping_level(struct kvm *kvm, 
> gfn_t gfn,
>
>  int kvm_mmu_max_mapping_level(struct kvm *kvm,
>   const struct kvm_memory_slot *slot, gfn_t gfn,
> - int max_level)
> + int max_level, bool is_private)
>  {
> struct kvm_lpage_info *linfo;
> int host_level;
> @@ -3070,6 +3070,9 @@ int kvm_mmu_max_mapping_level(struct kvm *kvm,
> break;
> }
>
> +   if (is_private)
> +   return max_level;
> +
> if (max_level == PG_LEVEL_4K)
> return PG_LEVEL_4K;
>
> @@ -3098,7 +3101,8 @@ void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, 
> struct kvm_page_fault *fault
>  * level, which will be used to do precise, accurate accounting.
>  */
> fault->req_level = kvm_mmu_max_mapping_level(vcpu->kvm, slot,
> -fault->gfn, 
> fault->max_level);
> +fault->gfn, 
> fault->max_level,
> +fault->is_private);
> if (fault->req_level == PG_LEVEL_4K || fault->huge_page_disallowed)
> return;
>
> @@ -4178,6 +4182,49 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, 
> struct kvm_async_pf *work)
> kvm_mmu_do_page_fault(vcpu, work->cr2_or_gpa, 0, true);
>  }
>
> +static inline u8 order_to_level(int order)
> +{
> +   BUILD_BUG_ON(KVM_MAX_HUGEPAGE_LEVEL > PG_LEVEL_1G);
> +
> +   if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G))
> +   return PG_LEVEL_1G;
> +
> +   if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M))
> +   return PG_LEVEL_2M;
> +
> +   return PG_LEVEL_4K;
> +}
> +
> +static int kvm_do_memory_fault_exit(struct kvm_vcpu *vcpu,
> +   struct kvm_page_fault *fault)
> +{
> +   vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT;
> +   if (fault->is_private)
> +   vcpu->run->memory.flags = KVM_MEMORY_EXIT_FLAG_PRIVATE;
> +   else
> +   vcpu->run->memory.flags = 0;
> +   vcpu->run->memory.gpa = fault->gfn << PAGE_SHIFT;

nit: As in previous patches, use helpers (for this and other similar
shifts in this patch)?

> +   vcpu->run->memory.size = PAGE_SIZE;
> +   return RET_PF_USER;
> +}
> +
> +static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
> +  struct kvm_page_fault *fault)
> +{
> +   int order;
> +   struct kvm_memory_slot *slot = fault->slot;
> +
> +   if (!kvm_slot_can_be_private(slot))
> +   return kvm_do_memory_fault_exit(vcpu, fault);
> +
> +   if (kvm_restricted_mem_get_pfn(slot, fault->gfn, &fault->pfn, &order))
> +   return RET_PF_RETRY;
> +
> +   fault->max_level = min(order_to_level(order), fault->max_level);
> +   fault->map_writable = !(slot->flags & KVM_MEM_READONLY);
> +   return RET_PF_CONTINUE;
> +}
> +
>  static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault 
> *fault)
>  {
> struct kvm_memory_slot *slot = fault->slot;
> @@ -4210,6 +4257,12 @@ static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, 
> struct kvm_page_fault *fault)
> return RET_PF_EMULATE;
> }
>
> +   if (fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn))
> +   retur

Re: [PATCH v10 9/9] KVM: Enable and expose KVM_MEM_PRIVATE

2022-12-09 Thread Fuad Tabba
Hi,

On Fri, Dec 2, 2022 at 6:20 AM Chao Peng  wrote:
>
> Register/unregister private memslot to fd-based memory backing store
> restrictedmem and implement the callbacks for restrictedmem_notifier:
>   - invalidate_start()/invalidate_end() to zap the existing memory
> mappings in the KVM page table.
>   - error() to request KVM_REQ_MEMORY_MCE and later exit to userspace
> with KVM_EXIT_SHUTDOWN.
>
> Expose KVM_MEM_PRIVATE for memslot and KVM_MEMORY_ATTRIBUTE_PRIVATE for
> KVM_GET_SUPPORTED_MEMORY_ATTRIBUTES to userspace but either are
> controlled by kvm_arch_has_private_mem() which should be rewritten by
> architecture code.
>
> Co-developed-by: Yu Zhang 
> Signed-off-by: Yu Zhang 
> Signed-off-by: Chao Peng 
> Reviewed-by: Fuad Tabba 

With the code to port it to pKVM/arm64:
Tested-by: Fuad Tabba 

Cheers,
/fuad


> ---
>  arch/x86/include/asm/kvm_host.h |   1 +
>  arch/x86/kvm/x86.c  |  13 +++
>  include/linux/kvm_host.h|   3 +
>  virt/kvm/kvm_main.c | 179 +++-
>  4 files changed, 191 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 7772ab37ac89..27ef31133352 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -114,6 +114,7 @@
> KVM_ARCH_REQ_FLAGS(31, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
>  #define KVM_REQ_HV_TLB_FLUSH \
> KVM_ARCH_REQ_FLAGS(32, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
> +#define KVM_REQ_MEMORY_MCE KVM_ARCH_REQ(33)
>
>  #define CR0_RESERVED_BITS   \
> (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 5aefcff614d2..c67e22f3e2ee 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6587,6 +6587,13 @@ int kvm_arch_pm_notifier(struct kvm *kvm, unsigned 
> long state)
>  }
>  #endif /* CONFIG_HAVE_KVM_PM_NOTIFIER */
>
> +#ifdef CONFIG_HAVE_KVM_RESTRICTED_MEM
> +void kvm_arch_memory_mce(struct kvm *kvm)
> +{
> +   kvm_make_all_cpus_request(kvm, KVM_REQ_MEMORY_MCE);
> +}
> +#endif
> +
>  static int kvm_vm_ioctl_get_clock(struct kvm *kvm, void __user *argp)
>  {
> struct kvm_clock_data data = { 0 };
> @@ -10357,6 +10364,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>
> if (kvm_check_request(KVM_REQ_UPDATE_CPU_DIRTY_LOGGING, vcpu))
> static_call(kvm_x86_update_cpu_dirty_logging)(vcpu);
> +
> +   if (kvm_check_request(KVM_REQ_MEMORY_MCE, vcpu)) {
> +   vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;
> +   r = 0;
> +   goto out;
> +   }
> }
>
> if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win ||
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 153842bb33df..f032d878e034 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -590,6 +590,7 @@ struct kvm_memory_slot {
> struct file *restricted_file;
> loff_t restricted_offset;
> struct restrictedmem_notifier notifier;
> +   struct kvm *kvm;
>  };
>
>  static inline bool kvm_slot_can_be_private(const struct kvm_memory_slot 
> *slot)
> @@ -2363,6 +2364,8 @@ static inline int kvm_restricted_mem_get_pfn(struct 
> kvm_memory_slot *slot,
> *pfn = page_to_pfn(page);
> return ret;
>  }
> +
> +void kvm_arch_memory_mce(struct kvm *kvm);
>  #endif /* CONFIG_HAVE_KVM_RESTRICTED_MEM */
>
>  #endif
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index e107afea32f0..ac835fc77273 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -936,6 +936,121 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
>
>  #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
>
> +#ifdef CONFIG_HAVE_KVM_RESTRICTED_MEM
> +static bool restrictedmem_range_is_valid(struct kvm_memory_slot *slot,
> +pgoff_t start, pgoff_t end,
> +gfn_t *gfn_start, gfn_t *gfn_end)
> +{
> +   unsigned long base_pgoff = slot->restricted_offset >> PAGE_SHIFT;
> +
> +   if (start > base_pgoff)
> +   *gfn_start = slot->base_gfn + start - base_pgoff;
> +   else
> +   *gfn_start = slot->base_gfn;
> +
> +   if (end < base_pgoff + slot->npages)
> +   *gfn_end = slot->base_gfn + end - base_pgoff;
> +   else
> +   *gfn_end = slot->base_gfn + slot->npages;
> +
> +   if (*gfn_start >= *gfn_end)
> +   return false;
> +
> +   return true;
> +}
> +
> +static void kvm_restrictedmem_invalidate_begin(struct restrictedmem_notifier 
> *notifier,
> +  pgoff_t start, pgoff_t end)
> +{
> +   struct kvm_memory_slot *slot = container_of(notifier,
> +  

Re: [PATCH for-8.0] hw/rtc/mc146818rtc: Make this rtc device target independent

2022-12-09 Thread Thomas Huth

On 07/12/2022 16.29, Mark Cave-Ayland wrote:

On 06/12/2022 20:06, Thomas Huth wrote:


The only code that is really, really target dependent is the apic-related
code in rtc_policy_slew_deliver_irq(). By moving this code into the hw/i386/
folder (renamed to rtc_apic_policy_slew_deliver_irq()) and passing this
function as parameter to mc146818_rtc_init(), we can make the RTC completely
target-independent.

Signed-off-by: Thomas Huth 
---
  include/hw/rtc/mc146818rtc.h |  7 +--
  hw/alpha/dp264.c |  2 +-
  hw/hppa/machine.c    |  2 +-
  hw/i386/microvm.c    |  3 ++-
  hw/i386/pc.c | 10 +-
  hw/mips/jazz.c   |  2 +-
  hw/ppc/pnv.c |  2 +-
  hw/rtc/mc146818rtc.c | 34 +++---
  hw/rtc/meson.build   |  3 +--
  9 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h
index 1db0fcee92..c687953cc4 100644
--- a/include/hw/rtc/mc146818rtc.h
+++ b/include/hw/rtc/mc146818rtc.h
@@ -46,14 +46,17 @@ struct RTCState {
  Notifier clock_reset_notifier;
  LostTickPolicy lost_tick_policy;
  Notifier suspend_notifier;
+    bool (*policy_slew_deliver_irq)(RTCState *s);
  QLIST_ENTRY(RTCState) link;
  };

[...]
These days we really should try and avoid setting function pointers outside 
of _init() and class_init() where possible. If I were looking to model this 
today I'd probably try an approach like this:


- Move apic_irq_delivered into APICCommonState

- Define apic_reset_irq_delivered() and apic_get_irq_delivered() as function 
pointers in APICCommonState and assign them to the current implementations 
in apic_common_initfn() adding an APICCommonState parameter as required


- Grab a reference to APICCommonState in mc146818rtc.c's rtc_realizefn() 
using either an object property link or object_resolve_path_type("", 
TYPE_APIC_COMMON, NULL)


- Use "if (s->apic) { .. }" or similar in mc146818rtc.c to guard calling the 
apic_*() functions


That also doesn't really fly since the apic_* functions are only available 
on x86 (and maybe arm), but not in the other targets, so this won't link 
there. Ok, we could provide stubs for the other targets, but that's IMHO 
almost as ugly as having a function pointer in RTCState ... ? I can give it 
a try with using a stub, but not sure whether it will really look much better...


 Thomas





Re: [PATCH v3 7/8] accel/tcg: Move PageDesc tree into tb-maint.c for system

2022-12-09 Thread Philippe Mathieu-Daudé

On 9/12/22 06:19, Richard Henderson wrote:

Now that PageDesc is not used for user-only, and for system
it is only used for tb maintenance, move the implementation
into tb-main.c appropriately ifdefed.

We have not yet eliminated all references to PageDesc for
user-only, so retain a typedef to the structure without definition.

Signed-off-by: Richard Henderson 
---
  accel/tcg/internal.h  |  49 +++---
  accel/tcg/tb-maint.c  | 130 --
  accel/tcg/translate-all.c |  95 
  3 files changed, 134 insertions(+), 140 deletions(-)




diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index 20e86c813d..9b996bbeb2 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c


Expanding diff context:

#ifdef CONFIG_USER_ONLY

...


  #else




+PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc)
+{
+PageDesc *pd;
+void **lp;
+int i;
+
+/* Level 1.  Always allocated.  */
+lp = l1_map + ((index >> v_l1_shift) & (v_l1_size - 1));
+
+/* Level 2..N-1.  */
+for (i = v_l2_levels; i > 0; i--) {
+void **p = qatomic_rcu_read(lp);
+
+if (p == NULL) {
+void *existing;
+
+if (!alloc) {
+return NULL;
+}
+p = g_new0(void *, V_L2_SIZE);
+existing = qatomic_cmpxchg(lp, NULL, p);
+if (unlikely(existing)) {
+g_free(p);
+p = existing;
+}
+}
+
+lp = p + ((index >> (i * V_L2_BITS)) & (V_L2_SIZE - 1));
+}
+
+pd = qatomic_rcu_read(lp);
+if (pd == NULL) {
+void *existing;


   int i;


+
+if (!alloc) {
+return NULL;
+}
+pd = g_new0(PageDesc, V_L2_SIZE);
+#ifndef CONFIG_USER_ONLY


CONFIG_USER_ONLY never defined here, so this block can be simplified.


+{
+int i;
+
+for (i = 0; i < V_L2_SIZE; i++) {
+qemu_spin_init(&pd[i].lock);
+}
+}
+#endif
+existing = qatomic_cmpxchg(lp, NULL, pd);
+if (unlikely(existing)) {
+#ifndef CONFIG_USER_ONLY
+{


Ditto.


+int i;
+
+for (i = 0; i < V_L2_SIZE; i++) {
+qemu_spin_destroy(&pd[i].lock);
+}
+}
+#endif
+g_free(pd);
+pd = existing;
+}
+}
+
+return pd + (index & (V_L2_SIZE - 1));
+}





[PATCH-for-8.0 1/5] accel/tcg: Restrict cpu_io_recompile() to system emulation

2022-12-09 Thread Philippe Mathieu-Daudé
Missed in commit 6526919224 ("accel/tcg: Restrict cpu_io_recompile()
from other accelerators").

Signed-off-by: Philippe Mathieu-Daudé 
---
 accel/tcg/internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index e1429a53ac..35419f3fe1 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -43,12 +43,12 @@ void tb_invalidate_phys_page_fast(struct page_collection 
*pages,
 struct page_collection *page_collection_lock(tb_page_addr_t start,
  tb_page_addr_t end);
 void page_collection_unlock(struct page_collection *set);
+G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
 #endif /* CONFIG_SOFTMMU */
 
 TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc,
   target_ulong cs_base, uint32_t flags,
   int cflags);
-G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
 void page_init(void);
 void tb_htable_init(void);
 void tb_reset_jump(TranslationBlock *tb, int n);
-- 
2.38.1




[PATCH-for-8.0 3/5] accel/tcg: Rename tb_invalidate_phys_page_[locked_]fast()

2022-12-09 Thread Philippe Mathieu-Daudé
Emphasize this function is called with pages locked.

Signed-off-by: Philippe Mathieu-Daudé 
---
 accel/tcg/cputlb.c   | 2 +-
 accel/tcg/internal.h | 6 +++---
 accel/tcg/tb-maint.c | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index ac459478f4..6402fe11c1 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1510,7 +1510,7 @@ static void notdirty_write(CPUState *cpu, vaddr 
mem_vaddr, unsigned size,
 if (!cpu_physical_memory_get_dirty_flag(ram_addr, DIRTY_MEMORY_CODE)) {
 struct page_collection *pages
 = page_collection_lock(ram_addr, ram_addr + size);
-tb_invalidate_phys_page_fast(pages, ram_addr, size, retaddr);
+tb_invalidate_phys_page_locked_fast(pages, ram_addr, size, retaddr);
 page_collection_unlock(pages);
 }
 
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index 35419f3fe1..d8b58c1e70 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -37,9 +37,9 @@ void page_table_config_init(void);
 
 #ifdef CONFIG_SOFTMMU
 struct page_collection;
-void tb_invalidate_phys_page_fast(struct page_collection *pages,
-  tb_page_addr_t start, int len,
-  uintptr_t retaddr);
+void tb_invalidate_phys_page_locked_fast(struct page_collection *pages,
+ tb_page_addr_t start, int len,
+ uintptr_t retaddr);
 struct page_collection *page_collection_lock(tb_page_addr_t start,
  tb_page_addr_t end);
 void page_collection_unlock(struct page_collection *set);
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index 0c56e81d8c..bf84728910 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -1200,9 +1200,9 @@ void tb_invalidate_phys_range(tb_page_addr_t start, 
tb_page_addr_t end)
  *
  * Call with all @pages in the range [@start, @start + len[ locked.
  */
-void tb_invalidate_phys_page_fast(struct page_collection *pages,
-  tb_page_addr_t start, int len,
-  uintptr_t retaddr)
+void tb_invalidate_phys_page_locked_fast(struct page_collection *pages,
+ tb_page_addr_t start, int len,
+ uintptr_t retaddr)
 {
 PageDesc *p;
 
-- 
2.38.1




[PATCH-for-8.0 2/5] accel/tcg: Remove trace events from trace-root.h

2022-12-09 Thread Philippe Mathieu-Daudé
Commit d9bb58e510 ("tcg: move tcg related files into accel/tcg/
subdirectory") introduced accel/tcg/trace-events, so we don't
need to use the root trace-events anymore.

Signed-off-by: Philippe Mathieu-Daudé 
---
 accel/tcg/cputlb.c | 2 +-
 accel/tcg/trace-events | 4 
 trace-events   | 4 
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 6f1c00682b..ac459478f4 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -33,7 +33,7 @@
 #include "qemu/atomic.h"
 #include "qemu/atomic128.h"
 #include "exec/translate-all.h"
-#include "trace/trace-root.h"
+#include "trace.h"
 #include "tb-hash.h"
 #include "internal.h"
 #ifdef CONFIG_PLUGIN
diff --git a/accel/tcg/trace-events b/accel/tcg/trace-events
index 59eab96f26..4e9b450520 100644
--- a/accel/tcg/trace-events
+++ b/accel/tcg/trace-events
@@ -6,5 +6,9 @@ exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
 exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
 exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=0x%x"
 
+# cputlb.c
+memory_notdirty_write_access(uint64_t vaddr, uint64_t ram_addr, unsigned size) 
"0x%" PRIx64 " ram_addr 0x%" PRIx64 " size %u"
+memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64
+
 # translate-all.c
 translate_block(void *tb, uintptr_t pc, const void *tb_code) "tb:%p, 
pc:0x%"PRIxPTR", tb_code:%p"
diff --git a/trace-events b/trace-events
index 035f3d570d..b6b84b175e 100644
--- a/trace-events
+++ b/trace-events
@@ -42,10 +42,6 @@ find_ram_offset(uint64_t size, uint64_t offset) "size: 0x%" 
PRIx64 " @ 0x%" PRIx
 find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, 
uint64_t next, uint64_t mingap) "trying size: 0x%" PRIx64 " @ 0x%" PRIx64 ", 
offset: 0x%" PRIx64" next: 0x%" PRIx64 " mingap: 0x%" PRIx64
 ram_block_discard_range(const char *rbname, void *hva, size_t length, bool 
need_madvise, bool need_fallocate, int ret) "%s@%p + 0x%zx: madvise: %d 
fallocate: %d ret: %d"
 
-# accel/tcg/cputlb.c
-memory_notdirty_write_access(uint64_t vaddr, uint64_t ram_addr, unsigned size) 
"0x%" PRIx64 " ram_addr 0x%" PRIx64 " size %u"
-memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64
-
 # job.c
 job_state_transition(void *job,  int ret, const char *legal, const char *s0, 
const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
 job_apply_verb(void *job, const char *state, const char *verb, const char 
*legal) "job %p in state %s; applying verb %s (%s)"
-- 
2.38.1




[PATCH-for-8.0 4/5] accel/tcg: Factor tb_invalidate_phys_range_fast() out

2022-12-09 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 accel/tcg/cputlb.c   |  5 +
 accel/tcg/internal.h |  3 +++
 accel/tcg/tb-maint.c | 21 +
 3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 6402fe11c1..03674d598f 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1508,10 +1508,7 @@ static void notdirty_write(CPUState *cpu, vaddr 
mem_vaddr, unsigned size,
 trace_memory_notdirty_write_access(mem_vaddr, ram_addr, size);
 
 if (!cpu_physical_memory_get_dirty_flag(ram_addr, DIRTY_MEMORY_CODE)) {
-struct page_collection *pages
-= page_collection_lock(ram_addr, ram_addr + size);
-tb_invalidate_phys_page_locked_fast(pages, ram_addr, size, retaddr);
-page_collection_unlock(pages);
+tb_invalidate_phys_range_fast(ram_addr, size, retaddr);
 }
 
 /*
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index d8b58c1e70..db078390b1 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -42,6 +42,9 @@ void tb_invalidate_phys_page_locked_fast(struct 
page_collection *pages,
  uintptr_t retaddr);
 struct page_collection *page_collection_lock(tb_page_addr_t start,
  tb_page_addr_t end);
+void tb_invalidate_phys_range_fast(ram_addr_t ram_addr,
+   unsigned size,
+   uintptr_t retaddr);
 void page_collection_unlock(struct page_collection *set);
 G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
 #endif /* CONFIG_SOFTMMU */
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index bf84728910..4dc2fa1060 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -1194,10 +1194,6 @@ void tb_invalidate_phys_range(tb_page_addr_t start, 
tb_page_addr_t end)
 }
 
 /*
- * len must be <= 8 and start must be a multiple of len.
- * Called via softmmu_template.h when code areas are written to with
- * iothread mutex not held.
- *
  * Call with all @pages in the range [@start, @start + len[ locked.
  */
 void tb_invalidate_phys_page_locked_fast(struct page_collection *pages,
@@ -1215,4 +1211,21 @@ void tb_invalidate_phys_page_locked_fast(struct 
page_collection *pages,
 tb_invalidate_phys_page_range__locked(pages, p, start, start + len,
   retaddr);
 }
+
+/*
+ * len must be <= 8 and start must be a multiple of len.
+ * Called via softmmu_template.h when code areas are written to with
+ * iothread mutex not held.
+ */
+void tb_invalidate_phys_range_fast(ram_addr_t ram_addr,
+   unsigned size,
+   uintptr_t retaddr)
+{
+struct page_collection *pages;
+
+pages = page_collection_lock(ram_addr, ram_addr + size);
+tb_invalidate_phys_page_locked_fast(pages, ram_addr, size, retaddr);
+page_collection_unlock(pages);
+}
+
 #endif /* CONFIG_USER_ONLY */
-- 
2.38.1




[PATCH-for-8.0 0/5] accel/tcg: Restrict page_collection structure to system TB maintainance

2022-12-09 Thread Philippe Mathieu-Daudé
Few cleanups noticed while reviewing Richard's "Rewrite user-only
vma tracking" v3 ([*], based on top of it).

- Move accel/tcg/ trace events out of trace-root.h
- Refactor tb_invalidate_phys_range_fast() to restrict page_collection
  to sysemu.

[*] 
https://lore.kernel.org/qemu-devel/20221209051914.398215-1-richard.hender...@linaro.org/
Based-on: <20221209051914.398215-1-richard.hender...@linaro.org>

Philippe Mathieu-Daudé (5):
  accel/tcg: Restrict cpu_io_recompile() to system emulation
  accel/tcg: Remove trace events from trace-root.h
  accel/tcg: Rename tb_invalidate_phys_page_[locked_]fast()
  accel/tcg: Factor tb_invalidate_phys_range_fast() out
  accel/tcg: Restrict page_collection structure to system TB
maintainance

 accel/tcg/cputlb.c |  7 ++-
 accel/tcg/internal.h   | 12 
 accel/tcg/tb-maint.c   | 33 +++--
 accel/tcg/trace-events |  4 
 trace-events   |  4 
 5 files changed, 33 insertions(+), 27 deletions(-)

-- 
2.38.1




[PATCH-for-8.0 5/5] accel/tcg: Restrict page_collection structure to system TB maintainance

2022-12-09 Thread Philippe Mathieu-Daudé
Only the system emulation part of TB maintainance uses the
page_collection structure. Restrict its declaration (and the
functions requiring it) to tb-maint.c.

Convert the 'len' argument of tb_invalidate_phys_page_locked_fast()
from signed to unsigned.

Signed-off-by: Philippe Mathieu-Daudé 
---
 accel/tcg/internal.h |  7 ---
 accel/tcg/tb-maint.c | 12 ++--
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index db078390b1..6edff16fb0 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -36,16 +36,9 @@ void page_table_config_init(void);
 #endif
 
 #ifdef CONFIG_SOFTMMU
-struct page_collection;
-void tb_invalidate_phys_page_locked_fast(struct page_collection *pages,
- tb_page_addr_t start, int len,
- uintptr_t retaddr);
-struct page_collection *page_collection_lock(tb_page_addr_t start,
- tb_page_addr_t end);
 void tb_invalidate_phys_range_fast(ram_addr_t ram_addr,
unsigned size,
uintptr_t retaddr);
-void page_collection_unlock(struct page_collection *set);
 G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
 #endif /* CONFIG_SOFTMMU */
 
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index 4dc2fa1060..10d7e4b7a8 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -523,8 +523,8 @@ static gint tb_page_addr_cmp(gconstpointer ap, 
gconstpointer bp, gpointer udata)
  * intersecting TBs.
  * Locking order: acquire locks in ascending order of page index.
  */
-struct page_collection *
-page_collection_lock(tb_page_addr_t start, tb_page_addr_t end)
+static struct page_collection *page_collection_lock(tb_page_addr_t start,
+tb_page_addr_t end)
 {
 struct page_collection *set = g_malloc(sizeof(*set));
 tb_page_addr_t index;
@@ -568,7 +568,7 @@ page_collection_lock(tb_page_addr_t start, tb_page_addr_t 
end)
 return set;
 }
 
-void page_collection_unlock(struct page_collection *set)
+static void page_collection_unlock(struct page_collection *set)
 {
 /* entries are unlocked and freed via page_entry_destroy */
 g_tree_destroy(set->tree);
@@ -1196,9 +1196,9 @@ void tb_invalidate_phys_range(tb_page_addr_t start, 
tb_page_addr_t end)
 /*
  * Call with all @pages in the range [@start, @start + len[ locked.
  */
-void tb_invalidate_phys_page_locked_fast(struct page_collection *pages,
- tb_page_addr_t start, int len,
- uintptr_t retaddr)
+static void tb_invalidate_phys_page_locked_fast(struct page_collection *pages,
+tb_page_addr_t start,
+unsigned len, uintptr_t 
retaddr)
 {
 PageDesc *p;
 
-- 
2.38.1




[RFC PATCH v2 08/22] xen_platform: exclude vfio-pci from the PCI platform unplug

2022-12-09 Thread David Woodhouse
From: Joao Martins 

Such that PCI passthrough devices work for Xen emulated guests.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 hw/i386/xen/xen_platform.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index 914619d140..15d5ae7c69 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -109,12 +109,25 @@ static void log_writeb(PCIXenPlatformState *s, char val)
 #define _UNPLUG_NVME_DISKS 3
 #define UNPLUG_NVME_DISKS (1u << _UNPLUG_NVME_DISKS)
 
+static bool pci_device_is_passthrough(PCIDevice *d)
+{
+if (!strcmp(d->name, "xen-pci-passthrough")) {
+return true;
+}
+
+if (xen_mode == XEN_EMULATE && !strcmp(d->name, "vfio-pci")) {
+return true;
+}
+
+return false;
+}
+
 static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
 {
 /* We have to ignore passthrough devices */
 if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
 PCI_CLASS_NETWORK_ETHERNET
-&& strcmp(d->name, "xen-pci-passthrough") != 0) {
+&& !pci_device_is_passthrough(d)) {
 object_unparent(OBJECT(d));
 }
 }
@@ -187,9 +200,8 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void 
*opaque)
 !(flags & UNPLUG_IDE_SCSI_DISKS);
 
 /* We have to ignore passthrough devices */
-if (!strcmp(d->name, "xen-pci-passthrough")) {
+if (pci_device_is_passthrough(d))
 return;
-}
 
 switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) {
 case PCI_CLASS_STORAGE_IDE:
-- 
2.35.3




[RFC PATCH v2 06/22] hw/xen_backend: refactor xen_be_init()

2022-12-09 Thread David Woodhouse
From: Joao Martins 

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 hw/xen/xen-legacy-backend.c | 40 +
 include/hw/xen/xen-legacy-backend.h |  3 +++
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
index 085fd31ef7..694e7bbc54 100644
--- a/hw/xen/xen-legacy-backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -676,17 +676,40 @@ void xenstore_update_fe(char *watch, struct 
XenLegacyDevice *xendev)
 }
 /*  */
 
-int xen_be_init(void)
+int xen_be_xenstore_open(void)
 {
-xengnttab_handle *gnttabdev;
-
 xenstore = xs_daemon_open();
 if (!xenstore) {
-xen_pv_printf(NULL, 0, "can't connect to xenstored\n");
 return -1;
 }
 
 qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL);
+return 0;
+}
+
+void xen_be_xenstore_close(void)
+{
+qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);
+xs_daemon_close(xenstore);
+xenstore = NULL;
+}
+
+void xen_be_sysdev_init(void)
+{
+xen_sysdev = qdev_new(TYPE_XENSYSDEV);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal);
+xen_sysbus = qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
+qbus_set_bus_hotplug_handler(xen_sysbus);
+}
+
+int xen_be_init(void)
+{
+xengnttab_handle *gnttabdev;
+
+if (xen_be_xenstore_open()) {
+xen_pv_printf(NULL, 0, "can't connect to xenstored\n");
+return -1;
+}
 
 if (xen_xc == NULL || xen_fmem == NULL) {
 /* Check if xen_init() have been called */
@@ -701,17 +724,12 @@ int xen_be_init(void)
 xengnttab_close(gnttabdev);
 }
 
-xen_sysdev = qdev_new(TYPE_XENSYSDEV);
-sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal);
-xen_sysbus = qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
-qbus_set_bus_hotplug_handler(xen_sysbus);
+xen_be_sysdev_init();
 
 return 0;
 
 err:
-qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);
-xs_daemon_close(xenstore);
-xenstore = NULL;
+xen_be_xenstore_close();
 
 return -1;
 }
diff --git a/include/hw/xen/xen-legacy-backend.h 
b/include/hw/xen/xen-legacy-backend.h
index be281e1f38..0aa171f6c2 100644
--- a/include/hw/xen/xen-legacy-backend.h
+++ b/include/hw/xen/xen-legacy-backend.h
@@ -42,6 +42,9 @@ int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, 
const char *node,
 void xen_be_check_state(struct XenLegacyDevice *xendev);
 
 /* xen backend driver bits */
+int xen_be_xenstore_open(void);
+void xen_be_xenstore_close(void);
+void xen_be_sysdev_init(void);
 int xen_be_init(void);
 void xen_be_register_common(void);
 int xen_be_register(const char *type, struct XenDevOps *ops);
-- 
2.35.3




[RFC PATCH v2 05/22] xen-platform-pci: allow its creation with XEN_EMULATE mode

2022-12-09 Thread David Woodhouse
From: Joao Martins 

The only thing we need to handle on KVM side is to change the
pfn from R/W to R/O.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 hw/i386/xen/xen_platform.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index a64265cca0..914619d140 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -271,7 +271,10 @@ static void platform_fixed_ioport_writeb(void *opaque, 
uint32_t addr, uint32_t v
 case 0: /* Platform flags */ {
 hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
 HVMMEM_ram_ro : HVMMEM_ram_rw;
-if (xen_set_mem_type(xen_domid, mem_type, 0xc0, 0x40)) {
+if (xen_mode == XEN_EMULATE) {
+/* XXX */
+s->flags = val & PFFLAG_ROM_LOCK;
+} else if (xen_set_mem_type(xen_domid, mem_type, 0xc0, 0x40)) {
 DPRINTF("unable to change ro/rw state of ROM memory area!\n");
 } else {
 s->flags = val & PFFLAG_ROM_LOCK;
@@ -496,12 +499,6 @@ static void xen_platform_realize(PCIDevice *dev, Error 
**errp)
 PCIXenPlatformState *d = XEN_PLATFORM(dev);
 uint8_t *pci_conf;
 
-/* Device will crash on reset if xen is not initialized */
-if (!xen_enabled()) {
-error_setg(errp, "xen-platform device requires the Xen accelerator");
-return;
-}
-
 pci_conf = dev->config;
 
 pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-- 
2.35.3




[RFC PATCH v2 20/22] i386/xen: HVMOP_set_param / HVM_PARAM_CALLBACK_IRQ

2022-12-09 Thread David Woodhouse
From: Ankur Arora 

The HVM_PARAM_CALLBACK_IRQ parameter controls the system-wide event
channel upcall method.  The vector support is handled by KVM internally,
when the evtchn_upcall_pending field in the vcpu_info is set.

The GSI and PCI_INTX delivery methods are not supported. yet; those
need to simulate a level-triggered event on the I/OAPIC.

Add a 'xen_evtchn' device to host the migration state, as we'll shortly
be adding a full event channel table there too.

Signed-off-by: Ankur Arora 
Signed-off-by: Joao Martins 
[dwmw2: Rework for upstream kernel changes, split from per-VCPU vector]
Signed-off-by: David Woodhouse 
---
 hw/i386/kvm/meson.build  |   5 +-
 hw/i386/kvm/xen_evtchn.c | 117 +++
 hw/i386/kvm/xen_evtchn.h |  13 +
 hw/i386/pc_piix.c|   2 +
 target/i386/xen.c|  44 +--
 5 files changed, 174 insertions(+), 7 deletions(-)
 create mode 100644 hw/i386/kvm/xen_evtchn.c
 create mode 100644 hw/i386/kvm/xen_evtchn.h

diff --git a/hw/i386/kvm/meson.build b/hw/i386/kvm/meson.build
index 6165cbf019..cab64df339 100644
--- a/hw/i386/kvm/meson.build
+++ b/hw/i386/kvm/meson.build
@@ -4,6 +4,9 @@ i386_kvm_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c'))
 i386_kvm_ss.add(when: 'CONFIG_I8254', if_true: files('i8254.c'))
 i386_kvm_ss.add(when: 'CONFIG_I8259', if_true: files('i8259.c'))
 i386_kvm_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
-i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen_overlay.c'))
+i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files(
+  'xen_overlay.c',
+  'xen_evtchn.c',
+  ))
 
 i386_ss.add_all(when: 'CONFIG_KVM', if_true: i386_kvm_ss)
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
new file mode 100644
index 00..1ca0c034e7
--- /dev/null
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -0,0 +1,117 @@
+/*
+ * QEMU Xen emulation: Shared/overlay pages support
+ *
+ * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Authors: David Woodhouse 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+#include "qemu/module.h"
+#include "qemu/main-loop.h"
+#include "qapi/error.h"
+#include "qom/object.h"
+#include "exec/target_page.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+
+#include "hw/sysbus.h"
+#include "hw/xen/xen.h"
+#include "xen_evtchn.h"
+
+#include "sysemu/kvm.h"
+#include 
+
+#include "standard-headers/xen/memory.h"
+#include "standard-headers/xen/hvm/params.h"
+
+#define TYPE_XEN_EVTCHN "xenevtchn"
+OBJECT_DECLARE_SIMPLE_TYPE(XenEvtchnState, XEN_EVTCHN)
+
+struct XenEvtchnState {
+/*< private >*/
+SysBusDevice busdev;
+/*< public >*/
+
+uint64_t callback_param;
+};
+
+struct XenEvtchnState *xen_evtchn_singleton;
+
+static int xen_evtchn_post_load(void *opaque, int version_id)
+{
+XenEvtchnState *s = opaque;
+
+if (s->callback_param) {
+xen_evtchn_set_callback_param(s->callback_param);
+}
+
+return 0;
+}
+
+static bool xen_evtchn_is_needed(void *opaque)
+{
+return xen_mode == XEN_EMULATE;
+}
+
+static const VMStateDescription xen_evtchn_vmstate = {
+.name = "xen_evtchn",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = xen_evtchn_is_needed,
+.post_load = xen_evtchn_post_load,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(callback_param, XenEvtchnState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void xen_evtchn_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->vmsd = &xen_evtchn_vmstate;
+}
+
+static const TypeInfo xen_evtchn_info = {
+.name  = TYPE_XEN_EVTCHN,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(XenEvtchnState),
+.class_init= xen_evtchn_class_init,
+};
+
+void xen_evtchn_create(void)
+{
+xen_evtchn_singleton = XEN_EVTCHN(sysbus_create_simple(TYPE_XEN_EVTCHN, 
-1, NULL));
+}
+
+static void xen_evtchn_register_types(void)
+{
+type_register_static(&xen_evtchn_info);
+}
+
+type_init(xen_evtchn_register_types)
+
+
+#define CALLBACK_VIA_TYPE_SHIFT   56
+
+int xen_evtchn_set_callback_param(uint64_t param)
+{
+int ret = -ENOSYS;
+
+if (param >> CALLBACK_VIA_TYPE_SHIFT == HVM_PARAM_CALLBACK_TYPE_VECTOR) {
+struct kvm_xen_hvm_attr xa = {
+.type = KVM_XEN_ATTR_TYPE_UPCALL_VECTOR,
+.u.vector = (uint8_t)param,
+};
+
+ret = kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &xa);
+if (!ret && xen_evtchn_singleton)
+xen_evtchn_singleton->callback_param = param;
+}
+return ret;
+}
diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h
new file mode 100644
index 00..11c6ed22a0
--- /dev/null
+++ b/hw/i386/kvm/xen_evtchn.h
@@ -0,0 +1,13 @@
+/*
+ * QEMU Xen emulation: Event channel support
+ *
+ *

[RFC PATCH v2 22/22] i386/xen: implement HYPERVISOR_sched_op

2022-12-09 Thread David Woodhouse
From: Joao Martins 

It allows to shutdown itself via hypercall with any of the 3 reasons:
  1) self-reboot
  2) shutdown
  3) crash

Implementing SCHEDOP_shutdown sub op let us handle crashes gracefully rather
than leading to triple faults if it remains unimplemented.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 target/i386/xen.c | 45 +
 1 file changed, 45 insertions(+)

diff --git a/target/i386/xen.c b/target/i386/xen.c
index f102c40f04..5f3b91450d 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -17,6 +17,7 @@
 #include "trace.h"
 #include "hw/i386/kvm/xen_overlay.h"
 #include "hw/i386/kvm/xen_evtchn.h"
+#include "sysemu/runstate.h"
 
 #define __XEN_INTERFACE_VERSION__ 0x00040400
 
@@ -25,6 +26,7 @@
 #include "standard-headers/xen/hvm/hvm_op.h"
 #include "standard-headers/xen/hvm/params.h"
 #include "standard-headers/xen/vcpu.h"
+#include "standard-headers/xen/sched.h"
 #include "standard-headers/xen/event_channel.h"
 
 static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa,
@@ -491,6 +493,45 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit 
*exit,
 return true;
 }
 
+static int schedop_shutdown(CPUState *cs, uint64_t arg)
+{
+struct sched_shutdown shutdown;
+
+if (kvm_copy_from_gva(cs, arg, &shutdown, sizeof(shutdown))) {
+return -EFAULT;
+}
+
+if (shutdown.reason == SHUTDOWN_crash) {
+cpu_dump_state(cs, stderr, CPU_DUMP_CODE);
+qemu_system_guest_panicked(NULL);
+} else if (shutdown.reason == SHUTDOWN_reboot) {
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+} else if (shutdown.reason == SHUTDOWN_poweroff) {
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+}
+
+return 0;
+}
+
+static bool kvm_xen_hcall_sched_op(struct kvm_xen_exit *exit, X86CPU *cpu,
+   int cmd, uint64_t arg)
+{
+CPUState *cs = CPU(cpu);
+int err = -ENOSYS;
+
+switch (cmd) {
+case SCHEDOP_shutdown: {
+  err = schedop_shutdown(cs, arg);
+  break;
+   }
+default:
+return false;
+}
+
+exit->u.hcall.result = err;
+return true;
+}
+
 static bool __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
 {
 uint16_t code = exit->u.hcall.input;
@@ -501,6 +542,10 @@ static bool __kvm_xen_handle_exit(X86CPU *cpu, struct 
kvm_xen_exit *exit)
 }
 
 switch (code) {
+case __HYPERVISOR_sched_op_compat:
+case __HYPERVISOR_sched_op:
+return kvm_xen_hcall_sched_op(exit, cpu, exit->u.hcall.params[0],
+  exit->u.hcall.params[1]);
 case __HYPERVISOR_event_channel_op_compat:
 return kvm_xen_hcall_evtchn_op_compat(exit, cpu,
   exit->u.hcall.params[0]);
-- 
2.35.3




[RFC PATCH v2 03/22] i386/xen: Add xen-version machine property and init KVM Xen support

2022-12-09 Thread David Woodhouse
From: David Woodhouse 

This is a machine property for two main reasons. One is that it allows
us to set it in default_machine_opts for the xenfv platform when not
running on actual Xen. The other is that theoretically we *could* do
this with TCG too; we'd just have to implement a bunch of the stuff that
KVM already does for us.

Signed-off-by: David Woodhouse 
---
 hw/i386/pc.c| 32 +++
 hw/i386/pc_piix.c   | 10 +++--
 include/hw/i386/pc.h|  3 +++
 target/i386/kvm/kvm.c   | 26 ++
 target/i386/meson.build |  1 +
 target/i386/xen.c   | 49 +
 target/i386/xen.h   | 19 
 7 files changed, 138 insertions(+), 2 deletions(-)
 create mode 100644 target/i386/xen.c
 create mode 100644 target/i386/xen.h

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 546b703cb4..9bada1a8ff 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1811,6 +1811,32 @@ static void pc_machine_set_max_fw_size(Object *obj, 
Visitor *v,
 pcms->max_fw_size = value;
 }
 
+static void pc_machine_get_xen_version(Object *obj, Visitor *v,
+   const char *name, void *opaque,
+   Error **errp)
+{
+PCMachineState *pcms = PC_MACHINE(obj);
+uint32_t value = pcms->xen_version;
+
+visit_type_uint32(v, name, &value, errp);
+}
+
+static void pc_machine_set_xen_version(Object *obj, Visitor *v,
+   const char *name, void *opaque,
+   Error **errp)
+{
+PCMachineState *pcms = PC_MACHINE(obj);
+Error *error = NULL;
+uint32_t value;
+
+visit_type_uint32(v, name, &value, &error);
+if (error) {
+error_propagate(errp, error);
+return;
+}
+
+pcms->xen_version = value;
+}
 
 static void pc_machine_initfn(Object *obj)
 {
@@ -1978,6 +2004,12 @@ static void pc_machine_class_init(ObjectClass *oc, void 
*data)
 NULL, NULL);
 object_class_property_set_description(oc, PC_MACHINE_SMBIOS_EP,
 "SMBIOS Entry Point type [32, 64]");
+
+object_class_property_add(oc, "xen-version", "uint32",
+pc_machine_get_xen_version, pc_machine_set_xen_version,
+NULL, NULL);
+object_class_property_set_description(oc, "xen-version",
+"Xen version to be emulated (in XENVER_version form e.g. 0x4000a for 
4.10)");
 }
 
 static const TypeInfo pc_machine_info = {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 0ad0ed1603..13286d0739 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -876,7 +876,10 @@ static void xenfv_4_2_machine_options(MachineClass *m)
 pc_i440fx_4_2_machine_options(m);
 m->desc = "Xen Fully-virtualized PC";
 m->max_cpus = HVM_MAX_VCPUS;
-m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
+if (xen_enabled())
+m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
+else
+m->default_machine_opts = "accel=kvm,xen-version=0x40002";
 }
 
 DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init,
@@ -888,7 +891,10 @@ static void xenfv_3_1_machine_options(MachineClass *m)
 m->desc = "Xen Fully-virtualized PC";
 m->alias = "xenfv";
 m->max_cpus = HVM_MAX_VCPUS;
-m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
+if (xen_enabled())
+m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
+else
+m->default_machine_opts = "accel=kvm,xen-version=0x30001";
 }
 
 DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c95333514e..9b14b18836 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -52,6 +52,9 @@ typedef struct PCMachineState {
 bool default_bus_bypass_iommu;
 uint64_t max_fw_size;
 
+/* Xen HVM emulation */
+uint32_t xen_version;
+
 /* ACPI Memory hotplug IO base address */
 hwaddr memhp_io_base;
 
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index a213209379..0a2069b117 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -31,6 +31,7 @@
 #include "sysemu/runstate.h"
 #include "kvm_i386.h"
 #include "sev.h"
+#include "xen.h"
 #include "hyperv.h"
 #include "hyperv-proto.h"
 
@@ -774,6 +775,17 @@ static inline bool freq_within_bounds(int freq, int 
target_freq)
 return false;
 }
 
+static uint32_t kvm_arch_xen_version(MachineState *ms)
+{
+uint32_t v = object_property_get_int(OBJECT(ms), "xen-version", NULL);
+
+/* If it was unset, return zero */
+if (v == (uint32_t) -1)
+return 0;
+
+return v;
+}
+
 static int kvm_arch_set_tsc_khz(CPUState *cs)
 {
 X86CPU *cpu = X86_CPU(cs);
@@ -2459,6 +2471,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 {
 uint64_t identity_base = 0xfffbc000;
 uint64_t shadow_mem;
+uint32_t xen_version;
 int ret;
 struct utsname utsname;
 Error *local_err = NULL;
@@ -2513,6 +

[RFC PATCH v2 10/22] i386/xen: handle guest hypercalls

2022-12-09 Thread David Woodhouse
From: Joao Martins 

This means handling the new exit reason for Xen but still
crashing on purpose. As we implement each of the hypercalls
we will then return the right return code.

Signed-off-by: Joao Martins 
[dwmw2: Add CPL to hypercall tracing, disallow hypercalls from CPL > 0]
Signed-off-by: David Woodhouse 
---
 target/i386/kvm/kvm.c|  5 +
 target/i386/trace-events |  3 +++
 target/i386/xen.c| 39 +++
 target/i386/xen.h|  1 +
 4 files changed, 48 insertions(+)

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 0d3eddf9de..ebde6bc204 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -5471,6 +5471,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
*run)
 assert(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER);
 ret = kvm_handle_wrmsr(cpu, run);
 break;
+#ifdef CONFIG_XEN_EMU
+case KVM_EXIT_XEN:
+ret = kvm_xen_handle_exit(cpu, &run->xen);
+break;
+#endif
 default:
 fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
 ret = -1;
diff --git a/target/i386/trace-events b/target/i386/trace-events
index 2cd8726eeb..1bf9558811 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -11,3 +11,6 @@ kvm_sev_launch_measurement(const char *value) "data %s"
 kvm_sev_launch_finish(void) ""
 kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) 
"hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d"
 kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s 
data %s"
+
+# target/i386/xen.c
+kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t 
a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " 
a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64
diff --git a/target/i386/xen.c b/target/i386/xen.c
index bc183dce4e..708ab908a0 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -10,8 +10,10 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "kvm/kvm_i386.h"
 #include "xen.h"
+#include "trace.h"
 
 int kvm_xen_init(KVMState *s, uint32_t xen_version)
 {
@@ -47,3 +49,40 @@ int kvm_xen_init(KVMState *s, uint32_t xen_version)
 
 return 0;
 }
+
+static bool __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
+{
+uint16_t code = exit->u.hcall.input;
+
+if (exit->u.hcall.cpl > 0) {
+exit->u.hcall.result = -EPERM;
+return true;
+}
+
+switch (code) {
+default:
+return false;
+}
+}
+
+int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
+{
+if (exit->type != KVM_EXIT_XEN_HCALL)
+return -1;
+
+if (!__kvm_xen_handle_exit(cpu, exit)) {
+/* Some hypercalls will be deliberately "implemented" by returning
+ * -ENOSYS. This case is for hypercalls which are unexpected. */
+exit->u.hcall.result = -ENOSYS;
+qemu_log_mask(LOG_GUEST_ERROR, "Unimplemented Xen hypercall %"
+  PRId64 " (0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 ")\n",
+  (uint64_t)exit->u.hcall.input, 
(uint64_t)exit->u.hcall.params[0],
+  (uint64_t)exit->u.hcall.params[1], 
(uint64_t)exit->u.hcall.params[1]);
+}
+
+trace_kvm_xen_hypercall(CPU(cpu)->cpu_index, exit->u.hcall.cpl,
+exit->u.hcall.input, exit->u.hcall.params[0],
+exit->u.hcall.params[1], exit->u.hcall.params[2],
+exit->u.hcall.result);
+return 0;
+}
diff --git a/target/i386/xen.h b/target/i386/xen.h
index ae880c47bc..9134d78685 100644
--- a/target/i386/xen.h
+++ b/target/i386/xen.h
@@ -23,5 +23,6 @@
 #define XEN_VERSION(maj, min) ((maj) << 16 | (min))
 
 int kvm_xen_init(KVMState *s, uint32_t xen_version);
+int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit);
 
 #endif /* QEMU_I386_XEN_H */
-- 
2.35.3




[RFC PATCH v2 14/22] i386/xen: implement HYPERVISOR_hvm_op

2022-12-09 Thread David Woodhouse
From: Joao Martins 

This is when guest queries for support for HVMOP_pagetable_dying.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 target/i386/xen.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/target/i386/xen.c b/target/i386/xen.c
index ddd144039a..2847b4f864 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -18,6 +18,7 @@
 #include "hw/i386/kvm/xen_overlay.h"
 #include "standard-headers/xen/version.h"
 #include "standard-headers/xen/memory.h"
+#include "standard-headers/xen/hvm/hvm_op.h"
 
 static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz,
   bool is_write)
@@ -180,6 +181,19 @@ static bool kvm_xen_hcall_memory_op(struct kvm_xen_exit 
*exit,
 return true;
 }
 
+static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *exit,
+ int cmd, uint64_t arg)
+{
+switch (cmd) {
+case HVMOP_pagetable_dying:
+exit->u.hcall.result = -ENOSYS;
+return true;
+
+default:
+return false;
+}
+}
+
 static bool __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
 {
 uint16_t code = exit->u.hcall.input;
@@ -190,6 +204,9 @@ static bool __kvm_xen_handle_exit(X86CPU *cpu, struct 
kvm_xen_exit *exit)
 }
 
 switch (code) {
+case __HYPERVISOR_hvm_op:
+return kvm_xen_hcall_hvm_op(exit, exit->u.hcall.params[0],
+exit->u.hcall.params[1]);
 case __HYPERVISOR_memory_op:
 return kvm_xen_hcall_memory_op(exit, exit->u.hcall.params[0],
exit->u.hcall.params[1], cpu);
-- 
2.35.3




[RFC PATCH v2 02/22] xen: add CONFIG_XENFV_MACHINE and CONFIG_XEN_EMU options for Xen emulation

2022-12-09 Thread David Woodhouse
From: David Woodhouse 

The XEN_EMU option will cover core Xen support in target/, which exists
only for x86 with KVM today but could theoretically also be implemented
on Arm/Aarch64 and with TCG or other accelerators. It will also cover
the support for architecture-independent grant table and event channel
support which will be added in hw/xen/.

The XENFV_MACHINE option is for the xenfv platform support, which will
now be used both by XEN_EMU and by real Xen.

The XEN option remains dependent on the Xen runtime libraries, and covers
support for real Xen. Some code which currently resides under CONFIG_XEN
will be moving to CONFIG_XENFV_MACHINE over time.

Signed-off-by: David Woodhouse 
---
 accel/Kconfig  | 1 +
 hw/Kconfig | 1 +
 hw/xen/Kconfig | 3 +++
 meson.build| 1 +
 target/Kconfig | 4 
 5 files changed, 10 insertions(+)
 create mode 100644 hw/xen/Kconfig

diff --git a/accel/Kconfig b/accel/Kconfig
index 8bdedb7d15..41e089e610 100644
--- a/accel/Kconfig
+++ b/accel/Kconfig
@@ -15,6 +15,7 @@ config TCG
 
 config KVM
 bool
+imply XEN_EMU if (I386 || X86_64)
 
 config XEN
 bool
diff --git a/hw/Kconfig b/hw/Kconfig
index 38233bbb0f..ba62ff6417 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -41,6 +41,7 @@ source tpm/Kconfig
 source usb/Kconfig
 source virtio/Kconfig
 source vfio/Kconfig
+source xen/Kconfig
 source watchdog/Kconfig
 
 # arch Kconfig
diff --git a/hw/xen/Kconfig b/hw/xen/Kconfig
new file mode 100644
index 00..755c8b1faf
--- /dev/null
+++ b/hw/xen/Kconfig
@@ -0,0 +1,3 @@
+config XENFV_MACHINE
+bool
+default y if (XEN || XEN_EMU)
diff --git a/meson.build b/meson.build
index 5c6b5a1c75..9348cf572c 100644
--- a/meson.build
+++ b/meson.build
@@ -3828,6 +3828,7 @@ if have_system
   if xen.found()
 summary_info += {'xen ctrl version':  xen.version()}
   endif
+  summary_info += {'Xen emulation': config_all.has_key('CONFIG_XEN_EMU')}
 endif
 summary_info += {'TCG support':   config_all.has_key('CONFIG_TCG')}
 if config_all.has_key('CONFIG_TCG')
diff --git a/target/Kconfig b/target/Kconfig
index 83da0bd293..e19c9d77b5 100644
--- a/target/Kconfig
+++ b/target/Kconfig
@@ -18,3 +18,7 @@ source sh4/Kconfig
 source sparc/Kconfig
 source tricore/Kconfig
 source xtensa/Kconfig
+
+config XEN_EMU
+bool
+depends on KVM && (I386 || X86_64)
-- 
2.35.3




[RFC PATCH v2 21/22] i386/xen: implement HYPERVISOR_event_channel_op

2022-12-09 Thread David Woodhouse
From: Joao Martins 

Additionally set XEN_INTERFACE_VERSION to most recent in order to
exercise both event_channel_op and event_channel_op_compat.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 target/i386/xen.c | 45 +
 1 file changed, 45 insertions(+)

diff --git a/target/i386/xen.c b/target/i386/xen.c
index 1af336d9e5..f102c40f04 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -18,11 +18,14 @@
 #include "hw/i386/kvm/xen_overlay.h"
 #include "hw/i386/kvm/xen_evtchn.h"
 
+#define __XEN_INTERFACE_VERSION__ 0x00040400
+
 #include "standard-headers/xen/version.h"
 #include "standard-headers/xen/memory.h"
 #include "standard-headers/xen/hvm/hvm_op.h"
 #include "standard-headers/xen/hvm/params.h"
 #include "standard-headers/xen/vcpu.h"
+#include "standard-headers/xen/event_channel.h"
 
 static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa,
size_t *len, bool is_write)
@@ -452,6 +455,42 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit 
*exit, X86CPU *cpu,
 return true;
 }
 
+static bool kvm_xen_hcall_evtchn_op_compat(struct kvm_xen_exit *exit,
+  X86CPU *cpu, uint64_t arg)
+{
+struct evtchn_op op;
+int err = -EFAULT;
+
+if (kvm_copy_from_gva(CPU(cpu), arg, &op, sizeof(op))) {
+goto err;
+}
+
+switch (op.cmd) {
+default:
+return false;
+}
+err:
+exit->u.hcall.result = err;
+return true;
+}
+
+static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit *exit,
+int cmd, uint64_t arg)
+{
+int err = -ENOSYS;
+
+switch (cmd) {
+case EVTCHNOP_init_control:
+err = -ENOSYS;
+break;
+default:
+return false;
+}
+
+exit->u.hcall.result = err;
+return true;
+}
+
 static bool __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
 {
 uint16_t code = exit->u.hcall.input;
@@ -462,6 +501,12 @@ static bool __kvm_xen_handle_exit(X86CPU *cpu, struct 
kvm_xen_exit *exit)
 }
 
 switch (code) {
+case __HYPERVISOR_event_channel_op_compat:
+return kvm_xen_hcall_evtchn_op_compat(exit, cpu,
+  exit->u.hcall.params[0]);
+case __HYPERVISOR_event_channel_op:
+return kvm_xen_hcall_evtchn_op(exit, exit->u.hcall.params[0],
+   exit->u.hcall.params[1]);
 case __HYPERVISOR_vcpu_op:
 return kvm_xen_hcall_vcpu_op(exit, cpu,
  exit->u.hcall.params[0],
-- 
2.35.3




[RFC PATCH v2 00/22] Xen HVM support under KVM

2022-12-09 Thread David Woodhouse
Continuing the revival of Oracle's work at
https://github.com/jpemartins/qemu/commits/xen-shim-rfc to work against
the Xen guest support as it was finally merged into the kernel, and
updated to today's QEMU. When complete, this will allow us to run native
Xen guests on top of Linux/KVM without them noticing that it's not Xen.

Thanks for the useful feedback in response to v1. Hopefully I've taken
it all on board correctly.

The main question I have right now is about the way the target KVM
code calls directly into things like xen_overlay_map_page() which
live in hw/i386/kvm/ — and the way that function uses a singleton
object. That can't be right, but I figured I should just keep typing
and get the actual code working to show what I'm trying to do...

v2:
 • Attempt to implement migration support; every Xen enlightenment is
   now recorded either from vmstate_x86_cpu or from a new sysdev device
   created for that purpose. And — I believe — correctly restored, in
   the right order, on vmload.

 • The shared_info page is created as a proper overlay instead of abusing
   the underlying guest page. This is important because Windows doesn't
   even select a GPA which had RAM behind it beforehand. This will be
   extended to handle the grant frames too, in the fullness of time.

 • Set vCPU attributes from the correct vCPU thread to avoid deadlocks.

 • Carefully copy the entire hypercall argument structure from userspace
   instead of assuming that it's contiguous in HVA space.

 • Distinguish between "handled but intentionally returns -ENOSYS" and
   "no idea what that was" in hypercalls, allowing us to emit a
   GUEST_ERROR (actually, shouldn't that change to UNIMP?) on the
   latter. Experience shows that to we'll end up having to intentionally
   return -ENOSYS to a bunch of weird crap that ancient guests still
   attempt to use, including XenServer local hacks that nobody even
   remembers what they were (hvmop 0x101, anyone? Some old Windows
   PV driver appears to be trying to use it...).

 * Drop the '+xen' CPU property and present Xen CPUID instead of KVM
   unconditionally when running in Xen mode. Make the Xen CPUID coexist
   with Hyper-V CPUID as it should, though.

 • Add XEN_EMU and XENFV_MACHINE (the latter to be XEN_EMU||XEN) config
   options. Some more work on this, and the incestuous relationships
   between the KVM target code and the 'platform' code, is going to be
   required but it's probably better to get on with implementing the
   real code so we can see those interactions in all their glory,
   before losing too much sleep over the details here.

 • Drop the GSI-2 hack, and also the patch which made the PCI platform
   device have real RAM (which isn't needed now we have overlays, qv).

 • Drop the XenState and XenVcpuState from KVMState and CPUArchState
   respectively. The Xen-specific fields are natively included in
   CPUArchState now though, for migration purposes. And we don't
   keep a host pointer to the shared_info or vcpu_info at all any
   more. With the kernel doing everything for us, we don't actually
   need them.
 
The guest boots as far as panicking when it can't register the timer
VIRQ because we haven't implemented event channel hypercalls yet. 

The xen-platform-pci and pc_piix patches still need a little cleaning
up but I'll rework them when the dust settles on the config options and
how the target/machine components interact rather than bikeshedding them
too much early on. For now, we just need to be able to use the xenfv
machine in order to instantiate the shinfo and evtchn objects.

  qemu-system-x86_64 -serial mon:stdio -machine xenfv,xen-version=0x4000a \
 -cpu host,+xen-vapic  -display none --trace "kvm_xen*" \
 -kernel /boot/vmlinuz-5.17.8-200.fc35.x86_64 \
 -append "console=ttyS0,115200 earlyprintk=ttyS0,115200"

Ankur Arora (2):
  i386/xen: implement HVMOP_set_evtchn_upcall_vector
  i386/xen: HVMOP_set_param / HVM_PARAM_CALLBACK_IRQ

David Woodhouse (3):
  xen: add CONFIG_XENFV_MACHINE and CONFIG_XEN_EMU options for Xen emulation
  i386/xen: Add xen-version machine property and init KVM Xen support
  hw/xen: Add xen_overlay device for emulating shared xenheap pages

Joao Martins (17):
  include: import xen public headers
  i386/kvm: handle Xen HVM cpuid leaves
  xen-platform-pci: allow its creation with XEN_EMULATE mode
  hw/xen_backend: refactor xen_be_init()
  pc_piix: handle XEN_EMULATE backend init
  xen_platform: exclude vfio-pci from the PCI platform unplug
  pc_piix: allow xenfv machine with XEN_EMULATE
  i386/xen: handle guest hypercalls
  i386/xen: implement HYPERCALL_xen_version
  i386/xen: implement HYPERVISOR_memory_op
  i386/xen: implement HYPERVISOR_hvm_op
  i386/xen: implement HYPERVISOR_vcpu_op
  i386/xen: handle VCPUOP_register_vcpu_info
  i386/xen: handle VCPUOP_register_vcpu_time_info
  i386/xen: handle VCPUOP_register_runstate_memo

[RFC PATCH v2 16/22] i386/xen: handle VCPUOP_register_vcpu_info

2022-12-09 Thread David Woodhouse
From: Joao Martins 

Handle the hypercall to set a per vcpu info, and also wire up the default
vcpu_info in the shared_info page for the first 32 vCPUs.

To avoid deadlock within KVM a vCPU thread must set its *own* vcpu_info
rather than it being set from the context in which the hypercall is
invoked.

Add the vcpu_info (and default) GPA to the vmstate_x86_cpu for migration,
and restore it in kvm_arch_put_registers() appropriately.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 target/i386/cpu.h|  2 ++
 target/i386/kvm/kvm.c| 19 +++
 target/i386/machine.c| 21 
 target/i386/trace-events |  1 +
 target/i386/xen.c| 74 +---
 target/i386/xen.h|  1 +
 6 files changed, 113 insertions(+), 5 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c6c57baed5..109b2e5669 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1788,6 +1788,8 @@ typedef struct CPUArchState {
 #endif
 #if defined(CONFIG_KVM)
 struct kvm_nested_state *nested_state;
+uint64_t xen_vcpu_info_gpa;
+uint64_t xen_vcpu_info_default_gpa;
 #endif
 #if defined(CONFIG_HVF)
 HVFX86LazyFlags hvf_lflags;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index ebde6bc204..fa45e2f99a 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1811,6 +1811,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
 has_msr_hv_hypercall = true;
 }
 
+env->xen_vcpu_info_gpa = UINT64_MAX;
+env->xen_vcpu_info_default_gpa = UINT64_MAX;
+
 xen_version = kvm_arch_xen_version(MACHINE(qdev_get_machine()));
 if (xen_version) {
 #ifdef CONFIG_XEN_EMU
@@ -4728,6 +4731,22 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
 kvm_arch_set_tsc_khz(cpu);
 }
 
+#ifdef CONFIG_XEN_EMU
+if (level == KVM_PUT_FULL_STATE) {
+uint64_t gpa = x86_cpu->env.xen_vcpu_info_gpa;
+if (gpa == UINT64_MAX) {
+gpa = x86_cpu->env.xen_vcpu_info_default_gpa;
+}
+
+if (gpa != UINT64_MAX) {
+ret = kvm_xen_set_vcpu_attr(cpu, KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO, 
gpa);
+if (ret < 0) {
+return ret;
+}
+}
+}
+#endif
+
 ret = kvm_getput_regs(x86_cpu, 1);
 if (ret < 0) {
 return ret;
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 310b125235..104cd6047c 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1257,6 +1257,26 @@ static const VMStateDescription vmstate_nested_state = {
 }
 };
 
+static bool xen_vcpu_needed(void *opaque)
+{
+X86CPU *cpu = opaque;
+CPUX86State *env = &cpu->env;
+
+return (env->xen_vcpu_info_gpa != UINT64_MAX ||
+env->xen_vcpu_info_default_gpa != UINT64_MAX);
+}
+
+static const VMStateDescription vmstate_xen_vcpu = {
+.name = "cpu/xen_vcpu",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = xen_vcpu_needed,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(env.xen_vcpu_info_gpa, X86CPU),
+VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU),
+VMSTATE_END_OF_LIST()
+}
+};
 #endif
 
 static bool mcg_ext_ctl_needed(void *opaque)
@@ -1716,6 +1736,7 @@ const VMStateDescription vmstate_x86_cpu = {
 #endif
 #ifdef CONFIG_KVM
 &vmstate_nested_state,
+&vmstate_xen_vcpu,
 #endif
 &vmstate_msr_tsx_ctrl,
 &vmstate_msr_intel_sgx,
diff --git a/target/i386/trace-events b/target/i386/trace-events
index fb999d0052..7118640697 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -15,3 +15,4 @@ kvm_sev_attestation_report(const char *mnonce, const char 
*data) "mnonce %s data
 # target/i386/xen.c
 kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t 
a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " 
a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64
 kvm_xen_set_shared_info(uint64_t gfn) "shared info at gfn 0x%" PRIx64
+kvm_xen_set_vcpu_attr(int cpu, int type, uint64_t gpa) "vcpu attr cpu %d type 
%d gpa 0x%" PRIx64
diff --git a/target/i386/xen.c b/target/i386/xen.c
index 9d1daadee1..cd816bb711 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -129,10 +129,47 @@ static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit 
*exit, X86CPU *cpu,
 return true;
 }
 
+int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa)
+{
+struct kvm_xen_vcpu_attr xhsi;
+
+xhsi.type = type;
+xhsi.u.gpa = gpa;
+
+trace_kvm_xen_set_vcpu_attr(cs->cpu_index, type, gpa);
+
+return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xhsi);
+}
+
+static void do_set_vcpu_info_default_gpa(CPUState *cs, run_on_cpu_data data)
+{
+X86CPU *cpu = X86_CPU(cs);
+CPUX86State *env = &cpu->env;
+
+env->xen_vcpu_info_default_gpa = data.host_ulong;
+
+/* Changing the default does nothing if a vcpu_info was explicitly set. */
+if (env->xen_vcpu_info_gpa =

[RFC PATCH v2 04/22] i386/kvm: handle Xen HVM cpuid leaves

2022-12-09 Thread David Woodhouse
From: Joao Martins 

Introduce support for emulating CPUID for Xen HVM guests. It doesn't make
sense to advertise the KVM leaves to a Xen guest, so do it unconditionally
when the xen-version machine property is set.

Signed-off-by: Joao Martins 
[dwmw2: Obtain xen_version from machine property, make it automatic]
Signed-off-by: David Woodhouse 
---
 target/i386/cpu.c |  1 +
 target/i386/cpu.h |  2 ++
 target/i386/kvm/kvm.c | 72 +--
 target/i386/xen.h |  8 +
 4 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 22b681ca37..50aa95f134 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7069,6 +7069,7 @@ static Property x86_cpu_properties[] = {
  * own cache information (see x86_cpu_load_def()).
  */
 DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true),
+DEFINE_PROP_BOOL("xen-vapic", X86CPU, xen_vapic, false),
 
 /*
  * From "Requirements for Implementing the Microsoft
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d4bc19577a..c6c57baed5 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1964,6 +1964,8 @@ struct ArchCPU {
 int32_t thread_id;
 
 int32_t hv_max_vps;
+
+bool xen_vapic;
 };
 
 
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 0a2069b117..0d3eddf9de 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -22,6 +22,7 @@
 
 #include 
 #include "standard-headers/asm-x86/kvm_para.h"
+#include "standard-headers/xen/arch-x86/cpuid.h"
 
 #include "cpu.h"
 #include "host-cpu.h"
@@ -1752,14 +1753,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
 X86CPU *cpu = X86_CPU(cs);
 CPUX86State *env = &cpu->env;
 uint32_t limit, i, j, cpuid_i;
-uint32_t unused;
+uint32_t unused, xen_version = 0;
 struct kvm_cpuid_entry2 *c;
 uint32_t signature[3];
 int kvm_base = KVM_CPUID_SIGNATURE;
 int max_nested_state_len;
 int r;
 Error *local_err = NULL;
-
 memset(&cpuid_data, 0, sizeof(cpuid_data));
 
 cpuid_i = 0;
@@ -1811,7 +1811,73 @@ int kvm_arch_init_vcpu(CPUState *cs)
 has_msr_hv_hypercall = true;
 }
 
-if (cpu->expose_kvm) {
+xen_version = kvm_arch_xen_version(MACHINE(qdev_get_machine()));
+if (xen_version) {
+#ifdef CONFIG_XEN_EMU
+struct kvm_cpuid_entry2 *xen_max_leaf;
+
+memcpy(signature, "XenVMMXenVMM", 12);
+
+xen_max_leaf = c = &cpuid_data.entries[cpuid_i++];
+c->function = kvm_base + XEN_CPUID_SIGNATURE;
+c->eax = kvm_base + XEN_CPUID_TIME;
+c->ebx = signature[0];
+c->ecx = signature[1];
+c->edx = signature[2];
+
+c = &cpuid_data.entries[cpuid_i++];
+c->function = kvm_base + XEN_CPUID_VENDOR;
+c->eax = xen_version;
+c->ebx = 0;
+c->ecx = 0;
+c->edx = 0;
+
+c = &cpuid_data.entries[cpuid_i++];
+c->function = kvm_base + XEN_CPUID_HVM_MSR;
+/* Number of hypercall-transfer pages */
+c->eax = 1;
+/* Hypercall MSR base address */
+c->ebx = XEN_HYPERCALL_MSR;
+c->ecx = 0;
+c->edx = 0;
+
+c = &cpuid_data.entries[cpuid_i++];
+c->function = kvm_base + XEN_CPUID_TIME;
+c->eax = ((!!tsc_is_stable_and_known(env) << 1) |
+(!!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_RDTSCP) << 2));
+/* default=0 (emulate if necessary) */
+c->ebx = 0;
+/* guest tsc frequency */
+c->ecx = env->user_tsc_khz;
+/* guest tsc incarnation (migration count) */
+c->edx = 0;
+
+c = &cpuid_data.entries[cpuid_i++];
+c->function = kvm_base + XEN_CPUID_HVM;
+xen_max_leaf->eax = kvm_base + XEN_CPUID_HVM;
+if (xen_version >= XEN_VERSION(4,5)) {
+c->function = kvm_base + XEN_CPUID_HVM;
+
+if (cpu->xen_vapic) {
+c->eax |= XEN_HVM_CPUID_APIC_ACCESS_VIRT;
+c->eax |= XEN_HVM_CPUID_X2APIC_VIRT;
+}
+
+c->eax |= XEN_HVM_CPUID_IOMMU_MAPPINGS;
+
+if (xen_version >= XEN_VERSION(4,6)) {
+c->eax |= XEN_HVM_CPUID_VCPU_ID_PRESENT;
+c->ebx = cs->cpu_index;
+}
+}
+
+kvm_base += 0x100;
+#else /* CONFIG_XEN_EMU */
+/* This should never happen as kvm_arch_init() would have died first. 
*/
+fprintf(stderr, "Cannot enable Xen CPUID without Xen support\n");
+abort();
+#endif
+} else if (cpu->expose_kvm) {
 memcpy(signature, "KVMKVMKVM\0\0\0", 12);
 c = &cpuid_data.entries[cpuid_i++];
 c->function = KVM_CPUID_SIGNATURE | kvm_base;
diff --git a/target/i386/xen.h b/target/i386/xen.h
index 6c4f3b7822..ae880c47bc 100644
--- a/target/i386/xen.h
+++ b/target/i386/xen.h
@@ -14,6 +14,14 @@
 
 #define XEN_HYPERCALL_MSR 0x4000
 
+#define XEN_CPUID_SIGNATURE0
+#define XEN_CPUID_VENDOR   1
+#define XEN_CPUID_HVM

[RFC PATCH v2 07/22] pc_piix: handle XEN_EMULATE backend init

2022-12-09 Thread David Woodhouse
From: Joao Martins 

And use newly added xen_emulated_machine_init() to iniitalize
the xenstore and the sysdev bus for future emulated devices.

Signed-off-by: Joao Martins 
[dwmw2: Move it to xen-legacy-backend.c]
Signed-off-by: David Woodhouse 
---
 hw/i386/pc_piix.c   |  5 +
 hw/xen/xen-legacy-backend.c | 22 --
 include/hw/xen/xen-legacy-backend.h |  2 ++
 3 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 13286d0739..3dcac2f4b6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -47,6 +47,7 @@
 #include "hw/sysbus.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/xen/xen-x86.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "exec/memory.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/piix4.h"
@@ -155,6 +156,10 @@ static void pc_init1(MachineState *machine,
 x86ms->above_4g_mem_size = 0;
 x86ms->below_4g_mem_size = machine->ram_size;
 }
+
+if (pcms->xen_version && !xen_be_xenstore_open()) {
+xen_emulated_machine_init();
+}
 }
 
 pc_machine_init_sgx_epc(pcms);
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
index 694e7bbc54..60a7bc7ab6 100644
--- a/hw/xen/xen-legacy-backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -31,6 +31,7 @@
 #include "qapi/error.h"
 #include "hw/xen/xen-legacy-backend.h"
 #include "hw/xen/xen_pvdev.h"
+#include "hw/xen/xen-bus.h"
 #include "monitor/qdev.h"
 
 DeviceState *xen_sysdev;
@@ -294,13 +295,15 @@ static struct XenLegacyDevice *xen_be_get_xendev(const 
char *type, int dom,
 xendev->debug  = debug;
 xendev->local_port = -1;
 
-xendev->evtchndev = xenevtchn_open(NULL, 0);
-if (xendev->evtchndev == NULL) {
-xen_pv_printf(NULL, 0, "can't open evtchn device\n");
-qdev_unplug(DEVICE(xendev), NULL);
-return NULL;
+if (xen_mode != XEN_EMULATE) {
+xendev->evtchndev = xenevtchn_open(NULL, 0);
+if (xendev->evtchndev == NULL) {
+xen_pv_printf(NULL, 0, "can't open evtchn device\n");
+qdev_unplug(DEVICE(xendev), NULL);
+return NULL;
+}
+qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev));
 }
-qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev));
 
 xen_pv_insert_xendev(xendev);
 
@@ -859,3 +862,10 @@ static void xenbe_register_types(void)
 }
 
 type_init(xenbe_register_types)
+
+void xen_emulated_machine_init(void)
+{
+xen_bus_init();
+xen_be_sysdev_init();
+xen_be_register_common();
+}
diff --git a/include/hw/xen/xen-legacy-backend.h 
b/include/hw/xen/xen-legacy-backend.h
index 0aa171f6c2..aa09015662 100644
--- a/include/hw/xen/xen-legacy-backend.h
+++ b/include/hw/xen/xen-legacy-backend.h
@@ -105,4 +105,6 @@ int xen_config_dev_vfb(int vdev, const char *type);
 int xen_config_dev_vkbd(int vdev);
 int xen_config_dev_console(int vdev);
 
+void xen_emulated_machine_init(void);
+
 #endif /* HW_XEN_LEGACY_BACKEND_H */
-- 
2.35.3




[RFC PATCH v2 11/22] i386/xen: implement HYPERCALL_xen_version

2022-12-09 Thread David Woodhouse
From: Joao Martins 

This is just meant to serve as an example on how we can implement
hypercalls. xen_version specifically since Qemu does all kind of
feature controllability. So handling that here seems appropriate.

Signed-off-by: Joao Martins 
[dwmw2: Implement kvm_gva_rw() safely]
Signed-off-by: David Woodhouse 
---
 target/i386/xen.c | 79 +++
 1 file changed, 79 insertions(+)

diff --git a/target/i386/xen.c b/target/i386/xen.c
index 708ab908a0..55beed1913 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -12,9 +12,51 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "kvm/kvm_i386.h"
+#include "exec/address-spaces.h"
 #include "xen.h"
 #include "trace.h"
 
+#include "standard-headers/xen/version.h"
+
+static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz,
+  bool is_write)
+{
+uint8_t *buf = (uint8_t *)_buf;
+size_t i = 0, len = 0;
+int ret;
+
+for (i = 0; i < sz; i+= len) {
+struct kvm_translation tr = {
+.linear_address = gva + i,
+};
+
+len = TARGET_PAGE_SIZE - (tr.linear_address & ~TARGET_PAGE_MASK);
+if (len > sz)
+len = sz;
+
+ret = kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr);
+if (ret || !tr.valid || (is_write && !tr.writeable)) {
+return -EFAULT;
+}
+
+cpu_physical_memory_rw(tr.physical_address, buf + i, len, is_write);
+}
+
+return 0;
+}
+
+static inline int kvm_copy_from_gva(CPUState *cs, uint64_t gva, void *buf,
+size_t sz)
+{
+return kvm_gva_rw(cs, gva, buf, sz, false);
+}
+
+static inline int kvm_copy_to_gva(CPUState *cs, uint64_t gva, void *buf,
+  size_t sz)
+{
+return kvm_gva_rw(cs, gva, buf, sz, false);
+}
+
 int kvm_xen_init(KVMState *s, uint32_t xen_version)
 {
 const int required_caps = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR |
@@ -50,6 +92,40 @@ int kvm_xen_init(KVMState *s, uint32_t xen_version)
 return 0;
 }
 
+static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit *exit, X86CPU *cpu,
+ int cmd, uint64_t arg)
+{
+int err = 0;
+
+switch (cmd) {
+case XENVER_get_features: {
+struct xen_feature_info fi;
+
+err = kvm_copy_from_gva(CPU(cpu), arg, &fi, sizeof(fi));
+if (err) {
+break;
+}
+
+fi.submap = 0;
+if (fi.submap_idx == 0) {
+fi.submap |= 1 << XENFEAT_writable_page_tables |
+ 1 << XENFEAT_writable_descriptor_tables |
+ 1 << XENFEAT_auto_translated_physmap |
+ 1 << XENFEAT_supervisor_mode_kernel;
+}
+
+err = kvm_copy_to_gva(CPU(cpu), arg, &fi, sizeof(fi));
+break;
+}
+
+default:
+return false;
+}
+
+exit->u.hcall.result = err;
+return true;
+}
+
 static bool __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
 {
 uint16_t code = exit->u.hcall.input;
@@ -60,6 +136,9 @@ static bool __kvm_xen_handle_exit(X86CPU *cpu, struct 
kvm_xen_exit *exit)
 }
 
 switch (code) {
+case __HYPERVISOR_xen_version:
+return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0],
+ exit->u.hcall.params[1]);
 default:
 return false;
 }
-- 
2.35.3




[RFC PATCH v2 18/22] i386/xen: handle VCPUOP_register_runstate_memory_area

2022-12-09 Thread David Woodhouse
From: Joao Martins 

Allow guest to setup the vcpu runstates which is used as
steal clock.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 target/i386/cpu.h |  1 +
 target/i386/kvm/kvm.c |  9 +
 target/i386/machine.c |  4 +++-
 target/i386/xen.c | 35 +++
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 96c2d0d5cb..bf44a87ddb 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1791,6 +1791,7 @@ typedef struct CPUArchState {
 uint64_t xen_vcpu_info_gpa;
 uint64_t xen_vcpu_info_default_gpa;
 uint64_t xen_vcpu_time_info_gpa;
+uint64_t xen_vcpu_runstate_gpa;
 #endif
 #if defined(CONFIG_HVF)
 HVFX86LazyFlags hvf_lflags;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 3f19fff21f..a5e67a3119 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1814,6 +1814,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 env->xen_vcpu_info_gpa = UINT64_MAX;
 env->xen_vcpu_info_default_gpa = UINT64_MAX;
 env->xen_vcpu_time_info_gpa = UINT64_MAX;
+env->xen_vcpu_runstate_gpa = UINT64_MAX;
 
 xen_version = kvm_arch_xen_version(MACHINE(qdev_get_machine()));
 if (xen_version) {
@@ -4753,6 +4754,14 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
 return ret;
 }
 }
+
+gpa = x86_cpu->env.xen_vcpu_runstate_gpa;
+if (gpa != UINT64_MAX) {
+ret = kvm_xen_set_vcpu_attr(cpu, 
KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, gpa);
+if (ret < 0) {
+return ret;
+}
+}
 }
 #endif
 
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 9acef102a3..6a510e5cbd 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1264,7 +1264,8 @@ static bool xen_vcpu_needed(void *opaque)
 
 return (env->xen_vcpu_info_gpa != UINT64_MAX ||
 env->xen_vcpu_info_default_gpa != UINT64_MAX ||
-env->xen_vcpu_time_info_gpa != UINT64_MAX);
+env->xen_vcpu_time_info_gpa != UINT64_MAX ||
+env->xen_vcpu_runstate_gpa != UINT64_MAX);
 }
 
 static const VMStateDescription vmstate_xen_vcpu = {
@@ -1276,6 +1277,7 @@ static const VMStateDescription vmstate_xen_vcpu = {
 VMSTATE_UINT64(env.xen_vcpu_info_gpa, X86CPU),
 VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU),
 VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU),
+VMSTATE_UINT64(env.xen_vcpu_runstate_gpa, X86CPU),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/target/i386/xen.c b/target/i386/xen.c
index 427729ab4d..97032049e6 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -190,6 +190,17 @@ static void do_set_vcpu_time_info_gpa(CPUState *cs, 
run_on_cpu_data data)
   env->xen_vcpu_time_info_gpa);
 }
 
+static void do_set_vcpu_runstate_gpa(CPUState *cs, run_on_cpu_data data)
+{
+X86CPU *cpu = X86_CPU(cs);
+CPUX86State *env = &cpu->env;
+
+env->xen_vcpu_runstate_gpa = data.host_ulong;
+
+kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,
+  env->xen_vcpu_runstate_gpa);
+}
+
 static int xen_set_shared_info(CPUState *cs, uint64_t gfn)
 {
 uint64_t gpa = gfn << TARGET_PAGE_BITS;
@@ -303,6 +314,27 @@ static int vcpuop_register_vcpu_time_info(CPUState *cs, 
CPUState *target,
 return 0;
 }
 
+static int vcpuop_register_runstate_info(CPUState *cs, CPUState *target,
+ uint64_t arg)
+{
+struct vcpu_register_runstate_memory_area rma;
+uint64_t gpa;
+size_t len;
+
+if (kvm_copy_from_gva(cs, arg, &rma, sizeof(*rma.addr.v))) {
+return -EFAULT;
+}
+
+if (!kvm_gva_to_gpa(cs, rma.addr.p, &gpa, &len, false) ||
+len < sizeof(struct vcpu_time_info)) {
+return -EFAULT;
+}
+
+async_run_on_cpu(target, do_set_vcpu_runstate_gpa,
+ RUN_ON_CPU_HOST_ULONG(gpa));
+return 0;
+}
+
 static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu,
   int cmd, int vcpu_id, uint64_t arg)
 {
@@ -311,6 +343,9 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit 
*exit, X86CPU *cpu,
 int err;
 
 switch (cmd) {
+case VCPUOP_register_runstate_memory_area:
+err = vcpuop_register_runstate_info(cs, dest, arg);
+break;
 case VCPUOP_register_vcpu_time_memory_area:
 err = vcpuop_register_vcpu_time_info(cs, dest, arg);
 break;
-- 
2.35.3




[RFC PATCH v2 09/22] pc_piix: allow xenfv machine with XEN_EMULATE

2022-12-09 Thread David Woodhouse
From: Joao Martins 

This allows -machine xenfv to work with Xen emulated guests.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 hw/i386/pc_piix.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3dcac2f4b6..d1127adde0 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -404,8 +404,8 @@ static void pc_xen_hvm_init(MachineState *machine)
 {
 PCMachineState *pcms = PC_MACHINE(machine);
 
-if (!xen_enabled()) {
-error_report("xenfv machine requires the xen accelerator");
+if (!xen_enabled() && (xen_mode != XEN_EMULATE)) {
+error_report("xenfv machine requires the xen or kvm accelerator");
 exit(1);
 }
 
-- 
2.35.3




[RFC PATCH v2 19/22] i386/xen: implement HVMOP_set_evtchn_upcall_vector

2022-12-09 Thread David Woodhouse
From: Ankur Arora 

The HVMOP_set_evtchn_upcall_vector hypercall sets the per-vCPU upcall
vector, to be delivered to the local APIC just like an MSI (with an EOI).

This takes precedence over the system-wide delivery method set by the
HVMOP_set_param hypercall with HVM_PARAM_CALLBACK_IRQ. It's used by
Windows and Xen (PV shim) guests but normally not by Linux.

Signed-off-by: Ankur Arora 
Signed-off-by: Joao Martins 
[dwmw2: Rework for upstream kernel changes and split from HVMOP_set_param]
Signed-off-by: David Woodhouse 
---
 target/i386/cpu.h|  1 +
 target/i386/kvm/kvm.c|  7 
 target/i386/machine.c|  4 ++-
 target/i386/trace-events |  1 +
 target/i386/xen.c| 69 +---
 target/i386/xen.h|  1 +
 6 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index bf44a87ddb..938a1b9c8b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1792,6 +1792,7 @@ typedef struct CPUArchState {
 uint64_t xen_vcpu_info_default_gpa;
 uint64_t xen_vcpu_time_info_gpa;
 uint64_t xen_vcpu_runstate_gpa;
+uint8_t xen_vcpu_callback_vector;
 #endif
 #if defined(CONFIG_HVF)
 HVFX86LazyFlags hvf_lflags;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index a5e67a3119..dc1b3fc502 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -4762,6 +4762,13 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
 return ret;
 }
 }
+
+if (x86_cpu->env.xen_vcpu_callback_vector) {
+ret = kvm_xen_set_vcpu_callback_vector(cpu);
+if (ret < 0) {
+return ret;
+}
+}
 }
 #endif
 
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 6a510e5cbd..09e13cf716 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1265,7 +1265,8 @@ static bool xen_vcpu_needed(void *opaque)
 return (env->xen_vcpu_info_gpa != UINT64_MAX ||
 env->xen_vcpu_info_default_gpa != UINT64_MAX ||
 env->xen_vcpu_time_info_gpa != UINT64_MAX ||
-env->xen_vcpu_runstate_gpa != UINT64_MAX);
+env->xen_vcpu_runstate_gpa != UINT64_MAX ||
+env->xen_vcpu_callback_vector != 0);
 }
 
 static const VMStateDescription vmstate_xen_vcpu = {
@@ -1278,6 +1279,7 @@ static const VMStateDescription vmstate_xen_vcpu = {
 VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU),
 VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU),
 VMSTATE_UINT64(env.xen_vcpu_runstate_gpa, X86CPU),
+VMSTATE_UINT8(env.xen_vcpu_callback_vector, X86CPU),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/target/i386/trace-events b/target/i386/trace-events
index 7118640697..58e28f1a19 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -16,3 +16,4 @@ kvm_sev_attestation_report(const char *mnonce, const char 
*data) "mnonce %s data
 kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t 
a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " 
a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64
 kvm_xen_set_shared_info(uint64_t gfn) "shared info at gfn 0x%" PRIx64
 kvm_xen_set_vcpu_attr(int cpu, int type, uint64_t gpa) "vcpu attr cpu %d type 
%d gpa 0x%" PRIx64
+kvm_xen_set_vcpu_callback(int cpu, int vector) "callback vcpu %d vector %d"
diff --git a/target/i386/xen.c b/target/i386/xen.c
index 97032049e6..2583c00a6b 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -19,6 +19,7 @@
 #include "standard-headers/xen/version.h"
 #include "standard-headers/xen/memory.h"
 #include "standard-headers/xen/hvm/hvm_op.h"
+#include "standard-headers/xen/hvm/params.h"
 #include "standard-headers/xen/vcpu.h"
 
 static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa,
@@ -127,7 +128,8 @@ static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit 
*exit, X86CPU *cpu,
 fi.submap |= 1 << XENFEAT_writable_page_tables |
  1 << XENFEAT_writable_descriptor_tables |
  1 << XENFEAT_auto_translated_physmap |
- 1 << XENFEAT_supervisor_mode_kernel;
+ 1 << XENFEAT_supervisor_mode_kernel |
+ 1 << XENFEAT_hvm_callback_vector;
 }
 
 err = kvm_copy_to_gva(CPU(cpu), arg, &fi, sizeof(fi));
@@ -154,6 +156,29 @@ int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, 
uint64_t gpa)
 return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xhsi);
 }
 
+int kvm_xen_set_vcpu_callback_vector(CPUState *cs)
+{
+uint8_t vector = X86_CPU(cs)->env.xen_vcpu_callback_vector;
+struct kvm_xen_vcpu_attr xva;
+
+xva.type = KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR;
+xva.u.vector = vector;
+
+trace_kvm_xen_set_vcpu_callback(cs->cpu_index, vector);
+
+return kvm_vcpu_ioctl(cs, KVM_XEN_HVM_SET_ATTR, &xva);
+}
+
+static void do_set_vcpu_callbac

[RFC PATCH v2 15/22] i386/xen: implement HYPERVISOR_vcpu_op

2022-12-09 Thread David Woodhouse
From: Joao Martins 

This is simply when guest tries to register a vcpu_info
and since vcpu_info placement is optional in the minimum ABI
therefore we can just fail with -ENOSYS

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 target/i386/xen.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/target/i386/xen.c b/target/i386/xen.c
index 2847b4f864..9d1daadee1 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -19,6 +19,7 @@
 #include "standard-headers/xen/version.h"
 #include "standard-headers/xen/memory.h"
 #include "standard-headers/xen/hvm/hvm_op.h"
+#include "standard-headers/xen/vcpu.h"
 
 static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz,
   bool is_write)
@@ -194,6 +195,25 @@ static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *exit,
 }
 }
 
+static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu,
+  int cmd, int vcpu_id, uint64_t arg)
+{
+int err;
+
+switch (cmd) {
+case VCPUOP_register_vcpu_info:
+/* no vcpu info placement for now */
+err = -ENOSYS;
+break;
+
+default:
+return false;
+}
+
+exit->u.hcall.result = err;
+return true;
+}
+
 static bool __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
 {
 uint16_t code = exit->u.hcall.input;
@@ -204,6 +224,11 @@ static bool __kvm_xen_handle_exit(X86CPU *cpu, struct 
kvm_xen_exit *exit)
 }
 
 switch (code) {
+case __HYPERVISOR_vcpu_op:
+return kvm_xen_hcall_vcpu_op(exit, cpu,
+ exit->u.hcall.params[0],
+ exit->u.hcall.params[1],
+ exit->u.hcall.params[2]);
 case __HYPERVISOR_hvm_op:
 return kvm_xen_hcall_hvm_op(exit, exit->u.hcall.params[0],
 exit->u.hcall.params[1]);
-- 
2.35.3




[RFC PATCH v2 12/22] hw/xen: Add xen_overlay device for emulating shared xenheap pages

2022-12-09 Thread David Woodhouse
From: David Woodhouse 

For the shared info page and for grant tables, Xen shares its own pages
from the "Xen heap" to the guest. The guest requests that a given page
from a certain address space (XENMAPSPACE_shared_info, etc.) be mapped
to a given GPA using the XENMEM_add_to_physmap hypercall.

To support that in qemu when *emulating* Xen, create a memory region
(migratable) and allow it to be mapped as an overlay when requested.

Xen theoretically allows the same page to be mapped multiple times
into the guest, but that's hard to track and reinstate over migration,
so we automatically *unmap* any previous mapping when creating a new
one. This approach has been used in production with a non-trivial
number of guests expecting true Xen, without any problems yet being
noticed.

This adds just the shared info page for now. The grant tables will be
a larger region, and will need to be overlaid one page at a time. I
think that means I need to create separate aliases for each page of
the overall grant_frames region, so that they can be mapped individually.

Expecting some heckling at the use of xen_overlay_singleton. What is
the best way to do that? Using qemu_find_recursive() every time seemed
a bit wrong. But I suppose mapping it into the *guest* isn't a fast
path, and if the actual grant table code is allowed to just stash the
pointer it gets from xen_overlay_page_ptr() for later use then that
isn't a fast path for device I/O either.

Signed-off-by: David Woodhouse 
---
 hw/i386/kvm/meson.build   |   1 +
 hw/i386/kvm/xen_overlay.c | 198 ++
 hw/i386/kvm/xen_overlay.h |  14 +++
 hw/i386/pc_piix.c |   8 ++
 4 files changed, 221 insertions(+)
 create mode 100644 hw/i386/kvm/xen_overlay.c
 create mode 100644 hw/i386/kvm/xen_overlay.h

diff --git a/hw/i386/kvm/meson.build b/hw/i386/kvm/meson.build
index 95467f1ded..6165cbf019 100644
--- a/hw/i386/kvm/meson.build
+++ b/hw/i386/kvm/meson.build
@@ -4,5 +4,6 @@ i386_kvm_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c'))
 i386_kvm_ss.add(when: 'CONFIG_I8254', if_true: files('i8254.c'))
 i386_kvm_ss.add(when: 'CONFIG_I8259', if_true: files('i8259.c'))
 i386_kvm_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
+i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen_overlay.c'))
 
 i386_ss.add_all(when: 'CONFIG_KVM', if_true: i386_kvm_ss)
diff --git a/hw/i386/kvm/xen_overlay.c b/hw/i386/kvm/xen_overlay.c
new file mode 100644
index 00..c3eeb8dae8
--- /dev/null
+++ b/hw/i386/kvm/xen_overlay.c
@@ -0,0 +1,198 @@
+/*
+ * QEMU Xen emulation: Shared/overlay pages support
+ *
+ * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Authors: David Woodhouse 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+#include "qemu/module.h"
+#include "qemu/main-loop.h"
+#include "qapi/error.h"
+#include "qom/object.h"
+#include "exec/target_page.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+
+#include "hw/sysbus.h"
+#include "hw/xen/xen.h"
+#include "xen_overlay.h"
+
+#include "sysemu/kvm.h"
+#include 
+
+#include "standard-headers/xen/memory.h"
+
+static int xen_overlay_map_page_locked(uint32_t space, uint64_t idx, uint64_t 
gpa);
+
+#define INVALID_GPA UINT64_MAX
+#define INVALID_GFN UINT64_MAX
+
+#define TYPE_XEN_OVERLAY "xenoverlay"
+OBJECT_DECLARE_SIMPLE_TYPE(XenOverlayState, XEN_OVERLAY)
+
+#define XEN_PAGE_SHIFT 12
+#define XEN_PAGE_SIZE (1ULL << XEN_PAGE_SHIFT)
+
+struct XenOverlayState {
+/*< private >*/
+SysBusDevice busdev;
+/*< public >*/
+
+MemoryRegion shinfo_mem;
+void *shinfo_ptr;
+uint64_t shinfo_gpa;
+};
+
+struct XenOverlayState *xen_overlay_singleton;
+
+static void xen_overlay_realize(DeviceState *dev, Error **errp)
+{
+XenOverlayState *s = XEN_OVERLAY(dev);
+
+if (xen_mode != XEN_EMULATE) {
+error_setg(errp, "Xen overlay page support is for Xen emulation");
+return;
+}
+
+memory_region_init_ram(&s->shinfo_mem, OBJECT(dev), "xen:shared_info", 
XEN_PAGE_SIZE, &error_abort);
+memory_region_set_enabled(&s->shinfo_mem, true);
+s->shinfo_ptr = memory_region_get_ram_ptr(&s->shinfo_mem);
+s->shinfo_gpa = INVALID_GPA;
+memset(s->shinfo_ptr, 0, XEN_PAGE_SIZE);
+}
+
+static int xen_overlay_post_load(void *opaque, int version_id)
+{
+XenOverlayState *s = opaque;
+
+if (s->shinfo_gpa != INVALID_GPA) {
+xen_overlay_map_page_locked(XENMAPSPACE_shared_info, 0, 
s->shinfo_gpa);
+}
+
+return 0;
+}
+
+static bool xen_overlay_is_needed(void *opaque)
+{
+return xen_mode == XEN_EMULATE;
+}
+
+static const VMStateDescription xen_overlay_vmstate = {
+.name = "xen_overlay",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = xen_overlay_is_needed,
+.post_load = xen_overlay_post_load,
+.fields = (

[RFC PATCH v2 13/22] i386/xen: implement HYPERVISOR_memory_op

2022-12-09 Thread David Woodhouse
From: Joao Martins 

Specifically XENMEM_add_to_physmap with space XENMAPSPACE_shared_info to
allow the guest to set its shared_info page.

Signed-off-by: Joao Martins 
[dwmw2: Use the xen_overlay device]
Signed-off-by: David Woodhouse 
---
 target/i386/trace-events |  1 +
 target/i386/xen.c| 59 +++-
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/target/i386/trace-events b/target/i386/trace-events
index 1bf9558811..fb999d0052 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -14,3 +14,4 @@ kvm_sev_attestation_report(const char *mnonce, const char 
*data) "mnonce %s data
 
 # target/i386/xen.c
 kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t 
a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " 
a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64
+kvm_xen_set_shared_info(uint64_t gfn) "shared info at gfn 0x%" PRIx64
diff --git a/target/i386/xen.c b/target/i386/xen.c
index 55beed1913..ddd144039a 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -15,8 +15,9 @@
 #include "exec/address-spaces.h"
 #include "xen.h"
 #include "trace.h"
-
+#include "hw/i386/kvm/xen_overlay.h"
 #include "standard-headers/xen/version.h"
+#include "standard-headers/xen/memory.h"
 
 static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz,
   bool is_write)
@@ -126,6 +127,59 @@ static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit 
*exit, X86CPU *cpu,
 return true;
 }
 
+static int xen_set_shared_info(CPUState *cs, uint64_t gfn)
+{
+uint64_t gpa = gfn << TARGET_PAGE_BITS;
+int err;
+
+/* The xen_overlay device tells KVM about it too, since it had to
+ * do that on migration load anyway (unless we're going to jump
+ * through lots of hoops to maintain the fiction that this isn't
+ * KVM-specific */
+err = xen_overlay_map_page(XENMAPSPACE_shared_info, 0, gpa);
+if (err)
+return err;
+
+trace_kvm_xen_set_shared_info(gfn);
+
+return err;
+}
+
+static bool kvm_xen_hcall_memory_op(struct kvm_xen_exit *exit,
+   int cmd, uint64_t arg, X86CPU *cpu)
+{
+CPUState *cs = CPU(cpu);
+int err = 0;
+
+switch (cmd) {
+case XENMEM_add_to_physmap: {
+struct xen_add_to_physmap xatp;
+
+err = kvm_copy_from_gva(cs, arg, &xatp, sizeof(xatp));
+if (err) {
+break;
+}
+
+switch (xatp.space) {
+case XENMAPSPACE_shared_info:
+break;
+default:
+err = -ENOSYS;
+break;
+}
+
+err = xen_set_shared_info(cs, xatp.gpfn);
+break;
+ }
+
+default:
+return false;
+}
+
+exit->u.hcall.result = err;
+return true;
+}
+
 static bool __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
 {
 uint16_t code = exit->u.hcall.input;
@@ -136,6 +190,9 @@ static bool __kvm_xen_handle_exit(X86CPU *cpu, struct 
kvm_xen_exit *exit)
 }
 
 switch (code) {
+case __HYPERVISOR_memory_op:
+return kvm_xen_hcall_memory_op(exit, exit->u.hcall.params[0],
+   exit->u.hcall.params[1], cpu);
 case __HYPERVISOR_xen_version:
 return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0],
  exit->u.hcall.params[1]);
-- 
2.35.3




[RFC PATCH v2 17/22] i386/xen: handle VCPUOP_register_vcpu_time_info

2022-12-09 Thread David Woodhouse
From: Joao Martins 

In order to support Linux vdso in Xen.

Signed-off-by: Joao Martins 
Signed-off-by: David Woodhouse 
---
 target/i386/cpu.h |  1 +
 target/i386/kvm/kvm.c |  9 ++
 target/i386/machine.c |  4 ++-
 target/i386/xen.c | 70 ---
 4 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 109b2e5669..96c2d0d5cb 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1790,6 +1790,7 @@ typedef struct CPUArchState {
 struct kvm_nested_state *nested_state;
 uint64_t xen_vcpu_info_gpa;
 uint64_t xen_vcpu_info_default_gpa;
+uint64_t xen_vcpu_time_info_gpa;
 #endif
 #if defined(CONFIG_HVF)
 HVFX86LazyFlags hvf_lflags;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index fa45e2f99a..3f19fff21f 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1813,6 +1813,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
 env->xen_vcpu_info_gpa = UINT64_MAX;
 env->xen_vcpu_info_default_gpa = UINT64_MAX;
+env->xen_vcpu_time_info_gpa = UINT64_MAX;
 
 xen_version = kvm_arch_xen_version(MACHINE(qdev_get_machine()));
 if (xen_version) {
@@ -4744,6 +4745,14 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
 return ret;
 }
 }
+
+gpa = x86_cpu->env.xen_vcpu_time_info_gpa;
+if (gpa != UINT64_MAX) {
+ret = kvm_xen_set_vcpu_attr(cpu, 
KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, gpa);
+if (ret < 0) {
+return ret;
+}
+}
 }
 #endif
 
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 104cd6047c..9acef102a3 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1263,7 +1263,8 @@ static bool xen_vcpu_needed(void *opaque)
 CPUX86State *env = &cpu->env;
 
 return (env->xen_vcpu_info_gpa != UINT64_MAX ||
-env->xen_vcpu_info_default_gpa != UINT64_MAX);
+env->xen_vcpu_info_default_gpa != UINT64_MAX ||
+env->xen_vcpu_time_info_gpa != UINT64_MAX);
 }
 
 static const VMStateDescription vmstate_xen_vcpu = {
@@ -1274,6 +1275,7 @@ static const VMStateDescription vmstate_xen_vcpu = {
 .fields = (VMStateField[]) {
 VMSTATE_UINT64(env.xen_vcpu_info_gpa, X86CPU),
 VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU),
+VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/target/i386/xen.c b/target/i386/xen.c
index cd816bb711..427729ab4d 100644
--- a/target/i386/xen.c
+++ b/target/i386/xen.c
@@ -21,28 +21,41 @@
 #include "standard-headers/xen/hvm/hvm_op.h"
 #include "standard-headers/xen/vcpu.h"
 
+static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa,
+   size_t *len, bool is_write)
+{
+struct kvm_translation tr = {
+.linear_address = gva,
+};
+
+if (len) {
+*len = TARGET_PAGE_SIZE - (gva & ~TARGET_PAGE_MASK);
+}
+
+if (kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr) || !tr.valid ||
+(is_write && !tr.writeable)) {
+return false;
+}
+*gpa = tr.physical_address;
+return true;
+}
+
 static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz,
   bool is_write)
 {
 uint8_t *buf = (uint8_t *)_buf;
 size_t i = 0, len = 0;
-int ret;
 
 for (i = 0; i < sz; i+= len) {
-struct kvm_translation tr = {
-.linear_address = gva + i,
-};
+uint64_t gpa;
 
-len = TARGET_PAGE_SIZE - (tr.linear_address & ~TARGET_PAGE_MASK);
+if (!kvm_gva_to_gpa(cs, gva + i, &gpa, &len, is_write)) {
+return -EFAULT;
+}
 if (len > sz)
 len = sz;
 
-ret = kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr);
-if (ret || !tr.valid || (is_write && !tr.writeable)) {
-return -EFAULT;
-}
-
-cpu_physical_memory_rw(tr.physical_address, buf + i, len, is_write);
+cpu_physical_memory_rw(gpa, buf + i, len, is_write);
 }
 
 return 0;
@@ -166,6 +179,17 @@ static void do_set_vcpu_info_gpa(CPUState *cs, 
run_on_cpu_data data)
   env->xen_vcpu_info_gpa);
 }
 
+static void do_set_vcpu_time_info_gpa(CPUState *cs, run_on_cpu_data data)
+{
+X86CPU *cpu = X86_CPU(cs);
+CPUX86State *env = &cpu->env;
+
+env->xen_vcpu_time_info_gpa = data.host_ulong;
+
+kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO,
+  env->xen_vcpu_time_info_gpa);
+}
+
 static int xen_set_shared_info(CPUState *cs, uint64_t gfn)
 {
 uint64_t gpa = gfn << TARGET_PAGE_BITS;
@@ -258,6 +282,27 @@ static int vcpuop_register_vcpu_info(CPUState *cs, 
CPUState *target,
 return 0;
 }
 
+static int vcpuop_register_vcpu_time_info(CPUState *cs, CPUState *target,
+  uint64

Re: [PATCH] target/i386: Fix wrong XSAVE feature names

2022-12-09 Thread Yang Zhong
In fact, one month ago, I have sent out V2 for this issue. thanks!
https://lists.nongnu.org/archive/html/qemu-devel/2022-10/msg04825.html

Yang


On Wed, Dec 07, 2022 at 09:47:47PM -0500, Xiaocheng Dong wrote:
> The previous patch changes the name from FEAT_XSAVE_COMP_{LO|HI}
> to FEAT_XSAVE_XCR0_{LO|HI}, the changes for CPUID.0x12.0x1 should be
> FEAT_XSAVE_XCR0_{LO|HI}, the SGX can't work in VM if these are not right
> 
> Fixes: 301e90675c3f ("target/i386: Enable support for XSAVES based features")
> 
> Signed-off-by: Xiaocheng Dong 
> ---
>  target/i386/cpu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 22b681ca37..0f71ff9fea 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -5584,8 +5584,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>  } else {
>  *eax &= env->features[FEAT_SGX_12_1_EAX];
>  *ebx &= 0; /* ebx reserve */
> -*ecx &= env->features[FEAT_XSAVE_XSS_LO];
> -*edx &= env->features[FEAT_XSAVE_XSS_HI];
> +*ecx &= env->features[FEAT_XSAVE_XCR0_LO];
> +*edx &= env->features[FEAT_XSAVE_XCR0_HI];
>  
>  /* FP and SSE are always allowed regardless of XSAVE/XCR0. */
>  *ecx |= XSTATE_FP_MASK | XSTATE_SSE_MASK;
> -- 
> 2.31.1
> 
> 



[PATCH] linux-user: Enhance strace output for various syscalls

2022-12-09 Thread Helge Deller
Add appropriate strace printf formats for various Linux syscalls.

Signed-off-by: Helge Deller 
---
 linux-user/strace.list | 43 ++
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/linux-user/strace.list b/linux-user/strace.list
index 3a898e2532..4091a9e79d 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -337,7 +337,7 @@
 { TARGET_NR_getpagesize, "getpagesize" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_getpeername
-{ TARGET_NR_getpeername, "getpeername" , NULL, NULL, NULL },
+{ TARGET_NR_getpeername, "getpeername" , "%s(%d,%p,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getpgid
 { TARGET_NR_getpgid, "getpgid" , "%s(%u)", NULL, NULL },
@@ -361,19 +361,19 @@
 { TARGET_NR_getrandom, "getrandom", "%s(%p,%u,%u)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getresgid
-{ TARGET_NR_getresgid, "getresgid" , NULL, NULL, NULL },
+{ TARGET_NR_getresgid, "getresgid" , "%s(%p,%p,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getresgid32
 { TARGET_NR_getresgid32, "getresgid32" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_getresuid
-{ TARGET_NR_getresuid, "getresuid" , NULL, NULL, NULL },
+{ TARGET_NR_getresuid, "getresuid" , "%s(%p,%p,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getresuid32
 { TARGET_NR_getresuid32, "getresuid32" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_getrlimit
-{ TARGET_NR_getrlimit, "getrlimit" , NULL, NULL, NULL },
+{ TARGET_NR_getrlimit, "getrlimit" , "%s(%d,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_get_robust_list
 { TARGET_NR_get_robust_list, "get_robust_list" , NULL, NULL, NULL },
@@ -385,10 +385,10 @@
 { TARGET_NR_getsid, "getsid" , "%s(%d)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getsockname
-{ TARGET_NR_getsockname, "getsockname" , NULL, NULL, NULL },
+{ TARGET_NR_getsockname, "getsockname" , "%s(%d,%p,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getsockopt
-{ TARGET_NR_getsockopt, "getsockopt" , NULL, NULL, NULL },
+{ TARGET_NR_getsockopt, "getsockopt" , "%s(%d,%d,%d,%p,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_get_thread_area
 #if defined(TARGET_I386) && defined(TARGET_ABI32)
@@ -1052,10 +1052,10 @@
 { TARGET_NR_pivot_root, "pivot_root" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_poll
-{ TARGET_NR_poll, "poll" , NULL, NULL, NULL },
+{ TARGET_NR_poll, "poll" , "%s(%p,%d,%d)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_ppoll
-{ TARGET_NR_ppoll, "ppoll" , NULL, NULL, NULL },
+{ TARGET_NR_ppoll, "ppoll" , "%s(%p,%d,%p,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_prctl
 { TARGET_NR_prctl, "prctl" , NULL, NULL, NULL },
@@ -1124,7 +1124,7 @@
 { TARGET_NR_reboot, "reboot" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_recv
-{ TARGET_NR_recv, "recv" , NULL, NULL, NULL },
+{ TARGET_NR_recv, "recv" , "%s(%d,%p,%d,%u)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_recvfrom
 { TARGET_NR_recvfrom, "recvfrom" , NULL, NULL, NULL },
@@ -1184,7 +1184,7 @@
 { TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, print_rt_sigqueueinfo, 
NULL },
 #endif
 #ifdef TARGET_NR_rt_sigreturn
-{ TARGET_NR_rt_sigreturn, "rt_sigreturn" , NULL, NULL, NULL },
+{ TARGET_NR_rt_sigreturn, "rt_sigreturn" , "%s(%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_rt_sigsuspend
 { TARGET_NR_rt_sigsuspend, "rt_sigsuspend" , NULL, NULL, NULL },
@@ -1196,16 +1196,19 @@
 { TARGET_NR_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" , NULL, 
print_rt_tgsigqueueinfo, NULL },
 #endif
 #ifdef TARGET_NR_sched_getaffinity
-{ TARGET_NR_sched_getaffinity, "sched_getaffinity" , NULL, NULL, NULL },
+{ TARGET_NR_sched_getaffinity, "sched_getaffinity" , "%s(%d,%u,%p)", NULL, 
NULL },
 #endif
 #ifdef TARGET_NR_sched_get_affinity
 { TARGET_NR_sched_get_affinity, "sched_get_affinity" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_sched_getattr
-{ TARGET_NR_sched_getattr, "sched_getattr" , NULL, NULL, NULL },
+{ TARGET_NR_sched_getattr, "sched_getattr" , "%s(%d,%p,%u,%u)", NULL, NULL },
+#endif
+#ifdef TARGET_NR_sched_setattr
+{ TARGET_NR_sched_setattr, "sched_setattr" , "%s(%p,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_sched_getparam
-{ TARGET_NR_sched_getparam, "sched_getparam" , NULL, NULL, NULL },
+{ TARGET_NR_sched_getparam, "sched_getparam" , "%s(%d,%p)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_sched_get_priority_max
 { TARGET_NR_sched_get_priority_max, "sched_get_priority_max" , NULL, NULL, 
NULL },
@@ -1220,7 +1223,7 @@
 { TARGET_NR_sched_rr_get_interval, "sched_rr_get_interval" , NULL, NULL, NULL 
},
 #endif
 #ifdef TARGET_NR_sched_setaffinity
-{ TARGET_NR_sched_setaffinity, "sched_setaffinity" , NULL, NULL, NULL },
+{ TARGET_NR_sched_setaffinity, "sched_setaffinity" , "%s(%d,%u,%p)", NULL, 
NULL },
 #endif
 #ifdef TARGET_NR_sched_setatt
 { TARGET_NR_sched_setatt, "sched_setatt" , NULL, NULL, NULL },
@@ -1353,23 +1356,23 @@
 { TARGET_NR_setreuid32, "setreuid32" , "%s(%u,%u)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_setrlimit
-{ TARGET_NR_setrlimit, "setrlimit" , NULL, NULL, NULL },
+{ TARGET_NR_setrlimit, "setrlimit" , "%s(%d,%p)", NULL, NULL },
 #endif
 #ifdef

Re: [PATCH qemu.git 0/1] hw/arm/virt: add 2x sp804 timer

2022-12-09 Thread Peter Maydell
On Thu, 8 Dec 2022 at 17:25, Axel Heider  wrote:
> >> For the seL4 specific case, this is currently not possible in
> >> the standard configuration. It's only exposed for a special
> >> debug and benchmarking configuration.
> >>
> > It's not clear to me what you mean here -- the generic
> > timer in the CPU exists in all configurations, so there
> > should be no obstacle to seL4 using it.
>
> Access is not exposed to userland in the standard configuration
> and the standard kernel API has no no timeouts besides zero and
> infinite. It's a design thing in the end. Nothing that could not
> be hacked around or be changed in the design in the long run. But
> my goal is not to hack around, but have a "proper" machine
> simulation instead. Which basically falls down to having a generic
> machine in mainline that has a few more customization options.

So, my take on this is that I'm open to adding things to
the virt board where we don't provide a feature that's
useful to guest code. The second UART falls in this category:
it lets you do things that you otherwise could not do (like
have one UART for firmware and one for a kernel). On the
other hand, this case with the sp804 sounds more like QEMU
is already providing functional timer facilities and the
problem is on the guest software side. To me the "non-hacky"
solution sounds like it is "sel4 should provide a better timer
related API to userland". I don't really want to work around
guest OS deficiencies in QEMU.

thanks
-- PMM



Re: [PATCH v3 1/2] hw/nvme: Implement shadow doorbell buffer support

2022-12-09 Thread Guenter Roeck
On Thu, Dec 08, 2022 at 12:39:57PM -0800, Guenter Roeck wrote:
> On Thu, Dec 08, 2022 at 12:13:55PM -0800, Guenter Roeck wrote:
> > On Thu, Dec 08, 2022 at 10:47:42AM -0800, Guenter Roeck wrote:
> > > > 
> > > > A cq head doorbell mmio is skipped... And it is not the fault of the
> > > > kernel. The kernel is in it's good right to skip the mmio since the cq
> > > > eventidx is not properly updated.
> > > > 
> > > > Adding that and it boots properly on riscv. But I'm perplexed as to why
> > > > this didnt show up on our regularly tested platforms.
> > > > 
> > > > Gonna try to get this in for 7.2!
> > > 
> > > I see another problem with sparc64.
> > > 
> > > [5.261508] could not locate request for tag 0x0
> > > [5.261711] nvme nvme0: invalid id 0 completed on queue 1
> > > 
> > > That is seen repeatedly until the request times out. I'll test with
> > > your patch to see if it resolves this problem as well, and will bisect
> > > otherwise.
> > > 
> > The second problem is unrelated to the doorbell problem.
> > It is first seen in qemu v7.1. I'll try to bisect.
> > 
> 
> Unfortunately, the problem observed with sparc64 also bisects to this
> patch. Making things worse, "hw/nvme: fix missing cq eventidx update"
> does not fix it (which is why I initially thought it was unrelated).
> 
> I used the following qemu command line.
> 
> qemu-system-sparc64 -M sun4v -cpu "TI UltraSparc IIi" -m 512 -snapshot \
> -device nvme,serial=foo,drive=d0,bus=pciB \
> -drive file=rootfs.ext2,if=none,format=raw,id=d0 \
> -kernel arch/sparc/boot/image -no-reboot \
> -append "root=/dev/nvme0n1 console=ttyS0" \
> -nographic -monitor none
> 

With completed tests, it turns out the problem is seen with various
emulations running big endian CPUs.

Example from arm64be:

[4.736752] nvme nvme0: pci function :00:02.0
[4.737829] nvme :00:02.0: enabling device ( -> 0002)
[4.774673] nvme nvme0: 2/0/0 default/read/poll queues
[4.779331] nvme nvme0: Ignoring bogus Namespace Identifiers
[4.799400] could not locate request for tag 0x0
[4.799533] nvme nvme0: invalid id 0 completed on queue 2
[4.799612] could not locate request for tag 0x0
[4.799676] nvme nvme0: invalid id 0 completed on queue 2
[4.799744] could not locate request for tag 0x0

powerpc:

could not locate request for tag 0x0
nvme nvme0: invalid id 0 completed on queue 1
could not locate request for tag 0x0
nvme nvme0: invalid id 0 completed on queue 1

trace logs (arm64be, good, qemu v7.0):

pci_nvme_admin_cmd cid 2864 sqid 0 opc 0x6 opname 'NVME_ADM_CMD_IDENTIFY'
pci_nvme_identify cid 2864 cns 0x5 ctrlid 0 csi 0x0
pci_nvme_identify_ns_csi nsid=1, csi=0x0
pci_nvme_map_prp trans_len 4096 len 4096 prp1 0x44a84000 prp2 0x0 num_prps 2
pci_nvme_map_addr addr 0x44a84000 len 4096
pci_nvme_enqueue_req_completion cid 2864 cqid 0 dw0 0x0 dw1 0x0 status 0x0
pci_nvme_irq_msix raising MSI-X IRQ vector 0
pci_nvme_mmio_write addr 0x1004 data 0x10 size 4
pci_nvme_mmio_doorbell_cq cqid 0 new_head 16
pci_nvme_mmio_write addr 0x1008 data 0x1 size 4
pci_nvme_mmio_doorbell_sq sqid 1 new_tail 1
pci_nvme_io_cmd cid 32770 nsid 0x1 sqid 1 opc 0x2 opname 'NVME_NVM_CMD_READ'
pci_nvme_read cid 32770 nsid 1 nlb 8 count 4096 lba 0x0
pci_nvme_map_prp trans_len 4096 len 4096 prp1 0x44879000 prp2 0x0 num_prps 2
pci_nvme_map_addr addr 0x44879000 len 4096
pci_nvme_rw_cb cid 32770 blk 'd0'
pci_nvme_rw_complete_cb cid 32770 blk 'd0'
pci_nvme_enqueue_req_completion cid 32770 cqid 1 dw0 0x0 dw1 0x0 status 0x0
pci_nvme_irq_msix raising MSI-X IRQ vector 1
pci_nvme_mmio_write addr 0x100c data 0x1 size 4
pci_nvme_mmio_doorbell_cq cqid 1 new_head 1
pci_nvme_mmio_write addr 0x1008 data 0x2 size 4
pci_nvme_mmio_doorbell_sq sqid 1 new_tail 2

trace log (arm64be, bad, qemu v7.2):

pci_nvme_admin_cmd cid 5184 sqid 0 opc 0x6 opname 'NVME_ADM_CMD_IDENTIFY'
pci_nvme_identify cid 5184 cns 0x5 ctrlid 0 csi 0x0
pci_nvme_identify_ns_csi nsid=1, csi=0x0
pci_nvme_map_prp trans_len 4096 len 4096 prp1 0x44e56000 prp2 0x0 num_prps 2
pci_nvme_map_addr addr 0x44e56000 len 4096
pci_nvme_enqueue_req_completion cid 5184 cqid 0 dw0 0x0 dw1 0x0 status 0x0
pci_nvme_update_sq_eventidx sqid 0 new_eventidx 18
pci_nvme_update_sq_tail sqid 0 new_tail 18
pci_nvme_update_cq_eventidx cqid 0 new_eventidx 16
pci_nvme_update_cq_head cqid 0 new_head 16
pci_nvme_irq_msix raising MSI-X IRQ vector 0
pci_nvme_mmio_write addr 0x1004 data 0x11 size 4
pci_nvme_mmio_doorbell_cq cqid 0 new_head 17
pci_nvme_mmio_write addr 0x1010 data 0x1 size 4
pci_nvme_mmio_doorbell_sq sqid 2 new_tail 1
pci_nvme_update_sq_tail sqid 2 new_tail 0
pci_nvme_io_cmd cid 16384 nsid 0x1 sqid 2 opc 0x2 opname 'NVME_NVM_CMD_READ'
pci_nvme_read cid 16384 nsid 1 nlb 8 count 4096 lba 0x0
pci_nvme_map_prp trans_len 4096 len 4096 prp1 0x44cea000 prp2 0x0 num_prps 2
pci_nvme_map_addr addr 0x44cea000 len 4096
pci_nvme_update_sq_eventidx sqid 2 new_eventidx 0
pci_nvme_update_sq_tail sqid 2 new_tail 0
pci_nvme_io_cmd cid 0 nsid 0x0

[PATCH-for-8.0 v3 0/2] physmem: Remove trace events from trace-root.h

2022-12-09 Thread Philippe Mathieu-Daudé
Trivial housekeeping patches.

Philippe Mathieu-Daudé (2):
  physmem: Remove unused "exec/translate-all.h"
  physmem: Remove trace events from trace-root.h

 softmmu/physmem.c| 3 +--
 softmmu/trace-events | 5 +
 trace-events | 5 -
 3 files changed, 6 insertions(+), 7 deletions(-)

-- 
2.38.1




[PATCH-for-8.0 v3 1/2] physmem: Remove unused "exec/translate-all.h"

2022-12-09 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 softmmu/physmem.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 1b606a3002..d562c0bb93 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -58,7 +58,6 @@
 
 #include "qemu/rcu_queue.h"
 #include "qemu/main-loop.h"
-#include "exec/translate-all.h"
 #include "sysemu/replay.h"
 
 #include "exec/memory-internal.h"
-- 
2.38.1




[PATCH-for-8.0 v3 2/2] physmem: Remove trace events from trace-root.h

2022-12-09 Thread Philippe Mathieu-Daudé
Missed in d9f24bf572 ("exec: split out non-softmmu-specific parts").

Signed-off-by: Philippe Mathieu-Daudé 
---
 softmmu/physmem.c| 2 +-
 softmmu/trace-events | 5 +
 trace-events | 5 -
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index d562c0bb93..94ee981917 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -50,7 +50,7 @@
 #include "sysemu/hostmem.h"
 #include "sysemu/hw_accel.h"
 #include "sysemu/xen-mapcache.h"
-#include "trace/trace-root.h"
+#include "trace.h"
 
 #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
 #include 
diff --git a/softmmu/trace-events b/softmmu/trace-events
index 22606dc27b..c7d709151d 100644
--- a/softmmu/trace-events
+++ b/softmmu/trace-events
@@ -21,6 +21,11 @@ flatview_destroy(void *view, void *root) "%p (root %p)"
 flatview_destroy_rcu(void *view, void *root) "%p (root %p)"
 global_dirty_changed(unsigned int bitmask) "bitmask 0x%"PRIx32
 
+# physmem.c
+find_ram_offset(uint64_t size, uint64_t offset) "size: 0x%" PRIx64 " @ 0x%" 
PRIx64
+find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, 
uint64_t next, uint64_t mingap) "trying size: 0x%" PRIx64 " @ 0x%" PRIx64 ", 
offset: 0x%" PRIx64" next: 0x%" PRIx64 " mingap: 0x%" PRIx64
+ram_block_discard_range(const char *rbname, void *hva, size_t length, bool 
need_madvise, bool need_fallocate, int ret) "%s@%p + 0x%zx: madvise: %d 
fallocate: %d ret: %d"
+
 # softmmu.c
 vm_stop_flush_all(int ret) "ret %d"
 
diff --git a/trace-events b/trace-events
index b6b84b175e..6e67dfe91b 100644
--- a/trace-events
+++ b/trace-events
@@ -37,11 +37,6 @@ dma_complete(void *dbs, int ret, void *cb) "dbs=%p ret=%d 
cb=%p"
 dma_blk_cb(void *dbs, int ret) "dbs=%p ret=%d"
 dma_map_wait(void *dbs) "dbs=%p"
 
-# exec.c
-find_ram_offset(uint64_t size, uint64_t offset) "size: 0x%" PRIx64 " @ 0x%" 
PRIx64
-find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, 
uint64_t next, uint64_t mingap) "trying size: 0x%" PRIx64 " @ 0x%" PRIx64 ", 
offset: 0x%" PRIx64" next: 0x%" PRIx64 " mingap: 0x%" PRIx64
-ram_block_discard_range(const char *rbname, void *hva, size_t length, bool 
need_madvise, bool need_fallocate, int ret) "%s@%p + 0x%zx: madvise: %d 
fallocate: %d ret: %d"
-
 # job.c
 job_state_transition(void *job,  int ret, const char *legal, const char *s0, 
const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
 job_apply_verb(void *job, const char *state, const char *verb, const char 
*legal) "job %p in state %s; applying verb %s (%s)"
-- 
2.38.1




[PATCH-for-8.0] target/arm: Restrict arm_cpu_exec_interrupt() to TCG accelerator

2022-12-09 Thread Philippe Mathieu-Daudé
When building with --disable-tcg on Darwin we get:

  target/arm/cpu.c:725:16: error: incomplete definition of type 'struct 
TCGCPUOps'
cc->tcg_ops->do_interrupt(cs);
~~~^

Commit 083afd18a9 ("target/arm: Restrict cpu_exec_interrupt()
handler to sysemu") limited this block to system emulation,
but neglected to also limit it to TCG.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/arm/cpu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 38d066c294..0f55004d7e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -528,7 +528,7 @@ static void arm_cpu_reset(DeviceState *dev)
 arm_rebuild_hflags(env);
 }
 
-#ifndef CONFIG_USER_ONLY
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
 
 static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
  unsigned int target_el,
@@ -725,7 +725,8 @@ static bool arm_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 cc->tcg_ops->do_interrupt(cs);
 return true;
 }
-#endif /* !CONFIG_USER_ONLY */
+
+#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
 
 void arm_cpu_update_virq(ARMCPU *cpu)
 {
-- 
2.38.1




[PATCH v2 for-8.0] hw/rtc/mc146818rtc: Make this rtc device target independent

2022-12-09 Thread Thomas Huth
The only reason for this code being target dependent is the apic-related
code in rtc_policy_slew_deliver_irq(). Since these apic functions are rather
simple, we can easily move them into a new, separate file (apic_irqcount.c)
which will always be compiled and linked if either APIC or the mc146818 device
are required. This way we can get rid of the #ifdef TARGET_I386 switches in
mc146818rtc.c and declare it in the softmmu_ss instead of specific_ss, so
that the code only gets compiled once for all targets.

Signed-off-by: Thomas Huth 
---
 v2: Move the apic functions into a separate file instead of using
 an ugly function pointer

 include/hw/i386/apic.h  |  1 +
 include/hw/i386/apic_internal.h |  1 -
 include/hw/rtc/mc146818rtc.h|  1 +
 hw/intc/apic_common.c   | 27 -
 hw/intc/apic_irqcount.c | 53 +
 hw/rtc/mc146818rtc.c| 25 +---
 hw/intc/meson.build |  6 +++-
 hw/rtc/meson.build  |  3 +-
 8 files changed, 68 insertions(+), 49 deletions(-)
 create mode 100644 hw/intc/apic_irqcount.c

diff --git a/include/hw/i386/apic.h b/include/hw/i386/apic.h
index da1d2fe155..96b9939425 100644
--- a/include/hw/i386/apic.h
+++ b/include/hw/i386/apic.h
@@ -9,6 +9,7 @@ int apic_accept_pic_intr(DeviceState *s);
 void apic_deliver_pic_intr(DeviceState *s, int level);
 void apic_deliver_nmi(DeviceState *d);
 int apic_get_interrupt(DeviceState *s);
+void apic_report_irq_delivered(int delivered);
 void apic_reset_irq_delivered(void);
 int apic_get_irq_delivered(void);
 void cpu_set_apic_base(DeviceState *s, uint64_t val);
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index c175e7e718..e61ad04769 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -199,7 +199,6 @@ typedef struct VAPICState {
 
 extern bool apic_report_tpr_access;
 
-void apic_report_irq_delivered(int delivered);
 bool apic_next_timer(APICCommonState *s, int64_t current_time);
 void apic_enable_tpr_access_reporting(DeviceState *d, bool enable);
 void apic_enable_vapic(DeviceState *d, hwaddr paddr);
diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h
index 1db0fcee92..45bcd6f040 100644
--- a/include/hw/rtc/mc146818rtc.h
+++ b/include/hw/rtc/mc146818rtc.h
@@ -55,5 +55,6 @@ ISADevice *mc146818_rtc_init(ISABus *bus, int base_year,
  qemu_irq intercept_irq);
 void rtc_set_memory(ISADevice *dev, int addr, int val);
 int rtc_get_memory(ISADevice *dev, int addr);
+void qmp_rtc_reset_reinjection(Error **errp);
 
 #endif /* HW_RTC_MC146818RTC_H */
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 2a20982066..b0f85f9384 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -33,7 +33,6 @@
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 
-static int apic_irq_delivered;
 bool apic_report_tpr_access;
 
 void cpu_set_apic_base(DeviceState *dev, uint64_t val)
@@ -122,32 +121,6 @@ void apic_handle_tpr_access_report(DeviceState *dev, 
target_ulong ip,
 vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access);
 }
 
-void apic_report_irq_delivered(int delivered)
-{
-apic_irq_delivered += delivered;
-
-trace_apic_report_irq_delivered(apic_irq_delivered);
-}
-
-void apic_reset_irq_delivered(void)
-{
-/* Copy this into a local variable to encourage gcc to emit a plain
- * register for a sys/sdt.h marker.  For details on this workaround, see:
- * https://sourceware.org/bugzilla/show_bug.cgi?id=13296
- */
-volatile int a_i_d = apic_irq_delivered;
-trace_apic_reset_irq_delivered(a_i_d);
-
-apic_irq_delivered = 0;
-}
-
-int apic_get_irq_delivered(void)
-{
-trace_apic_get_irq_delivered(apic_irq_delivered);
-
-return apic_irq_delivered;
-}
-
 void apic_deliver_nmi(DeviceState *dev)
 {
 APICCommonState *s = APIC_COMMON(dev);
diff --git a/hw/intc/apic_irqcount.c b/hw/intc/apic_irqcount.c
new file mode 100644
index 00..0aadef1cb5
--- /dev/null
+++ b/hw/intc/apic_irqcount.c
@@ -0,0 +1,53 @@
+/*
+ * APIC support - functions for counting the delivered IRQs.
+ * (this code is in a separate file since it is used from the
+ * mc146818rtc code on targets without APIC, too)
+ *
+ *  Copyright (c) 2011  Jan Kiszka, Siemens AG
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 

[RFC PATCH-for-8.0] target/arm: Keep "internals.h" internal to target/arm/

2022-12-09 Thread Philippe Mathieu-Daudé
"target/arm/internals.h" is supposed to be *internal* to
target/arm/. hw/arm/virt.c includes it to get arm_pamax()
declaration. Move this declaration to "cpu.h" which can
be included out of target/arm/, and move the implementation
in machine.c which is always built with system emulation.

Signed-off-by: Philippe Mathieu-Daudé 
---
RFC: Do we need a new pair of c/h for architectural helpers?

ptw.c should be restricted to TCG.
---
 hw/arm/virt.c  |  2 +-
 target/arm/cpu.h   |  9 +
 target/arm/internals.h |  9 -
 target/arm/machine.c   | 39 +++
 target/arm/ptw.c   | 39 ---
 5 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b871350856..4528ca8da2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -70,7 +70,6 @@
 #include "standard-headers/linux/input.h"
 #include "hw/arm/smmuv3.h"
 #include "hw/acpi/acpi.h"
-#include "target/arm/internals.h"
 #include "hw/mem/memory-device.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
@@ -79,6 +78,7 @@
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/char/pl011.h"
 #include "qemu/guest-random.h"
+#include "target/arm/cpu.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
 static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9aeed3c848..8cdad4855f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3444,6 +3444,15 @@ static inline target_ulong cpu_untagged_addr(CPUState 
*cs, target_ulong x)
 }
 #endif
 
+/*
+ * arm_pamax
+ * @cpu: ARMCPU
+ *
+ * Returns the implementation defined bit-width of physical addresses.
+ * The ARMv8 reference manuals refer to this as PAMax().
+ */
+unsigned int arm_pamax(ARMCPU *cpu);
+
 /*
  * Naming convention for isar_feature functions:
  * Functions which test 32-bit ID registers should have _aa32_ in
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 161e42d50f..5e9546b6a3 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -241,15 +241,6 @@ static inline void update_spsel(CPUARMState *env, uint32_t 
imm)
 aarch64_restore_sp(env, cur_el);
 }
 
-/*
- * arm_pamax
- * @cpu: ARMCPU
- *
- * Returns the implementation defined bit-width of physical addresses.
- * The ARMv8 reference manuals refer to this as PAMax().
- */
-unsigned int arm_pamax(ARMCPU *cpu);
-
 /* Return true if extended addresses are enabled.
  * This is always the case if our translation regime is 64 bit,
  * but depends on TTBCR.EAE for 32 bit.
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 54c5c62433..51f84f90f0 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -6,6 +6,45 @@
 #include "internals.h"
 #include "migration/cpu.h"
 
+/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
+static const uint8_t pamax_map[] = {
+[0] = 32,
+[1] = 36,
+[2] = 40,
+[3] = 42,
+[4] = 44,
+[5] = 48,
+[6] = 52,
+};
+
+/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
+unsigned int arm_pamax(ARMCPU *cpu)
+{
+if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
+unsigned int parange =
+FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
+
+/*
+ * id_aa64mmfr0 is a read-only register so values outside of the
+ * supported mappings can be considered an implementation error.
+ */
+assert(parange < ARRAY_SIZE(pamax_map));
+return pamax_map[parange];
+}
+
+/*
+ * In machvirt_init, we call arm_pamax on a cpu that is not fully
+ * initialized, so we can't rely on the propagation done in realize.
+ */
+if (arm_feature(&cpu->env, ARM_FEATURE_LPAE) ||
+arm_feature(&cpu->env, ARM_FEATURE_V7VE)) {
+/* v7 with LPAE */
+return 40;
+}
+/* Anything else */
+return 32;
+}
+
 static bool vfp_needed(void *opaque)
 {
 ARMCPU *cpu = opaque;
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index f812734bfb..03703cb107 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -42,45 +42,6 @@ static bool get_phys_addr_with_struct(CPUARMState *env, 
S1Translate *ptw,
   ARMMMUFaultInfo *fi)
 __attribute__((nonnull));
 
-/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
-static const uint8_t pamax_map[] = {
-[0] = 32,
-[1] = 36,
-[2] = 40,
-[3] = 42,
-[4] = 44,
-[5] = 48,
-[6] = 52,
-};
-
-/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
-unsigned int arm_pamax(ARMCPU *cpu)
-{
-if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
-unsigned int parange =
-FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
-
-/*
- * id_aa64mmfr0 is a read-only register so values outside of the
- * supported mappings can be considered an impl

[PATCH 02/30] configure: remove dead function

2022-12-09 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 configure | 4 
 1 file changed, 4 deletions(-)

diff --git a/configure b/configure
index e31d4522ea63..543fd5a48bf0 100755
--- a/configure
+++ b/configure
@@ -210,10 +210,6 @@ version_ge () {
 done
 }
 
-glob() {
-eval test -z '"${1#'"$2"'}"'
-}
-
 if printf %s\\n "$source_path" "$PWD" | grep -q "[[:space:]:]";
 then
   error_exit "main directory cannot contain spaces nor colons"
-- 
2.38.1




[PATCH for-8.0 00/30] Meson changes for QEMU 8.0

2022-12-09 Thread Paolo Bonzini
The final bout of conversions removes the remaining compiler tests
for emulators, applies a few cleanups that are enabled by version 0.63
of Meson, and updates the documentation.

Committing this however requires first a libvirt-ci update, in order to
enable using Python 3.8/3.9 on CentOS 8 and SLES 15.  I am still working
on it but the review can start early for these patches.

A final comparison for the effort has a net negative of around 4000
lines of code, despite the growth of QEMU itself in the meanwhile:

  before after
--
 8647 configure 4240 meson.build
 1296 Makefile  1970 configure
  985 tests/Makefile.include 337 Makefile
  440 rules.mak  224 scripts/meson-buildoptions.py
  379 scripts/tap-driver.pl  171 tests/Makefile.include
  287 Makefile.target129 scripts/nsis.py
  263 tests/tcg/configure.sh 113 scripts/mtest2make.py
  129 scripts/create_config   48 scripts/undefsym.py
~5500 various Makefile fragments   ~6500 various meson.build files
--
17926 total13732 total

Completing the conversion took roughly two years and a lot of the complexity
in how QEMU is built is indeed essential, but I think it's agreed that:

- the disruption to the developers was minimal, and even Windows only took
  a month or so to solidify;

- there is overall feature parity for both configure/Makefile<->meson and for
  tap-driver.pl<->"meson test", but with fewer bugs and fewer (though not zero)
  workarounds required.  For Meson, the main recurring issue is probably the
  gnutls headers issue on Homebrew; see for example commit 76f67bac79f6,
  "meson: Propagate gnutls dependency to migration", 2021-04-01)

- the original target of the conversion ("make it trivial to do trivial
  things; easy to extend existing things; possible to do everything else")
  has been achieved.  New dependencies such as ninja, were introduced in
  such a way as to make them familiar to shell/Make users, and did
  provide subtle quality of life improvements (e.g. rebuild targets
  on command line changes)

New build system features since the introduction of Meson include switching
to config/targets files, custom device configuration (--with-devices-ARCH=),
the modinfo mechanism for module loading, entitlement support for
Hypervisor.framework, the preinstall tree, autogenerated parsing of the
configure command line, and cross-compilation of pc-bios/ (admittedly
not done by Meson, but not hindered either).

Big thanks to Akihiko, Alex, Daniel, Marc-André, Richard, Thomas and
everybody else that shared the work and the reviews!

Thanks,

Paolo

Paolo Bonzini (30):
  configure: remove useless write_c_skeleton
  configure: remove dead function
  configure: remove useless test
  configure: preserve qemu-ga variables
  configure: remove backwards-compatibility and obsolete options
  meson: tweak hardening options for Windows
  meson: support meson 0.64 -Doptimization=plain
  meson: require 0.63.0
  meson: use prefer_static option
  meson: remove static_kwargs
  meson: cleanup dummy-cpus.c rules
  modinfo: lookup compile_commands.json by object
  configure: remove backwards-compatibility code
  configure: test all warnings
  meson: cleanup compiler detection
  build: move glib detection and workarounds to meson
  configure: remove pkg-config functions
  configure, meson: move --enable-modules to Meson
  configure, meson: move --enable-debug-info to Meson
  meson: prepare move of QEMU_CFLAGS to meson
  build: move sanitizer tests to meson
  build: move SafeStack tests to meson
  build: move coroutine backend selection to meson
  build: move stack protector flag selection to meson
  build: move warning flag selection to meson
  build: move remaining compiler flag tests to meson
  build: move compiler version check to meson
  docs: update build system docs
  configure: do not rerun the tests with -Werror
  meson: always log qemu-iotests verbosely

 accel/meson.build |   9 +-
 block/meson.build |   1 +
 configure | 760 +-
 contrib/plugins/Makefile  |   7 +-
 docs/devel/build-system.rst   | 286 ---
 meson |   2 +-
 meson.build   | 684 +++-
 meson_options.txt |  13 +
 plugins/meson.build   |   2 +-
 qga/meson.build   |   2 +-
 scripts/meson-buildoptions.py |   3 +
 scripts/meson-buildoptions.sh |  22 +
 scripts/modinfo-collect.py|  23 +-
 tcg/meson.build

[PATCH 03/30] configure: remove useless test

2022-12-09 Thread Paolo Bonzini
$cpu is derived from preprocessor defines rather than uname these days,
so do not bother using isainfo on Solaris.  Likewise do not recognize
BeOS's uname -m output.

Signed-off-by: Paolo Bonzini 
---
 configure | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/configure b/configure
index 543fd5a48bf0..db2b45740449 100755
--- a/configure
+++ b/configure
@@ -337,9 +337,6 @@ for opt do
   ;;
   esac
 done
-# OS specific
-# Using uname is really, really broken.  Once we have the right set of checks
-# we can eliminate its usage altogether.
 
 # Preferred compiler:
 #  ${CC} (if set)
@@ -489,13 +486,6 @@ sunos)
   QEMU_CFLAGS="-D_XOPEN_SOURCE=600 $QEMU_CFLAGS"
 # needed for TIOCWIN* defines in termios.h
   QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS"
-  # $(uname -m) returns i86pc even on an x86_64 box, so default based on 
isainfo
-  # Note that this check is broken for cross-compilation: if you're
-  # cross-compiling to one of these OSes then you'll need to specify
-  # the correct CPU with the --cpu option.
-  if test -z "$cpu" && test "$(isainfo -k)" = "amd64"; then
-cpu="x86_64"
-  fi
 ;;
 haiku)
   pie="no"
@@ -559,7 +549,7 @@ case "$cpu" in
   armv*b|armv*l|arm)
 cpu="arm" ;;
 
-  i386|i486|i586|i686|i86pc|BePC)
+  i386|i486|i586|i686)
 cpu="i386"
 CPU_CFLAGS="-m32" ;;
   x32)
-- 
2.38.1




[PATCH 08/30] meson: require 0.63.0

2022-12-09 Thread Paolo Bonzini
This allows cleanups cleanups in modinfo collection and supports the
equivalent of QEMU's --static option to configure.

Signed-off-by: Paolo Bonzini 
---
 configure   | 2 +-
 meson   | 2 +-
 meson.build | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index adfff30a6204..411dfe977958 100755
--- a/configure
+++ b/configure
@@ -1043,7 +1043,7 @@ fi
 python="$python -B"
 
 if test -z "$meson"; then
-if test "$explicit_python" = no && has meson && version_ge "$(meson 
--version)" 0.61.5; then
+if test "$explicit_python" = no && has meson && version_ge "$(meson 
--version)" 0.63.0; then
 meson=meson
 elif test "$git_submodules_action" != 'ignore' ; then
 meson=git
diff --git a/meson b/meson
index 3a9b285a55b9..9c6dab2cfd31 16
--- a/meson
+++ b/meson
@@ -1 +1 @@
-Subproject commit 3a9b285a55b91b53b2acda987192274352ecb5be
+Subproject commit 9c6dab2cfd310ef2d840a2a7a479ce6b9e563b1d
diff --git a/meson.build b/meson.build
index dbd0b5563446..19b023985325 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project('qemu', ['c'], meson_version: '>=0.61.3',
+project('qemu', ['c'], meson_version: '>=0.63.0',
 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 
'b_colorout=auto',
   'b_staticpic=false', 'stdsplit=false', 
'optimization=2', 'b_pie=true'],
 version: files('VERSION'))
-- 
2.38.1




[PATCH 16/30] build: move glib detection and workarounds to meson

2022-12-09 Thread Paolo Bonzini
QEMU adds the path to glib.h is added to all compilation commands.
This is simpler due to the pervasive use of static_library, and was
grandfathered in from the previous Make-based build system.  Until
Meson 0.63 the only way to do this was to detect glib in configure
and use add_project_arguments, but now it is possible to use
add_project_dependencies instead.

gmodule is detected in a separate variable and added via both
block_ss (for --enable-modules) and plugins/meson.build (for
--enable-plugins).

Signed-off-by: Paolo Bonzini 
---
 block/meson.build|  1 +
 configure| 83 +---
 contrib/plugins/Makefile |  4 +-
 meson.build  | 81 +--
 plugins/meson.build  |  2 +-
 5 files changed, 74 insertions(+), 97 deletions(-)

diff --git a/block/meson.build b/block/meson.build
index b7c68b83a36f..f2e0e86f3b0a 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -145,6 +145,7 @@ block_gen_c = custom_target('block-gen.c',
 block_ss.add(block_gen_c)
 
 block_ss.add(files('stream.c'))
+block_ss.add(gmodule)
 
 softmmu_ss.add(files('qapi-sysemu.c'))
 
diff --git a/configure b/configure
index 9c5393a25de7..fb28dd3963bd 100755
--- a/configure
+++ b/configure
@@ -1426,84 +1426,6 @@ if ! has "$pkg_config_exe"; then
   error_exit "pkg-config binary '$pkg_config_exe' not found"
 fi
 
-##
-# glib support probe
-
-# When bumping glib_req_ver, please check also whether we should increase
-# the _WIN32_WINNT setting in osdep.h according to the value from glib
-glib_req_ver=2.56
-glib_modules=gthread-2.0
-if test "$modules" = yes; then
-glib_modules="$glib_modules gmodule-export-2.0"
-elif test "$plugins" = "yes"; then
-glib_modules="$glib_modules gmodule-no-export-2.0"
-fi
-
-for i in $glib_modules; do
-if $pkg_config --atleast-version=$glib_req_ver $i; then
-glib_cflags=$($pkg_config --cflags $i)
-glib_libs=$($pkg_config --libs $i)
-else
-error_exit "glib-$glib_req_ver $i is required to compile QEMU"
-fi
-done
-
-glib_bindir="$($pkg_config --variable=bindir glib-2.0)"
-if test -z "$glib_bindir" ; then
-   glib_bindir="$($pkg_config --variable=prefix glib-2.0)"/bin
-fi
-
-# This workaround is required due to a bug in pkg-config file for glib as it
-# doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
-
-if test "$static" = yes && test "$mingw32" = yes; then
-glib_cflags="-DGLIB_STATIC_COMPILATION $glib_cflags"
-fi
-
-# Sanity check that the current size_t matches the
-# size that glib thinks it should be. This catches
-# problems on multi-arch where people try to build
-# 32-bit QEMU while pointing at 64-bit glib headers
-cat > $TMPC <
-#include 
-
-#define QEMU_BUILD_BUG_ON(x) \
-  typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
-
-int main(void) {
-   QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
-   return 0;
-}
-EOF
-
-if ! compile_prog "$glib_cflags" "$glib_libs" ; then
-error_exit "sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T."\
-   "You probably need to set PKG_CONFIG_LIBDIR"\
-  "to point to the right pkg-config files for your"\
-  "build target"
-fi
-
-# Silence clang warnings triggered by glib < 2.57.2
-cat > $TMPC << EOF
-#include 
-typedef struct Foo {
-int i;
-} Foo;
-static void foo_free(Foo *f)
-{
-g_free(f);
-}
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
-int main(void) { return 0; }
-EOF
-if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
-if cc_has_warning_flag "-Wno-unused-function"; then
-glib_cflags="$glib_cflags -Wno-unused-function"
-CONFIGURE_CFLAGS="$CONFIGURE_CFLAGS -Wno-unused-function"
-fi
-fi
-
 ##
 # fdt probe
 
@@ -2361,13 +2283,10 @@ echo "PYTHON=$python" >> $config_host_mak
 echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
 echo "MESON=$meson" >> $config_host_mak
 echo "NINJA=$ninja" >> $config_host_mak
+echo "PKG_CONFIG=${pkg_config_exe}" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
 echo "QEMU_OBJCFLAGS=$QEMU_OBJCFLAGS" >> $config_host_mak
-echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
-echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
-echo "GLIB_BINDIR=$glib_bindir" >> $config_host_mak
-echo "GLIB_VERSION=$(pkg-config --modversion glib-2.0)" >> $config_host_mak
 echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
 echo "EXESUF=$EXESUF" >> $config_host_mak
 
diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile
index 23e0396687e8..8a316cd76f2f 100644
--- a/contrib/plugins/Makefile
+++ b/contrib/plugins/Makefile
@@ -3,7 +3,7 @@
 # This Makefile example is fairly independent from the main makefile
 # so users can take and adapt it for their build. We only really
 # include config-host.mak so we don't have to repeat probing for
-# cflags that the 

[PATCH 04/30] configure: preserve qemu-ga variables

2022-12-09 Thread Paolo Bonzini
Ensure that qemu-ga variables set at configure time are kept
later when the script is rerun.  For preserve_env to work,
the variables need to be empty so move the default values
to config-host.mak generation.

Signed-off-by: Paolo Bonzini 
---
 configure | 23 ++-
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/configure b/configure
index db2b45740449..4d14ff9c319c 100755
--- a/configure
+++ b/configure
@@ -,20 +,6 @@ if test "$have_ubsan" = "yes"; then
   QEMU_LDFLAGS="-fsanitize=undefined $QEMU_LDFLAGS"
 fi
 
-##
-# Guest agent Windows MSI package
-
-if test "$QEMU_GA_MANUFACTURER" = ""; then
-  QEMU_GA_MANUFACTURER=QEMU
-fi
-if test "$QEMU_GA_DISTRO" = ""; then
-  QEMU_GA_DISTRO=Linux
-fi
-if test "$QEMU_GA_VERSION" = ""; then
-QEMU_GA_VERSION=$(cat "$source_path"/VERSION)
-fi
-
-
 ###
 # cross-compiled firmware targets
 
@@ -2331,9 +2317,9 @@ if test "$debug_tcg" = "yes" ; then
 fi
 if test "$mingw32" = "yes" ; then
   echo "CONFIG_WIN32=y" >> $config_host_mak
-  echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER}" >> $config_host_mak
-  echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO}" >> $config_host_mak
-  echo "QEMU_GA_VERSION=${QEMU_GA_VERSION}" >> $config_host_mak
+  echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER-QEMU}" >> $config_host_mak
+  echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO-Linux}" >> $config_host_mak
+  echo "QEMU_GA_VERSION=${QEMU_GA_VERSION-$(cat "$source_path"/VERSION)}" >> 
$config_host_mak
 else
   echo "CONFIG_POSIX=y" >> $config_host_mak
 fi
@@ -2647,6 +2633,9 @@ preserve_env PKG_CONFIG
 preserve_env PKG_CONFIG_LIBDIR
 preserve_env PKG_CONFIG_PATH
 preserve_env PYTHON
+preserve_env QEMU_GA_MANUFACTURER
+preserve_env QEMU_GA_DISTRO
+preserve_env QEMU_GA_VERSION
 preserve_env SDL2_CONFIG
 preserve_env SMBD
 preserve_env STRIP
-- 
2.38.1




[PATCH 13/30] configure: remove backwards-compatibility code

2022-12-09 Thread Paolo Bonzini
The cmd_line.txt mangling is only needed when rebuilding from very old
trees and is kept mostly as an example of how to extend it.  However,
Meson 0.63 introduces a deprecation mechanism for meson_options.txt
that can be used instead, so get rid of our home-grown hack.

Signed-off-by: Paolo Bonzini 
---
 configure | 10 --
 1 file changed, 10 deletions(-)

diff --git a/configure b/configure
index 6efc2055ce09..113db838a16f 100755
--- a/configure
+++ b/configure
@@ -2556,16 +2556,6 @@ if test "$skip_meson" = no; then
   if test "$?" -ne 0 ; then
   error_exit "meson setup failed"
   fi
-else
-  if test -f meson-private/cmd_line.txt; then
-# Adjust old command line options whose type was changed
-# Avoids having to use "setup --wipe" when Meson is upgraded
-perl -i -ne '
-  s/^gettext = true$/gettext = auto/;
-  s/^gettext = false$/gettext = disabled/;
-  /^b_staticpic/ && next;
-  print;' meson-private/cmd_line.txt
-  fi
 fi
 
 # Save the configure command line for later reuse.
-- 
2.38.1




[PATCH 28/30] docs: update build system docs

2022-12-09 Thread Paolo Bonzini
Now that configure is only doing compiler and host setup, adjust the
relevant documentation.  It is also possible to build emulators with
ninja directly if one is so inclined.

Signed-off-by: Paolo Bonzini 
---
 docs/devel/build-system.rst | 275 +---
 1 file changed, 164 insertions(+), 111 deletions(-)

diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 4a733fc0a747..a25070fcaac8 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -4,30 +4,14 @@ The QEMU build system architecture
 
 This document aims to help developers understand the architecture of the
 QEMU build system. As with projects using GNU autotools, the QEMU build
-system has two stages, first the developer runs the "configure" script
+system has two stages; first the developer runs the "configure" script
 to determine the local build environment characteristics, then they run
-"make" to build the project. There is about where the similarities with
+"make" to build the project.  This is about where the similarities with
 GNU autotools end, so try to forget what you know about them.
 
+The two general ways to perform a build are as follows:
 
-Stage 1: configure
-==
-
-The QEMU configure script is written directly in shell, and should be
-compatible with any POSIX shell, hence it uses #!/bin/sh. An important
-implication of this is that it is important to avoid using bash-isms on
-development platforms where bash is the primary host.
-
-In contrast to autoconf scripts, QEMU's configure is expected to be
-silent while it is checking for features. It will only display output
-when an error occurs, or to show the final feature enablement summary
-on completion.
-
-Because QEMU uses the Meson build system under the hood, only VPATH
-builds are supported.  There are two general ways to invoke configure &
-perform a build:
-
- - VPATH, build artifacts outside of QEMU source tree entirely::
+ - build artifacts outside of QEMU source tree entirely::
 
  cd ../
  mkdir build
@@ -35,80 +19,114 @@ perform a build:
  ../qemu/configure
  make
 
- - VPATH, build artifacts in a subdir of QEMU source tree::
+ - build artifacts in a subdir of QEMU source tree::
 
  mkdir build
  cd build
  ../configure
  make
 
-The configure script automatically recognizes
-command line options for which a same-named Meson option exists;
-dashes in the command line are replaced with underscores.
+Most of the actual build process uses Meson under the hood, therefore
+build artifacts cannot be placed in the source tree itself.
 
-Many checks on the compilation environment are still found in configure
-rather than ``meson.build``, but new checks should be added directly to
-``meson.build``.
 
-Patches are also welcome to move existing checks from the configure
-phase to ``meson.build``.  When doing so, ensure that ``meson.build`` does
-not use anymore the keys that you have removed from ``config-host.mak``.
-Typically these will be replaced in ``meson.build`` by boolean variables,
-``get_option('optname')`` invocations, or ``dep.found()`` expressions.
-In general, the remaining checks have little or no interdependencies,
-so they can be moved one by one.
+Stage 1: configure
+==
 
-Helper functions
-
+The configure script has four tasks:
 
-The configure script provides a variety of helper functions to assist
-developers in checking for system features:
+ - detect the host architecture
 
-``do_cc $ARGS...``
-   Attempt to run the system C compiler passing it $ARGS...
+ - list the targets for which to build emulators; the list of
+   targets also affects which firmware binaries and tests to build
 
-``do_cxx $ARGS...``
-   Attempt to run the system C++ compiler passing it $ARGS...
+ - find the compilers (native and cross) used to build executables,
+   firmware and tests.  The results are written as either Makefile
+   fragments (``config-host.mak``) or a Meson machine file
+   (``config-meson.cross``)
 
-``compile_object $CFLAGS``
-   Attempt to compile a test program with the system C compiler using
-   $CFLAGS. The test program must have been previously written to a file
-   called $TMPC.  The replacement in Meson is the compiler object ``cc``,
-   which has methods such as ``cc.compiles()``,
-   ``cc.check_header()``, ``cc.has_function()``.
+ - invoke Meson to perform the actual configuration step for the
+   emulator build
 
-``compile_prog $CFLAGS $LDFLAGS``
-   Attempt to compile a test program with the system C compiler using
-   $CFLAGS and link it with the system linker using $LDFLAGS. The test
-   program must have been previously written to a file called $TMPC.
-   The replacement in Meson is ``cc.find_library()`` and ``cc.links()``.
+The configure script automatically recognizes command line options for
+which a same-named Meson option exists; dashes in the command line are
+replaced with underscores.
+
+Almo

[PATCH 14/30] configure: test all warnings

2022-12-09 Thread Paolo Bonzini
Some warnings are hardcoded in QEMU_CFLAGS and not tested.  There is
no particular reason to single out these five, as many more -W flags are
present on all the supported compilers.  For homogeneity when moving
the detection to meson, make them use the same warn_flags infrastructure.

Signed-off-by: Paolo Bonzini 
---
 configure | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 113db838a16f..9c5393a25de7 100755
--- a/configure
+++ b/configure
@@ -378,8 +378,6 @@ sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
 # 2s-complement style results. (Both clang and gcc agree that it
 # provides these semantics.)
 QEMU_CFLAGS="-fno-strict-aliasing -fno-common -fwrapv"
-QEMU_CFLAGS="-Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
-QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
 QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 
$QEMU_CFLAGS"
 
 QEMU_LDFLAGS=
@@ -1161,6 +1159,11 @@ fi
 # just silently disable some features, so it's too error prone.
 
 warn_flags=
+add_to warn_flags -Wundef
+add_to warn_flags -Wwrite-strings
+add_to warn_flags -Wmissing-prototypes
+add_to warn_flags -Wstrict-prototypes
+add_to warn_flags -Wredundant-decls
 add_to warn_flags -Wold-style-declaration
 add_to warn_flags -Wold-style-definition
 add_to warn_flags -Wtype-limits
-- 
2.38.1




[PATCH 10/30] meson: remove static_kwargs

2022-12-09 Thread Paolo Bonzini
After static_kwargs has been changed to an empty dictionary, it has
no functional effect and can be removed.

Signed-off-by: Paolo Bonzini 
---
 meson.build | 212 +++-
 tcg/meson.build |   2 +-
 2 files changed, 84 insertions(+), 130 deletions(-)

diff --git a/meson.build b/meson.build
index dced840bfbee..9ccbe0f6e4ee 100644
--- a/meson.build
+++ b/meson.build
@@ -18,7 +18,6 @@ sh = find_program('sh')
 cc = meson.get_compiler('c')
 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
 enable_modules = 'CONFIG_MODULES' in config_host
-static_kwargs = {}
 
 # Temporary directory used for files created while
 # configure runs. Since it is in the build directory
@@ -510,7 +509,7 @@ gdbus_codegen = not_found
 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
 if not get_option('gio').auto() or have_system
   gio = dependency('gio-2.0', required: get_option('gio'),
-   method: 'pkg-config', kwargs: static_kwargs)
+   method: 'pkg-config')
   if gio.found() and not cc.links('''
 #include 
 int main(void)
@@ -527,7 +526,7 @@ if not get_option('gio').auto() or have_system
 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
  required: get_option('gio'))
 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
-  method: 'pkg-config', kwargs: static_kwargs)
+  method: 'pkg-config')
 gio = declare_dependency(dependencies: [gio, gio_unix],
  version: gio.version())
   endif
@@ -540,20 +539,19 @@ endif
 lttng = not_found
 if 'ust' in get_option('trace_backends')
   lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
- method: 'pkg-config', kwargs: static_kwargs)
+ method: 'pkg-config')
 endif
 pixman = not_found
 if have_system or have_tools
   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
-  method: 'pkg-config', kwargs: static_kwargs)
+  method: 'pkg-config')
 endif
-zlib = dependency('zlib', required: true, kwargs: static_kwargs)
+zlib = dependency('zlib', required: true)
 
 libaio = not_found
 if not get_option('linux_aio').auto() or have_block
   libaio = cc.find_library('aio', has_headers: ['libaio.h'],
-   required: get_option('linux_aio'),
-   kwargs: static_kwargs)
+   required: get_option('linux_aio'))
 endif
 
 linux_io_uring_test = '''
@@ -566,7 +564,7 @@ linux_io_uring = not_found
 if not get_option('linux_io_uring').auto() or have_block
   linux_io_uring = dependency('liburing', version: '>=0.3',
   required: get_option('linux_io_uring'),
-  method: 'pkg-config', kwargs: static_kwargs)
+  method: 'pkg-config')
   if not cc.links(linux_io_uring_test)
 linux_io_uring = not_found
   endif
@@ -576,7 +574,7 @@ libnfs = not_found
 if not get_option('libnfs').auto() or have_block
   libnfs = dependency('libnfs', version: '>=1.9.3',
   required: get_option('libnfs'),
-  method: 'pkg-config', kwargs: static_kwargs)
+  method: 'pkg-config')
 endif
 
 libattr_test = '''
@@ -596,8 +594,7 @@ if get_option('attr').allowed()
 libattr = declare_dependency()
   else
 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
-  required: get_option('attr'),
-  kwargs: static_kwargs)
+  required: get_option('attr'))
 if libattr.found() and not \
   cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
   libattr = not_found
@@ -632,7 +629,7 @@ seccomp_has_sysrawrc = false
 if not get_option('seccomp').auto() or have_system or have_tools
   seccomp = dependency('libseccomp', version: '>=2.3.0',
required: get_option('seccomp'),
-   method: 'pkg-config', kwargs: static_kwargs)
+   method: 'pkg-config')
   if seccomp.found()
 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
 'SCMP_FLTATR_API_SYSRAWRC',
@@ -643,8 +640,7 @@ endif
 libcap_ng = not_found
 if not get_option('cap_ng').auto() or have_system or have_tools
   libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
-  required: get_option('cap_ng'),
-  kwargs: static_kwargs)
+  required: get_option('cap_ng'))
 endif
 if libcap_ng.found() and not cc.links('''
#include 
@@ -665,13 +661,13 @@ if get_option('xkbcommon').auto() and not have_system and 
not have_tools
   xkbcommon = not_found
 else
   xkbcommon = dependency('

[PATCH 30/30] meson: always log qemu-iotests verbosely

2022-12-09 Thread Paolo Bonzini
---
 tests/qemu-iotests/meson.build | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build
index 583468c5b9b3..3d8637c8f2b6 100644
--- a/tests/qemu-iotests/meson.build
+++ b/tests/qemu-iotests/meson.build
@@ -43,5 +43,6 @@ foreach format, speed: qemu_iotests_formats
protocol: 'tap',
suite: suites,
timeout: 0,
+   verbose: true,
is_parallel: false)
 endforeach
-- 
2.38.1




[PATCH 15/30] meson: cleanup compiler detection

2022-12-09 Thread Paolo Bonzini
Detect all compilers at the beginning of meson.build, and store
the available languages in an array.

Signed-off-by: Paolo Bonzini 
---
 meson.build | 62 ++---
 1 file changed, 35 insertions(+), 27 deletions(-)

diff --git a/meson.build b/meson.build
index 8a9ed5628317..c4fa82ae8ba4 100644
--- a/meson.build
+++ b/meson.build
@@ -15,9 +15,21 @@ ss = import('sourceset')
 fs = import('fs')
 
 sh = find_program('sh')
-cc = meson.get_compiler('c')
 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
 enable_modules = 'CONFIG_MODULES' in config_host
+targetos = host_machine.system()
+
+cc = meson.get_compiler('c')
+all_languages = ['c']
+if add_languages('cpp', required: false, native: false)
+  all_languages += ['cpp']
+  cxx = meson.get_compiler('cpp')
+endif
+if targetos == 'darwin' and \
+   add_languages('objc', required: get_option('cocoa'), native: false)
+  all_languages += ['objc']
+  objc = meson.get_compiler('objc')
+endif
 
 # Temporary directory used for files created while
 # configure runs. Since it is in the build directory
@@ -54,8 +66,6 @@ if cpu in ['riscv32', 'riscv64']
   cpu = 'riscv'
 endif
 
-targetos = host_machine.system()
-
 target_dirs = config_host['TARGET_DIRS'].split()
 have_linux_user = false
 have_bsd_user = false
@@ -161,7 +171,7 @@ if 'dtrace' in get_option('trace_backends')
 # semaphores are linked into the main binary and not the module's shared
 # object.
 add_global_arguments('-DSTAP_SDT_V2',
- native: false, language: ['c', 'cpp', 'objc'])
+ native: false, language: all_languages)
   endif
 endif
 
@@ -203,7 +213,7 @@ endif
 if get_option('fuzzing')
   add_project_link_arguments(['-Wl,-T,',
   (meson.current_source_dir() / 
'tests/qtest/fuzz/fork_fuzz.ld')],
- native: false, language: ['c', 'cpp', 'objc'])
+ native: false, language: all_languages)
 
   # Specify a filter to only instrument code that is directly related to
   # virtual-devices.
@@ -216,7 +226,7 @@ if get_option('fuzzing')
  args: ['-fsanitize-coverage-allowlist=/dev/null',
 '-fsanitize-coverage=trace-pc'] )
 
add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
- native: false, language: ['c', 'cpp', 'objc'])
+ native: false, language: all_languages)
   endif
 
   if get_option('fuzzing_engine') == ''
@@ -225,9 +235,9 @@ if get_option('fuzzing')
 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
 # unable to bind the fuzzer-related callbacks added by instrumentation.
 add_global_arguments('-fsanitize=fuzzer-no-link',
- native: false, language: ['c', 'cpp', 'objc'])
+ native: false, language: all_languages)
 add_global_link_arguments('-fsanitize=fuzzer-no-link',
-  native: false, language: ['c', 'cpp', 'objc'])
+  native: false, language: all_languages)
 # For the actual fuzzer binaries, we need to link against the libfuzzer
 # library. They need to be configurable, to support OSS-Fuzz
 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
@@ -238,15 +248,11 @@ if get_option('fuzzing')
   endif
 endif
 
-add_global_arguments(qemu_cflags, native: false, language: ['c'])
-add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
-
 # Check that the C++ compiler exists and works with the C compiler.
 link_language = 'c'
 linker = cc
 qemu_cxxflags = []
-if add_languages('cpp', required: false, native: false)
-  cxx = meson.get_compiler('cpp')
+if 'cpp' in all_languages
   add_global_arguments(['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', 
'-D__STDC_FORMAT_MACROS'],
native: false, language: 'cpp')
   foreach k: qemu_cflags
@@ -255,7 +261,6 @@ if add_languages('cpp', required: false, native: false)
   qemu_cxxflags += [k]
 endif
   endforeach
-  add_global_arguments(qemu_cxxflags, native: false, language: 'cpp')
 
   if cxx.links(files('scripts/main.c'), args: qemu_cflags)
 link_language = 'cpp'
@@ -271,22 +276,21 @@ if targetos != 'sunos' and not 
config_host.has_key('CONFIG_TSAN')
   qemu_ldflags += linker.get_supported_link_arguments('-Wl,--warn-common')
 endif
 
-add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 
'objc'])
+add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
 
+add_global_arguments(qemu_cflags, native: false, language: 'c')
+add_global_arguments(qemu_cxxflags, native: false, language: 'cpp')
+add_global_arguments(qemu_objcflags, native: false, language: 'objc')
 if targetos == 'linux'
   add_project_arguments('-isystem', meson.current_source_dir() / 
'linux-headers',
 '-isystem', 'linux-headers'

[PATCH 20/30] meson: prepare move of QEMU_CFLAGS to meson

2022-12-09 Thread Paolo Bonzini
Clean up the handling of compiler flags in meson.build, splitting
the general flags that should be included in subprojects as well,
from warning flags that only apply to QEMU itself.  The two were
mixed in both configure tests and meson tests.

This split makes it easier to move the compiler tests piecewise
from configure to Meson.

Signed-off-by: Paolo Bonzini 
---
 meson.build | 53 +
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/meson.build b/meson.build
index 99c1bde4d154..dac343d14797 100644
--- a/meson.build
+++ b/meson.build
@@ -190,10 +190,23 @@ endif
 # Compiler flags #
 ##
 
-qemu_cflags = config_host['QEMU_CFLAGS'].split()
+qemu_common_flags = []
+qemu_cflags = []
+foreach arg : config_host['QEMU_CFLAGS'].split()
+  if arg.startswith('-W')
+qemu_cflags += arg
+  else
+qemu_common_flags += arg
+  endif
+endforeach
 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
 
+if get_option('gprof')
+  qemu_common_flags += ['-p']
+  qemu_ldflags += ['-p']
+endif
+
 if get_option('prefer_static')
   qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
 endif
@@ -207,10 +220,9 @@ if targetos == 'windows'
   qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', 
'-Wl,--high-entropy-va')
 endif
 
-if get_option('gprof')
-  qemu_cflags += ['-p']
-  qemu_objcflags += ['-p']
-  qemu_ldflags += ['-p']
+# Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
+if targetos != 'sunos' and not config_host.has_key('CONFIG_TSAN')
+  qemu_ldflags += cc.get_supported_link_arguments('-Wl,--warn-common')
 endif
 
 # Specify linker-script with add_project_link_arguments so that it is not 
placed
@@ -230,8 +242,7 @@ if get_option('fuzzing')
   name: '-fsanitize-coverage-allowlist=/dev/null',
  args: ['-fsanitize-coverage-allowlist=/dev/null',
 '-fsanitize-coverage=trace-pc'] )
-
add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
- native: false, language: all_languages)
+qemu_common_flags += 
['-fsanitize-coverage-allowlist=instrumentation-filter']
   endif
 
   if get_option('fuzzing_engine') == ''
@@ -239,10 +250,8 @@ if get_option('fuzzing')
 # compiled code.  To build non-fuzzer binaries with --enable-fuzzing, link
 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
 # unable to bind the fuzzer-related callbacks added by instrumentation.
-add_global_arguments('-fsanitize=fuzzer-no-link',
- native: false, language: all_languages)
-add_global_link_arguments('-fsanitize=fuzzer-no-link',
-  native: false, language: all_languages)
+qemu_common_flags += ['-fsanitize=fuzzer-no-link']
+qemu_ldflags += ['-fsanitize=fuzzer-no-link']
 # For the actual fuzzer binaries, we need to link against the libfuzzer
 # library. They need to be configurable, to support OSS-Fuzz
 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
@@ -253,6 +262,9 @@ if get_option('fuzzing')
   endif
 endif
 
+add_global_arguments(qemu_common_flags, native: false, language: all_languages)
+add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
+
 # Check that the C++ compiler exists and works with the C compiler.
 link_language = 'c'
 linker = cc
@@ -276,16 +288,9 @@ if 'cpp' in all_languages
   endif
 endif
 
-# Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
-if targetos != 'sunos' and not config_host.has_key('CONFIG_TSAN')
-  qemu_ldflags += linker.get_supported_link_arguments('-Wl,--warn-common')
-endif
-
-add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
-
-add_global_arguments(qemu_cflags, native: false, language: 'c')
-add_global_arguments(qemu_cxxflags, native: false, language: 'cpp')
-add_global_arguments(qemu_objcflags, native: false, language: 'objc')
+add_project_arguments(qemu_cflags, native: false, language: 'c')
+add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
+add_project_arguments(qemu_objcflags, native: false, language: 'objc')
 if targetos == 'linux'
   add_project_arguments('-isystem', meson.current_source_dir() / 
'linux-headers',
 '-isystem', 'linux-headers',
@@ -3778,12 +3783,12 @@ link_args = get_option(link_language + '_link_args')
 if link_args.length() > 0
   summary_info += {'LDFLAGS': ' '.join(link_args)}
 endif
-summary_info += {'QEMU_CFLAGS':   ' '.join(qemu_cflags)}
+summary_info += {'QEMU_CFLAGS':   ' '.join(qemu_common_flags + 
qemu_cflags)}
 if 'cpp' in all_languages
-  summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
+  summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + 
qemu_cxxflags)}
 endif
 if 'objc' in all_languages
-  summary_info += {'QE

[PATCH 07/30] meson: support meson 0.64 -Doptimization=plain

2022-12-09 Thread Paolo Bonzini
In Meson 0.64, the optimization built-in option now accepts the "plain" value,
which will not set any optimization flags.  While QEMU does not check the
contents of the option and therefore does not suffer any ill effect
from the new value, it uses get_option to print the optimization flags
in the summary.  Clean the code up to remove duplication, and check for
-Doptimization=plain at the same time.

Signed-off-by: Paolo Bonzini 
---
 meson.build | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/meson.build b/meson.build
index d61c7a82f112..dbd0b5563446 100644
--- a/meson.build
+++ b/meson.build
@@ -3752,18 +3752,16 @@ endif
 if targetos == 'darwin'
   summary_info += {'Objective-C compiler': ' 
'.join(meson.get_compiler('objc').cmd_array())}
 endif
-summary_info += {'CFLAGS':' '.join(get_option('c_args')
-   + ['-O' + 
get_option('optimization')]
-   + (get_option('debug') ? ['-g'] 
: []))}
+option_cflags = (get_option('debug') ? ['-g'] : [])
+if get_option('optimization') != 'plain'
+  option_cflags += ['-O' + get_option('optimization')]
+endif
+summary_info += {'CFLAGS':' '.join(get_option('c_args') + 
option_cflags)}
 if link_language == 'cpp'
-  summary_info += {'CXXFLAGS':' '.join(get_option('cpp_args')
-   + ['-O' + 
get_option('optimization')]
-   + (get_option('debug') ? ['-g'] 
: []))}
+  summary_info += {'CXXFLAGS':' '.join(get_option('cpp_args') + 
option_cflags)}
 endif
 if targetos == 'darwin'
-  summary_info += {'OBJCFLAGS':   ' '.join(get_option('objc_args')
-   + ['-O' + 
get_option('optimization')]
-   + (get_option('debug') ? ['-g'] 
: []))}
+  summary_info += {'OBJCFLAGS':   ' '.join(get_option('objc_args') + 
option_cflags)}
 endif
 link_args = get_option(link_language + '_link_args')
 if link_args.length() > 0
-- 
2.38.1




[PATCH 06/30] meson: tweak hardening options for Windows

2022-12-09 Thread Paolo Bonzini
-Wl,--dynamicbase has been enabled for DLLs upstream for roughly 2
years (https://sourceware.org/bugzilla/show_bug.cgi?id=19011), and
also by some distros including Debian for 6 years even
(https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=836365), so
just enable it unconditionally.

Also add -Wl,--high-entropy-va.

Signed-off-by: Paolo Bonzini 
---
 meson.build | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/meson.build b/meson.build
index 5c6b5a1c757f..d61c7a82f112 100644
--- a/meson.build
+++ b/meson.build
@@ -193,10 +193,7 @@ qemu_ldflags += 
cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
 
 if targetos == 'windows'
   qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', 
'-Wl,--nxcompat')
-  # Disable ASLR for debug builds to allow debugging with gdb
-  if get_option('optimization') == '0'
-qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase')
-  endif
+  qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', 
'-Wl,--high-entropy-va')
 endif
 
 if get_option('gprof')
-- 
2.38.1




[PATCH 23/30] build: move coroutine backend selection to meson

2022-12-09 Thread Paolo Bonzini
To simplify the code, rename coroutine-win32.c to match the option
passed to configure.

Signed-off-by: Paolo Bonzini 
---
 configure | 62 ---
 meson.build   | 32 +-
 meson_options.txt |  3 +
 scripts/meson-buildoptions.py |  1 +
 scripts/meson-buildoptions.sh |  3 +
 ...{coroutine-win32.c => coroutine-windows.c} |  0
 util/meson.build  |  2 +-
 7 files changed, 38 insertions(+), 65 deletions(-)
 rename util/{coroutine-win32.c => coroutine-windows.c} (100%)

diff --git a/configure b/configure
index fea9cbf3abd0..1f7c5bbba4b9 100755
--- a/configure
+++ b/configure
@@ -275,7 +275,6 @@ softmmu="yes"
 linux_user=""
 bsd_user=""
 pie=""
-coroutine=""
 plugins="$default_feature"
 meson=""
 ninja=""
@@ -792,8 +791,6 @@ for opt do
   ;;
   --enable-fdt=*) fdt="$optarg"
   ;;
-  --with-coroutine=*) coroutine="$optarg"
-  ;;
   --with-git=*) git="$optarg"
   ;;
   --with-git-submodules=*)
@@ -949,8 +946,6 @@ Advanced options (experts only):
   --disable-werror disable compilation abort on warning
   --disable-stack-protector disable compiler-provided stack protection
   --cpu=CPUBuild for host CPU [$cpu]
-  --with-coroutine=BACKEND coroutine backend. Supported options:
-   ucontext, sigaltstack, windows
   --enable-plugins
enable plugins via shared library loading
   --disable-containers don't use containers for cross-building
@@ -1373,61 +1368,6 @@ case "$fdt" in
 ;;
 esac
 
-##
-# check and set a backend for coroutine
-
-# We prefer ucontext, but it's not always possible. The fallback
-# is sigcontext. On Windows the only valid backend is the Windows
-# specific one.
-
-ucontext_works=no
-if test "$darwin" != "yes"; then
-  cat > $TMPC << EOF
-#include 
-#ifdef __stub_makecontext
-#error Ignoring glibc stub makecontext which will always fail
-#endif
-int main(void) { makecontext(0, 0, 0); return 0; }
-EOF
-  if compile_prog "" "" ; then
-ucontext_works=yes
-  fi
-fi
-
-if test "$coroutine" = ""; then
-  if test "$mingw32" = "yes"; then
-coroutine=win32
-  elif test "$ucontext_works" = "yes"; then
-coroutine=ucontext
-  else
-coroutine=sigaltstack
-  fi
-else
-  case $coroutine in
-  windows)
-if test "$mingw32" != "yes"; then
-  error_exit "'windows' coroutine backend only valid for Windows"
-fi
-# Unfortunately the user visible backend name doesn't match the
-# coroutine-*.c filename for this case, so we have to adjust it here.
-coroutine=win32
-;;
-  ucontext)
-if test "$ucontext_works" != "yes"; then
-  error_exit "'ucontext' backend requested but makecontext not available"
-fi
-;;
-  sigaltstack)
-if test "$mingw32" = "yes"; then
-  error_exit "only the 'windows' coroutine backend is valid for Windows"
-fi
-;;
-  *)
-error_exit "unknown coroutine backend $coroutine"
-;;
-  esac
-fi
-
 
 # check if ccache is interfering with
 # semantic analysis of macros
@@ -2002,8 +1942,6 @@ if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak
 fi
 
-echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
-
 if test "$plugins" = "yes" ; then
 echo "CONFIG_PLUGIN=y" >> $config_host_mak
 fi
diff --git a/meson.build b/meson.build
index 7ee9f081d0a1..b9df49667a19 100644
--- a/meson.build
+++ b/meson.build
@@ -211,6 +211,34 @@ if get_option('prefer_static')
   qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
 endif
 
+coroutine_backend = get_option('coroutine_backend')
+ucontext_probe = '''
+  #include 
+  #ifdef __stub_makecontext
+  #error Ignoring glibc stub makecontext which will always fail
+  #endif
+  int main(void) { makecontext(0, 0, 0); return 0; }'''
+
+# On Windows the only valid backend is the Windows specific one.
+# For POSIX prefer ucontext, but it's not always possible. The fallback
+# is sigcontext.
+supported_backends = []
+if targetos == 'windows'
+  supported_backends += ['windows']
+else
+  if targetos != 'darwin' and cc.links(ucontext_probe)
+supported_backends += ['ucontext']
+  endif
+  supported_backends += ['sigaltstack']
+endif
+
+if coroutine_backend == 'auto'
+  coroutine_backend = supported_backends[0]
+elif coroutine_backend not in supported_backends
+  error('"@0@" backend requested but not available.  Available backends: @1@' \
+.format(coroutine_backend, ', '.join(supported_backends)))
+endif
+
 # Compiles if SafeStack *not* enabled
 safe_stack_probe = '''
   int main(void)
@@ -232,7 +260,7 @@ if get_option('safe_stack') != not 
cc.compiles(safe_stack_probe)
   qemu_cflags += safe_stack_arg
   qemu_ldflags += safe_stack_arg
 endif
-if get_option('safe_stack') and config_host['CONFIG_COROUTINE_BACKEND'] != 
'ucontext'
+if

[PATCH 17/30] configure: remove pkg-config functions

2022-12-09 Thread Paolo Bonzini
All uses of pkg-config have been moved to Meson.

Signed-off-by: Paolo Bonzini 
---
 configure   | 19 +++
 docs/devel/build-system.rst |  4 
 2 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/configure b/configure
index fb28dd3963bd..9c336203d8d9 100755
--- a/configure
+++ b/configure
@@ -365,11 +365,7 @@ smbd="$SMBD"
 strip="${STRIP-${cross_prefix}strip}"
 widl="${WIDL-${cross_prefix}widl}"
 windres="${WINDRES-${cross_prefix}windres}"
-pkg_config_exe="${PKG_CONFIG-${cross_prefix}pkg-config}"
-query_pkg_config() {
-"${pkg_config_exe}" ${QEMU_PKG_CONFIG_FLAGS} "$@"
-}
-pkg_config=query_pkg_config
+pkg_config="${PKG_CONFIG-${cross_prefix}pkg-config}"
 sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
 
 # default flags for all hosts
@@ -745,9 +741,7 @@ for opt do
   ;;
   --without-default-features) # processed above
   ;;
-  --static)
-static="yes"
-QEMU_PKG_CONFIG_FLAGS="--static $QEMU_PKG_CONFIG_FLAGS"
+  --static) static="yes"
   ;;
   --bindir=*) bindir="$optarg"
   ;;
@@ -1419,13 +1413,6 @@ EOF
   fi
 fi
 
-##
-# pkg-config probe
-
-if ! has "$pkg_config_exe"; then
-  error_exit "pkg-config binary '$pkg_config_exe' not found"
-fi
-
 ##
 # fdt probe
 
@@ -2423,7 +2410,7 @@ if test "$skip_meson" = no; then
   test -n "$objcc" && echo "objc = [$(meson_quote $objcc $CPU_CFLAGS)]" >> 
$cross
   echo "ar = [$(meson_quote $ar)]" >> $cross
   echo "nm = [$(meson_quote $nm)]" >> $cross
-  echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
+  echo "pkgconfig = [$(meson_quote $pkg_config)]" >> $cross
   echo "ranlib = [$(meson_quote $ranlib)]" >> $cross
   if has $sdl2_config; then
 echo "sdl2-config = [$(meson_quote $sdl2_config)]" >> $cross
diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 9db18aff159e..66cfe7b8bdc8 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -103,10 +103,6 @@ developers in checking for system features:
Print $MESSAGE to stderr, followed by $MORE... and then exit from the
configure script with non-zero status
 
-``query_pkg_config $ARGS...``
-   Run pkg-config passing it $ARGS. If QEMU is doing a static build,
-   then --static will be automatically added to $ARGS
-
 
 Stage 2: Meson
 ==
-- 
2.38.1




[PATCH 26/30] build: move remaining compiler flag tests to meson

2022-12-09 Thread Paolo Bonzini
Remove the only remaining uses of QEMU_CFLAGS.  Now that no
feature tests are done in configure, it is possible to remove
CONFIGURE_CFLAGS and CONFIGURE_LDFLAGS as well.

Signed-off-by: Paolo Bonzini 
---
 configure   | 79 -
 meson.build | 49 -
 2 files changed, 59 insertions(+), 69 deletions(-)

diff --git a/configure b/configure
index 6df61f4337e4..d5491fc3b986 100755
--- a/configure
+++ b/configure
@@ -158,14 +158,14 @@ do_cc() {
 
 compile_object() {
   local_cflags="$1"
-  do_cc $CFLAGS $EXTRA_CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -c 
-o $TMPO $TMPC
+  do_cc $CFLAGS $EXTRA_CFLAGS $local_cflags -c -o $TMPO $TMPC
 }
 
 compile_prog() {
   local_cflags="$1"
   local_ldflags="$2"
-  do_cc $CFLAGS $EXTRA_CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -o 
$TMPE $TMPC \
-  $LDFLAGS $EXTRA_LDFLAGS $CONFIGURE_LDFLAGS $local_ldflags
+  do_cc $CFLAGS $EXTRA_CFLAGS $local_cflags -o $TMPE $TMPC \
+  $LDFLAGS $EXTRA_LDFLAGS $local_ldflags
 }
 
 # symbolically link $1 to $2.  Portable version of "ln -sf".
@@ -351,19 +351,6 @@ windres="${WINDRES-${cross_prefix}windres}"
 pkg_config="${PKG_CONFIG-${cross_prefix}pkg-config}"
 sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
 
-# default flags for all hosts
-# We use -fwrapv to tell the compiler that we require a C dialect where
-# left shift of signed integers is well defined and has the expected
-# 2s-complement style results. (Both clang and gcc agree that it
-# provides these semantics.)
-QEMU_CFLAGS="-fno-strict-aliasing -fno-common -fwrapv"
-QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 
$QEMU_CFLAGS"
-
-# Flags that are needed during configure but later taken care of by Meson
-CONFIGURE_CFLAGS="-std=gnu11 -Wall"
-CONFIGURE_LDFLAGS=
-
-
 check_define() {
 cat > $TMPC < $TMPC << EOF
-static int sfaa(int *ptr)
-{
-  return __sync_fetch_and_and(ptr, 0);
-}
-
-int main(void)
-{
-  int val = 42;
-  val = __sync_val_compare_and_swap(&val, 0, 1);
-  sfaa(&val);
-  return val;
-}
-EOF
-  if ! compile_prog "" "" ; then
-QEMU_CFLAGS="-march=i486 $QEMU_CFLAGS"
-  fi
-fi
 
 if test -z "${target_list+xxx}" ; then
 default_targets=yes
@@ -1834,7 +1778,6 @@ echo "MESON=$meson" >> $config_host_mak
 echo "NINJA=$ninja" >> $config_host_mak
 echo "PKG_CONFIG=${pkg_config_exe}" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
-echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
 echo "EXESUF=$EXESUF" >> $config_host_mak
 
 # use included Linux headers
diff --git a/meson.build b/meson.build
index 4ec8104b73a3..01c6ac0045bc 100644
--- a/meson.build
+++ b/meson.build
@@ -190,10 +190,50 @@ endif
 # Compiler flags #
 ##
 
-qemu_common_flags = config_host['QEMU_CFLAGS'].split()
+# default flags for all hosts
+# We use -fwrapv to tell the compiler that we require a C dialect where
+# left shift of signed integers is well defined and has the expected
+# 2s-complement style results. (Both clang and gcc agree that it
+# provides these semantics.)
+
+qemu_common_flags = [
+  '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
+  '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
 qemu_cflags = []
 qemu_ldflags = []
 
+if targetos == 'darwin'
+  # Disable attempts to use ObjectiveC features in os/object.h since they
+  # won't work when we're compiling with gcc as a C compiler.
+  qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+elif targetos == 'solaris'
+  # needed for CMSG_ macros in sys/socket.h
+  qemu_common_flags += '-D_XOPEN_SOURCE=600'
+  # needed for TIOCWIN* defines in termios.h
+  qemu_common_flags += '-D__EXTENSIONS__'
+elif targetos == 'haiku'
+  qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', 
'-fPIC']
+endif
+
+# __sync_fetch_and_and requires at least -march=i486. Many toolchains
+# use i686 as default anyway, but for those that don't, an explicit
+# specification is necessary
+if host_arch == 'i386' and not cc.links('''
+  static int sfaa(int *ptr)
+  {
+return __sync_fetch_and_and(ptr, 0);
+  }
+
+  int main(void)
+  {
+int val = 42;
+val = __sync_val_compare_and_swap(&val, 0, 1);
+sfaa(&val);
+return val;
+  }''')
+  qemu_common_flags = ['-march=i486'] + qemu_common_flags
+endif
+
 if get_option('gprof')
   qemu_common_flags += ['-p']
   qemu_ldflags += ['-p']
@@ -203,6 +243,13 @@ if get_option('prefer_static')
   qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
 endif
 
+# Meson currently only handles pie as a boolean for now, so if the user
+# has explicitly disabled PIE we need to extend our cflags.
+if not get_option('b_pie')
+  qemu_cflags += cc.get_supported_arguments('-fno-pie')
+  qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
+endif
+
 if not get_option('stack_protector').disabled()
   stack_protector_probe = '''
 int main(int argc, char *argv[])
-- 
2.38.1




[PATCH 22/30] build: move SafeStack tests to meson

2022-12-09 Thread Paolo Bonzini
This disables the old behavior of detecting SafeStack from environment
CFLAGS.  SafeStack is now enabled purely based on the configure arguments.

Signed-off-by: Paolo Bonzini 
---
 configure | 73 ---
 meson.build   | 26 +
 meson_options.txt |  2 +
 scripts/meson-buildoptions.sh |  4 ++
 4 files changed, 32 insertions(+), 73 deletions(-)

diff --git a/configure b/configure
index babcf5d28a85..fea9cbf3abd0 100755
--- a/configure
+++ b/configure
@@ -222,7 +222,6 @@ cross_compile="no"
 cross_prefix=""
 host_cc="cc"
 stack_protector=""
-safe_stack=""
 use_containers="yes"
 gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
 
@@ -779,10 +778,6 @@ for opt do
   ;;
   --disable-stack-protector) stack_protector="no"
   ;;
-  --enable-safe-stack) safe_stack="yes"
-  ;;
-  --disable-safe-stack) safe_stack="no"
-  ;;
   --enable-cfi)
   cfi="true";
   meson_option_add -Db_lto=true
@@ -969,8 +964,6 @@ cat << EOF
   bsd-userall BSD usermode emulation targets
   pie Position Independent Executables
   debug-tcg   TCG debugging (default is disabled)
-  safe-stack  SafeStack Stack Smash Protection. Depends on
-  clang/llvm >= 3.7 and requires coroutine backend ucontext.
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -1435,68 +1428,6 @@ else
   esac
 fi
 
-##
-# SafeStack
-
-
-if test "$safe_stack" = "yes"; then
-cat > $TMPC << EOF
-int main(void)
-{
-#if ! __has_feature(safe_stack)
-#error SafeStack Disabled
-#endif
-return 0;
-}
-EOF
-  flag="-fsanitize=safe-stack"
-  # Check that safe-stack is supported and enabled.
-  if compile_prog "-Werror $flag" "$flag"; then
-# Flag needed both at compilation and at linking
-QEMU_CFLAGS="$QEMU_CFLAGS $flag"
-QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
-  else
-error_exit "SafeStack not supported by your compiler"
-  fi
-  if test "$coroutine" != "ucontext"; then
-error_exit "SafeStack is only supported by the coroutine backend ucontext"
-  fi
-else
-cat > $TMPC << EOF
-int main(void)
-{
-#if defined(__has_feature)
-#if __has_feature(safe_stack)
-#error SafeStack Enabled
-#endif
-#endif
-return 0;
-}
-EOF
-if test "$safe_stack" = "no"; then
-  # Make sure that safe-stack is disabled
-  if ! compile_prog "-Werror" ""; then
-# SafeStack was already enabled, try to explicitly remove the feature
-flag="-fno-sanitize=safe-stack"
-if ! compile_prog "-Werror $flag" "$flag"; then
-  error_exit "Configure cannot disable SafeStack"
-fi
-QEMU_CFLAGS="$QEMU_CFLAGS $flag"
-QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
-  fi
-else # "$safe_stack" = ""
-  # Set safe_stack to yes or no based on pre-existing flags
-  if compile_prog "-Werror" ""; then
-safe_stack="no"
-  else
-safe_stack="yes"
-if test "$coroutine" != "ucontext"; then
-  error_exit "SafeStack is only supported by the coroutine backend 
ucontext"
-fi
-  fi
-fi
-fi
-
 
 # check if ccache is interfering with
 # semantic analysis of macros
@@ -2153,10 +2084,6 @@ if test "$ccache_cpp2" = "yes"; then
   echo "export CCACHE_CPP2=y" >> $config_host_mak
 fi
 
-if test "$safe_stack" = "yes"; then
-  echo "CONFIG_SAFESTACK=y" >> $config_host_mak
-fi
-
 # tests/tcg configuration
 (config_host_mak=tests/tcg/config-host.mak
 mkdir -p tests/tcg
diff --git a/meson.build b/meson.build
index 41a45fa495b2..7ee9f081d0a1 100644
--- a/meson.build
+++ b/meson.build
@@ -211,6 +211,31 @@ if get_option('prefer_static')
   qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
 endif
 
+# Compiles if SafeStack *not* enabled
+safe_stack_probe = '''
+  int main(void)
+  {
+  #if defined(__has_feature)
+  #if __has_feature(safe_stack)
+  #error SafeStack Enabled
+  #endif
+  #endif
+  return 0;
+  }'''
+if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
+  safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : 
'-fno-sanitize=safe-stack'
+  if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: 
safe_stack_arg)
+error(get_option('safe_stack') \
+  ? 'SafeStack not supported by your compiler' \
+  : 'Cannot disable SafeStack')
+  endif
+  qemu_cflags += safe_stack_arg
+  qemu_ldflags += safe_stack_arg
+endif
+if get_option('safe_stack') and config_host['CONFIG_COROUTINE_BACKEND'] != 
'ucontext'
+  error('SafeStack is only supported with the ucontext coroutine backend')
+endif
+
 if get_option('sanitizers')
   if cc.has_argument('-fsanitize=address')
 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
@@ -1928,6 +1953,7 @@ config_host_data.set('CONFIG_OPENGL', opengl.found())
 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
 config_host_data.set('CONFIG_RBD', rbd.found())
 config_host_data.set('CONFIG_RDMA', rdma.found())
+config_host_data.

[PATCH 21/30] build: move sanitizer tests to meson

2022-12-09 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 configure  | 151 -
 docs/devel/build-system.rst|   4 -
 meson.build|  63 +-
 meson_options.txt  |   4 +
 scripts/meson-buildoptions.sh  |   6 ++
 tests/qemu-iotests/meson.build |   2 +-
 tests/unit/meson.build |   2 +-
 7 files changed, 73 insertions(+), 159 deletions(-)

diff --git a/configure b/configure
index b0df6c3cf754..babcf5d28a85 100755
--- a/configure
+++ b/configure
@@ -269,9 +269,6 @@ EXTRA_OBJCFLAGS=""
 EXTRA_LDFLAGS=""
 
 debug_tcg="no"
-sanitizers="no"
-tsan="no"
-fortify_source="yes"
 EXESUF=""
 prefix="/usr/local"
 qemu_suffix="qemu"
@@ -392,14 +389,6 @@ EOF
   compile_object
 }
 
-check_include() {
-cat > $TMPC <
-int main(void) { return 0; }
-EOF
-  compile_object
-}
-
 write_c_skeleton() {
 cat > $TMPC < /dev/null 2>&1 ; then
-fortify_source="no";
-  elif test -n "$cxx" && has $cxx &&
-   echo | $cxx -dM -E - | grep __clang__ >/dev/null 2>&1 ; then
-fortify_source="no";
-  else
-fortify_source="yes"
-  fi
-fi
-
-##
-# checks for sanitizers
-
-have_asan=no
-have_ubsan=no
-have_asan_iface_h=no
-have_asan_iface_fiber=no
-
-if test "$sanitizers" = "yes" ; then
-  write_c_skeleton
-  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address" ""; then
-  have_asan=yes
-  fi
-
-  # we could use a simple skeleton for flags checks, but this also
-  # detect the static linking issue of ubsan, see also:
-  # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
-  cat > $TMPC << EOF
-#include 
-int main(void) {
-void *tmp = malloc(10);
-if (tmp != NULL) {
-return *(int *)(tmp + 2);
-}
-return 1;
-}
-EOF
-  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=undefined" ""; then
-  have_ubsan=yes
-  fi
-
-  if check_include "sanitizer/asan_interface.h" ; then
-  have_asan_iface_h=yes
-  fi
-
-  cat > $TMPC << EOF
-#include 
-int main(void) {
-  __sanitizer_start_switch_fiber(0, 0, 0);
-  return 0;
-}
-EOF
-  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address" "" ; then
-  have_asan_iface_fiber=yes
-  fi
-fi
-
-# Thread sanitizer is, for now, much noisier than the other sanitizers;
-# keep it separate until that is not the case.
-if test "$tsan" = "yes" && test "$sanitizers" = "yes"; then
-  error_exit "TSAN is not supported with other sanitiziers."
-fi
-have_tsan=no
-have_tsan_iface_fiber=no
-if test "$tsan" = "yes" ; then
-  write_c_skeleton
-  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=thread" "" ; then
-  have_tsan=yes
-  fi
-  cat > $TMPC << EOF
-#include 
-int main(void) {
-  __tsan_create_fiber(0);
-  return 0;
-}
-EOF
-  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=thread" "" ; then
-  have_tsan_iface_fiber=yes
-  fi
-fi
-
 ##
 # functions to probe cross compilers
 
@@ -2057,42 +1950,6 @@ case "$vfio_user_server" in
 ;;
 esac
 
-##
-# End of CC checks
-# After here, no more $cc or $ld runs
-
-write_c_skeleton
-
-if test "$fortify_source" = "yes" ; then
-  QEMU_CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
-fi
-
-if test "$have_asan" = "yes"; then
-  QEMU_CFLAGS="-fsanitize=address $QEMU_CFLAGS"
-  QEMU_LDFLAGS="-fsanitize=address $QEMU_LDFLAGS"
-  if test "$have_asan_iface_h" = "no" ; then
-  echo "ASAN build enabled, but ASAN header missing." \
-   "Without code annotation, the report may be inferior."
-  elif test "$have_asan_iface_fiber" = "no" ; then
-  echo "ASAN build enabled, but ASAN header is too old." \
-   "Without code annotation, the report may be inferior."
-  fi
-fi
-if test "$have_tsan" = "yes" ; then
-  if test "$have_tsan_iface_fiber" = "yes" ; then
-QEMU_CFLAGS="-fsanitize=thread $QEMU_CFLAGS"
-QEMU_LDFLAGS="-fsanitize=thread $QEMU_LDFLAGS"
-  else
-error_exit "Cannot enable TSAN due to missing fiber annotation interface."
-  fi
-elif test "$tsan" = "yes" ; then
-  error_exit "Cannot enable TSAN due to missing sanitize thread interface."
-fi
-if test "$have_ubsan" = "yes"; then
-  QEMU_CFLAGS="-fsanitize=undefined $QEMU_CFLAGS"
-  QEMU_LDFLAGS="-fsanitize=undefined $QEMU_LDFLAGS"
-fi
-
 ###
 # cross-compiled firmware targets
 
@@ -2216,14 +2073,6 @@ fi
 
 echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
 
-if test "$have_asan_iface_fiber" = "yes" ; then
-echo "CONFIG_ASAN_IFACE_FIBER=y" >> $config_host_mak
-fi
-
-if test "$have_tsan" = "yes" && test "$have_tsan_iface_fiber" = "yes" ; then
-echo "CONFIG_TSAN=y" >> $config_host_mak
-fi
-
 if test "$plugins" = "yes" ; then
 echo "CONFIG_PLUGIN=y" >> $config_host_mak
 fi
diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 66cfe7b8bdc8..4a733fc0a747 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -91,10 +91,6 @@ developers in checki

[PATCH 09/30] meson: use prefer_static option

2022-12-09 Thread Paolo Bonzini
The option is new in Meson 0.63 and removes the need to pass "static:
true" to all dependency and find_library invocation.  Actually cleaning
up the invocations is left for a separate patch.

Signed-off-by: Paolo Bonzini 
---
 configure   |  4 +---
 docs/devel/build-system.rst |  3 +--
 meson.build | 11 ---
 qga/meson.build |  2 +-
 4 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/configure b/configure
index 411dfe977958..6efc2055ce09 100755
--- a/configure
+++ b/configure
@@ -2315,9 +2315,6 @@ fi
 if test "$solaris" = "yes" ; then
   echo "CONFIG_SOLARIS=y" >> $config_host_mak
 fi
-if test "$static" = "yes" ; then
-  echo "CONFIG_STATIC=y" >> $config_host_mak
-fi
 echo "SRC_PATH=$source_path" >> $config_host_mak
 echo "TARGET_DIRS=$target_list" >> $config_host_mak
 if test "$modules" = "yes"; then
@@ -2540,6 +2537,7 @@ if test "$skip_meson" = no; then
   # Built-in options
   test "$bindir" != "bin" && meson_option_add "-Dbindir=$bindir"
   test "$default_feature" = no && meson_option_add -Dauto_features=disabled
+  test "$static" = yes && meson_option_add -Dprefer_static=true
   test "$pie" = no && meson_option_add -Db_pie=false
   test "$werror" = yes && meson_option_add -Dwerror=true
 
diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 189472174340..9db18aff159e 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -311,8 +311,7 @@ dependency will be used::
   sdl_image = not_found
   if not get_option('sdl_image').auto() or have_system
 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
-   method: 'pkg-config',
-   static: enable_static)
+   method: 'pkg-config')
   endif
 
 This avoids warnings on static builds of user-mode emulators, for example.
diff --git a/meson.build b/meson.build
index 19b023985325..dced840bfbee 100644
--- a/meson.build
+++ b/meson.build
@@ -18,10 +18,7 @@ sh = find_program('sh')
 cc = meson.get_compiler('c')
 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
 enable_modules = 'CONFIG_MODULES' in config_host
-enable_static = 'CONFIG_STATIC' in config_host
-
-# Allow both shared and static libraries unless --enable-static
-static_kwargs = enable_static ? {'static': true} : {}
+static_kwargs = {}
 
 # Temporary directory used for files created while
 # configure runs. Since it is in the build directory
@@ -183,7 +180,7 @@ qemu_cflags = config_host['QEMU_CFLAGS'].split()
 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
 
-if enable_static
+if get_option('prefer_static')
   qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
 endif
 
@@ -830,7 +827,7 @@ if targetos == 'linux' and have_tools and 
get_option('mpath').allowed()
 kwargs: static_kwargs)
   if libmpathpersist.found()
 mpathlibs += libmpathpersist
-if enable_static
+if get_option('prefer_static')
   mpathlibs += cc.find_library('devmapper',
  required: get_option('mpath'),
  kwargs: static_kwargs)
@@ -1214,7 +1211,7 @@ if not gnutls_crypto.found()
 # Debian has removed -lgpg-error from libgcrypt-config
 # as it "spreads unnecessary dependencies" which in
 # turn breaks static builds...
-if gcrypt.found() and enable_static
+if gcrypt.found() and get_option('prefer_static')
   gcrypt = declare_dependency(dependencies: [
 gcrypt,
 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
diff --git a/qga/meson.build b/qga/meson.build
index 3cfb9166e5d8..ec67326b25f3 100644
--- a/qga/meson.build
+++ b/qga/meson.build
@@ -22,7 +22,7 @@ have_qga_vss = get_option('qga_vss') \
 Then run configure with: --extra-cxxflags="-isystem 
/path/to/vss/inc/win2003"''') \
   .require(midl.found() or widl.found(),
error_message: 'VSS support requires midl or widl') \
-  .require(not enable_static,
+  .require(not get_option('prefer_static'),
error_message: 'VSS support requires dynamic linking with GLib') \
   .allowed()
 
-- 
2.38.1




[PATCH 27/30] build: move compiler version check to meson

2022-12-09 Thread Paolo Bonzini
Instead of checking with preprocessor defines, use the Meson compiler object.
Because of the mess Apple does with its versioning scheme, check for an
option that was added in clang 6.0 instead of looking at the version number.

Signed-off-by: Paolo Bonzini 
---
 configure   | 25 -
 meson.build | 11 +++
 2 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/configure b/configure
index d5491fc3b986..a7c95535fd01 100755
--- a/configure
+++ b/configure
@@ -1033,31 +1033,6 @@ if test "$targetos" = "bogus"; then
 error_exit "Unrecognized host OS (uname -s reports '$(uname -s)')"
 fi
 
-# Check whether the compiler matches our minimum requirements:
-cat > $TMPC << EOF
-#if defined(__clang_major__) && defined(__clang_minor__)
-# ifdef __apple_build_version__
-#  if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
-#   error You need at least XCode Clang v10.0 to compile QEMU
-#  endif
-# else
-#  if __clang_major__ < 6 || (__clang_major__ == 6 && __clang_minor__ < 0)
-#   error You need at least Clang v6.0 to compile QEMU
-#  endif
-# endif
-#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
-# if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 4)
-#  error You need at least GCC v7.4.0 to compile QEMU
-# endif
-#else
-# error You either need GCC or Clang to compiler QEMU
-#endif
-int main (void) { return 0; }
-EOF
-if ! compile_prog "" "" ; then
-error_exit "You need at least GCC v7.4 or Clang v6.0 (or XCode Clang 
v10.0)"
-fi
-
 # Resolve default for --enable-plugins
 if test "$static" = "yes" ; then
   if test "$plugins" = "yes"; then
diff --git a/meson.build b/meson.build
index 01c6ac0045bc..3316ff005cfc 100644
--- a/meson.build
+++ b/meson.build
@@ -190,6 +190,17 @@ endif
 # Compiler flags #
 ##
 
+foreach lang : all_languages
+  compiler = meson.get_compiler(lang)
+  if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
+# ok
+  elif compiler.get_id() == 'clang' and compiler.has_argument('-Wpragma-pack')
+# ok
+  else
+error('You either need GCC v7.4 or Clang v6.0 (or XCode Clang v10.0) to 
compile QEMU')
+  endif
+endforeach
+
 # default flags for all hosts
 # We use -fwrapv to tell the compiler that we require a C dialect where
 # left shift of signed integers is well defined and has the expected
-- 
2.38.1




Re: [RFC PATCH-for-8.0] target/arm: Keep "internals.h" internal to target/arm/

2022-12-09 Thread Peter Maydell
On Fri, 9 Dec 2022 at 11:17, Philippe Mathieu-Daudé  wrote:
>
> "target/arm/internals.h" is supposed to be *internal* to
> target/arm/. hw/arm/virt.c includes it to get arm_pamax()
> declaration. Move this declaration to "cpu.h" which can
> be included out of target/arm/, and move the implementation
> in machine.c which is always built with system emulation.

machine.c doesn't seem like the right place for this --
that file is purely concerned with migration. I don't know
why we use 'machine.c' as our name for the file where the
target CPU migration code lives, but that's fairly consistently
what we name it across all architectures and we don't put
other stuff in that file. I suppose it would be less confusing
to rename all those files to migration.c...

thanks
-- PMM



[PATCH v2] scripts/archive-source: Use GNU tar on Darwin

2022-12-09 Thread Philippe Mathieu-Daudé
When using the archive-source.sh script on Darwin we get:

  tar: Option --concatenate is not supported
  Usage:
List:tar -tf 
Extract: tar -xf 
Create:  tar -cf  [filenames...]
Help:tar --help

'tar' default to the BSD implementation:

  $ tar --version
  bsdtar 3.5.3 - libarchive 3.5.3 zlib/1.2.11 liblzma/5.0.5 bz2lib/1.0.8

Try to use the GNU implementation if it is available (from homebrew).

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Philippe Mathieu-Daudé 
---
Supersedes: <20221208162051.29509-1-phi...@linaro.org>
---
 scripts/archive-source.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/archive-source.sh b/scripts/archive-source.sh
index 23e042dacd..e3d0c23fe5 100755
--- a/scripts/archive-source.sh
+++ b/scripts/archive-source.sh
@@ -18,6 +18,7 @@ if test $# -lt 1; then
 error "Usage: $0 "
 fi
 
+test $(uname -s) = "Darwin" && tar=gtar || tar=tar
 tar_file=$(realpath "$1")
 sub_tdir=$(mktemp -d "${tar_file%.tar}.sub.")
 sub_file="${sub_tdir}/submodule.tar"
@@ -67,7 +68,7 @@ for sm in $submodules; do
 esac
 (cd $sm; git archive --format tar --prefix "$sm/" $(tree_ish)) > 
"$sub_file"
 test $? -ne 0 && error "failed to archive submodule $sm ($smhash)"
-tar --concatenate --file "$tar_file" "$sub_file"
+$tar --concatenate --file "$tar_file" "$sub_file"
 test $? -ne 0 && error "failed append submodule $sm to $tar_file"
 done
 exit 0
-- 
2.38.1




[PATCH 12/30] modinfo: lookup compile_commands.json by object

2022-12-09 Thread Paolo Bonzini
With Meson 0.63 having fixed various issues with extract_objects, the
compile_commands.json lookups can be simplified.  If the lookup uses
the object file as key, there is no need to use the command line to
distinguish among all entries for a given source.

Cc: Gerd Hoffmann 
Signed-off-by: Paolo Bonzini 
---
 meson.build| 14 --
 scripts/modinfo-collect.py | 23 +++
 2 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/meson.build b/meson.build
index 9ccbe0f6e4ee..8a9ed5628317 100644
--- a/meson.build
+++ b/meson.build
@@ -3123,16 +3123,11 @@ foreach d, list : modules
 softmmu_mods += sl
   endif
   if module_ss.sources() != []
-# FIXME: Should use sl.extract_all_objects(recursive: true) as
-# input. Sources can be used multiple times but objects are
-# unique when it comes to lookup in compile_commands.json.
-# Depnds on a mesion version with
-# https://github.com/mesonbuild/meson/pull/8900
 modinfo_files += custom_target(d + '-' + m + '.modinfo',
output: d + '-' + m + '.modinfo',
-   input: module_ss.sources() + genh,
+   input: 
sl.extract_all_objects(recursive: true),
capture: true,
-   command: [modinfo_collect, 
module_ss.sources()])
+   command: [modinfo_collect, '@INPUT@'])
   endif
 else
   if d == 'block'
@@ -3165,12 +3160,11 @@ foreach d, list : target_modules
 c_args: c_args,
 pic: true)
 softmmu_mods += sl
-# FIXME: Should use sl.extract_all_objects(recursive: true) too.
 modinfo_files += custom_target(module_name + '.modinfo',
output: module_name + '.modinfo',
-   input: target_module_ss.sources() + 
genh,
+   input: 
sl.extract_all_objects(recursive: true),
capture: true,
-   command: [modinfo_collect, 
'--target', target, target_module_ss.sources()])
+   command: [modinfo_collect, 
'--target', target, '@INPUT@'])
   endif
 endif
   endforeach
diff --git a/scripts/modinfo-collect.py b/scripts/modinfo-collect.py
index 4e7584df6676..48bd92bd6180 100755
--- a/scripts/modinfo-collect.py
+++ b/scripts/modinfo-collect.py
@@ -7,15 +7,6 @@
 import shlex
 import subprocess
 
-def find_command(src, target, compile_commands):
-for command in compile_commands:
-if command['file'] != src:
-continue
-if target != '' and command['command'].find(target) == -1:
-continue
-return command['command']
-return 'false'
-
 def process_command(src, command):
 skip = False
 out = []
@@ -43,14 +34,22 @@ def main(args):
 print("MODINFO_DEBUG target %s" % target)
 arch = target[:-8] # cut '-softmmu'
 print("MODINFO_START arch \"%s\" MODINFO_END" % arch)
+
 with open('compile_commands.json') as f:
-compile_commands = json.load(f)
-for src in args:
+compile_commands_json = json.load(f)
+compile_commands = { x['output']: x for x in compile_commands_json }
+
+for obj in args:
+entry = compile_commands.get(obj, None)
+if not entry:
+sys.stderr.print('modinfo: Could not find object file', obj)
+sys.exit(1)
+src = entry['file']
 if not src.endswith('.c'):
 print("MODINFO_DEBUG skip %s" % src)
 continue
+command = entry['command']
 print("MODINFO_DEBUG src %s" % src)
-command = find_command(src, target, compile_commands)
 cmdline = process_command(src, command)
 print("MODINFO_DEBUG cmd", cmdline)
 result = subprocess.run(cmdline, stdout = subprocess.PIPE,
-- 
2.38.1




Re: [PATCH 02/30] configure: remove dead function

2022-12-09 Thread Peter Maydell
On Fri, 9 Dec 2022 at 11:25, Paolo Bonzini  wrote:
>
> Signed-off-by: Paolo Bonzini 
> ---
>  configure | 4 
>  1 file changed, 4 deletions(-)
>
> diff --git a/configure b/configure
> index e31d4522ea63..543fd5a48bf0 100755
> --- a/configure
> +++ b/configure
> @@ -210,10 +210,6 @@ version_ge () {
>  done
>  }
>
> -glob() {
> -eval test -z '"${1#'"$2"'}"'
> -}
> -
>  if printf %s\\n "$source_path" "$PWD" | grep -q "[[:space:]:]";
>  then
>error_exit "main directory cannot contain spaces nor colons"
> --
Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH 03/30] configure: remove useless test

2022-12-09 Thread Peter Maydell
On Fri, 9 Dec 2022 at 11:25, Paolo Bonzini  wrote:
>
> $cpu is derived from preprocessor defines rather than uname these days,
> so do not bother using isainfo on Solaris.  Likewise do not recognize
> BeOS's uname -m output.
>
> Signed-off-by: Paolo Bonzini 
> ---
>  configure | 12 +---
>  1 file changed, 1 insertion(+), 11 deletions(-)
>
> diff --git a/configure b/configure
> index 543fd5a48bf0..db2b45740449 100755
> --- a/configure
> +++ b/configure
> @@ -337,9 +337,6 @@ for opt do
>;;
>esac
>  done
> -# OS specific
> -# Using uname is really, really broken.  Once we have the right set of checks
> -# we can eliminate its usage altogether.

I note that the fallback if we match no #defines is still "use uname".
We can only get rid of that if we're willing to say "must be a
known host architecture, even if using TCI", though. Or we could
force the 1 person using that setup to specify --cpu manually, perhaps.

>  # Preferred compiler:
>  #  ${CC} (if set)
> @@ -489,13 +486,6 @@ sunos)
>QEMU_CFLAGS="-D_XOPEN_SOURCE=600 $QEMU_CFLAGS"
>  # needed for TIOCWIN* defines in termios.h
>QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS"
> -  # $(uname -m) returns i86pc even on an x86_64 box, so default based on 
> isainfo
> -  # Note that this check is broken for cross-compilation: if you're
> -  # cross-compiling to one of these OSes then you'll need to specify
> -  # the correct CPU with the --cpu option.
> -  if test -z "$cpu" && test "$(isainfo -k)" = "amd64"; then
> -cpu="x86_64"
> -  fi

I found a random stackoverflow answer that says the Solaris
compiler does define the __x86_64__ macro that we check for, so
this should be OK.

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH 01/30] configure: remove useless write_c_skeleton

2022-12-09 Thread Peter Maydell
On Fri, 9 Dec 2022 at 11:26, Paolo Bonzini  wrote:
>
> This is not needed ever since QEMU stopped detecting -liberty; this
> happened with the Meson switch but it is quite likely that the
> library was not really necessary years before.
>
> Signed-off-by: Paolo Bonzini 
> ---
>  configure | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/configure b/configure
> index 26c7bc515468..e31d4522ea63 100755
> --- a/configure
> +++ b/configure
> @@ -638,7 +638,6 @@ if test "$mingw32" = "yes" ; then
>EXESUF=".exe"
># MinGW needs -mthreads for TLS and macro _MT.
>CONFIGURE_CFLAGS="-mthreads $CONFIGURE_CFLAGS"
> -  write_c_skeleton;
>prefix="/qemu"
>bindir=""
>qemu_suffix=""
> --
> 2.38.1

Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH 24/30] build: move stack protector flag selection to meson

2022-12-09 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 configure | 44 ++-
 meson.build   | 28 +-
 meson_options.txt |  2 ++
 scripts/meson-buildoptions.sh |  3 +++
 4 files changed, 34 insertions(+), 43 deletions(-)

diff --git a/configure b/configure
index 1f7c5bbba4b9..5d31294f316f 100755
--- a/configure
+++ b/configure
@@ -175,7 +175,7 @@ compile_prog() {
   local_cflags="$1"
   local_ldflags="$2"
   do_cc $CFLAGS $EXTRA_CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -o 
$TMPE $TMPC \
-  $LDFLAGS $EXTRA_LDFLAGS $CONFIGURE_LDFLAGS $QEMU_LDFLAGS $local_ldflags
+  $LDFLAGS $EXTRA_LDFLAGS $CONFIGURE_LDFLAGS $local_ldflags
 }
 
 # symbolically link $1 to $2.  Portable version of "ln -sf".
@@ -221,7 +221,6 @@ static="no"
 cross_compile="no"
 cross_prefix=""
 host_cc="cc"
-stack_protector=""
 use_containers="yes"
 gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
 
@@ -370,8 +369,6 @@ sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
 QEMU_CFLAGS="-fno-strict-aliasing -fno-common -fwrapv"
 QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 
$QEMU_CFLAGS"
 
-QEMU_LDFLAGS=
-
 # Flags that are needed during configure but later taken care of by Meson
 CONFIGURE_CFLAGS="-std=gnu11 -Wall"
 CONFIGURE_LDFLAGS=
@@ -773,10 +770,6 @@ for opt do
   ;;
   --disable-werror) werror="no"
   ;;
-  --enable-stack-protector) stack_protector="yes"
-  ;;
-  --disable-stack-protector) stack_protector="no"
-  ;;
   --enable-cfi)
   cfi="true";
   meson_option_add -Db_lto=true
@@ -944,7 +937,6 @@ Advanced options (experts only):
   --with-devices-ARCH=NAME override default configs/devices
   --enable-debug   enable common debug build options
   --disable-werror disable compilation abort on warning
-  --disable-stack-protector disable compiler-provided stack protection
   --cpu=CPUBuild for host CPU [$cpu]
   --enable-plugins
enable plugins via shared library loading
@@ -1157,7 +1149,7 @@ EOF
 optflag="$(echo $1 | sed -e 's/^-Wno-/-W/')"
 do_objc -Werror $optflag \
   $OBJCFLAGS $EXTRA_OBJCFLAGS $CONFIGURE_OBJCFLAGS $QEMU_OBJCFLAGS \
-  -o $TMPE $TMPM $QEMU_LDFLAGS
+  -o $TMPE $TMPM
 }
 
 for flag in $gcc_flags; do
@@ -1169,37 +1161,6 @@ for flag in $gcc_flags; do
 fi
 done
 
-if test "$stack_protector" != "no"; then
-  cat > $TMPC << EOF
-int main(int argc, char *argv[])
-{
-char arr[64], *p = arr, *c = argv[argc - 1];
-while (*c) {
-*p++ = *c++;
-}
-return 0;
-}
-EOF
-  gcc_flags="-fstack-protector-strong -fstack-protector-all"
-  sp_on=0
-  for flag in $gcc_flags; do
-# We need to check both a compile and a link, since some compiler
-# setups fail only on a .c->.o compile and some only at link time
-if compile_object "-Werror $flag" &&
-   compile_prog "-Werror $flag" ""; then
-  QEMU_CFLAGS="$QEMU_CFLAGS $flag"
-  QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
-  sp_on=1
-  break
-fi
-  done
-  if test "$stack_protector" = yes; then
-if test $sp_on = 0; then
-  error_exit "Stack protector not supported"
-fi
-  fi
-fi
-
 # Disable -Wmissing-braces on older compilers that warn even for
 # the "universal" C zero initializer {0}.
 cat > $TMPC << EOF
@@ -1968,7 +1929,6 @@ echo "PKG_CONFIG=${pkg_config_exe}" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
 echo "QEMU_OBJCFLAGS=$QEMU_OBJCFLAGS" >> $config_host_mak
-echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
 echo "EXESUF=$EXESUF" >> $config_host_mak
 
 # use included Linux headers
diff --git a/meson.build b/meson.build
index b9df49667a19..c5a8dce9e1d6 100644
--- a/meson.build
+++ b/meson.build
@@ -200,7 +200,7 @@ foreach arg : config_host['QEMU_CFLAGS'].split()
   endif
 endforeach
 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
-qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
+qemu_ldflags = []
 
 if get_option('gprof')
   qemu_common_flags += ['-p']
@@ -211,6 +211,32 @@ if get_option('prefer_static')
   qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
 endif
 
+if not get_option('stack_protector').disabled()
+  stack_protector_probe = '''
+int main(int argc, char *argv[])
+{
+  char arr[64], *p = arr, *c = argv[argc - 1];
+  while (*c) {
+  *p++ = *c++;
+  }
+  return 0;
+}'''
+  have_stack_protector = false
+  foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
+# We need to check both a compile and a link, since some compiler
+# setups fail only on a .c->.o compile and some only at link time
+if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
+   cc.links(stack_protector_probe, args: ['-Werror', arg])
+  have_stack_protector = true
+  qemu_cflags += arg
+  qemu_ldflags += arg
+  break
+endif
+  endforeach
+  get_

[PATCH 29/30] configure: do not rerun the tests with -Werror

2022-12-09 Thread Paolo Bonzini
Tests run in configure are pretty trivial at this point, so
do not bother with the extra complication of running tests
both with and without -Werror.

Signed-off-by: Paolo Bonzini 
---
 configure | 35 +--
 1 file changed, 1 insertion(+), 34 deletions(-)

diff --git a/configure b/configure
index a7c95535fd01..745745ded35b 100755
--- a/configure
+++ b/configure
@@ -119,41 +119,8 @@ lines: ${BASH_LINENO[*]}"
   $compiler "$@" >> config.log 2>&1 || return $?
 }
 
-do_compiler_werror() {
-# Run the compiler, capturing its output to the log. First argument
-# is compiler binary to execute.
-compiler="$1"
-shift
-if test -n "$BASH_VERSION"; then eval '
-echo >>config.log "
-funcs: ${FUNCNAME[*]}
-lines: ${BASH_LINENO[*]}"
-'; fi
-echo $compiler "$@" >> config.log
-$compiler "$@" >> config.log 2>&1 || return $?
-# Test passed. If this is an --enable-werror build, rerun
-# the test with -Werror and bail out if it fails. This
-# makes warning-generating-errors in configure test code
-# obvious to developers.
-if test "$werror" != "yes"; then
-return 0
-fi
-# Don't bother rerunning the compile if we were already using -Werror
-case "$*" in
-*-Werror*)
-   return 0
-;;
-esac
-echo $compiler -Werror "$@" >> config.log
-$compiler -Werror "$@" >> config.log 2>&1 && return $?
-error_exit "configure test passed without -Werror but failed with 
-Werror." \
-"This is probably a bug in the configure script. The failing command" \
-"will be at the bottom of config.log." \
-"You can run configure with --disable-werror to bypass this check."
-}
-
 do_cc() {
-do_compiler_werror "$cc" $CPU_CFLAGS "$@"
+do_compiler "$cc" $CPU_CFLAGS "$@"
 }
 
 compile_object() {
-- 
2.38.1




[PATCH 05/30] configure: remove backwards-compatibility and obsolete options

2022-12-09 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 configure | 20 
 1 file changed, 20 deletions(-)

diff --git a/configure b/configure
index 4d14ff9c319c..adfff30a6204 100755
--- a/configure
+++ b/configure
@@ -838,17 +838,6 @@ for opt do
   ;;
   --with-coroutine=*) coroutine="$optarg"
   ;;
-  --disable-zlib-test)
-  ;;
-  --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
-  echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2
-  ;;
-  --enable-vhdx|--disable-vhdx)
-  echo "$0: $opt is obsolete, VHDX driver is always built" >&2
-  ;;
-  --enable-uuid|--disable-uuid)
-  echo "$0: $opt is obsolete, UUID support is always built" >&2
-  ;;
   --with-git=*) git="$optarg"
   ;;
   --with-git-submodules=*)
@@ -868,19 +857,10 @@ for opt do
   ;;
   --gdb=*) gdb_bin="$optarg"
   ;;
-  # backwards compatibility options
-  --enable-trace-backend=*) meson_option_parse 
"--enable-trace-backends=$optarg" "$optarg"
-  ;;
-  --disable-blobs) meson_option_parse --disable-install-blobs ""
-  ;;
   --enable-vfio-user-server) vfio_user_server="enabled"
   ;;
   --disable-vfio-user-server) vfio_user_server="disabled"
   ;;
-  --enable-tcmalloc) meson_option_parse --enable-malloc=tcmalloc tcmalloc
-  ;;
-  --enable-jemalloc) meson_option_parse --enable-malloc=jemalloc jemalloc
-  ;;
   # everything else has the same name in configure and meson
   --*) meson_option_parse "$opt" "$optarg"
   ;;
-- 
2.38.1




[PATCH 19/30] configure, meson: move --enable-debug-info to Meson

2022-12-09 Thread Paolo Bonzini
Older versions of Meson had an unclear description of the -Ddebug option,
but this is fixed in 0.63.0 that is required now.

Signed-off-by: Paolo Bonzini 
---
 configure | 5 -
 scripts/meson-buildoptions.py | 2 ++
 scripts/meson-buildoptions.sh | 3 +++
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index 26d10aeffd82..b0df6c3cf754 100755
--- a/configure
+++ b/configure
@@ -700,10 +700,6 @@ for opt do
   ;;
   --cross-prefix-*)
   ;;
-  --enable-debug-info) meson_option_add -Ddebug=true
-  ;;
-  --disable-debug-info) meson_option_add -Ddebug=false
-  ;;
   --cpu=*)
   ;;
   --target-list=*) target_list="$optarg"
@@ -995,7 +991,6 @@ cat << EOF
   bsd-userall BSD usermode emulation targets
   pie Position Independent Executables
   debug-tcg   TCG debugging (default is disabled)
-  debug-info  debugging information
   safe-stack  SafeStack Stack Smash Protection. Depends on
   clang/llvm >= 3.7 and requires coroutine backend ucontext.
 
diff --git a/scripts/meson-buildoptions.py b/scripts/meson-buildoptions.py
index 3e2b4785388f..8e4e5c4e8bd6 100755
--- a/scripts/meson-buildoptions.py
+++ b/scripts/meson-buildoptions.py
@@ -35,6 +35,7 @@
 OPTION_NAMES = {
 "b_coverage": "gcov",
 "b_lto": "lto",
+"debug": "debug-info",
 "malloc": "enable-malloc",
 "pkgversion": "with-pkgversion",
 "qemu_firmwarepath": "firmwarepath",
@@ -45,6 +46,7 @@
 BUILTIN_OPTIONS = {
 "b_coverage",
 "b_lto",
+"debug",
 "datadir",
 "includedir",
 "libdir",
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index f91797741eef..cb277347bb18 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -10,6 +10,7 @@ meson_options_help() {
   printf "%s\n" '   affects only QEMU, not tools like 
qemu-img)'
   printf "%s\n" '  --datadir=VALUE  Data file directory [share]'
   printf "%s\n" '  --disable-coroutine-pool coroutine freelist (better 
performance)'
+  printf "%s\n" '  --disable-debug-info Enable debug symbols and other 
information'
   printf "%s\n" '  --disable-install-blobs  install provided firmware blobs'
   printf "%s\n" '  --docdir=VALUE   Base directory for documentation 
installation'
   printf "%s\n" '   (can be empty) [share/doc]'
@@ -242,6 +243,8 @@ _meson_option_parse() {
 --datadir=*) quote_sh "-Ddatadir=$2" ;;
 --enable-dbus-display) printf "%s" -Ddbus_display=enabled ;;
 --disable-dbus-display) printf "%s" -Ddbus_display=disabled ;;
+--enable-debug-info) printf "%s" -Ddebug=true ;;
+--disable-debug-info) printf "%s" -Ddebug=false ;;
 --enable-debug-mutex) printf "%s" -Ddebug_mutex=true ;;
 --disable-debug-mutex) printf "%s" -Ddebug_mutex=false ;;
 --enable-debug-stack-usage) printf "%s" -Ddebug_stack_usage=true ;;
-- 
2.38.1




[PATCH 18/30] configure, meson: move --enable-modules to Meson

2022-12-09 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 configure | 21 +
 meson.build   |  7 ++-
 meson_options.txt |  2 ++
 scripts/meson-buildoptions.sh |  3 +++
 4 files changed, 12 insertions(+), 21 deletions(-)

diff --git a/configure b/configure
index 9c336203d8d9..26d10aeffd82 100755
--- a/configure
+++ b/configure
@@ -273,7 +273,6 @@ sanitizers="no"
 tsan="no"
 fortify_source="yes"
 EXESUF=""
-modules="no"
 prefix="/usr/local"
 qemu_suffix="qemu"
 softmmu="yes"
@@ -705,12 +704,6 @@ for opt do
   ;;
   --disable-debug-info) meson_option_add -Ddebug=false
   ;;
-  --enable-modules)
-  modules="yes"
-  ;;
-  --disable-modules)
-  modules="no"
-  ;;
   --cpu=*)
   ;;
   --target-list=*) target_list="$optarg"
@@ -1001,7 +994,6 @@ cat << EOF
   linux-user  all linux usermode emulation targets
   bsd-userall BSD usermode emulation targets
   pie Position Independent Executables
-  modules modules support (non-Windows)
   debug-tcg   TCG debugging (default is disabled)
   debug-info  debugging information
   safe-stack  SafeStack Stack Smash Protection. Depends on
@@ -1260,16 +1252,8 @@ else
   QEMU_CFLAGS="$QEMU_CFLAGS -Wno-missing-braces"
 fi
 
-# Our module code doesn't support Windows
-if test "$modules" = "yes" && test "$mingw32" = "yes" ; then
-  error_exit "Modules are not available for Windows"
-fi
-
-# Static linking is not possible with plugins, modules or PIE
+# Resolve default for --enable-plugins
 if test "$static" = "yes" ; then
-  if test "$modules" = "yes" ; then
-error_exit "static and modules are mutually incompatible"
-  fi
   if test "$plugins" = "yes"; then
 error_exit "static and plugins are mutually incompatible"
   else
@@ -2229,9 +2213,6 @@ if test "$solaris" = "yes" ; then
 fi
 echo "SRC_PATH=$source_path" >> $config_host_mak
 echo "TARGET_DIRS=$target_list" >> $config_host_mak
-if test "$modules" = "yes"; then
-  echo "CONFIG_MODULES=y" >> $config_host_mak
-fi
 
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
diff --git a/meson.build b/meson.build
index f63ab7f83bed..99c1bde4d154 100644
--- a/meson.build
+++ b/meson.build
@@ -16,7 +16,6 @@ fs = import('fs')
 
 sh = find_program('sh')
 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
-enable_modules = 'CONFIG_MODULES' in config_host
 targetos = host_machine.system()
 
 cc = meson.get_compiler('c')
@@ -84,6 +83,12 @@ have_ga = get_option('guest_agent') \
   .require(targetos in ['sunos', 'linux', 'windows', 'freebsd'],
error_message: 'unsupported OS for QEMU guest agent') \
   .allowed()
+enable_modules = get_option('modules') \
+  .require(targetos != 'windows',
+   error_message: 'Modules are not available for Windows') \
+  .require(not get_option('prefer_static'),
+   error_message: 'Modules are incompatible with static linking') \
+  .allowed()
 have_block = have_system or have_tools
 
 python = import('python').find_installation()
diff --git a/meson_options.txt b/meson_options.txt
index 4b749ca54900..e492aaa73fbc 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -44,6 +44,8 @@ option('fuzzing', type : 'boolean', value: false,
description: 'build fuzzing targets')
 option('gettext', type : 'feature', value : 'auto',
description: 'Localization of the GTK+ user interface')
+option('modules', type : 'feature', value : 'disabled',
+   description: 'modules support (non Windows)')
 option('module_upgrades', type : 'boolean', value : false,
description: 'try to load modules from alternate paths for upgrades')
 option('install_blobs', type : 'boolean', value : true,
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index aa6e30ea911e..f91797741eef 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -119,6 +119,7 @@ meson_options_help() {
   printf "%s\n" '  lzo lzo compression support'
   printf "%s\n" '  malloc-trim enable libc malloc_trim() for memory 
optimization'
   printf "%s\n" '  membarrier  membarrier system call (for Linux 4.14+ or 
Windows'
+  printf "%s\n" '  modules modules support (non Windows)'
   printf "%s\n" '  mpath   Multipath persistent reservation 
passthrough'
   printf "%s\n" '  multiprocessOut of process device emulation support'
   printf "%s\n" '  netmap  netmap network backend support'
@@ -338,6 +339,8 @@ _meson_option_parse() {
 --disable-membarrier) printf "%s" -Dmembarrier=disabled ;;
 --enable-module-upgrades) printf "%s" -Dmodule_upgrades=true ;;
 --disable-module-upgrades) printf "%s" -Dmodule_upgrades=false ;;
+--enable-modules) printf "%s" -Dmodules=enabled ;;
+--disable-modules) printf "%s" -Dmodules=disabled ;;
 --enable-mpath) printf "%s" -Dmpath=enabled ;;
 --disable-mpath) printf "%s" -Dmpath=disabled ;;
 --enable-multiprocess) printf "%s" -Dmultiprocess=enabled

[PATCH 25/30] build: move warning flag selection to meson

2022-12-09 Thread Paolo Bonzini
Meson already knows to test with the positive form of the flag, which
simplifies the test.  Warnings are now tested explicitly for the C++
compiler, instead of hardcoding those that are only available for
the C language.

At this point all compiler flags in QEMU_CFLAGS are global and only
depend on the OS.  No feature tests are performed in configure.

Signed-off-by: Paolo Bonzini 
---
 configure| 94 
 contrib/plugins/Makefile |  3 +-
 meson.build  | 72 --
 3 files changed, 51 insertions(+), 118 deletions(-)

diff --git a/configure b/configure
index 5d31294f316f..6df61f4337e4 100755
--- a/configure
+++ b/configure
@@ -75,7 +75,6 @@ fi
 TMPB="qemu-conf"
 TMPC="${TMPDIR1}/${TMPB}.c"
 TMPO="${TMPDIR1}/${TMPB}.o"
-TMPM="${TMPDIR1}/${TMPB}.m"
 TMPE="${TMPDIR1}/${TMPB}.exe"
 
 rm -f config.log
@@ -157,15 +156,6 @@ do_cc() {
 do_compiler_werror "$cc" $CPU_CFLAGS "$@"
 }
 
-do_objc() {
-do_compiler_werror "$objcc" $CPU_CFLAGS "$@"
-}
-
-# Append $2 to the variable named $1, with space separation
-add_to() {
-eval $1=\${$1:+\"\$$1 \"}\$2
-}
-
 compile_object() {
   local_cflags="$1"
   do_cc $CFLAGS $EXTRA_CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -c 
-o $TMPO $TMPC
@@ -1091,89 +1081,6 @@ if ! compile_prog "" "" ; then
 error_exit "You need at least GCC v7.4 or Clang v6.0 (or XCode Clang 
v10.0)"
 fi
 
-# Accumulate -Wfoo and -Wno-bar separately.
-# We will list all of the enable flags first, and the disable flags second.
-# Note that we do not add -Werror, because that would enable it for all
-# configure tests. If a configure test failed due to -Werror this would
-# just silently disable some features, so it's too error prone.
-
-warn_flags=
-add_to warn_flags -Wundef
-add_to warn_flags -Wwrite-strings
-add_to warn_flags -Wmissing-prototypes
-add_to warn_flags -Wstrict-prototypes
-add_to warn_flags -Wredundant-decls
-add_to warn_flags -Wold-style-declaration
-add_to warn_flags -Wold-style-definition
-add_to warn_flags -Wtype-limits
-add_to warn_flags -Wformat-security
-add_to warn_flags -Wformat-y2k
-add_to warn_flags -Winit-self
-add_to warn_flags -Wignored-qualifiers
-add_to warn_flags -Wempty-body
-add_to warn_flags -Wnested-externs
-add_to warn_flags -Wendif-labels
-add_to warn_flags -Wexpansion-to-defined
-add_to warn_flags -Wimplicit-fallthrough=2
-
-nowarn_flags=
-add_to nowarn_flags -Wno-initializer-overrides
-add_to nowarn_flags -Wno-missing-include-dirs
-add_to nowarn_flags -Wno-shift-negative-value
-add_to nowarn_flags -Wno-string-plus-int
-add_to nowarn_flags -Wno-typedef-redefinition
-add_to nowarn_flags -Wno-tautological-type-limit-compare
-add_to nowarn_flags -Wno-psabi
-add_to nowarn_flags -Wno-gnu-variable-sized-type-not-at-end
-
-gcc_flags="$warn_flags $nowarn_flags"
-
-cc_has_warning_flag() {
-write_c_skeleton;
-
-# Use the positive sense of the flag when testing for -Wno-wombat
-# support (gcc will happily accept the -Wno- form of unknown
-# warning options).
-optflag="$(echo $1 | sed -e 's/^-Wno-/-W/')"
-compile_prog "-Werror $optflag" ""
-}
-
-objcc_has_warning_flag() {
-cat > $TMPM < $TMPC << EOF
-struct {
-  int a[2];
-} x = {0};
-EOF
-if compile_object "-Werror" "" ; then
-  :
-else
-  QEMU_CFLAGS="$QEMU_CFLAGS -Wno-missing-braces"
-fi
-
 # Resolve default for --enable-plugins
 if test "$static" = "yes" ; then
   if test "$plugins" = "yes"; then
@@ -1928,7 +1835,6 @@ echo "NINJA=$ninja" >> $config_host_mak
 echo "PKG_CONFIG=${pkg_config_exe}" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
-echo "QEMU_OBJCFLAGS=$QEMU_OBJCFLAGS" >> $config_host_mak
 echo "EXESUF=$EXESUF" >> $config_host_mak
 
 # use included Linux headers
diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile
index 8a316cd76f2f..b2b9db9f51af 100644
--- a/contrib/plugins/Makefile
+++ b/contrib/plugins/Makefile
@@ -27,8 +27,7 @@ SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
 # The main QEMU uses Glib extensively so it's perfectly fine to use it
 # in plugins (which many example do).
 CFLAGS := $(shell $(PKG_CONFIG) --cflags glib-2.0)
-CFLAGS += -fPIC -Wall $(filter -W%, $(QEMU_CFLAGS))
-CFLAGS += $(if $(findstring no-psabi,$(QEMU_CFLAGS)),-Wpsabi)
+CFLAGS += -fPIC -Wall
 CFLAGS += $(if $(CONFIG_DEBUG_TCG), -ggdb -O0)
 CFLAGS += -I$(SRC_PATH)/include/qemu
 
diff --git a/meson.build b/meson.build
index c5a8dce9e1d6..4ec8104b73a3 100644
--- a/meson.build
+++ b/meson.build
@@ -190,16 +190,8 @@ endif
 # Compiler flags #
 ##
 
-qemu_common_flags = []
+qemu_common_flags = config_host['QEMU_CFLAGS'].split()
 qemu_cflags = []
-foreach arg : config_host['QEMU_CFLAGS'].split()
-  if arg.startswith('-W')
-qemu_cflags += arg
-  else
-qemu_common_flags += arg
-  endif
-endforeach
-qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
 qemu_ldflags = []
 
 if get_option('gprof')
@@ -380,20 +

[PATCH 11/30] meson: cleanup dummy-cpus.c rules

2022-12-09 Thread Paolo Bonzini
Now that qtest is available on all targets including Windows, dummy-cpus.c
is included unconditionally in the build.

Signed-off-by: Paolo Bonzini 
---
 accel/meson.build | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/accel/meson.build b/accel/meson.build
index 259c35c4c882..3a480cc2efef 100644
--- a/accel/meson.build
+++ b/accel/meson.build
@@ -11,10 +11,5 @@ if have_system
   subdir('stubs')
 endif
 
-dummy_ss = ss.source_set()
-dummy_ss.add(files(
-  'dummy-cpus.c',
-))
-
-specific_ss.add_all(when: ['CONFIG_SOFTMMU'], if_true: dummy_ss)
-specific_ss.add_all(when: ['CONFIG_XEN'], if_true: dummy_ss)
+# qtest
+softmmu_ss.add(files('dummy-cpus.c'))
-- 
2.38.1




[PATCH 01/30] configure: remove useless write_c_skeleton

2022-12-09 Thread Paolo Bonzini
This is not needed ever since QEMU stopped detecting -liberty; this
happened with the Meson switch but it is quite likely that the
library was not really necessary years before.

Signed-off-by: Paolo Bonzini 
---
 configure | 1 -
 1 file changed, 1 deletion(-)

diff --git a/configure b/configure
index 26c7bc515468..e31d4522ea63 100755
--- a/configure
+++ b/configure
@@ -638,7 +638,6 @@ if test "$mingw32" = "yes" ; then
   EXESUF=".exe"
   # MinGW needs -mthreads for TLS and macro _MT.
   CONFIGURE_CFLAGS="-mthreads $CONFIGURE_CFLAGS"
-  write_c_skeleton;
   prefix="/qemu"
   bindir=""
   qemu_suffix=""
-- 
2.38.1




Re: [PATCH-for-8.0 v3 1/2] physmem: Remove unused "exec/translate-all.h"

2022-12-09 Thread Peter Maydell
On Fri, 9 Dec 2022 at 11:07, Philippe Mathieu-Daudé  wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  softmmu/physmem.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/softmmu/physmem.c b/softmmu/physmem.c
> index 1b606a3002..d562c0bb93 100644
> --- a/softmmu/physmem.c
> +++ b/softmmu/physmem.c
> @@ -58,7 +58,6 @@
>
>  #include "qemu/rcu_queue.h"
>  #include "qemu/main-loop.h"
> -#include "exec/translate-all.h"
>  #include "sysemu/replay.h"
>
>  #include "exec/memory-internal.h"
> --

physmem.c has a call to tb_check_watchpoint(), which is declared
in translate-all.h -- where does it get the prototype from if
the header isn't included any more ?

thanks
-- PMM



Re: [SeaBIOS] Re: [PATCH 4/4] be less conservative with the 64bit pci io window

2022-12-09 Thread Gerd Hoffmann
  Hi,

> > Well, the idea is to adapt to the world moving forward.  Running a
> > 64-bit capable OS is standard these days, and the resources needed
> > by devices (especially GPUs) are becoming larger and larger.
> > 
> > Yes, there is the risk that (old) guests are unhappy with their
> > PCI bars suddenly being mapped above 4G.  Can happen only in case
> > seabios handles pci initialization (i.e. when running on qemu,
> > otherwise coreboot initializes the pci bars).  I hope the memory
> > check handles the 'old guest' case: when the guest can't handle
> > addresses above 4G it is unlikely that qemu is configured to have
> > memory mapped above 4G ...
> 
> does it break 32-bit PAE enabled guests
> (which can have more then 4Gb RAM configured)?

Well, depends on the guest OS I guess.  Modern linux copes just fine,
either uses PAE paging to access the PCI bars (seen with debian, works
even in case the PCI bars are above the 64G limit of 32bit processors),
or or it remaps the bars to places below 4G (seen with alpine which
compiles i386 kernels with PAE=n).

take care,
  Gerd




Re: [PATCH 27/30] build: move compiler version check to meson

2022-12-09 Thread Peter Maydell
On Fri, 9 Dec 2022 at 11:40, Paolo Bonzini  wrote:
>
> Instead of checking with preprocessor defines, use the Meson compiler object.
> Because of the mess Apple does with its versioning scheme, check for an
> option that was added in clang 6.0 instead of looking at the version number.

> -# Check whether the compiler matches our minimum requirements:
> -cat > $TMPC << EOF
> -#if defined(__clang_major__) && defined(__clang_minor__)
> -# ifdef __apple_build_version__
> -#  if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
> -#   error You need at least XCode Clang v10.0 to compile QEMU
> -#  endif
> -# else
> -#  if __clang_major__ < 6 || (__clang_major__ == 6 && __clang_minor__ < 0)
> -#   error You need at least Clang v6.0 to compile QEMU
> -#  endif
> -# endif
> -#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
> -# if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 4)
> -#  error You need at least GCC v7.4.0 to compile QEMU
> -# endif
> -#else
> -# error You either need GCC or Clang to compiler QEMU
> -#endif
> -int main (void) { return 0; }
> -EOF
> -if ! compile_prog "" "" ; then
> -error_exit "You need at least GCC v7.4 or Clang v6.0 (or XCode Clang 
> v10.0)"
> -fi
>
> +foreach lang : all_languages
> +  compiler = meson.get_compiler(lang)
> +  if compiler.get_id() == 'gcc' and 
> compiler.version().version_compare('>=7.4')
> +# ok
> +  elif compiler.get_id() == 'clang' and 
> compiler.has_argument('-Wpragma-pack')
> +# ok
> +  else
> +error('You either need GCC v7.4 or Clang v6.0 (or XCode Clang v10.0) to 
> compile QEMU')
> +  endif
> +endforeach

The new code makes it much harder to move our compiler version
requirements forward in future, because there's no longer a simple
"check for normal clang X or apple clang Y" test where we can
bump up X and Y based on what's provided in the various host
platforms we have to support. Doesn't meson provide a way to do
the version check on the version number the way we were doing
previously?

thanks
-- PMM



Re: [RFC PATCH] test-bdrv-drain: keep graph manipulations out of coroutines

2022-12-09 Thread Emanuele Giuseppe Esposito



Am 05/12/2022 um 14:01 schrieb Kevin Wolf:
> Am 02.12.2022 um 18:22 hat Paolo Bonzini geschrieben:
>> On 12/2/22 14:42, Emanuele Giuseppe Esposito wrote:
>>>
>>>
>>> Am 02/12/2022 um 14:27 schrieb Paolo Bonzini:
 Changes to the BlockDriverState graph will have to take the
 corresponding lock for writing, and therefore cannot be done
 inside a coroutine.  Move them outside the test body.

 Signed-off-by: Paolo Bonzini 
 ---
   tests/unit/test-bdrv-drain.c | 63 ++--
   1 file changed, 46 insertions(+), 17 deletions(-)

 diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
 index 6ae44116fe79..d85083dd4f9e 100644
 --- a/tests/unit/test-bdrv-drain.c
 +++ b/tests/unit/test-bdrv-drain.c
 @@ -199,25 +199,40 @@ static void do_drain_end_unlocked(enum drain_type 
 drain_type, BlockDriverState *
   }
   }
 +static BlockBackend *blk;
 +static BlockDriverState *bs, *backing;
 +
 +static void test_drv_cb_init(void)
 +{
 +blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
 +bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
 +  &error_abort);
 +blk_insert_bs(blk, bs, &error_abort);
 +
 +backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, 
 &error_abort);
 +bdrv_set_backing_hd(bs, backing, &error_abort);
 +}
 +
 +static void test_drv_cb_fini(void)
>>>
>>> fini stands for "finito"? :)
>>
>> No, for finish :)
>> http://ftp.math.utah.edu/u/ma/hohn/linux/misc/elf/node3.html
>>
>>> Anyways, an alternative solution for this is also here (probably coming
>>> from you too):
>>> https://lists.nongnu.org/archive/html/qemu-devel/2022-03/msg03517.html
>>
>> Much better.  At least patches 7-8 from that series have to be salvaged,
>> possibly 10 as well.
> 
> I wonder if we need a more general solution for this because this test
> is not the only place that calls this kind of functions in a coroutine.
> The one I'm aware of in particular is all the .bdrv_co_create
> implementations, but I'm almost sure there are more.
> 
> Can we use a yield_to_drain()-like mechanism for these functions? Maybe
> even something like the opposite of co_wrapper, a no_co_wrapper that
> generates a foo_co() variant that drops out of coroutine context before
> calling foo()?
> 

I implemented something like yield_to_drain as you suggested, but when
thinking about it aren't we making a fix that will cost us even more
work in the future? If we use a yield_to_drain-like function, we are
doing something similar to g_c_w, and losing track of whether the caller
is a coroutine or not. And the function could then be used potentially
everywhere. Then we will realize "oh we need to get rid of this and
split the functions differentiating the coroutine context" and
eventually go through ALL the callers again to figure what is doing
what, and implement the same fix of this patch or my series once again.

Instead, even though this is just a test, we have a clear separation and
one less case to worry about in the future.

Thank you,
Emanuele




Re: [RFC PATCH] test-bdrv-drain: keep graph manipulations out of coroutines

2022-12-09 Thread Emanuele Giuseppe Esposito



Am 09/12/2022 um 13:18 schrieb Emanuele Giuseppe Esposito:
> 
> 
> Am 05/12/2022 um 14:01 schrieb Kevin Wolf:
>> Am 02.12.2022 um 18:22 hat Paolo Bonzini geschrieben:
>>> On 12/2/22 14:42, Emanuele Giuseppe Esposito wrote:


 Am 02/12/2022 um 14:27 schrieb Paolo Bonzini:
> Changes to the BlockDriverState graph will have to take the
> corresponding lock for writing, and therefore cannot be done
> inside a coroutine.  Move them outside the test body.
>
> Signed-off-by: Paolo Bonzini 
> ---
>   tests/unit/test-bdrv-drain.c | 63 ++--
>   1 file changed, 46 insertions(+), 17 deletions(-)
>
> diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
> index 6ae44116fe79..d85083dd4f9e 100644
> --- a/tests/unit/test-bdrv-drain.c
> +++ b/tests/unit/test-bdrv-drain.c
> @@ -199,25 +199,40 @@ static void do_drain_end_unlocked(enum drain_type 
> drain_type, BlockDriverState *
>   }
>   }
> +static BlockBackend *blk;
> +static BlockDriverState *bs, *backing;
> +
> +static void test_drv_cb_init(void)
> +{
> +blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
> +bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
> +  &error_abort);
> +blk_insert_bs(blk, bs, &error_abort);
> +
> +backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, 
> &error_abort);
> +bdrv_set_backing_hd(bs, backing, &error_abort);
> +}
> +
> +static void test_drv_cb_fini(void)

 fini stands for "finito"? :)
>>>
>>> No, for finish :)
>>> http://ftp.math.utah.edu/u/ma/hohn/linux/misc/elf/node3.html
>>>
 Anyways, an alternative solution for this is also here (probably coming
 from you too):
 https://lists.nongnu.org/archive/html/qemu-devel/2022-03/msg03517.html
>>>
>>> Much better.  At least patches 7-8 from that series have to be salvaged,
>>> possibly 10 as well.
>>
>> I wonder if we need a more general solution for this because this test
>> is not the only place that calls this kind of functions in a coroutine.
>> The one I'm aware of in particular is all the .bdrv_co_create
>> implementations, but I'm almost sure there are more.
>>
>> Can we use a yield_to_drain()-like mechanism for these functions? Maybe
>> even something like the opposite of co_wrapper, a no_co_wrapper that
>> generates a foo_co() variant that drops out of coroutine context before
>> calling foo()?
>>
> 
> I implemented something like yield_to_drain as you suggested, but when
> thinking about it aren't we making a fix that will cost us even more
> work in the future? If we use a yield_to_drain-like function, we are
> doing something similar to g_c_w, and losing track of whether the caller
> is a coroutine or not. And the function could then be used potentially
> everywhere. Then we will realize "oh we need to get rid of this and
> split the functions differentiating the coroutine context" and
> eventually go through ALL the callers again to figure what is doing
> what, and implement the same fix of this patch or my series once again.
> 
> Instead, even though this is just a test, we have a clear separation and
> one less case to worry about in the future.
> 
At least the above is valid if the change you are proposing is the
following (tested already, works)


diff --git a/block.c b/block.c
index 6191ac1f44..8d28c1daa4 100644
--- a/block.c
+++ b/block.c
@@ -42,6 +42,7 @@
 #include "qapi/qobject-output-visitor.h"
 #include "qapi/qapi-visit-block-core.h"
 #include "sysemu/block-backend.h"
+#include "sysemu/replay.h"
 #include "qemu/notify.h"
 #include "qemu/option.h"
 #include "qemu/coroutine.h"
@@ -2831,6 +2832,94 @@ uint64_t
bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
 return permissions[qapi_perm];
 }

+typedef struct {
+Coroutine *co;
+BlockDriverState *new_bs;
+BdrvChild *child;
+AioContext *ctx;
+bool done;
+} BdrvCoGraphModData;
+
+static void bdrv_co_graph_mod_bh_cb(void *opaque)
+{
+BdrvCoGraphModData *data = opaque;
+Coroutine *co = data->co;
+BlockDriverState *old_bs = data->child->bs;
+BlockDriverState *new_bs = data->new_bs;
+
+aio_context_acquire(data->ctx);
+
+ if (old_bs) {
+bdrv_dec_in_flight(old_bs);
+}
+
+if (new_bs) {
+bdrv_dec_in_flight(new_bs);
+}
+bdrv_replace_child_noperm(data->child, data->new_bs);
+aio_context_release(data->ctx);
+
+data->done = true;
+aio_co_wake(co);
+}
+
+/*
+ * If bdrv_replace_child_noperm is called in a coroutine, defer the
work to the
+ * Main Loop by scheduling a BH.
+ */
+static void bdrv_co_yield_to_graph_mod(BdrvChild *child,
BlockDriverState *new_bs)
+{
+BdrvCoGraphModData data;
+Coroutine *self = qemu_coroutine_self();
+AioContext *ctx = bdrv_get_aio_context(new_bs);
+BlockDriverState *old_bs = child->bs;
+
+GLOBAL_STATE

[PATCH] target/mips: Add nanoMIPS ISA support in QEMU

2022-12-09 Thread Milica Lazarevic
nanoMIPS ISA support is planned to be maintained.

Signed-off-by: Milica Lazarevic 
---
 MAINTAINERS | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6966490c94..66e083b455 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -237,10 +237,16 @@ R: Jiaxun Yang 
 R: Aleksandar Rikalo 
 S: Odd Fixes
 F: target/mips/
-F: disas/*mips.c
+F: disas/mips.c
 F: docs/system/cpu-models-mips.rst.inc
 F: tests/tcg/mips/
 
+MIPS TCG CPUs (nanoMIPS ISA)
+M: Milica Lazarevic 
+S: Maintained
+F: disas/nanomips.c
+F: target/mips/tcg/*nanomips*
+
 NiosII TCG CPUs
 M: Chris Wulff 
 M: Marek Vasut 
-- 
2.25.1




Re: [PATCH 14/30] configure: test all warnings

2022-12-09 Thread Philippe Mathieu-Daudé

On 9/12/22 12:23, Paolo Bonzini wrote:

Some warnings are hardcoded in QEMU_CFLAGS and not tested.  There is
no particular reason to single out these five, as many more -W flags are
present on all the supported compilers.  For homogeneity when moving
the detection to meson, make them use the same warn_flags infrastructure.

Signed-off-by: Paolo Bonzini 
---
  configure | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH-for-8.0] target/arm: Restrict arm_cpu_exec_interrupt() to TCG accelerator

2022-12-09 Thread Fabiano Rosas
Philippe Mathieu-Daudé  writes:

> When building with --disable-tcg on Darwin we get:
>
>   target/arm/cpu.c:725:16: error: incomplete definition of type 'struct 
> TCGCPUOps'
> cc->tcg_ops->do_interrupt(cs);
> ~~~^
>
> Commit 083afd18a9 ("target/arm: Restrict cpu_exec_interrupt()
> handler to sysemu") limited this block to system emulation,
> but neglected to also limit it to TCG.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Fabiano Rosas 



Re: [PATCH 16/30] build: move glib detection and workarounds to meson

2022-12-09 Thread Philippe Mathieu-Daudé

On 9/12/22 12:23, Paolo Bonzini wrote:

QEMU adds the path to glib.h is added to all compilation commands.


add/add/ not clear...

Otherwise:
Reviewed-by: Philippe Mathieu-Daudé 



This is simpler due to the pervasive use of static_library, and was
grandfathered in from the previous Make-based build system.  Until
Meson 0.63 the only way to do this was to detect glib in configure
and use add_project_arguments, but now it is possible to use
add_project_dependencies instead.

gmodule is detected in a separate variable and added via both
block_ss (for --enable-modules) and plugins/meson.build (for
--enable-plugins).

Signed-off-by: Paolo Bonzini 
---
  block/meson.build|  1 +
  configure| 83 +---
  contrib/plugins/Makefile |  4 +-
  meson.build  | 81 +--
  plugins/meson.build  |  2 +-
  5 files changed, 74 insertions(+), 97 deletions(-)





Re: [PATCH 19/30] configure, meson: move --enable-debug-info to Meson

2022-12-09 Thread Philippe Mathieu-Daudé

On 9/12/22 12:23, Paolo Bonzini wrote:

Older versions of Meson had an unclear description of the -Ddebug option,
but this is fixed in 0.63.0 that is required now.

Signed-off-by: Paolo Bonzini 
---
  configure | 5 -
  scripts/meson-buildoptions.py | 2 ++
  scripts/meson-buildoptions.sh | 3 +++
  3 files changed, 5 insertions(+), 5 deletions(-)




diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index f91797741eef..cb277347bb18 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh


# This file is generated by meson-buildoptions.py, do not edit!


@@ -10,6 +10,7 @@ meson_options_help() {
printf "%s\n" '   affects only QEMU, not tools like 
qemu-img)'
printf "%s\n" '  --datadir=VALUE  Data file directory [share]'
printf "%s\n" '  --disable-coroutine-pool coroutine freelist (better 
performance)'
+  printf "%s\n" '  --disable-debug-info Enable debug symbols and other 
information'


We should get '--enable-debug-info' here, ...


printf "%s\n" '  --disable-install-blobs  install provided firmware blobs'


... and here. Do we have a bug in meson-buildoptions.py?


printf "%s\n" '  --docdir=VALUE   Base directory for documentation 
installation'
printf "%s\n" '   (can be empty) [share/doc]'




Re: [PATCH 22/30] build: move SafeStack tests to meson

2022-12-09 Thread Philippe Mathieu-Daudé

On 9/12/22 12:24, Paolo Bonzini wrote:

This disables the old behavior of detecting SafeStack from environment
CFLAGS.  SafeStack is now enabled purely based on the configure arguments.

Signed-off-by: Paolo Bonzini 
---
  configure | 73 ---
  meson.build   | 26 +
  meson_options.txt |  2 +
  scripts/meson-buildoptions.sh |  4 ++
  4 files changed, 32 insertions(+), 73 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v12 0/1] vhost-vdpa: add support for vIOMMU

2022-12-09 Thread Cindy Lu
These patches are to support vIOMMU in vdpa device
Verified in vp_vdpa/vdpa_sim_net driverand intel_iommu
virtio-iommu device

changes in V3
1. Move function vfio_get_xlat_addr to memory.c
2. Use the existing memory listener, while the MR is
iommu MR then call the function iommu_region_add/
iommu_region_del

changes in V4
1.make the comments in vfio_get_xlat_addr more general

changes in V5
1. Address the comments in the last version
2. Add a new arg in the function vfio_get_xlat_addr, which shows whether
the memory is backed by a discard manager. So the device can have its
own warning.

changes in V6
move the error_report for the unpopulated discard back to
memeory_get_xlat_addr

changes in V7
organize the error massage to avoid the duplicate information

changes in V8
Organize the code follow the comments in the last version

changes in V9
Organize the code follow the comments

changes in V10
Address the comments

changes in V11
Address the comments
fix the crash found in test

changes in V12
Address the comments, squash patch 1 into the next patch
improve the code style issue

Cindy Lu (1):
  vhost-vdpa: add support for vIOMMU

 hw/virtio/vhost-vdpa.c | 162 ++---
 include/hw/virtio/vhost-vdpa.h |  10 ++
 2 files changed, 161 insertions(+), 11 deletions(-)

-- 
2.34.3




[PATCH v12 1/1] vhost-vdpa: add support for vIOMMU

2022-12-09 Thread Cindy Lu
1.Skip the check in vhost_vdpa_listener_skipped_section() while
MR is IOMMU, Move this check to  vhost_vdpa_iommu_map_notify()
2.Add support for vIOMMU.
Add the new function to deal with iommu MR.
- during iommu_region_add register a specific IOMMU notifier,
 and store all notifiers in a list.
- during iommu_region_del, compare and delete the IOMMU notifier from the list

Verified in vp_vdpa and vdpa_sim_net driver

Signed-off-by: Cindy Lu 
---
 hw/virtio/vhost-vdpa.c | 162 ++---
 include/hw/virtio/vhost-vdpa.h |  10 ++
 2 files changed, 161 insertions(+), 11 deletions(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 7468e44b87..2b3920c2a1 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -26,6 +26,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "hw/virtio/virtio-access.h"
 
 /*
  * Return one past the end of the end of section. Be careful with uint64_t
@@ -60,15 +61,22 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
  iova_min, section->offset_within_address_space);
 return true;
 }
+/*
+ * While using vIOMMU, Sometimes the section will be larger than iova_max
+ * but the memory that  actually mapping is smaller, So skip the check
+ * here. Will add the check in vhost_vdpa_iommu_map_notify,
+ *There is the real size that maps to the kernel
+ */
 
-llend = vhost_vdpa_section_end(section);
-if (int128_gt(llend, int128_make64(iova_max))) {
-error_report("RAM section out of device range (max=0x%" PRIx64
- ", end addr=0x%" PRIx64 ")",
- iova_max, int128_get64(llend));
-return true;
+if (!memory_region_is_iommu(section->mr)) {
+llend = vhost_vdpa_section_end(section);
+if (int128_gt(llend, int128_make64(iova_max))) {
+error_report("RAM section out of device range (max=0x%" PRIx64
+ ", end addr=0x%" PRIx64 ")",
+ iova_max, int128_get64(llend));
+return true;
+}
 }
-
 return false;
 }
 
@@ -173,6 +181,115 @@ static void vhost_vdpa_listener_commit(MemoryListener 
*listener)
 v->iotlb_batch_begin_sent = false;
 }
 
+static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
+{
+struct vdpa_iommu *iommu = container_of(n, struct vdpa_iommu, n);
+
+hwaddr iova = iotlb->iova + iommu->iommu_offset;
+struct vhost_vdpa *v = iommu->dev;
+void *vaddr;
+int ret;
+Int128 llend;
+
+if (iotlb->target_as != &address_space_memory) {
+error_report("Wrong target AS \"%s\", only system memory is allowed",
+ iotlb->target_as->name ? iotlb->target_as->name : "none");
+return;
+}
+RCU_READ_LOCK_GUARD();
+/* check if RAM section out of device range */
+llend = int128_add(int128_makes64(iotlb->addr_mask), int128_makes64(iova));
+if (int128_gt(llend, int128_make64(v->iova_range.last))) {
+error_report("RAM section out of device range (max=0x%" PRIx64
+ ", end addr=0x%" PRIx64 ")",
+ v->iova_range.last, int128_get64(llend));
+return;
+}
+
+vhost_vdpa_iotlb_batch_begin_once(v);
+
+if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
+bool read_only;
+
+if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL)) {
+return;
+}
+
+ret = vhost_vdpa_dma_map(v, iova, iotlb->addr_mask + 1, vaddr,
+read_only);
+if (ret) {
+error_report("vhost_vdpa_dma_map(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ", %p) = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, vaddr, ret);
+}
+} else {
+ret = vhost_vdpa_dma_unmap(v, iova, iotlb->addr_mask + 1);
+if (ret) {
+error_report("vhost_vdpa_dma_unmap(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ") = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, ret);
+}
+}
+}
+
+static void vhost_vdpa_iommu_region_add(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+Int128 end;
+int iommu_idx;
+IOMMUMemoryRegion *iommu_mr;
+int ret;
+
+iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+
+iommu = g_malloc0(sizeof(*iommu));
+end = int128_add(int128_make64(section->offset_within_region),
+section->size);
+end = int128_sub(end, int128_one());
+iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
+MEMTXATTRS_UNSPECIFIED);
+iommu->iommu_mr = iommu_mr;
+iommu_notifier_init(&iommu->n, vhost_vdpa_iommu_map_notify,
+IOMMU_NOTIFIER_IOTLB_EVENTS,
+section->

Re: How to best make include/hw/pci/pcie_sriov.h self-contained

2022-12-09 Thread Markus Armbruster
"Michael S. Tsirkin"  writes:

> On Wed, Dec 07, 2022 at 07:25:49AM +0100, Markus Armbruster wrote:
>> pcie_sriov.h needs PCI_NUM_REGIONS from pci.h, but doesn't include it.
>> pci.h must be included before pcie_sriov.h or else compile fails.
>> 
>> Adding #include "pci/pci.h" to pcie_sriov would be wrong, because it
>> would close an inclusion loop: pci.h includes pcie.h (for
>> PCIExpressDevice) includes pcie_sriov.h (for PCIESriovPF) includes pci.h
>> (for PCI_NUM_REGIONS).
>> 
>> The obvious solution is to move PCI_NUM_REGIONS pci.h somewhere
>> pcie_sriov.h can include without creating a loop.
>> 
>> We already have a few headers that don't include anything: pci_ids.h,
>> pci_regs.h (includes include/standard-headers/linux/pci_regs.h, which
>> doesn't count), pcie_regs.h.  Moving PCI_NUM_REGIONS to one of these
>> would work, but it doesn't feel right.
>> 
>> We could create a new one, say pci_defs.h.  Just for PCI_NUM_REGIONS
>> feels silly.  So, what else should move there?
>
> I'm ok with pci_defs.h
> However, I note that most headers including pci.h don't really
> need it. Consider include/hw/virtio/virtio-iommu.h all it needs is
> PCIBus typedef this is available from qemu/typedefs.h
> So if you are poking at this, want to clean that area up generally?

I looked into this, which made me reconsider my pci_defs.h idea.
Instead of splitting off pci_defs.h for PCI_NUM_REGIONS and similar
stuff (which stuff exactly?), I'm going to split off pci_device.h for
PCIDevice & friends.

[...]




[PATCH] migration/rdma: fix return value for qio_channel_rdma_{readv, writev}

2022-12-09 Thread Fiona Ebner
upon errors. As the documentation in include/io/channel.h states, only
-1 and QIO_CHANNEL_ERR_BLOCK should be returned upon error. Other
values have the potential to confuse the call sites.

error_setg is used rather than error_setg_errno, because there are
certain code paths where -1 (as a non-errno) is propagated up (e.g.
starting from qemu_rdma_block_for_wrid or qemu_rdma_post_recv_control)
all the way to qio_channel_rdma_{readv,writev}.

Similar to a216ec85b7 ("migration/channel-block: fix return value for
qio_channel_block_{readv,writev}").

Suggested-by: Zhang Chen 
Signed-off-by: Fiona Ebner 
---

I did only compile-test the patch, because I have no experience with
RDMA.

@Zhang Chen: In [0], besides qio_channel_rdma_writev/readv, you
mentioned qio_channel_buffer_writev/readv and 'etc.', but I did only
find the issue in the RDMA-specific implementation.

[0]: https://lists.nongnu.org/archive/html/qemu-devel/2022-10/msg02636.html

 migration/rdma.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/migration/rdma.c b/migration/rdma.c
index 94a55dd95b..0ba1668d70 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -2785,7 +2785,8 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
 rdma = qatomic_rcu_read(&rioc->rdmaout);
 
 if (!rdma) {
-return -EIO;
+error_setg(errp, "RDMA control channel output is not set");
+return -1;
 }
 
 CHECK_ERROR_STATE();
@@ -2797,7 +2798,8 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
 ret = qemu_rdma_write_flush(f, rdma);
 if (ret < 0) {
 rdma->error_state = ret;
-return ret;
+error_setg(errp, "qemu_rdma_write_flush returned %d", ret);
+return -1;
 }
 
 for (i = 0; i < niov; i++) {
@@ -2816,7 +2818,8 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
 
 if (ret < 0) {
 rdma->error_state = ret;
-return ret;
+error_setg(errp, "qemu_rdma_exchange_send returned %d", ret);
+return -1;
 }
 
 data += len;
@@ -2867,7 +2870,8 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
 rdma = qatomic_rcu_read(&rioc->rdmain);
 
 if (!rdma) {
-return -EIO;
+error_setg(errp, "RDMA control channel input is not set");
+return -1;
 }
 
 CHECK_ERROR_STATE();
@@ -2903,7 +2907,8 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
 
 if (ret < 0) {
 rdma->error_state = ret;
-return ret;
+error_setg(errp, "qemu_rdma_exchange_recv returned %d", ret);
+return -1;
 }
 
 /*
-- 
2.30.2





  1   2   >