Re: [Qemu-devel] [PATCH] Migration compatibility for serial
On Wed, Jun 17, 2015 at 08:52:42AM +0200, Markus Armbruster wrote: > "Dr. David Alan Gilbert (git)" writes: > > > From: "Dr. David Alan Gilbert" > > > > Older QEMUs dont understand the new (sub)sections that > > may be generated in the serial device. Limit their generation > > to newer machine types. > > Please explain briefly what state migration can lose with old machine > types, and how this could impact the guest. The commits adding the > subsections should have the information[*]. Pointers to them might > suffice. > > > [*] Should != do; I didn't check. OTOH if we have flags named after specific portions we skip, and not after qemu versions, this becomes evident from code.
Re: [Qemu-devel] [PATCH RFC 1/3] error: don't rely on pointer comparisons
On Tue, Jun 16, 2015 at 09:03:44AM -0600, Eric Blake wrote: > On 06/16/2015 06:53 AM, Michael S. Tsirkin wrote: > > makes it possible to copy error_abort pointers, > > not just pass them on directly. > > > > Signed-off-by: Michael S. Tsirkin > > --- > > util/error.c | 16 +++- > > 1 file changed, 11 insertions(+), 5 deletions(-) > > > > diff --git a/util/error.c b/util/error.c > > index 14f4351..ccf29ea 100644 > > --- a/util/error.c > > +++ b/util/error.c > > @@ -20,7 +20,13 @@ struct Error > > ErrorClass err_class; > > }; > > > > -Error *error_abort; > > +static Error error_abort_st = { .err_class = ERROR_CLASS_MAX }; > > +Error *error_abort = &error_abort_st; > > Looking at this a bit further, I still wonder if we can do a slightly > better job of coming up with something that will SIGSEGV (or SIGBUS) if > we (accidentally) try to dereference the pointer (similar to how SIG_IGN > is (sighandler_t)1) - because we know that the abort object should never > be dereferenced. Something like: > > Error *error_abort = (Error *)1; > > with no need for error_abort_st. (Might have to spell it as Error > *error_abort = (void*)(intptr_t)1; > to shut up compiler warnings) > > > + > > +static bool error_is_abort(Error **errp) > > +{ > > +return errp && *errp && (*errp)->err_class == ERROR_CLASS_MAX; > > +} > > and this would be: > > return errp && *errp == error_abort; > > The rest of this patch is still good. Then in patch 2, you'd have: > > Error *error_init_local(Error **errp) > { > return error_is_abort(errp) ? error_abort : NULL; > } > > That is, you still use pointer equality, but at one less level of > indirection (equality at the Error* level, not the Error** level). It's a clever trick, it'd work. But why do tricks? This is never performance-critical, is it? E.g. debugging is easier if pointers actually point to things. Let's see what do others say. > -- > Eric Blake eblake redhat com+1-919-301-3266 > Libvirt virtualization library http://libvirt.org >
Re: [Qemu-devel] [PATCH] Migration compatibility for serial
"Dr. David Alan Gilbert (git)" writes: > From: "Dr. David Alan Gilbert" > > Older QEMUs dont understand the new (sub)sections that > may be generated in the serial device. Limit their generation > to newer machine types. Please explain briefly what state migration can lose with old machine types, and how this could impact the guest. The commits adding the subsections should have the information[*]. Pointers to them might suffice. [*] Should != do; I didn't check.
Re: [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add SPCR table
On Wed, Jun 17, 2015 at 09:06:47AM +0800, Shannon Zhao wrote: > > > On 2015/6/16 22:19, Michael S. Tsirkin wrote: > > On Tue, Jun 16, 2015 at 09:33:19AM +0800, Shannon Zhao wrote: > >> > >> > >> On 2015/6/16 2:13, Michael S. Tsirkin wrote: > >>> On Mon, Jun 15, 2015 at 05:59:06PM +0100, Peter Maydell wrote: > On 15 June 2015 at 17:32, Andrew Jones wrote: > > On Mon, Jun 15, 2015 at 06:10:25PM +0200, Michael S. Tsirkin wrote: > >> On Mon, Jun 15, 2015 at 04:45:58PM +0100, Peter Maydell wrote: > >>> I'm still confused about when fields in these ACPI structs > >>> need to be converted to little-endian, and when they don't. > >>> Is there a rule-of-thumb I can use when I'm looking at patches? > > >> Normally it's all LE unless it's a single byte value. > >> Did not check this specific table. > >> We really need to add sparse support to check > >> endian-ness matches, or re-write it > >> all using byte_add so there's no duplication of info. > > > Everything used in the table is either a single byte, or I used le32, > > Well, I didn't bother for the pci_{device,vendor}_id assignments, as > > they're 0x anyway. I can change those two to make them more > > explicit, > > if that's preferred. > > Yep, I just looked over the struct definition, so since this > has been reviewed I'll apply it to target-arm.next. > > You could probably make it easier to review and write > code that has to do these endianness swaps with something > like > > #define acpi_struct_assign(FIELD, VAL) \ > ((FIELD) = \ > __builtin_choose_expr(sizeof(FIELD) == 1, VAL, \ > __builtin_choose_expr(sizeof(FIELD) == 2, cpu_to_le16(VAL), \ > __builtin_choose_expr(sizeof(FIELD) == 4, cpu_to_le32(VAL), \ > __builtin_choose_expr(sizeof(FIELD) == 8, cpu_to_le64(VAL), \ > abort > > (untested, but based on some code in linux-user/qemu.h). > > Then it's always > > acpi_struct_assign(spcr->field, value); > > whether the field is 1, 2, 4 or 8 bytes. > > Not my bit of the codebase though, so I'll leave it to the > ACPI maintainers to decide how much they like magic macros :-) > > thanks > -- PMM > >>> > >>> > >>> We don't much. One can use build_append_int_noprefix and just avoid > >>> structs altogether. > >> > >> But if we use build_append_int_noprefix, we have to bother about the > >> unused fields of the struct and have lots of > >> build_append_int_noprefix(table, 0, 1/2/4/8). > > > > With a struct you have a bunch of reserved fields - is that very > > different? > > > > Not only about the reserved fields, but also the fields which ARM > doesn't use or x86 doesn't use. For example, xpm1a_event_block in struct > AcpiFadtDescriptorRev5_1 is not used for ARM now, if we use > build_append_int_noprefix, we should add lots of > build_append_int_noprefix(table, 0, 1/2/4/8). But if we use struct, we > just need to care them when we define it, rather than every time we use. So the advice above assumes that you have a wrapper function for building each struct. Then you would just pass 0 as parameters as appropriate. But I am not claiming we need to switch all code away from structs. If you like it like this, keep it around. > >>> We did this for some structures and I'm thinking it's a good direction > >>> generally. > >>> > >> > >> -- > >> Shannon > > -- > Shannon
Re: [Qemu-devel] [RFC v10 13/19] pci: add bus reset_notifiers callbacks for host bus reset
On Wed, Jun 17, 2015 at 09:41:40AM +0800, Chen Fan wrote: > > On 06/16/2015 06:20 PM, Michael S. Tsirkin wrote: > >On Tue, Jun 16, 2015 at 04:10:57PM +0800, Chen Fan wrote: > >>Particularly, For vfio devices, Once need to recovery devices > >>by bus reset such as AER, we always need to reset the host bus > >>to recovery the devices under the bus, so we need to add pci bus > >>callbacks to specify to do host bus reset. > >> > >>Signed-off-by: Chen Fan > >Interesting. What prevents guest from triggering reset at an arbitrary > >time, killing all VFs for all guests? > If the VF device was assigned to VM, with enable aer, we check the > VF affected devices e.g. the other VFs and PF is belonged to VM or not. > so It can't to affect other VMs for this. if disable aer, there will no > affection. > > Thanks, > Chen So fundamentally this assumes PF is assigned to the VM? Why even bother with this aer on VFs then? Do this for PFs only. > > > >>--- > >> hw/pci/pci.c | 16 > >> hw/pci/pci_bridge.c | 6 ++ > >> include/hw/pci/pci.h | 4 > >> include/hw/pci/pci_bus.h | 2 ++ > >> 4 files changed, 28 insertions(+) > >> > >>diff --git a/hw/pci/pci.c b/hw/pci/pci.c > >>index 3423c3a..3bd954e 100644 > >>--- a/hw/pci/pci.c > >>+++ b/hw/pci/pci.c > >>@@ -74,11 +74,27 @@ static const VMStateDescription vmstate_pcibus = { > >> } > >> }; > >>+void pci_bus_add_reset_notifier(PCIBus *bus, Notifier *notify) > >>+{ > >>+notifier_list_add(&bus->reset_notifiers, notify); > >>+} > >>+ > >>+void pci_bus_remove_reset_notifier(Notifier *notify) > >>+{ > >>+notifier_remove(notify); > >>+} > >>+ > >>+void pci_bus_run_reset_notifier(PCIBus *bus, void *opaque) > >>+{ > >>+notifier_list_notify(&bus->reset_notifiers, opaque); > >>+} > >>+ > >> static void pci_bus_realize(BusState *qbus, Error **errp) > >> { > >> PCIBus *bus = PCI_BUS(qbus); > >> vmstate_register(NULL, -1, &vmstate_pcibus, bus); > >>+notifier_list_init(&bus->reset_notifiers); > >> } > >> static void pci_bus_unrealize(BusState *qbus, Error **errp) > >>diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c > >>index 40c97b1..a8e3f57 100644 > >>--- a/hw/pci/pci_bridge.c > >>+++ b/hw/pci/pci_bridge.c > >>@@ -267,6 +267,12 @@ void pci_bridge_write_config(PCIDevice *d, > >> newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL); > >> if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) { > >>+/* > >>+ * Notify all vfio-pci devices under the bus > >>+ * to do physical bus reset. > >>+ */ > >>+pci_for_each_bus(&s->sec_bus, > >>+pci_bus_run_reset_notifier, d); > >> /* Trigger hot reset on 0->1 transition. */ > >> qbus_reset_all(&s->sec_bus.qbus); > >> } > >>diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h > >>index 6c2af0d..d353c9d 100644 > >>--- a/include/hw/pci/pci.h > >>+++ b/include/hw/pci/pci.h > >>@@ -7,6 +7,7 @@ > >> #include "exec/memory.h" > >> #include "sysemu/dma.h" > >> #include "qapi/error.h" > >>+#include "qemu/notify.h" > >> /* PCI includes legacy ISA access. */ > >> #include "hw/isa/isa.h" > >>@@ -377,6 +378,9 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus); > >> void pci_device_set_intx_routing_notifier(PCIDevice *dev, > >>PCIINTxRoutingNotifier > >> notifier); > >> void pci_device_reset(PCIDevice *dev); > >>+void pci_bus_add_reset_notifier(PCIBus *bus, Notifier *notify); > >>+void pci_bus_remove_reset_notifier(Notifier *notify); > >>+void pci_bus_run_reset_notifier(PCIBus *bus, void *opaque); > >> PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, > >> const char *default_model, > >>diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h > >>index fabaeee..3b551d7 100644 > >>--- a/include/hw/pci/pci_bus.h > >>+++ b/include/hw/pci/pci_bus.h > >>@@ -29,6 +29,8 @@ struct PCIBus { > >> Keep a count of the number of devices with raised IRQs. */ > >> int nirq; > >> int *irq_count; > >>+ > >>+NotifierList reset_notifiers; > >> }; > >> typedef struct PCIBridgeWindows PCIBridgeWindows; > >>-- > >>1.9.3 > >> > >. > >
Re: [Qemu-devel] [PULL 0/5] virtio-gpu: pci support bits and virtio-vga
On Di, 2015-06-16 at 16:16 +0100, Dr. David Alan Gilbert wrote: > * Peter Maydell (peter.mayd...@linaro.org) wrote: > > On 16 June 2015 at 08:57, Gerd Hoffmann wrote: > > > Hi, > > > > > > This pull request almost completes virtio-gpu support, by adding pci > > > support (virtio-gpu-pci) and a variant with vga compatibility > > > (virtio-vga). The remaining missing bit is the vgabios for virtio-vga, > > > which will come with the seabios update later this week. > > I'm hitting: > install: cannot stat > â/home/dgilbert/git/qemu-world3/pc-bios/vgabios-virtio.binâ: No such file > or directory Oops. Try "touch pc-bios/vgabios-virtio.bin" as workaround. I'm busy doing the seabios 1.8.2 release right now, the pull request bringing the seabios update and the real virtio vgabios (and fixing this one as side effect) should be only hours away. cheers, Gerd
Re: [Qemu-devel] [PATCH v2 1/2] monitor: Split mon_get_cpu fn to remove ENV_GET_CPU
Peter Crosthwaite writes: > On Tue, Jun 16, 2015 at 8:09 AM, Markus Armbruster wrote: >> Peter Crosthwaite writes: >> >>> The monitor currently has one helper, mon_get_cpu() which will return >>> an env pointer. The target specific users of this API want an env, but >>> all the target agnostic users really just want the cpu pointer. These >>> users then need to use the target-specifically defined ENV_GET_CPU to >>> navigate back up to the CPU from the ENV. Split the API for the two >>> uses cases to remove all need for ENV_GET_CPU. >>> >>> Reviewed-by: Richard Henderson >>> Reviewed-by: Andreas Färber >>> Signed-off-by: Peter Crosthwaite >>> --- >>> Changed since v1: >>> s/mon_get_env/mon_get_cpu_env (Andreas review) >>> Avoid C99 declaration (RH review) >>> --- >>> monitor.c | 65 >>> --- >>> 1 file changed, 29 insertions(+), 36 deletions(-) >>> >> [...] >>> @@ -1208,16 +1203,14 @@ static void monitor_printc(Monitor *mon, int c) >>> static void memory_dump(Monitor *mon, int count, int format, int wsize, >>> hwaddr addr, int is_physical) >>> { >>> -CPUArchState *env; >>> int l, line_size, i, max_digits, len; >>> uint8_t buf[16]; >>> uint64_t v; >>> >>> if (format == 'i') { >>> -int flags; >>> -flags = 0; >>> -env = mon_get_cpu(); >>> +int flags = 0; >>> #ifdef TARGET_I386 >>> +CPUArchState *env = mon_get_cpu_env(); >>> if (wsize == 2) { >>> flags = 1; >>> } else if (wsize == 4) { >>> @@ -1238,10 +1231,11 @@ static void memory_dump(Monitor *mon, int count, >>> int format, int wsize, >>> } >>> #endif >>> #ifdef TARGET_PPC >>> +CPUArchState *env = mon_get_cpu_env(); >>> flags = msr_le << 16; >>> flags |= env->bfd_mach; >>> #endif >>> -monitor_disas(mon, env, addr, count, is_physical, flags); >>> +monitor_disas(mon, mon_get_cpu_env(), addr, count, is_physical, >>> flags); >>> return; >>> } >>> >>> @@ -1280,8 +1274,7 @@ static void memory_dump(Monitor *mon, int count, int >>> format, int wsize, >>> if (is_physical) { >>> cpu_physical_memory_read(addr, buf, l); >>> } else { >>> -env = mon_get_cpu(); >>> -if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < >>> 0) { >>> +if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) { >>> monitor_printf(mon, " Cannot access memory\n"); >>> break; >>> } >> >> You call mon_get_cpu_env() and mon_get_cpu() multiple times in this >> function, and declare CPUArchState *env twice (which rang my shadowing >> alarm bell; fortunately the two are under mutually exclusive #ifdef). >> Why not simply do >> >> CPUState *cpu = mon_get_cpu(); > > This we can do easily and the choice of the existing code is pure > personal preference. I generally prefer inline calls to trivial > getters for a low number of call sites as I think code is slightly > easier to read when you don't have to do a local variable lookup on > where all the function args are coming from. Point taken. The getter isn't quite trivial, though: cpu_synchronize_state(). >> CPUArchState *env = mon_get_cpu_env(); >> > > So the multiple decl of env is now needed to avoid an unused variable > werror for non-x86-non-PPC builds when considering the change in P2. > Not strictly needed until P2, but doing it this way straight up > slightly minimises churn. The ENV_GET_CPU removal and the change in P2 > remove the only two unconditional uses of env forcing this variable to > go local to its #ifdef usages. It also has the advantage that only > those two arches use the env at all. Envlessness is a good thing for > common code so prefer to leave the multi-defs in target specific code > with a plan to get rid of them one by one with X86/PPC specific > patches that operate solely on their respective #ifdef sections. > > FWIW, the follow up to this series adds the infrastructure needed for > getting rid of these #ifdef sections (once I muster the courage to > patch X86 and PPC): > > https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg04742.html > >> right at the beginning and be done with it? >> >> Not a big deal, I'm willing to take this patch through my tree as is. >> > > Let me know if you need respin for the first change. I can turn it Your choice. As I said, I'm willing to take it as is. > around quickly, i'd really like to get this one through as its > blocking a lot of the multi-arch work! Aiming for a pull request this week.
Re: [Qemu-devel] [PATCH v3 2/2] vhost user: Add RARP injection for legacy guest
On Wed, Jun 17, 2015 at 12:16:09PM +0800, Jason Wang wrote: > > > On 06/16/2015 04:16 PM, Thibaut Collet wrote: > > For a live migration my understanding is there are a suspend resume > > operation: > > - The VM image is regularly copied from the old host to the new one > > (modified pages due to VM operation can be copied several time) > > - As soon as there are only few pages to copy the VM is suspended on > > the old host, the last pages are copied, and the VM is resumed on the > > new host. Migration is not totally transparent to guest that has a > > small period of unavailability. > > But guest is not involved in the any of the migration process. Unless > the performance drop, guest should not notice the migration at all. It is easy for backend to detect that guest started using the device, e.g. detect DRIVER_OK status set. I think that's enough to send RARPs. > Btw, please use bottom-posting which is easier for reader to understand > the context. > > Thanks I agree, please don't top-post. -- MST
Re: [Qemu-devel] [RFC v9 14/18] vfio: improve vfio_pci_hot_reset to support more case
On 06/16/2015 10:08 PM, Alex Williamson wrote: On Tue, 2015-06-16 at 16:10 +0800, Chen Fan wrote: On 06/10/2015 05:24 AM, Alex Williamson wrote: On Tue, 2015-06-09 at 11:37 +0800, Chen Fan wrote: the vfio_pci_hot_reset differentiate the single and multi in-used devices for reset. but sometimes we own the group without any devices, that also should support hot reset. Nope, did you try it? It can be done, but the group still needs to be connected to a container for isolation. I'm sorry for that. because I have no such host in hand. but I think if we can keep connect container for each affected group, we also able to use this method to do host bus reset. All you need is a dual-port card with isolation, which includes all Intel 1G NICs (igb & e1000e) as of the quirks that are currently in linux-next to be pushed for v4.2. Intel 10G NICs are already quirked upstream. There are certainly ways to fake isolation for testing as well. Thanks, I just have a Intel Corporation 82576 dual-port card, but how can I fake isolation group for this card in linux-next kernel? can you tell me the document link? Thanks, Chen Alex Signed-off-by: Chen Fan --- hw/vfio/pci.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index a4e8658..6507f39 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -3398,6 +3398,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) PCIHostDeviceAddress host; VFIOPCIDevice *tmp; VFIODevice *vbasedev_iter; +bool found; host.domain = devices[i].segment; host.bus = devices[i].bus; @@ -3427,6 +3428,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) goto out; } +found = false; /* Prep dependent devices for reset and clear our marker. */ QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { if (vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) { @@ -3438,12 +3440,21 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) ret = -EINVAL; goto out_single; } +found = true; vfio_pci_pre_reset(tmp); tmp->vbasedev.needs_reset = false; multi = true; break; } } + +/* + * If we own the group but does not own the device, we also + * should call hot reset with multi. + */ +if (!single && !found) { +multi = true; +} } if (!single && !multi) { .
Re: [Qemu-devel] [PATCH] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)"
On Wed, 27 May 2015 19:52:56 +0200 Markus Armbruster wrote: > Since we now require GLib 2.22+ (commit f40685c), we don't have to > work around lack of g_hash_table_iter_init() & friends anymore. > > This reverts commit f8833a37c0c6b22ddd57b45e48cfb0f97dbd5af4. > > Signed-off-by: Markus Armbruster > --- > hw/ppc/spapr_pci.c | 28 +++- > 1 file changed, 11 insertions(+), 17 deletions(-) > > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c > index 05f4fac..e2b9e60 100644 > --- a/hw/ppc/spapr_pci.c > +++ b/hw/ppc/spapr_pci.c > @@ -962,34 +962,28 @@ static const VMStateDescription vmstate_spapr_pci_msi = > { > }, > }; > > -static void spapr_pci_fill_msi_devs(gpointer key, gpointer value, > -gpointer opaque) > -{ > -sPAPRPHBState *sphb = opaque; > - > -sphb->msi_devs[sphb->msi_devs_num].key = *(uint32_t *)key; > -sphb->msi_devs[sphb->msi_devs_num].value = *(spapr_pci_msi *)value; > -sphb->msi_devs_num++; > -} > - > static void spapr_pci_pre_save(void *opaque) > { > sPAPRPHBState *sphb = opaque; > -int msi_devs_num; > +GHashTableIter iter; > +gpointer key, value; > +int i; > > if (sphb->msi_devs) { > g_free(sphb->msi_devs); > sphb->msi_devs = NULL; > } > -sphb->msi_devs_num = 0; > -msi_devs_num = g_hash_table_size(sphb->msi); > -if (!msi_devs_num) { > +sphb->msi_devs_num = g_hash_table_size(sphb->msi); > +if (!sphb->msi_devs_num) { > return; > } > -sphb->msi_devs = g_malloc(msi_devs_num * sizeof(spapr_pci_msi_mig)); > +sphb->msi_devs = g_malloc(sphb->msi_devs_num * > sizeof(spapr_pci_msi_mig)); > > -g_hash_table_foreach(sphb->msi, spapr_pci_fill_msi_devs, sphb); > -assert(sphb->msi_devs_num == msi_devs_num); > +g_hash_table_iter_init(&iter, sphb->msi); > +for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) { > +sphb->msi_devs[i].key = *(uint32_t *) key; > +sphb->msi_devs[i].value = *(spapr_pci_msi *) value; > +} > } > > static int spapr_pci_post_load(void *opaque, int version_id) Reviewed-by: Thomas Huth
Re: [Qemu-devel] [PATCH v5 1/4] hw/pci-bridge: create interrupt-less, hotplug-less bridge for PXB
On Tue, Jun 16, 2015 at 08:30:42PM +0200, Laszlo Ersek wrote: > OVMF downloads the ACPI linker/loader script from QEMU when the edk2 PCI > Bus driver globally signals the firmware that PCI enumeration and resource > allocation have completed. At this point QEMU regenerates the ACPI payload > in an fw_cfg read callback, and this is when the PXB's _CRS gets > populated. > > Unfortunately, when this happens, the PCI_COMMAND_MEMORY bit is clear in > the root bus's command register, *unlike* under SeaBIOS. The consequences > unfold as follows: > > - When build_crs() fetches dev->io_regions[i].addr, it is all-bits-one, > because pci_update_mappings() --> pci_bar_address() calculated it as > PCI_BAR_UNMAPPED, due to the PCI_COMMAND_MEMORY bit being clear. > > - Consequently, the SHPC MMIO BAR (bar 0) of the bridge is not added to > the _CRS, *despite* having been programmed in PCI config space. > > - Similarly, the SHPC MMIO BAR of the PXB is not removed from the main > root bus's DWordMemory descriptor. > > - Guest OSes (Linux and Windows alike) notice the pre-programmed SHPC BAR > within the PXB's config space, and notice that it conflicts with the > main root bus's memory resource descriptors. Linux reports > > pci :04:00.0: BAR 0: can't assign mem (size 0x100) > pci :04:00.0: BAR 0: trying firmware assignment [mem >0x8820-0x882000ff 64bit] > pci :04:00.0: BAR 0: [mem 0x8820-0x882000ff 64bit] conflicts >with PCI Bus :00 [mem >0x8820-0xfebf] > > While Windows Server 2012 R2 reports > > https://technet.microsoft.com/en-us/library/cc732199%28v=ws.10%29.aspx > > This device cannot find enough free resources that it can use. If you > want to use this device, you will need to disable one of the other > devices on this system. (Code 12) > > This issue was apparently encountered earlier, see the "hack" in: > > https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg02983.html > > and the current hole-punching logic in build_crs() and build_ssdt() is > probably supposed to remedy exactly that problem -- however, for OVMF they > don't work, because at the end of the PCI enumeration and resource > allocation, which cues the ACPI linker/loader client, the command register > is clear. > > It has been suggested to implement the above "hack" more cleanly and > permanently. Unfortunately, we can't just disable the SHPC bar of > TYPE_PCI_BRIDGE_DEV based on a new property (or flag), because said device > model has a fixed (non-conditional) SHPC_VMSTATE() field, which would > crash outgoing migration without a preceding shpc_init() call. (And the > new property (or flag) would eliminate the shpc_init() call.) Changing > SHPC_VMSTATE() into an optional subsection, in order to prevent the crash, > would in turn break incoming migration from older hosts. > > Therefore implement a separate, more basic bridge device type, to be used > by PXB, that has no SHPC / hotplug support at all, and consequently (see > commit c008ac0c), no need for an interrupt / MSI either. The new device > model is a stripped-down copy of "pci-bridge"; it is very small and > simple, and shouldn't cause a significant maintenance burden. This is making user-visible changes because of implementation detail. To address cross-version migration, just add field_exists to SHPC_VMSTATE, checking the new property. > Suggested-by: Marcel Apfelbaum > Cc: Marcel Apfelbaum > Cc: Michael S. Tsirkin > Cc: Markus Armbruster > Signed-off-by: Laszlo Ersek > Reviewed-by: Marcel Apfelbaum > Tested-by: Marcel Apfelbaum > --- > > Notes: > v5: > - Describe in both the commit message and a code comment how > "pci-basic-bridge" relates to "pci-bridge" [Markus]. No functional > changes. > > v4: > - unchanged > > - unlike in v2 and v3, in v4 I'm formatting this as any other patch, > without "--find-copies-harder" etc. That formatting was visible (for > the exact same patch) in v3 and v4, so let's format the patch now in > its "genuine glory" :) It shows that the patch is quite small. > > v3: > - unchanged, added Marcel's R-b > > v2: > - Replaced the corresponding v1 patch with a new approach. Instead of > considering the PXB's disabled SHPC BAR in the PXB's _CRS (and > correspondingly, punching it out of the main _CRS), this patch creates > a separate device model that lacks the SHPC functionality completely. > > I already know from IRC that Michael doesn't like this, but that's > okay: I'm formatting this with "-C35% --find-copies-harder", so that > the differences are obvious against the clone origin, and Michael can > pinpoint the locations where and how I should use a new device > property instead, in the original device model. > > (That said, I did test
Re: [Qemu-devel] [PATCH v2 1/2] monitor: Split mon_get_cpu fn to remove ENV_GET_CPU
On Tue, Jun 16, 2015 at 8:09 AM, Markus Armbruster wrote: > Peter Crosthwaite writes: > >> The monitor currently has one helper, mon_get_cpu() which will return >> an env pointer. The target specific users of this API want an env, but >> all the target agnostic users really just want the cpu pointer. These >> users then need to use the target-specifically defined ENV_GET_CPU to >> navigate back up to the CPU from the ENV. Split the API for the two >> uses cases to remove all need for ENV_GET_CPU. >> >> Reviewed-by: Richard Henderson >> Reviewed-by: Andreas Färber >> Signed-off-by: Peter Crosthwaite >> --- >> Changed since v1: >> s/mon_get_env/mon_get_cpu_env (Andreas review) >> Avoid C99 declaration (RH review) >> --- >> monitor.c | 65 >> --- >> 1 file changed, 29 insertions(+), 36 deletions(-) >> > [...] >> @@ -1208,16 +1203,14 @@ static void monitor_printc(Monitor *mon, int c) >> static void memory_dump(Monitor *mon, int count, int format, int wsize, >> hwaddr addr, int is_physical) >> { >> -CPUArchState *env; >> int l, line_size, i, max_digits, len; >> uint8_t buf[16]; >> uint64_t v; >> >> if (format == 'i') { >> -int flags; >> -flags = 0; >> -env = mon_get_cpu(); >> +int flags = 0; >> #ifdef TARGET_I386 >> +CPUArchState *env = mon_get_cpu_env(); >> if (wsize == 2) { >> flags = 1; >> } else if (wsize == 4) { >> @@ -1238,10 +1231,11 @@ static void memory_dump(Monitor *mon, int count, int >> format, int wsize, >> } >> #endif >> #ifdef TARGET_PPC >> +CPUArchState *env = mon_get_cpu_env(); >> flags = msr_le << 16; >> flags |= env->bfd_mach; >> #endif >> -monitor_disas(mon, env, addr, count, is_physical, flags); >> +monitor_disas(mon, mon_get_cpu_env(), addr, count, is_physical, >> flags); >> return; >> } >> >> @@ -1280,8 +1274,7 @@ static void memory_dump(Monitor *mon, int count, int >> format, int wsize, >> if (is_physical) { >> cpu_physical_memory_read(addr, buf, l); >> } else { >> -env = mon_get_cpu(); >> -if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < 0) >> { >> +if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) { >> monitor_printf(mon, " Cannot access memory\n"); >> break; >> } > > You call mon_get_cpu_env() and mon_get_cpu() multiple times in this > function, and declare CPUArchState *env twice (which rang my shadowing > alarm bell; fortunately the two are under mutually exclusive #ifdef). > Why not simply do > > CPUState *cpu = mon_get_cpu(); This we can do easily and the choice of the existing code is pure personal preference. I generally prefer inline calls to trivial getters for a low number of call sites as I think code is slightly easier to read when you don't have to do a local variable lookup on where all the function args are coming from. > CPUArchState *env = mon_get_cpu_env(); > So the multiple decl of env is now needed to avoid an unused variable werror for non-x86-non-PPC builds when considering the change in P2. Not strictly needed until P2, but doing it this way straight up slightly minimises churn. The ENV_GET_CPU removal and the change in P2 remove the only two unconditional uses of env forcing this variable to go local to its #ifdef usages. It also has the advantage that only those two arches use the env at all. Envlessness is a good thing for common code so prefer to leave the multi-defs in target specific code with a plan to get rid of them one by one with X86/PPC specific patches that operate solely on their respective #ifdef sections. FWIW, the follow up to this series adds the infrastructure needed for getting rid of these #ifdef sections (once I muster the courage to patch X86 and PPC): https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg04742.html > right at the beginning and be done with it? > > Not a big deal, I'm willing to take this patch through my tree as is. > Let me know if you need respin for the first change. I can turn it around quickly, i'd really like to get this one through as its blocking a lot of the multi-arch work! Regards, Peter > [...] >
Re: [Qemu-devel] [PATCH v3 2/2] vhost user: Add RARP injection for legacy guest
On 06/16/2015 04:16 PM, Thibaut Collet wrote: > For a live migration my understanding is there are a suspend resume operation: > - The VM image is regularly copied from the old host to the new one > (modified pages due to VM operation can be copied several time) > - As soon as there are only few pages to copy the VM is suspended on > the old host, the last pages are copied, and the VM is resumed on the > new host. Migration is not totally transparent to guest that has a > small period of unavailability. But guest is not involved in the any of the migration process. Unless the performance drop, guest should not notice the migration at all. Btw, please use bottom-posting which is easier for reader to understand the context. Thanks > > > On Tue, Jun 16, 2015 at 10:05 AM, Jason Wang wrote: >> >> On 06/16/2015 03:24 PM, Thibaut Collet wrote: >>> If my understanding is correct, on a resume operation, we have the >>> following callback trace: >>> 1. virtio_pci_restore function that calls all restore call back of >>> virtio devices >>> 2. virtnet_restore that calls try_fill_recv function for each virtual queues >>> 3. try_fill_recv function kicks the virtual queue (through >>> virtqueue_kick function) >> Yes, but this happens only after pm resume not migration. Migration is >> totally transparent to guest. >> >>> >>> On Tue, Jun 16, 2015 at 7:29 AM, Jason Wang wrote: On 06/15/2015 08:12 PM, Thibaut Collet wrote: > After a resume operation the guest always kicks the backend for each > virtual queues. > A live migration does a suspend operation on the old host and a resume > operation on the new host. So the backend has a kick after migration. > > I have checked this point with a legacy guest (redhat 6-5 with kernel > version 2.6.32-431.29.2) and the kick occurs after migration or > resume. > > Jason have you an example of legacy guest that will not kick the > virtual queue after a resume ? I must miss something but migration should be transparent to guest. Could you show me the code that guest does the kick after migration? > On Mon, Jun 15, 2015 at 10:44 AM, Michael S. Tsirkin > wrote: >> On Mon, Jun 15, 2015 at 03:43:13PM +0800, Jason Wang wrote: >>> On 06/12/2015 10:28 PM, Michael S. Tsirkin wrote: On Fri, Jun 12, 2015 at 03:55:33PM +0800, Jason Wang wrote: > On 06/11/2015 08:13 PM, Michael S. Tsirkin wrote: >> On Thu, Jun 11, 2015 at 02:10:48PM +0200, Thibaut Collet wrote: >>> I am not sure to understand your remark: >>> It needs to be sent when backend is activated by guest kick (in case of virtio 1, it's possible to use DRIVER_OK for this). This does not happen when VM still runs on source. >>> Could you confirm rarp can be sent by backend when the >>> VHOST_USER_SET_VRING_KICK message is received by the backend ? >> No - the time to send pakets is when you start processing >> the rings. >> >> And the time to do that is when you detect a kick on >> an eventfd, not when said fd is set. >> > Probably not. What if guest is only doing receiving? Clarification: the kick can be on any VQs. In your example, guest kicks after adding receive buffers. >>> Yes, but refill only happens on we are lacking of receive buffers. It is >>> not guaranteed to happen just after migration, we may have still have >>> enough rx buffers for device to receive. >> I think we also kick the backend after migration, do we not? >> Further, DRIVER_OK can be used as a signal to start backend too. >> > In this case, you > won't detect any kick if you don't send the rarp first.
Re: [Qemu-devel] [PATCH v3] Enable vhost with vhostforce, vhost options for guests without MSI-X support
On 06/16/2015 04:18 PM, Pankaj Gupta wrote: > We use vhostforce to enable vhost even if Guests don't have MSI-X support > and we fall back to QEMU virtio-net. This patch will enable vhost > unconditionally > whenever we have vhostforce='ON' or vhost='ON'. > > Initially, I wanted to remove vhostforce completely as an additional > argument. > But after discussing this in mailing list found that some programs are using > vhostforce > and some vhost. So, we want to keep semantics of both the options. > > Changes from v2->v3 > Jason Wang : Remove functions which are not being used. > > Changes from v1->v2 > MST : Keep comamnd line semantic for options vhost= 'ON' || > vhostforce = 'ON', vhost should be ON. > > Signed-off-by: Pankaj Gupta Subject could be more compact like "start vhost without querying guest notifiers" and some lines in commit log exceeds 80 characters. Except from these: Reviewed-by: Jason Wang > --- > hw/net/vhost_net.c| 12 +--- > hw/net/virtio-net.c | 4 > hw/scsi/vhost-scsi.c | 2 +- > hw/virtio/vhost.c | 14 +- > include/hw/virtio/vhost.h | 3 +-- > include/net/vhost_net.h | 2 -- > net/tap.c | 1 - > net/vhost-user.c | 1 - > 8 files changed, 4 insertions(+), 35 deletions(-) > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c > index 1c55517..0a4577d 100644 > --- a/hw/net/vhost_net.c > +++ b/hw/net/vhost_net.c > @@ -162,7 +162,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) > net->dev.vq_index = net->nc->queue_index; > > r = vhost_dev_init(&net->dev, options->opaque, > - options->backend_type, options->force); > + options->backend_type); > if (r < 0) { > goto fail; > } > @@ -187,11 +187,6 @@ fail: > return NULL; > } > > -bool vhost_net_query(VHostNetState *net, VirtIODevice *dev) > -{ > -return vhost_dev_query(&net->dev, dev); > -} > - > static void vhost_net_set_vq_index(struct vhost_net *net, int vq_index) > { > net->dev.vq_index = vq_index; > @@ -412,11 +407,6 @@ struct vhost_net *vhost_net_init(VhostNetOptions > *options) > return NULL; > } > > -bool vhost_net_query(VHostNetState *net, VirtIODevice *dev) > -{ > -return false; > -} > - > int vhost_net_start(VirtIODevice *dev, > NetClientState *ncs, > int total_queues) > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > index 9281aa1..d728233 100644 > --- a/hw/net/virtio-net.c > +++ b/hw/net/virtio-net.c > @@ -128,10 +128,6 @@ static void virtio_net_vhost_status(VirtIONet *n, > uint8_t status) > if (!n->vhost_started) { > int r, i; > > -if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) { > -return; > -} > - > /* Any packets outstanding? Purge them to avoid touching rings > * when vhost is running. > */ > diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c > index 1941aa1..1c389c4 100644 > --- a/hw/scsi/vhost-scsi.c > +++ b/hw/scsi/vhost-scsi.c > @@ -246,7 +246,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error > **errp) > s->dev.backend_features = 0; > > ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd, > - VHOST_BACKEND_TYPE_KERNEL, true); > + VHOST_BACKEND_TYPE_KERNEL); > if (ret < 0) { > error_setg(errp, "vhost-scsi: vhost initialization failed: %s", > strerror(-ret)); > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c > index 2d6c27a..4f5bb15 100644 > --- a/hw/virtio/vhost.c > +++ b/hw/virtio/vhost.c > @@ -853,7 +853,7 @@ static void vhost_virtqueue_cleanup(struct > vhost_virtqueue *vq) > } > > int vhost_dev_init(struct vhost_dev *hdev, void *opaque, > - VhostBackendType backend_type, bool force) > + VhostBackendType backend_type) > { > uint64_t features; > int i, r; > @@ -916,7 +916,6 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, > hdev->started = false; > hdev->memory_changed = false; > memory_listener_register(&hdev->memory_listener, &address_space_memory); > -hdev->force = force; > return 0; > fail_vq: > while (--i >= 0) { > @@ -944,17 +943,6 @@ void vhost_dev_cleanup(struct vhost_dev *hdev) > hdev->vhost_ops->vhost_backend_cleanup(hdev); > } > > -bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev) > -{ > -BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); > -VirtioBusState *vbus = VIRTIO_BUS(qbus); > -VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus); > - > -return !k->query_guest_notifiers || > - k->query_guest_notifiers(qbus->parent) || > - hdev->force; > -} > - > /* Stop processing guest IO notifications in qemu. > * Start processing them in vhost in kernel. > */ > diff --git a/include/hw/virtio
Re: [Qemu-devel] [RFC PATCH v1 3/4] numa: Store boot memory address range in node_info
On Mon, Jun 15, 2015 at 01:31:20PM -0300, Eduardo Habkost wrote: > On Fri, Jun 12, 2015 at 02:30:27PM +0530, Bharata B Rao wrote: > > Store memory address range information of boot memory in address > > range list of numa_info. > > > > This helps to have a common NUMA node lookup by address function that > > works for both boot time memory and hotplugged memory. > > > > Signed-off-by: Bharata B Rao > > --- > > numa.c | 22 ++ > > 1 file changed, 22 insertions(+) > > > > diff --git a/numa.c b/numa.c > > index 27ca743..d67b1fb 100644 > > --- a/numa.c > > +++ b/numa.c > > @@ -75,6 +75,26 @@ void numa_unset_mem_node_id(ram_addr_t addr, uint64_t > > size, uint32_t node) > > } > > } > > > > +static void numa_set_mem_ranges(void) > > +{ > > +int i; > > +ram_addr_t mem_start, mem_end_prev; > > + > > +/* > > + * Deduce start address of each node and use it to store > > + * the address range info in numa_info address range list > > + */ > > +for (i = 0; i < nb_numa_nodes; i++) { > > +if (i) { > > +mem_start = mem_end_prev; > > +} else { > > +mem_start = 0; > > +} > > You could simply initialize mem_end_prev=0 before entering the loop, > instead. > > Actually, you don't even need the mem_end_prev variable: > > int i; > ram_addr_t mem_start = 0; > > for (i = 0; i < nb_numa_nodes; i++) { > numa_set_mem_node_id(mem_start, numa_info[i].node_mem, i); > mem_start = mem_start + numa_info[i].node_mem; > } Ok will change to this. > > I was going to suggest moving this to > memory_region_allocate_system_memory() instead (that already has a loop > calculating the start address for each NUMA node), but the problem is > that allocate_system_memory_nonnuma() may be called even if using NUMA > if no memdevs are used. So this can be done later, after refactoring > memory_region_allocate_system_memory() to have a single memory > allocation code path. If there are no more comments to be addressed in this series, I shall spin the next version. Regards, Bharata.
Re: [Qemu-devel] [PATCH v3 1/8] include/hw/boards.h: Add a member in MachineState to store irq array
On Tue, Jun 16, 2015 at 7:59 PM, Shannon Zhao wrote: > From: Shannon Zhao > > Here we add a member in MachineState to store the irq array returned > from qemu_allocate_irqs. Then these irq arrays will be free before QEMU > exit and it will be used to fix the memory leak due to misuse > qemu_allocate_irqs. > This is based on an assumption that IRQ are a global concept. This (as well as the one global address space) is something we really should get away from. A better appoach would be to child the IRQs to the Machine object (note that IRQs are QOM objects) for those machines where this assumption makes sense. Then we don't have to pollute common structs. Regards, Peter > Signed-off-by: Shannon Zhao > Signed-off-by: Shannon Zhao > --- > include/hw/boards.h | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/include/hw/boards.h b/include/hw/boards.h > index 6379901..0dea769 100644 > --- a/include/hw/boards.h > +++ b/include/hw/boards.h > @@ -148,6 +148,7 @@ struct MachineState { > char *initrd_filename; > const char *cpu_model; > AccelState *accelerator; > +qemu_irq *irqs; > }; > > #endif > -- > 2.0.4 > > >
[Qemu-devel] QOM patches
Hi Peter, Andreas, It's been a while since a QOM PULL and there are a good number of already-reviewed patches on list. Is Andreas on vacation and returning before hard freeze or should we do a PULL in the meantime? Regards, Peter
[Qemu-devel] [PATCH v3 0/8] Add a member in MachineState to store irq array
From: Shannon Zhao These are relevant to memory leak in machine init function. Here we add a member in MachineState to store irq array returned from qemu_allocate_irqs. PS. These patches are split from my previous patchset [1] since they are relevant to MachineState. Thanks, Shannon [1] [PATCH 00/29] Fix memory leak relevant to calling qemu_allocate_irqs changes since v2: * Rebased on QEMU upstream * Add a member in MachineState first, then fix the memory leak [mjt] changes since v1: * Add a member in MachineState to store irq array [Peter] Shannon Zhao (8): include/hw/boards.h: Add a member in MachineState to store irq array hw/ppc/ppc440_bamboo.c: Store irq array in MachineState to fix memory leak hw/sparc/leon3.c: Store irq array in MachineState to fix memory leak hw/m68k/an5206.c: Store irq array in MachineState to fix memory leak hw/sh4/r2d.c: Store irq array in MachineState to fix memory leak hw/arm/palm.c: Store irq array in MachineState to fix memory leak hw/arm/spitz.c: Store irq array in MachineState to fix memory leak hw/arm/tosa.c: Store irq array in MachineState to fix memory leak hw/arm/palm.c | 6 -- hw/arm/spitz.c | 8 +--- hw/arm/tosa.c | 10 +- hw/m68k/an5206.c | 2 +- hw/ppc/ppc440_bamboo.c | 1 + hw/sh4/r2d.c | 1 + hw/sparc/leon3.c | 1 + include/hw/boards.h| 1 + 8 files changed, 19 insertions(+), 11 deletions(-) -- 2.0.4
[Qemu-devel] [PATCH v3 7/8] hw/arm/spitz.c: Store irq array in MachineState to fix memory leak
From: Shannon Zhao Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- hw/arm/spitz.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c index 5bf032a..454919d 100644 --- a/hw/arm/spitz.c +++ b/hw/arm/spitz.c @@ -812,8 +812,8 @@ static void spitz_out_switch(void *opaque, int line, int level) #define SPITZ_SCP2_BACKLIGHT_ON8 #define SPITZ_SCP2_MIC_BIAS9 -static void spitz_scoop_gpio_setup(PXA2xxState *cpu, -DeviceState *scp0, DeviceState *scp1) +static qemu_irq *spitz_scoop_gpio_setup(PXA2xxState *cpu, + DeviceState *scp0, DeviceState *scp1) { qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8); @@ -828,6 +828,8 @@ static void spitz_scoop_gpio_setup(PXA2xxState *cpu, } qdev_connect_gpio_out(scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]); + +return outsignals; } #define SPITZ_GPIO_HSYNC 22 @@ -928,7 +930,7 @@ static void spitz_common_init(MachineState *machine, scp1 = sysbus_create_simple("scoop", 0x08800040, NULL); } -spitz_scoop_gpio_setup(mpu, scp0, scp1); +machine->irqs = spitz_scoop_gpio_setup(mpu, scp0, scp1); spitz_gpio_setup(mpu, (model == akita) ? 1 : 2); -- 2.0.4
[Qemu-devel] [PATCH v3 2/8] hw/ppc/ppc440_bamboo.c: Store irq array in MachineState to fix memory leak
From: Shannon Zhao Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- hw/ppc/ppc440_bamboo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index 778970a..944999d 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -203,6 +203,7 @@ static void bamboo_init(MachineState *machine) irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); +machine->irqs = pic; /* SDRAM controller */ memset(ram_bases, 0, sizeof(ram_bases)); -- 2.0.4
[Qemu-devel] [PATCH v3 1/8] include/hw/boards.h: Add a member in MachineState to store irq array
From: Shannon Zhao Here we add a member in MachineState to store the irq array returned from qemu_allocate_irqs. Then these irq arrays will be free before QEMU exit and it will be used to fix the memory leak due to misuse qemu_allocate_irqs. Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- include/hw/boards.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hw/boards.h b/include/hw/boards.h index 6379901..0dea769 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -148,6 +148,7 @@ struct MachineState { char *initrd_filename; const char *cpu_model; AccelState *accelerator; +qemu_irq *irqs; }; #endif -- 2.0.4
[Qemu-devel] [PATCH v3 8/8] hw/arm/tosa.c: Store irq array in MachineState to fix memory leak
From: Shannon Zhao Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- hw/arm/tosa.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index 73572eb..4711514 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -85,10 +85,8 @@ static void tosa_out_switch(void *opaque, int line, int level) } -static void tosa_gpio_setup(PXA2xxState *cpu, -DeviceState *scp0, -DeviceState *scp1, -TC6393xbState *tmio) +static qemu_irq *tosa_gpio_setup(PXA2xxState *cpu, DeviceState *scp0, + DeviceState *scp1, TC6393xbState *tmio) { qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4); /* MMC/SD host */ @@ -117,6 +115,8 @@ static void tosa_gpio_setup(PXA2xxState *cpu, /* UDC Vbus */ qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_USB_IN)); + +return outsignals; } static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value) @@ -238,7 +238,7 @@ static void tosa_init(MachineState *machine) scp0 = sysbus_create_simple("scoop", 0x0880, NULL); scp1 = sysbus_create_simple("scoop", 0x14800040, NULL); -tosa_gpio_setup(mpu, scp0, scp1, tmio); +machine->irqs = tosa_gpio_setup(mpu, scp0, scp1, tmio); tosa_microdrive_attach(mpu); -- 2.0.4
[Qemu-devel] [PATCH v3 5/8] hw/sh4/r2d.c: Store irq array in MachineState to fix memory leak
From: Shannon Zhao Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- hw/sh4/r2d.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index 5e22ed7..7f621b2 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -261,6 +261,7 @@ static void r2d_init(MachineState *machine) /* Register peripherals */ s = sh7750_init(cpu, address_space_mem); irq = r2d_fpga_init(address_space_mem, 0x0400, sh7750_irl(s)); +machine->irqs = irq; dev = qdev_create(NULL, "sh_pci"); busdev = SYS_BUS_DEVICE(dev); -- 2.0.4
[Qemu-devel] [PATCH v3 3/8] hw/sparc/leon3.c: Store irq array in MachineState to fix memory leak
From: Shannon Zhao Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- hw/sparc/leon3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 7f5dcd6..6733ebb 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -140,6 +140,7 @@ static void leon3_generic_hw_init(MachineState *machine) /* Allocate IRQ manager */ grlib_irqmp_create(0x8200, env, &cpu_irqs, MAX_PILS, &leon3_set_pil_in); +machine->irqs = cpu_irqs; env->qemu_irq_ack = leon3_irq_manager; -- 2.0.4
[Qemu-devel] [PATCH v3 6/8] hw/arm/palm.c: Store irq array in MachineState to fix memory leak
From: Shannon Zhao Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- hw/arm/palm.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/arm/palm.c b/hw/arm/palm.c index 7f1cfb8..6fe28e5 100644 --- a/hw/arm/palm.c +++ b/hw/arm/palm.c @@ -156,7 +156,7 @@ static void palmte_onoff_gpios(void *opaque, int line, int level) } } -static void palmte_gpio_setup(struct omap_mpu_state_s *cpu) +static qemu_irq *palmte_gpio_setup(struct omap_mpu_state_s *cpu) { qemu_irq *misc_gpio; @@ -183,6 +183,8 @@ static void palmte_gpio_setup(struct omap_mpu_state_s *cpu) qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]); qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]); qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]); + +return misc_gpio; } static struct arm_boot_info palmte_binfo = { @@ -236,7 +238,7 @@ static void palmte_init(MachineState *machine) qemu_add_kbd_event_handler(palmte_button_event, mpu); -palmte_gpio_setup(mpu); +machine->irqs = palmte_gpio_setup(mpu); /* Setup initial (reset) machine state */ if (nb_option_roms) { -- 2.0.4
[Qemu-devel] [PATCH v3 4/8] hw/m68k/an5206.c: Store irq array in MachineState to fix memory leak
From: Shannon Zhao Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao --- hw/m68k/an5206.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c index f63ab2b..6ebf2d2 100644 --- a/hw/m68k/an5206.c +++ b/hw/m68k/an5206.c @@ -58,7 +58,7 @@ static void an5206_init(MachineState *machine) vmstate_register_ram_global(sram); memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram); -mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, cpu); +machine->irqs = mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, cpu); /* Load kernel. */ if (!kernel_filename) { -- 2.0.4
[Qemu-devel] [PATCH 09/11] migration: No need to call trace_migrate_set_state()
We now use the helper everywhere, so no need to call this on this two places. See on previous commit that there were a place where we missed to mark the trace. Now all tracing is done in migrate_set_state(). Signed-off-by: Juan Quintela --- migration/migration.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 1c84249..b31c7f4 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -546,7 +546,6 @@ void migrate_fd_error(MigrationState *s) trace_migrate_fd_error(); assert(s->file == NULL); migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_FAILED); -trace_migrate_set_state(MIGRATION_STATUS_FAILED); notifier_list_notify(&migration_state_notifiers, s); } @@ -631,7 +630,6 @@ static MigrationState *migrate_init(const MigrationParams *params) decompress_thread_count; s->bandwidth_limit = bandwidth_limit; migrate_set_state(s, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP); -trace_migrate_set_state(MIGRATION_STATUS_SETUP); s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); return s; -- 2.4.3
[Qemu-devel] [PATCH 07/11] migration: Use cmpxchg correctly
cmpxchg returns the old value Signed-off-by: Juan Quintela --- migration/migration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration/migration.c b/migration/migration.c index f1ecf76..1791185 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -505,7 +505,7 @@ void qmp_migrate_set_parameters(bool has_compress_level, static void migrate_set_state(MigrationState *s, int old_state, int new_state) { -if (atomic_cmpxchg(&s->state, old_state, new_state) == new_state) { +if (atomic_cmpxchg(&s->state, old_state, new_state) == old_state) { trace_migrate_set_state(new_state); } } -- 2.4.3
[Qemu-devel] [PATCH 06/11] migration: Add configuration section
It needs to be the first one and it is not optional, that is the reason why it is opencoded. For new machine types, it is required than machine type name is the same in both sides. It is just done right now for pc's. Signed-off-by: Juan Quintela --- hw/i386/pc_piix.c | 1 + hw/i386/pc_q35.c | 1 + include/migration/migration.h | 2 ++ migration/savevm.c| 61 +++ 4 files changed, 65 insertions(+) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 735fb22..5009836 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -308,6 +308,7 @@ static void pc_compat_2_3(MachineState *machine) { savevm_skip_section_footers(); global_state_set_optional(); +savevm_skip_configuration(); } static void pc_compat_2_2(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 0523ecc..3dd060d 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -292,6 +292,7 @@ static void pc_compat_2_3(MachineState *machine) { savevm_skip_section_footers(); global_state_set_optional(); +savevm_skip_configuration(); } static void pc_compat_2_2(MachineState *machine) diff --git a/include/migration/migration.h b/include/migration/migration.h index bb53d93..cfc0608 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -34,6 +34,7 @@ #define QEMU_VM_SECTION_FULL 0x04 #define QEMU_VM_SUBSECTION 0x05 #define QEMU_VM_VMDESCRIPTION0x06 +#define QEMU_VM_CONFIGURATION0x07 #define QEMU_VM_SECTION_FOOTER 0x7e struct MigrationParams { @@ -199,4 +200,5 @@ void ram_mig_init(void); void savevm_skip_section_footers(void); void register_global_state(void); void global_state_set_optional(void); +void savevm_skip_configuration(void); #endif diff --git a/migration/savevm.c b/migration/savevm.c index b018f30..00ea10d 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -244,11 +244,55 @@ typedef struct SaveStateEntry { typedef struct SaveState { QTAILQ_HEAD(, SaveStateEntry) handlers; int global_section_id; +bool skip_configuration; +uint32_t len; +const char *name; } SaveState; static SaveState savevm_state = { .handlers = QTAILQ_HEAD_INITIALIZER(savevm_state.handlers), .global_section_id = 0, +.skip_configuration = false, +}; + +void savevm_skip_configuration(void) +{ +savevm_state.skip_configuration = true; +} + + +static void configuration_pre_save(void *opaque) +{ +SaveState *state = opaque; +const char *current_name = MACHINE_GET_CLASS(current_machine)->name; + +state->len = strlen(current_name); +state->name = current_name; +} + +static int configuration_post_load(void *opaque, int version_id) +{ +SaveState *state = opaque; +const char *current_name = MACHINE_GET_CLASS(current_machine)->name; + +if (strncmp(state->name, current_name, state->len) != 0) { +error_report("Machine type received is '%s' and local is '%s'", + state->name, current_name); +return -EINVAL; +} +return 0; +} + +static const VMStateDescription vmstate_configuration = { +.name = "configuration", +.version_id = 1, +.post_load = configuration_post_load, +.pre_save = configuration_pre_save, +.fields = (VMStateField[]) { +VMSTATE_UINT32(len, SaveState), +VMSTATE_VBUFFER_ALLOC_UINT32(name, SaveState, 0, NULL, 0, len), +VMSTATE_END_OF_LIST() +}, }; static void dump_vmstate_vmsd(FILE *out_file, @@ -721,6 +765,11 @@ void qemu_savevm_state_begin(QEMUFile *f, se->ops->set_params(params, se->opaque); } +if (!savevm_state.skip_configuration) { +qemu_put_byte(f, QEMU_VM_CONFIGURATION); +vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0); +} + QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { if (!se->ops || !se->ops->save_live_setup) { continue; @@ -1035,6 +1084,18 @@ int qemu_loadvm_state(QEMUFile *f) return -ENOTSUP; } +if (!savevm_state.skip_configuration) { +if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) { +error_report("Configuration section missing"); +return -EINVAL; +} +ret = vmstate_load_state(f, &vmstate_configuration, &savevm_state, 0); + +if (ret) { +return ret; +} +} + while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) { uint32_t instance_id, version_id, section_id; SaveStateEntry *se; -- 2.4.3
[Qemu-devel] [PATCH 08/11] migration: Use always helper to set state
There were three places that were not using the migrate_set_state() helper, just fix that. Signed-off-by: Juan Quintela --- migration/migration.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 1791185..1c84249 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -545,7 +545,7 @@ void migrate_fd_error(MigrationState *s) { trace_migrate_fd_error(); assert(s->file == NULL); -s->state = MIGRATION_STATUS_FAILED; +migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_FAILED); trace_migrate_set_state(MIGRATION_STATUS_FAILED); notifier_list_notify(&migration_state_notifiers, s); } @@ -630,7 +630,7 @@ static MigrationState *migrate_init(const MigrationParams *params) s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] = decompress_thread_count; s->bandwidth_limit = bandwidth_limit; -s->state = MIGRATION_STATUS_SETUP; +migrate_set_state(s, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP); trace_migrate_set_state(MIGRATION_STATUS_SETUP); s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); @@ -723,7 +723,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, #endif } else { error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); -s->state = MIGRATION_STATUS_FAILED; +migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_FAILED); return; } -- 2.4.3
[Qemu-devel] [PATCH 05/11] vmstate: Create optional sections
To make sections optional, we need to do it at the beggining of the code. Signed-off-by: Juan Quintela Reviewed-by: Dr. David Alan Gilbert --- include/migration/vmstate.h | 2 ++ migration/savevm.c | 8 migration/vmstate.c | 11 +++ trace-events| 1 + 4 files changed, 22 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 7153b1e..38de790 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -815,6 +815,8 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, void *opaque, QJSON *vmdesc); +bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque); + int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, const VMStateDescription *vmsd, void *base, int alias_id, diff --git a/migration/savevm.c b/migration/savevm.c index 2091882..b018f30 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -834,6 +834,11 @@ void qemu_savevm_state_complete(QEMUFile *f) if ((!se->ops || !se->ops->save_state) && !se->vmsd) { continue; } +if (se->vmsd && !vmstate_save_needed(se->vmsd, se->opaque)) { +trace_savevm_section_skip(se->idstr, se->section_id); +continue; +} + trace_savevm_section_start(se->idstr, se->section_id); json_start_object(vmdesc, NULL); @@ -947,6 +952,9 @@ static int qemu_save_device_state(QEMUFile *f) if ((!se->ops || !se->ops->save_state) && !se->vmsd) { continue; } +if (se->vmsd && !vmstate_save_needed(se->vmsd, se->opaque)) { +continue; +} save_section_header(f, se, QEMU_VM_SECTION_FULL); diff --git a/migration/vmstate.c b/migration/vmstate.c index 6138d1a..e8ccf22 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -276,6 +276,17 @@ static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc, json_end_object(vmdesc); } + +bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque) +{ +if (vmsd->needed && !vmsd->needed(opaque)) { +/* optional section not needed */ +return false; +} +return true; +} + + void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, void *opaque, QJSON *vmdesc) { diff --git a/trace-events b/trace-events index 52b7efa..bcdce29 100644 --- a/trace-events +++ b/trace-events @@ -1191,6 +1191,7 @@ qemu_loadvm_state_section_partend(uint32_t section_id) "%u" qemu_loadvm_state_section_startfull(uint32_t section_id, const char *idstr, uint32_t instance_id, uint32_t version_id) "%u(%s) %u %u" savevm_section_start(const char *id, unsigned int section_id) "%s, section_id %u" savevm_section_end(const char *id, unsigned int section_id, int ret) "%s, section_id %u -> %d" +savevm_section_skip(const char *id, unsigned int section_id) "%s, section_id %u" savevm_state_begin(void) "" savevm_state_header(void) "" savevm_state_iterate(void) "" -- 2.4.3
[Qemu-devel] [PATCH 11/11] migration: Add migration events on target side
We reuse the migration events from the source side, sending them on the appropiate place. Signed-off-by: Juan Quintela Reviewed-by: Eric Blake --- migration/migration.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/migration/migration.c b/migration/migration.c index 3637d36..2b4fd55 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -218,6 +218,7 @@ void qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p; +qapi_event_send_migration(MIGRATION_STATUS_SETUP, &error_abort); if (!strcmp(uri, "defer")) { deferred_incoming_migration(errp); } else if (strstart(uri, "tcp:", &p)) { @@ -246,7 +247,7 @@ static void process_incoming_migration_co(void *opaque) int ret; migration_incoming_state_new(f); - +qapi_event_send_migration(MIGRATION_STATUS_ACTIVE, &error_abort); ret = qemu_loadvm_state(f); qemu_fclose(f); @@ -254,10 +255,12 @@ static void process_incoming_migration_co(void *opaque) migration_incoming_state_destroy(); if (ret < 0) { +qapi_event_send_migration(MIGRATION_STATUS_FAILED, &error_abort); error_report("load of migration failed: %s", strerror(-ret)); migrate_decompress_threads_join(); exit(EXIT_FAILURE); } +qapi_event_send_migration(MIGRATION_STATUS_COMPLETED, &error_abort); qemu_announce_self(); /* Make sure all file formats flush their mutable metadata */ -- 2.4.3
[Qemu-devel] [PATCH 10/11] migration: create migration event
We have one argument that tells us what event has happened. Signed-off-by: Juan Quintela X3 Signed-off-by: Juan Quintela --- docs/qmp/qmp-events.txt | 14 ++ migration/migration.c | 2 ++ qapi/event.json | 14 ++ 3 files changed, 30 insertions(+) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 4c13d48..3fe8cb7 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -473,6 +473,20 @@ Example: { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, "event": "SPICE_MIGRATE_COMPLETED" } +MIGRATION +- + +Emitted when a migration event happens + +Data: None. + + - "status": migration status + See MigrationStatus in ~/qapi-scheme.json for possible values + +Example: + +{"timestamp": {"seconds": 1432121972, "microseconds": 744001}, + "event": "MIGRATION", "data": {"status": "completed"}} STOP diff --git a/migration/migration.c b/migration/migration.c index b31c7f4..3637d36 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -26,6 +26,7 @@ #include "qmp-commands.h" #include "trace.h" #include "qapi/util.h" +#include "qapi-event.h" #define MAX_THROTTLE (32 << 20) /* Migration speed throttling */ @@ -506,6 +507,7 @@ void qmp_migrate_set_parameters(bool has_compress_level, static void migrate_set_state(MigrationState *s, int old_state, int new_state) { if (atomic_cmpxchg(&s->state, old_state, new_state) == old_state) { +qapi_event_send_migration(new_state, &error_abort); trace_migrate_set_state(new_state); } } diff --git a/qapi/event.json b/qapi/event.json index 378dda5..fe5e182 100644 --- a/qapi/event.json +++ b/qapi/event.json @@ -243,6 +243,20 @@ { 'event': 'SPICE_MIGRATE_COMPLETED' } ## +# @MIGRATION +# +# Emitted when a migration event happens +# +# @status: @MigrationStatus describing the current migration status. +# If this field is not returned, no migration process +# has been initiated +# +# Since: 2.4 +## +{ 'event': 'MIGRATION', + 'data': {'status': 'MigrationStatus'}} + +## # @ACPI_DEVICE_OST # # Emitted when guest executes ACPI _OST method. -- 2.4.3
[Qemu-devel] [PATCH 00/11] Migraiton events + optional sections
Hi As the beggining of both series have been accepted, I merged both here. Changes: - answered all comments on list and applied suggested changes - Use migrate_set_state() consistently - we were misusing atomic_cmpxchg(), it didn't matter until now because we were missing only traces, but it showed with events missing. - Reorganized how the migration events are generated, now only on migrate_set_state. Please review. Juan Quintela (11): runstate: Add runstate store runstate: migration allows more transitions now migration: create new section to store global state global_state: Make section optional vmstate: Create optional sections migration: Add configuration section migration: Use cmpxchg correctly migration: Use always helper to set state migration: No need to call trace_migrate_set_state() migration: create migration event migration: Add migration events on target side docs/qmp/qmp-events.txt | 14 + hw/i386/pc_piix.c | 2 + hw/i386/pc_q35.c | 2 + include/migration/migration.h | 4 ++ include/migration/vmstate.h | 2 + include/sysemu/sysemu.h | 1 + migration/migration.c | 138 +++--- migration/savevm.c| 69 + migration/vmstate.c | 11 qapi/event.json | 14 + trace-events | 1 + vl.c | 15 + 12 files changed, 263 insertions(+), 10 deletions(-) -- 2.4.3
[Qemu-devel] [PATCH 02/11] runstate: migration allows more transitions now
Next commit would allow to move from incoming migration to error happening on source. Should we add more states to this transition? Luiz? Signed-off-by: Juan Quintela --- vl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vl.c b/vl.c index c659a00..555fd88 100644 --- a/vl.c +++ b/vl.c @@ -571,6 +571,8 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR }, +{ RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, -- 2.4.3
[Qemu-devel] [PATCH 04/11] global_state: Make section optional
This section would be sent: a- for all new machine types b- for old achine types if section state is different form {running,paused} that were the only giving us troubles. So, in new qemus: it is alwasy there. In old qemus: they are only there if it an error has happened, basically stoping on target. Signed-off-by: Juan Quintela --- hw/i386/pc_piix.c | 1 + hw/i386/pc_q35.c | 1 + include/migration/migration.h | 1 + migration/migration.c | 30 +- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e142f75..735fb22 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -307,6 +307,7 @@ static void pc_init1(MachineState *machine) static void pc_compat_2_3(MachineState *machine) { savevm_skip_section_footers(); +global_state_set_optional(); } static void pc_compat_2_2(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index b68263d..0523ecc 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -291,6 +291,7 @@ static void pc_q35_init(MachineState *machine) static void pc_compat_2_3(MachineState *machine) { savevm_skip_section_footers(); +global_state_set_optional(); } static void pc_compat_2_2(MachineState *machine) diff --git a/include/migration/migration.h b/include/migration/migration.h index 1280193..bb53d93 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -198,4 +198,5 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset, void ram_mig_init(void); void savevm_skip_section_footers(void); void register_global_state(void); +void global_state_set_optional(void); #endif diff --git a/migration/migration.c b/migration/migration.c index 01bb90d..f1ecf76 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -99,6 +99,7 @@ void migration_incoming_state_destroy(void) typedef struct { +bool optional; int32_t size; uint8_t runstate[100]; } GlobalState; @@ -119,6 +120,33 @@ static char *global_state_get_runstate(void) return (char *)global_state.runstate; } +void global_state_set_optional(void) +{ +global_state.optional = true; +} + +static bool global_state_needed(void *opaque) +{ +GlobalState *s = opaque; +char *runstate = (char *)s->runstate; + +/* If it is not optional, it is mandatory */ + +if (s->optional == false) { +return true; +} + +/* If state is running or paused, it is not needed */ + +if (strcmp(runstate, "running") == 0 || +strcmp(runstate, "paused") == 0) { +return false; +} + +/* for any other state it is needed */ +return true; +} + static int global_state_post_load(void *opaque, int version_id) { GlobalState *s = opaque; @@ -149,7 +177,6 @@ static void global_state_pre_save(void *opaque) GlobalState *s = opaque; s->size = strlen((char *)s->runstate) + 1; -printf("saved state: %s\n", s->runstate); } static const VMStateDescription vmstate_globalstate = { @@ -158,6 +185,7 @@ static const VMStateDescription vmstate_globalstate = { .minimum_version_id = 1, .post_load = global_state_post_load, .pre_save = global_state_pre_save, +.needed = global_state_needed, .fields = (VMStateField[]) { VMSTATE_INT32(size, GlobalState), VMSTATE_BUFFER(runstate, GlobalState), -- 2.4.3
[Qemu-devel] [PATCH 03/11] migration: create new section to store global state
This includes a new section that for now just stores the current qemu state. Right now, there are only one way to control what is the state of the target after migration. - If you run the target qemu with -S, it would start stopped. - If you run the target qemu without -S, it would run just after migration finishes. The problem here is what happens if we start the target without -S and there happens one error during migration that puts current state as -EIO. Migration would ends (notice that the error happend doing block IO, network IO, i.e. nothing related with migration), and when migration finish, we would just "continue" running on destination, probably hanging the guest/corruption data, whatever. Signed-off-by: Juan Quintela --- include/migration/migration.h | 1 + migration/migration.c | 93 +-- vl.c | 1 + 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/include/migration/migration.h b/include/migration/migration.h index 9387c8c..1280193 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -197,4 +197,5 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset, void ram_mig_init(void); void savevm_skip_section_footers(void); +void register_global_state(void); #endif diff --git a/migration/migration.c b/migration/migration.c index b04b457..01bb90d 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -25,6 +25,7 @@ #include "qemu/thread.h" #include "qmp-commands.h" #include "trace.h" +#include "qapi/util.h" #define MAX_THROTTLE (32 << 20) /* Migration speed throttling */ @@ -96,6 +97,81 @@ void migration_incoming_state_destroy(void) mis_current = NULL; } + +typedef struct { +int32_t size; +uint8_t runstate[100]; +} GlobalState; + +static GlobalState global_state; + +static void global_state_store(void) +{ +if (!runstate_store((char *)global_state.runstate, +sizeof(global_state.runstate))) { +printf("Runstate is too big\n"); +exit(-1); +} +} + +static char *global_state_get_runstate(void) +{ +return (char *)global_state.runstate; +} + +static int global_state_post_load(void *opaque, int version_id) +{ +GlobalState *s = opaque; +int ret = 0; +char *runstate = (char *)s->runstate; + +printf("loaded state: %s\n", runstate); + +if (strcmp(runstate, "running") != 0) { +Error *local_err = NULL; +int r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX, +-1, &local_err); + +if (r == -1) { +if (local_err) { +error_report_err(local_err); +} +return -1; +} +ret = vm_stop_force_state(r); +} + + return ret; +} + +static void global_state_pre_save(void *opaque) +{ +GlobalState *s = opaque; + +s->size = strlen((char *)s->runstate) + 1; +printf("saved state: %s\n", s->runstate); +} + +static const VMStateDescription vmstate_globalstate = { +.name = "globalstate", +.version_id = 1, +.minimum_version_id = 1, +.post_load = global_state_post_load, +.pre_save = global_state_pre_save, +.fields = (VMStateField[]) { +VMSTATE_INT32(size, GlobalState), +VMSTATE_BUFFER(runstate, GlobalState), +VMSTATE_END_OF_LIST() +}, +}; + +void register_global_state(void) +{ +/* We would use it independently that we receive it */ +strcpy((char *)&global_state.runstate, ""); +vmstate_register(NULL, 0, &vmstate_globalstate, &global_state); +} + /* * Called on -incoming with a defer: uri. * The migration can be started later after any parameters have been @@ -163,10 +239,20 @@ static void process_incoming_migration_co(void *opaque) exit(EXIT_FAILURE); } -if (autostart) { +/* runstate == "" means that we haven't received it through the + * wire, so we obey autostart. runstate == runing means that we + * need to run it, we need to make sure that we do it after + * everything else has finished. Every other state change is done + * at the post_load function */ + +if (strcmp(global_state_get_runstate(), "running") == 0) { vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); +} else if (strcmp(global_state_get_runstate(), "") == 0) { +if (autostart) { +vm_start(); +} else { +runstate_set(RUN_STATE_PAUSED); +} } migrate_decompress_threads_join(); } @@ -791,6 +877,7 @@ static void *migration_thread(void *opaque) qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); old_vm_running = runstate_is_running(); +global_state_store(); ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); if (ret >= 0) { qemu_file_set_rate_limit(s->file, INT64_MAX); diff --git a/vl
[Qemu-devel] [PATCH 01/11] runstate: Add runstate store
This allows us to store the current state to send it through migration. Signed-off-by: Juan Quintela --- include/sysemu/sysemu.h | 1 + vl.c| 12 2 files changed, 13 insertions(+) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 0304aa7..d7bec42 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -28,6 +28,7 @@ bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); bool runstate_needs_reset(void); +bool runstate_store(char *str, size_t size); typedef struct vm_change_state_entry VMChangeStateEntry; typedef void VMChangeStateHandler(void *opaque, int running, RunState state); diff --git a/vl.c b/vl.c index 2201e27..c659a00 100644 --- a/vl.c +++ b/vl.c @@ -630,6 +630,18 @@ bool runstate_check(RunState state) return current_run_state == state; } +bool runstate_store(char *str, size_t size) +{ +const char *state = RunState_lookup[current_run_state]; +size_t len = strlen(state) + 1; + +if (len > size) { +return false; +} +memcpy(str, state, len); +return true; +} + static void runstate_init(void) { const RunStateTransition *p; -- 2.4.3
Re: [Qemu-devel] [PATCH v8 0/4] remove icc bus/bridge
ping... On 06/08/2015 06:35 PM, Zhu Guihua wrote: ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on Eduardo's x86 tree. https://github.com/ehabkost/qemu.git v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized v6: -reword commit message -drop NULL check for APIC device -use C cast instead of QOM cast v5: -convert DEVICE() casts to C casts -use a local variable instead of doing the cast inline twice -drop to set cpu's parent bus -rename patch 3's subject -fix a bug about setting cpu's apic base v4: -add wrapper to get root memory region from address space -set cpu apic base's default value in x86_cpu_apic_create() -drop NULL check for cpu apic_state -put drop of the unused files about icc_bus into a seprate patch -put DEVICE() casts into a seprate patch v3: -replace init apic by object_new() -add reset apic at the time of CPU reset Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): hw: add a wrapper for registering reset handler icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - exec.c | 5 ++ hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 31 +++--- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 19 +++--- include/exec/memory.h | 5 ++ include/hw/cpu/icc_bus.h | 82 -- include/hw/hw.h| 4 ++ include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 25 +--- target-i386/cpu.h | 4 ++ vl.c | 18 +- 17 files changed, 78 insertions(+), 263 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h
Re: [Qemu-devel] [RFC v10 13/19] pci: add bus reset_notifiers callbacks for host bus reset
On 06/16/2015 06:20 PM, Michael S. Tsirkin wrote: On Tue, Jun 16, 2015 at 04:10:57PM +0800, Chen Fan wrote: Particularly, For vfio devices, Once need to recovery devices by bus reset such as AER, we always need to reset the host bus to recovery the devices under the bus, so we need to add pci bus callbacks to specify to do host bus reset. Signed-off-by: Chen Fan Interesting. What prevents guest from triggering reset at an arbitrary time, killing all VFs for all guests? If the VF device was assigned to VM, with enable aer, we check the VF affected devices e.g. the other VFs and PF is belonged to VM or not. so It can't to affect other VMs for this. if disable aer, there will no affection. Thanks, Chen --- hw/pci/pci.c | 16 hw/pci/pci_bridge.c | 6 ++ include/hw/pci/pci.h | 4 include/hw/pci/pci_bus.h | 2 ++ 4 files changed, 28 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 3423c3a..3bd954e 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -74,11 +74,27 @@ static const VMStateDescription vmstate_pcibus = { } }; +void pci_bus_add_reset_notifier(PCIBus *bus, Notifier *notify) +{ +notifier_list_add(&bus->reset_notifiers, notify); +} + +void pci_bus_remove_reset_notifier(Notifier *notify) +{ +notifier_remove(notify); +} + +void pci_bus_run_reset_notifier(PCIBus *bus, void *opaque) +{ +notifier_list_notify(&bus->reset_notifiers, opaque); +} + static void pci_bus_realize(BusState *qbus, Error **errp) { PCIBus *bus = PCI_BUS(qbus); vmstate_register(NULL, -1, &vmstate_pcibus, bus); +notifier_list_init(&bus->reset_notifiers); } static void pci_bus_unrealize(BusState *qbus, Error **errp) diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index 40c97b1..a8e3f57 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -267,6 +267,12 @@ void pci_bridge_write_config(PCIDevice *d, newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL); if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) { +/* + * Notify all vfio-pci devices under the bus + * to do physical bus reset. + */ +pci_for_each_bus(&s->sec_bus, +pci_bus_run_reset_notifier, d); /* Trigger hot reset on 0->1 transition. */ qbus_reset_all(&s->sec_bus.qbus); } diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 6c2af0d..d353c9d 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -7,6 +7,7 @@ #include "exec/memory.h" #include "sysemu/dma.h" #include "qapi/error.h" +#include "qemu/notify.h" /* PCI includes legacy ISA access. */ #include "hw/isa/isa.h" @@ -377,6 +378,9 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus); void pci_device_set_intx_routing_notifier(PCIDevice *dev, PCIINTxRoutingNotifier notifier); void pci_device_reset(PCIDevice *dev); +void pci_bus_add_reset_notifier(PCIBus *bus, Notifier *notify); +void pci_bus_remove_reset_notifier(Notifier *notify); +void pci_bus_run_reset_notifier(PCIBus *bus, void *opaque); PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, const char *default_model, diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index fabaeee..3b551d7 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -29,6 +29,8 @@ struct PCIBus { Keep a count of the number of devices with raised IRQs. */ int nirq; int *irq_count; + +NotifierList reset_notifiers; }; typedef struct PCIBridgeWindows PCIBridgeWindows; -- 1.9.3 .
Re: [Qemu-devel] [PATCH 9/9] migration: Add configuration section
"Dr. David Alan Gilbert" wrote: > * Juan Quintela (quint...@redhat.com) wrote: >> It needs to be the first one and it is not optional, that is the reason >> why it is opencoded. For new machine types, it is required than machine >> type name is the same in both sides. >> >> It is just done right now for pc's. >> >> Signed-off-by: Juan Quintela >> --- >> hw/i386/pc_piix.c | 1 + >> hw/i386/pc_q35.c | 1 + >> include/migration/migration.h | 2 ++ >> savevm.c | 72 >> --- >> 4 files changed, 71 insertions(+), 5 deletions(-) >> >> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c >> index 5c04784..95806b3 100644 >> --- a/hw/i386/pc_piix.c >> +++ b/hw/i386/pc_piix.c >> @@ -314,6 +314,7 @@ static void pc_init_pci(MachineState *machine) >> static void pc_compat_2_3(MachineState *machine) >> { >> global_state_set_optional(); >> +savevm_skip_configuration(); >> } >> >> static void pc_compat_2_2(MachineState *machine) >> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c >> index cc5827a..e32c040 100644 >> --- a/hw/i386/pc_q35.c >> +++ b/hw/i386/pc_q35.c >> @@ -293,6 +293,7 @@ static void pc_q35_init(MachineState *machine) >> static void pc_compat_2_3(MachineState *machine) >> { >> global_state_set_optional(); >> +savevm_skip_configuration(); > > It's a shame that these two functions, that do basically the same thing > (to two different pieces of data) have such different names. Code is similar, but meaning is different. 1st one: it is sent only if needed 2nd one: it is completely skiped. Calling the second: configuration_optional() looks weeird, when the meaning is NO_configuration. We could rename the 1st one to global_state_skip_if_not_needed, but not sure that it would be better :-( I am open to name changes if you provide better names O:-) > >> } >> >> static void pc_compat_2_2(MachineState *machine) >> diff --git a/include/migration/migration.h b/include/migration/migration.h >> index f939d88..da89827 100644 >> --- a/include/migration/migration.h >> +++ b/include/migration/migration.h >> @@ -34,6 +34,7 @@ >> #define QEMU_VM_SECTION_FULL 0x04 >> #define QEMU_VM_SUBSECTION 0x05 >> #define QEMU_VM_VMDESCRIPTION0x06 >> +#define QEMU_VM_CONFIGURATION0x07 >> >> struct MigrationParams { >> bool blk; >> @@ -184,4 +185,5 @@ void register_global_state(void); >> void global_state_store(void); >> char *global_state_get_runstate(void); >> void global_state_set_optional(void); >> +void savevm_skip_configuration(void); >> #endif >> diff --git a/savevm.c b/savevm.c >> index 2b4e554..ea149e7 100644 >> --- a/savevm.c >> +++ b/savevm.c >> @@ -238,11 +238,55 @@ typedef struct SaveStateEntry { >> typedef struct SaveState { >> QTAILQ_HEAD(, SaveStateEntry) handlers; >> int global_section_id; >> +bool skip_configuration; >> +uint32_t len; >> +char *name; >> } SaveState; >> >> static SaveState savevm_state = { >> .handlers = QTAILQ_HEAD_INITIALIZER(savevm_state.handlers), >> .global_section_id = 0, >> +.skip_configuration = false, >> +}; >> + >> +void savevm_skip_configuration(void) >> +{ >> +savevm_state.skip_configuration = true; >> +} >> + >> + >> +static void configuration_pre_save(void *opaque) >> +{ >> +SaveState *state = opaque; >> +const char *current_name = MACHINE_GET_CLASS(current_machine)->name; >> + >> +state->len = strlen(current_name); >> +state->name = strdup(current_name); > > Will that ever get freed? If it never gets freed is it safe to > just make it > >state->len = current_name; No, changed. > > >> + >> +static int configuration_post_load(void *opaque, int version_id) >> +{ >> +SaveState *state = opaque; >> +const char *current_name = MACHINE_GET_CLASS(current_machine)->name; >> + >> +if (strncmp(state->name, current_name, state->len) != 0) { >> +error_report("Machine type received is '%s' and local is '%s'", >> + state->name, current_name); >> +return -EINVAL; >> +} >> +return 0; >> +} >> + >> +static const VMStateDescription vmstate_configuration = { >> +.name = "configuartion", > > Typo! configuration Thanks.
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
On Tue, Jun 16, 2015 at 06:21:56PM -0700, Peter Crosthwaite wrote: > On Tue, Jun 16, 2015 at 6:12 PM, Edgar E. Iglesias > wrote: > > On Tue, Jun 16, 2015 at 06:09:22PM -0700, Peter Crosthwaite wrote: > >> On Tue, Jun 16, 2015 at 5:54 PM, Edgar E. Iglesias > >> wrote: > >> > On Tue, Jun 16, 2015 at 05:36:19PM -0700, Peter Crosthwaite wrote: > >> >> Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset > >> >> (this is true of real hardware) by default or selectable as the boot > >> >> processor. > >> > > >> > Hi Peter, > >> > > >> > I think it would be good if you could model at least a minimal > >> > way to release the R5s from reset the "real" way. The R5s are > >> > not covered by PSCI in real code and not all code uses PSCI, > >> > in particular not any R5 code. > >> > > >> > How would the R5s be useful with upstream with this version? > >> > Maybe I'm missing something. > >> > > >> > >> You can nominate an R5 instead of A53 as the one non-powered-off cpu > >> by setting the zynqmp boot-cpu property with -global: > >> > >> $ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel > >> ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]" > >> > >> This works with elf boots. > > > > In that mode, how do I release the A53s (or the other R5)? > > Will it be either one R5 or the A53s? > > > > Just one or the other so far unless you do a backdoor PSCI release > from SW. Loading multiple softwares needs either a more dynamic Note that you can't do PSCI from the R5s. The A53s could wake the R5s with PSCI in this QEMU but not on real SW stack which is a little confusing... > bootloader process or the reset controller model, both of which I want > to follow up later with. OK, it's quite limited ATM but I guess it's a step forward... Thanks, Edgar > > Regards, > Peter > > > Cheers, > > Edgar > > > > > >> > >> Regards, > >> Peter > >> > >> > Cheers, > >> > Edgar > >> > > >> > > >> >> > >> >> Signed-off-by: Peter Crosthwaite > >> >> --- > >> >> changed since v2: > >> >> Add boot-cpu start-powered-off conditional > >> >> changed since v1: > >> >> s/rcpu/rpu-cpu/ > >> >> > >> >> hw/arm/xlnx-zynqmp.c | 34 ++ > >> >> include/hw/arm/xlnx-zynqmp.h | 2 ++ > >> >> 2 files changed, 36 insertions(+) > >> >> > >> >> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c > >> >> index 0c966da..5e72078 100644 > >> >> --- a/hw/arm/xlnx-zynqmp.c > >> >> +++ b/hw/arm/xlnx-zynqmp.c > >> >> @@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) > >> >>&error_abort); > >> >> } > >> >> > >> >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { > >> >> +object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), > >> >> + "cortex-r5-" TYPE_ARM_CPU); > >> >> +object_property_add_child(obj, "rpu-cpu[*]", > >> >> OBJECT(&s->rpu_cpu[i]), > >> >> + &error_abort); > >> >> +} > >> >> + > >> >> object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); > >> >> qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); > >> >> > >> >> @@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, > >> >> Error **errp) > >> >> qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); > >> >> } > >> >> > >> >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { > >> >> +char *name; > >> >> + > >> >> +name = > >> >> object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); > >> >> +if (strcmp(name, boot_cpu)) { > >> >> +/* Secondary CPUs start in PSCI powered-down state */ > >> >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, > >> >> + "start-powered-off", > >> >> &error_abort); > >> >> +} else { > >> >> +s->boot_cpu_ptr = &s->rpu_cpu[i]; > >> >> +} > >> >> + > >> >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, > >> >> "reset-hivecs", > >> >> + &err); > >> >> +if (err != NULL) { > >> >> +error_propagate(errp, err); > >> >> +return; > >> >> +} > >> >> + > >> >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, > >> >> "realized", > >> >> + &err); > >> >> +if (err) { > >> >> +error_propagate((errp), (err)); > >> >> +return; > >> >> +} > >> >> +} > >> >> + > >> >> if (!s->boot_cpu_ptr) { > >> >> error_setg(errp, "ZynqMP Boot cpu %s not found\n", boot_cpu); > >> >> return; > >> >> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h > >> >> index 4f14a22..c379632 100644 > >> >> --- a/include/hw/arm/xlnx-zynqmp.h > >> >> +++ b/include/hw/arm/xlnx-zynqmp.h > >> >> @@ -28,6 +28,7 @@ > >> >> TYPE_XLNX_ZYNQMP) > >> >> > >> >> #defi
Re: [Qemu-devel] [PATCH 7/9] global_state: Make section optional
"Dr. David Alan Gilbert" wrote: > * Juan Quintela (quint...@redhat.com) wrote: >> This section would be sent: >> >> a- for all new machine types >> b- for old achine types if section state is different form {running,paused} >>that were the only giving us troubles. >> >> So, in new qemus: it is alwasy there. In old qemus: they are only >> there if it an error has happened, basically stoping on target. > > I worry about whether we should do that for old machine types; > in the current code, if the destination was started with -S it wouldn't > start in the case you were worried about, couldn't a careful managment > layer spot-the state on the source and ensure it didn't start the destination? > > (What happens with guests that have been shutdown during a migrate, or panic > or something - not that I'm sure what happens now). Old guest: If we start with -S, destination end in pause. If there has been an error during migration, management have to notice it. Guest hasn't been started with -S, there is one error during migration on source, but migration happens to end correctly. Destination will try to continue and will not notice the error on source. Crash if we are lucky, Disk corruption if we aren't. So, for old guests, if the end state of the source is different of paused/running, we just break migration, it is the safer thing to do, antyhing else is just guessing. > >> Signed-off-by: Juan Quintela >> --- >> hw/i386/pc_piix.c | 2 ++ >> hw/i386/pc_q35.c | 2 ++ >> include/migration/migration.h | 2 +- >> migration/migration.c | 29 + >> 4 files changed, 34 insertions(+), 1 deletion(-) >> >> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c >> index 212e263..5c04784 100644 >> --- a/hw/i386/pc_piix.c >> +++ b/hw/i386/pc_piix.c >> @@ -52,6 +52,7 @@ >> #ifdef CONFIG_XEN >> # include >> #endif >> +#include "migration/migration.h" >> >> #define MAX_IDE_BUS 2 >> >> @@ -312,6 +313,7 @@ static void pc_init_pci(MachineState *machine) >> >> static void pc_compat_2_3(MachineState *machine) >> { >> +global_state_set_optional(); >> } >> >> static void pc_compat_2_2(MachineState *machine) >> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c >> index e67f2de..cc5827a 100644 >> --- a/hw/i386/pc_q35.c >> +++ b/hw/i386/pc_q35.c >> @@ -45,6 +45,7 @@ >> #include "hw/usb.h" >> #include "hw/cpu/icc_bus.h" >> #include "qemu/error-report.h" >> +#include "migration/migration.h" >> >> /* ICH9 AHCI has 6 ports */ >> #define MAX_SATA_PORTS 6 >> @@ -291,6 +292,7 @@ static void pc_q35_init(MachineState *machine) >> >> static void pc_compat_2_3(MachineState *machine) >> { >> +global_state_set_optional(); >> } >> >> static void pc_compat_2_2(MachineState *machine) >> diff --git a/include/migration/migration.h b/include/migration/migration.h >> index 785c2dc..f939d88 100644 >> --- a/include/migration/migration.h >> +++ b/include/migration/migration.h >> @@ -183,5 +183,5 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t >> block_offset, >> void register_global_state(void); >> void global_state_store(void); >> char *global_state_get_runstate(void); >> - >> +void global_state_set_optional(void); >> #endif >> diff --git a/migration/migration.c b/migration/migration.c >> index ab69f81..1035689 100644 >> --- a/migration/migration.c >> +++ b/migration/migration.c >> @@ -868,6 +868,7 @@ void migrate_fd_connect(MigrationState *s) >> } >> >> typedef struct { >> +bool optional; >> int32_t size; >> uint8_t runstate[100]; >> } GlobalState; >> @@ -888,6 +889,33 @@ char *global_state_get_runstate(void) >> return (char *)global_state.runstate; >> } >> >> +void global_state_set_optional(void) >> +{ >> +global_state.optional = true; >> +} > > > It's a shame that it's not really a device class, because then > you could have used a DEFINE_PROP_BIT. Yeap. > >> +static bool global_state_needed(void *opaque) >> +{ >> +GlobalState *s = opaque; >> +char *runstate = (char *)s->runstate; >> + >> +/* If it is not optional, it is mandatory */ >> + >> +if (s->optional == false) { >> +return true; >> +} >> + >> +/* If state is running or paused, it is not needed */ >> + >> +if (strcmp(runstate, "running") == 0 || >> +strcmp(runstate, "paused") == 0) { >> +return false; >> +} >> + >> +/* for any other state it is needed */ >> +return true; >> +} >> + >> static int global_state_post_load(void *opaque, int version_id) >> { >> GlobalState *s = opaque; >> @@ -921,6 +949,7 @@ static const VMStateDescription vmstate_globalstate = { >> .minimum_version_id = 1, >> .post_load = global_state_post_load, >> .pre_save = global_state_pre_save, >> +.needed = global_state_needed, >> .fields = (VMStateField[]) { >> VMSTATE_INT32(size, GlobalState), >> VMSTATE_BUFFER(runstate, GlobalState), >> -- >> 2.4.0 >> >> > -- >
Re: [Qemu-devel] [PATCH target-arm v3 5/7] arm: xlnx-zynqmp: Preface CPU variables with "apu"
On Tue, Jun 16, 2015 at 05:36:14PM -0700, Peter Crosthwaite wrote: > The CPUs currently supported by zynqmp are the APU (application > processing unit) CPUs. There are other CPUs in Zynqmp so unqualified > "cpus" in ambiguous. Preface the variables with "APU" accordingly, to > prepare support adding the RPU (realtime processing unit) processors. > Reviewed-by: Edgar E. Iglesias > Signed-off-by: Peter Crosthwaite > --- > changed since v1: > s/acpu/apu-cpu/ > > hw/arm/xlnx-ep108.c | 2 +- > hw/arm/xlnx-zynqmp.c | 26 ++ > include/hw/arm/xlnx-zynqmp.h | 4 ++-- > 3 files changed, 17 insertions(+), 15 deletions(-) > > diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c > index b924f5e..7a98dd6 100644 > --- a/hw/arm/xlnx-ep108.c > +++ b/hw/arm/xlnx-ep108.c > @@ -65,7 +65,7 @@ static void xlnx_ep108_init(MachineState *machine) > xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline; > xlnx_ep108_binfo.initrd_filename = machine->initrd_filename; > xlnx_ep108_binfo.loader_start = 0; > -arm_load_kernel(&s->soc.cpu[0], &xlnx_ep108_binfo); > +arm_load_kernel(&s->soc.apu_cpu[0], &xlnx_ep108_binfo); > } > > static QEMUMachine xlnx_ep108_machine = { > diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c > index 6b01965..353ecad 100644 > --- a/hw/arm/xlnx-zynqmp.c > +++ b/hw/arm/xlnx-zynqmp.c > @@ -64,10 +64,10 @@ static void xlnx_zynqmp_init(Object *obj) > XlnxZynqMPState *s = XLNX_ZYNQMP(obj); > int i; > > -for (i = 0; i < XLNX_ZYNQMP_NUM_CPUS; i++) { > -object_initialize(&s->cpu[i], sizeof(s->cpu[i]), > +for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) { > +object_initialize(&s->apu_cpu[i], sizeof(s->apu_cpu[i]), >"cortex-a53-" TYPE_ARM_CPU); > -object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpu[i]), > +object_property_add_child(obj, "apu-cpu[*]", OBJECT(&s->apu_cpu[i]), >&error_abort); > } > > @@ -95,7 +95,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error > **errp) > > qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32); > qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2); > -qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_CPUS); > +qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", > XLNX_ZYNQMP_NUM_APU_CPUS); > object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); > if (err) { > error_propagate((errp), (err)); > @@ -121,38 +121,40 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error > **errp) > } > } > > -for (i = 0; i < XLNX_ZYNQMP_NUM_CPUS; i++) { > +for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) { > qemu_irq irq; > > -object_property_set_int(OBJECT(&s->cpu[i]), QEMU_PSCI_CONDUIT_SMC, > +object_property_set_int(OBJECT(&s->apu_cpu[i]), > QEMU_PSCI_CONDUIT_SMC, > "psci-conduit", &error_abort); > if (i > 0) { > /* Secondary CPUs start in PSCI powered-down state */ > -object_property_set_bool(OBJECT(&s->cpu[i]), true, > +object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, > "start-powered-off", &error_abort); > } > > -object_property_set_int(OBJECT(&s->cpu[i]), GIC_BASE_ADDR, > +object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR, > "reset-cbar", &err); > if (err) { > error_propagate((errp), (err)); > return; > } > > -object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); > +object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized", > + &err); > if (err) { > error_propagate((errp), (err)); > return; > } > > sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i, > - qdev_get_gpio_in(DEVICE(&s->cpu[i]), > ARM_CPU_IRQ)); > + qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]), > +ARM_CPU_IRQ)); > irq = qdev_get_gpio_in(DEVICE(&s->gic), > arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI)); > -qdev_connect_gpio_out(DEVICE(&s->cpu[i]), 0, irq); > +qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 0, irq); > irq = qdev_get_gpio_in(DEVICE(&s->gic), > arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI)); > -qdev_connect_gpio_out(DEVICE(&s->cpu[i]), 1, irq); > +qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); > } > > for (i = 0; i < GIC_NUM_SPI_INTR; i++) { > diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h > index 79c2b0b..d042df1 100644 > --- a/include/hw/arm/xlnx-zynqmp.h > +++ b/include/hw/ar
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
On Tue, Jun 16, 2015 at 6:12 PM, Edgar E. Iglesias wrote: > On Tue, Jun 16, 2015 at 06:09:22PM -0700, Peter Crosthwaite wrote: >> On Tue, Jun 16, 2015 at 5:54 PM, Edgar E. Iglesias >> wrote: >> > On Tue, Jun 16, 2015 at 05:36:19PM -0700, Peter Crosthwaite wrote: >> >> Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset >> >> (this is true of real hardware) by default or selectable as the boot >> >> processor. >> > >> > Hi Peter, >> > >> > I think it would be good if you could model at least a minimal >> > way to release the R5s from reset the "real" way. The R5s are >> > not covered by PSCI in real code and not all code uses PSCI, >> > in particular not any R5 code. >> > >> > How would the R5s be useful with upstream with this version? >> > Maybe I'm missing something. >> > >> >> You can nominate an R5 instead of A53 as the one non-powered-off cpu >> by setting the zynqmp boot-cpu property with -global: >> >> $ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel >> ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]" >> >> This works with elf boots. > > In that mode, how do I release the A53s (or the other R5)? > Will it be either one R5 or the A53s? > Just one or the other so far unless you do a backdoor PSCI release from SW. Loading multiple softwares needs either a more dynamic bootloader process or the reset controller model, both of which I want to follow up later with. Regards, Peter > Cheers, > Edgar > > >> >> Regards, >> Peter >> >> > Cheers, >> > Edgar >> > >> > >> >> >> >> Signed-off-by: Peter Crosthwaite >> >> --- >> >> changed since v2: >> >> Add boot-cpu start-powered-off conditional >> >> changed since v1: >> >> s/rcpu/rpu-cpu/ >> >> >> >> hw/arm/xlnx-zynqmp.c | 34 ++ >> >> include/hw/arm/xlnx-zynqmp.h | 2 ++ >> >> 2 files changed, 36 insertions(+) >> >> >> >> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c >> >> index 0c966da..5e72078 100644 >> >> --- a/hw/arm/xlnx-zynqmp.c >> >> +++ b/hw/arm/xlnx-zynqmp.c >> >> @@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) >> >>&error_abort); >> >> } >> >> >> >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { >> >> +object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), >> >> + "cortex-r5-" TYPE_ARM_CPU); >> >> +object_property_add_child(obj, "rpu-cpu[*]", >> >> OBJECT(&s->rpu_cpu[i]), >> >> + &error_abort); >> >> +} >> >> + >> >> object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); >> >> qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); >> >> >> >> @@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, >> >> Error **errp) >> >> qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); >> >> } >> >> >> >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { >> >> +char *name; >> >> + >> >> +name = >> >> object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); >> >> +if (strcmp(name, boot_cpu)) { >> >> +/* Secondary CPUs start in PSCI powered-down state */ >> >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, >> >> + "start-powered-off", &error_abort); >> >> +} else { >> >> +s->boot_cpu_ptr = &s->rpu_cpu[i]; >> >> +} >> >> + >> >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, >> >> "reset-hivecs", >> >> + &err); >> >> +if (err != NULL) { >> >> +error_propagate(errp, err); >> >> +return; >> >> +} >> >> + >> >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, >> >> "realized", >> >> + &err); >> >> +if (err) { >> >> +error_propagate((errp), (err)); >> >> +return; >> >> +} >> >> +} >> >> + >> >> if (!s->boot_cpu_ptr) { >> >> error_setg(errp, "ZynqMP Boot cpu %s not found\n", boot_cpu); >> >> return; >> >> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h >> >> index 4f14a22..c379632 100644 >> >> --- a/include/hw/arm/xlnx-zynqmp.h >> >> +++ b/include/hw/arm/xlnx-zynqmp.h >> >> @@ -28,6 +28,7 @@ >> >> TYPE_XLNX_ZYNQMP) >> >> >> >> #define XLNX_ZYNQMP_NUM_APU_CPUS 4 >> >> +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2 >> >> #define XLNX_ZYNQMP_NUM_GEMS 4 >> >> #define XLNX_ZYNQMP_NUM_UARTS 2 >> >> >> >> @@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState { >> >> >> >> /*< public >*/ >> >> ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS]; >> >> +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS]; >> >> GICState gic; >> >> MemoryRegion >> >> gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; >> >> CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; >> >> -- >> >> 2.4.3.3.g905f831 >> >> >> > >
Re: [Qemu-devel] [PATCH target-arm v3 4/7] target-arm: Add support for Cortex-R5
On Tue, Jun 16, 2015 at 05:36:12PM -0700, Peter Crosthwaite wrote: > Introduce a CPU model for the Cortex R5 processor. ARMv7 with MPU, > and both thumb and ARM div instructions. > > Also implement dummy ATCM and BTCM. These CPs are defined for R5 but > don't have a lot of meaning in QEMU yet. Raz them so the guest can > proceed if they are read. The TCM registers will return a size of 0, > indicating no TCM. > > Reviewed-by: Peter Maydell Reviewed-by: Edgar E. Iglesias > Signed-off-by: Peter Crosthwaite > --- > Based loosely on an old patch of Andreas' for the cortex-r4. > changed since v1: > Squashed in R5 specific CP regs patch > Reordered to be after supporting patches > set mp_is_up > > target-arm/cpu.c | 38 ++ > 1 file changed, 38 insertions(+) > > diff --git a/target-arm/cpu.c b/target-arm/cpu.c > index 4010d81..dce91bb 100644 > --- a/target-arm/cpu.c > +++ b/target-arm/cpu.c > @@ -847,6 +847,43 @@ static void arm_v7m_class_init(ObjectClass *oc, void > *data) > cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; > } > > +static const ARMCPRegInfo cortexr5_cp_reginfo[] = { > +/* Dummy the TCM region regs for the moment */ > +{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, > + .access = PL1_RW, .type = ARM_CP_CONST }, > +{ .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, > + .access = PL1_RW, .type = ARM_CP_CONST }, > +REGINFO_SENTINEL > +}; > + > +static void cortex_r5_initfn(Object *obj) > +{ > +ARMCPU *cpu = ARM_CPU(obj); > + > +set_feature(&cpu->env, ARM_FEATURE_V7); > +set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV); > +set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); > +set_feature(&cpu->env, ARM_FEATURE_V7MP); > +set_feature(&cpu->env, ARM_FEATURE_MPU); > +cpu->midr = 0x411fc153; /* r1p3 */ > +cpu->id_pfr0 = 0x0131; > +cpu->id_pfr1 = 0x001; > +cpu->id_dfr0 = 0x010400; > +cpu->id_afr0 = 0x0; > +cpu->id_mmfr0 = 0x0210030; > +cpu->id_mmfr1 = 0x; > +cpu->id_mmfr2 = 0x0120; > +cpu->id_mmfr3 = 0x0211; > +cpu->id_isar0 = 0x210; > +cpu->id_isar1 = 0x13112111; > +cpu->id_isar2 = 0x21232141; > +cpu->id_isar3 = 0x01112131; > +cpu->id_isar4 = 0x0010142; > +cpu->id_isar5 = 0x0; > +cpu->mp_is_up = true; > +define_arm_cp_regs(cpu, cortexr5_cp_reginfo); > +} > + > static const ARMCPRegInfo cortexa8_cp_reginfo[] = { > { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = > 0, >.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, > @@ -1238,6 +1275,7 @@ static const ARMCPUInfo arm_cpus[] = { > { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, > { .name = "cortex-m3", .initfn = cortex_m3_initfn, > .class_init = arm_v7m_class_init }, > +{ .name = "cortex-r5", .initfn = cortex_r5_initfn }, > { .name = "cortex-a8", .initfn = cortex_a8_initfn }, > { .name = "cortex-a9", .initfn = cortex_a9_initfn }, > { .name = "cortex-a15", .initfn = cortex_a15_initfn }, > -- > 2.4.3.3.g905f831 >
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
On Tue, Jun 16, 2015 at 06:09:22PM -0700, Peter Crosthwaite wrote: > On Tue, Jun 16, 2015 at 5:54 PM, Edgar E. Iglesias > wrote: > > On Tue, Jun 16, 2015 at 05:36:19PM -0700, Peter Crosthwaite wrote: > >> Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset > >> (this is true of real hardware) by default or selectable as the boot > >> processor. > > > > Hi Peter, > > > > I think it would be good if you could model at least a minimal > > way to release the R5s from reset the "real" way. The R5s are > > not covered by PSCI in real code and not all code uses PSCI, > > in particular not any R5 code. > > > > How would the R5s be useful with upstream with this version? > > Maybe I'm missing something. > > > > You can nominate an R5 instead of A53 as the one non-powered-off cpu > by setting the zynqmp boot-cpu property with -global: > > $ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel > ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]" > > This works with elf boots. In that mode, how do I release the A53s (or the other R5)? Will it be either one R5 or the A53s? Cheers, Edgar > > Regards, > Peter > > > Cheers, > > Edgar > > > > > >> > >> Signed-off-by: Peter Crosthwaite > >> --- > >> changed since v2: > >> Add boot-cpu start-powered-off conditional > >> changed since v1: > >> s/rcpu/rpu-cpu/ > >> > >> hw/arm/xlnx-zynqmp.c | 34 ++ > >> include/hw/arm/xlnx-zynqmp.h | 2 ++ > >> 2 files changed, 36 insertions(+) > >> > >> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c > >> index 0c966da..5e72078 100644 > >> --- a/hw/arm/xlnx-zynqmp.c > >> +++ b/hw/arm/xlnx-zynqmp.c > >> @@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) > >>&error_abort); > >> } > >> > >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { > >> +object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), > >> + "cortex-r5-" TYPE_ARM_CPU); > >> +object_property_add_child(obj, "rpu-cpu[*]", > >> OBJECT(&s->rpu_cpu[i]), > >> + &error_abort); > >> +} > >> + > >> object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); > >> qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); > >> > >> @@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, > >> Error **errp) > >> qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); > >> } > >> > >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { > >> +char *name; > >> + > >> +name = > >> object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); > >> +if (strcmp(name, boot_cpu)) { > >> +/* Secondary CPUs start in PSCI powered-down state */ > >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, > >> + "start-powered-off", &error_abort); > >> +} else { > >> +s->boot_cpu_ptr = &s->rpu_cpu[i]; > >> +} > >> + > >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, > >> "reset-hivecs", > >> + &err); > >> +if (err != NULL) { > >> +error_propagate(errp, err); > >> +return; > >> +} > >> + > >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "realized", > >> + &err); > >> +if (err) { > >> +error_propagate((errp), (err)); > >> +return; > >> +} > >> +} > >> + > >> if (!s->boot_cpu_ptr) { > >> error_setg(errp, "ZynqMP Boot cpu %s not found\n", boot_cpu); > >> return; > >> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h > >> index 4f14a22..c379632 100644 > >> --- a/include/hw/arm/xlnx-zynqmp.h > >> +++ b/include/hw/arm/xlnx-zynqmp.h > >> @@ -28,6 +28,7 @@ > >> TYPE_XLNX_ZYNQMP) > >> > >> #define XLNX_ZYNQMP_NUM_APU_CPUS 4 > >> +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2 > >> #define XLNX_ZYNQMP_NUM_GEMS 4 > >> #define XLNX_ZYNQMP_NUM_UARTS 2 > >> > >> @@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState { > >> > >> /*< public >*/ > >> ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS]; > >> +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS]; > >> GICState gic; > >> MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; > >> CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; > >> -- > >> 2.4.3.3.g905f831 > >> > >
Re: [Qemu-devel] [PATCH 6/9] migration: create new section to store global state
"Dr. David Alan Gilbert" wrote: > * Juan Quintela (quint...@redhat.com) wrote: >> This includes a new section that for now just stores the current qemu state. >> >> Right now, there are only one way to control what is the state of the >> target after migration. >> >> - If you run the target qemu with -S, it would start stopped. >> - If you run the target qemu without -S, it would run just after migration >> finishes. >> >> The problem here is what happens if we start the target without -S and >> there happens one error during migration that puts current state as >> -EIO. Migration would ends (notice that the error happend doing block >> IO, network IO, i.e. nothing related with migration), and when >> migration finish, we would just "continue" running on destination, >> probably hanging the guest/corruption data, whatever. >> >> Signed-off-by: Juan Quintela >> + >> +typedef struct { >> +int32_t size; >> +uint8_t runstate[100]; >> +} GlobalState; > > unsigned for size? Could use something smaller than a int32_t > I guess for a 100 byte buffer. uint8_t > >> + >> +static GlobalState global_state; >> + >> +void global_state_store(void) >> +{ >> +if (runstate_store((char *)global_state.runstate, >> + sizeof(global_state.runstate)) == -1) { >> +error_report("Runstate is too big: %s\n", global_state.runstate); > > error_report's don't need the \n done. > >> +exit(-1); >> +} >> +} >> + >> +char *global_state_get_runstate(void) >> +{ >> +return (char *)global_state.runstate; >> +} > > Is that needed outside of this file - if not then just make > it static or use the data directly? > State was born on vl.c, then I noticed that I could put it here, and forgot to remove globals. Don. >> + >> +static int global_state_post_load(void *opaque, int version_id) >> +{ >> +GlobalState *s = opaque; >> +int ret = 0; >> +char *runstate = (char *)s->runstate; >> + >> +if (strcmp(runstate, "running") != 0) { >> + >> +RunState r = runstate_index(runstate); >> + >> +if (r == -1) { >> +error_report("Unknown received state %s\n", runstate); > > error_report's don't need the \n > >> +return -1; >> +} >> +ret = vm_stop_force_state(r); > > Why do this here, rather than in process_incoming_migration_co; > that would seem neater to keep the state change in one place. If state is unknown for destination here, migration can still be aborted at this point, later that is not possible. Not possible in the sense that source would not noticed that destination has exited because it didn't understood something. But we could move that to incoming, just not clear that it is going to be easier, because then we have to do error control at a point that don't have it right now. Later, Juan. > > Dave > >> +} >> + >> + return ret; >> +} >> + >> +static void global_state_pre_save(void *opaque) >> +{ >> +GlobalState *s = opaque; >> + >> +s->size = strlen((char *)s->runstate) + 1; >> +} >> + >> +static const VMStateDescription vmstate_globalstate = { >> +.name = "globalstate", >> +.version_id = 1, >> +.minimum_version_id = 1, >> +.post_load = global_state_post_load, >> +.pre_save = global_state_pre_save, >> +.fields = (VMStateField[]) { >> +VMSTATE_INT32(size, GlobalState), >> +VMSTATE_BUFFER(runstate, GlobalState), >> +VMSTATE_END_OF_LIST() >> +}, >> +}; >> + >> +void register_global_state(void) >> +{ >> +/* We would use it independently that we receive it */ >> +strcpy((char *)&global_state.runstate, ""); >> +vmstate_register(NULL, 0, &vmstate_globalstate, &global_state); >> +} >> diff --git a/vl.c b/vl.c >> index b8844f6..8af6c79 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -4387,6 +4387,7 @@ int main(int argc, char **argv, char **envp) >> return 0; >> } >> >> +register_global_state(); >> if (incoming) { >> Error *local_err = NULL; >> qemu_start_incoming_migration(incoming, &local_err); >> -- >> 2.4.0 >> >> > -- > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
On Tue, Jun 16, 2015 at 5:54 PM, Edgar E. Iglesias wrote: > On Tue, Jun 16, 2015 at 05:36:19PM -0700, Peter Crosthwaite wrote: >> Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset >> (this is true of real hardware) by default or selectable as the boot >> processor. > > Hi Peter, > > I think it would be good if you could model at least a minimal > way to release the R5s from reset the "real" way. The R5s are > not covered by PSCI in real code and not all code uses PSCI, > in particular not any R5 code. > > How would the R5s be useful with upstream with this version? > Maybe I'm missing something. > You can nominate an R5 instead of A53 as the one non-powered-off cpu by setting the zynqmp boot-cpu property with -global: $ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]" This works with elf boots. Regards, Peter > Cheers, > Edgar > > >> >> Signed-off-by: Peter Crosthwaite >> --- >> changed since v2: >> Add boot-cpu start-powered-off conditional >> changed since v1: >> s/rcpu/rpu-cpu/ >> >> hw/arm/xlnx-zynqmp.c | 34 ++ >> include/hw/arm/xlnx-zynqmp.h | 2 ++ >> 2 files changed, 36 insertions(+) >> >> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c >> index 0c966da..5e72078 100644 >> --- a/hw/arm/xlnx-zynqmp.c >> +++ b/hw/arm/xlnx-zynqmp.c >> @@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) >>&error_abort); >> } >> >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { >> +object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), >> + "cortex-r5-" TYPE_ARM_CPU); >> +object_property_add_child(obj, "rpu-cpu[*]", OBJECT(&s->rpu_cpu[i]), >> + &error_abort); >> +} >> + >> object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); >> qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); >> >> @@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error >> **errp) >> qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); >> } >> >> +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { >> +char *name; >> + >> +name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); >> +if (strcmp(name, boot_cpu)) { >> +/* Secondary CPUs start in PSCI powered-down state */ >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, >> + "start-powered-off", &error_abort); >> +} else { >> +s->boot_cpu_ptr = &s->rpu_cpu[i]; >> +} >> + >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, >> "reset-hivecs", >> + &err); >> +if (err != NULL) { >> +error_propagate(errp, err); >> +return; >> +} >> + >> +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "realized", >> + &err); >> +if (err) { >> +error_propagate((errp), (err)); >> +return; >> +} >> +} >> + >> if (!s->boot_cpu_ptr) { >> error_setg(errp, "ZynqMP Boot cpu %s not found\n", boot_cpu); >> return; >> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h >> index 4f14a22..c379632 100644 >> --- a/include/hw/arm/xlnx-zynqmp.h >> +++ b/include/hw/arm/xlnx-zynqmp.h >> @@ -28,6 +28,7 @@ >> TYPE_XLNX_ZYNQMP) >> >> #define XLNX_ZYNQMP_NUM_APU_CPUS 4 >> +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2 >> #define XLNX_ZYNQMP_NUM_GEMS 4 >> #define XLNX_ZYNQMP_NUM_UARTS 2 >> >> @@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState { >> >> /*< public >*/ >> ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS]; >> +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS]; >> GICState gic; >> MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; >> CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; >> -- >> 2.4.3.3.g905f831 >> >
Re: [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add SPCR table
On 2015/6/16 22:19, Michael S. Tsirkin wrote: > On Tue, Jun 16, 2015 at 09:33:19AM +0800, Shannon Zhao wrote: >> >> >> On 2015/6/16 2:13, Michael S. Tsirkin wrote: >>> On Mon, Jun 15, 2015 at 05:59:06PM +0100, Peter Maydell wrote: On 15 June 2015 at 17:32, Andrew Jones wrote: > On Mon, Jun 15, 2015 at 06:10:25PM +0200, Michael S. Tsirkin wrote: >> On Mon, Jun 15, 2015 at 04:45:58PM +0100, Peter Maydell wrote: >>> I'm still confused about when fields in these ACPI structs >>> need to be converted to little-endian, and when they don't. >>> Is there a rule-of-thumb I can use when I'm looking at patches? >> Normally it's all LE unless it's a single byte value. >> Did not check this specific table. >> We really need to add sparse support to check >> endian-ness matches, or re-write it >> all using byte_add so there's no duplication of info. > Everything used in the table is either a single byte, or I used le32, > Well, I didn't bother for the pci_{device,vendor}_id assignments, as > they're 0x anyway. I can change those two to make them more explicit, > if that's preferred. Yep, I just looked over the struct definition, so since this has been reviewed I'll apply it to target-arm.next. You could probably make it easier to review and write code that has to do these endianness swaps with something like #define acpi_struct_assign(FIELD, VAL) \ ((FIELD) = \ __builtin_choose_expr(sizeof(FIELD) == 1, VAL, \ __builtin_choose_expr(sizeof(FIELD) == 2, cpu_to_le16(VAL), \ __builtin_choose_expr(sizeof(FIELD) == 4, cpu_to_le32(VAL), \ __builtin_choose_expr(sizeof(FIELD) == 8, cpu_to_le64(VAL), \ abort (untested, but based on some code in linux-user/qemu.h). Then it's always acpi_struct_assign(spcr->field, value); whether the field is 1, 2, 4 or 8 bytes. Not my bit of the codebase though, so I'll leave it to the ACPI maintainers to decide how much they like magic macros :-) thanks -- PMM >>> >>> >>> We don't much. One can use build_append_int_noprefix and just avoid >>> structs altogether. >> >> But if we use build_append_int_noprefix, we have to bother about the >> unused fields of the struct and have lots of >> build_append_int_noprefix(table, 0, 1/2/4/8). > > With a struct you have a bunch of reserved fields - is that very > different? > Not only about the reserved fields, but also the fields which ARM doesn't use or x86 doesn't use. For example, xpm1a_event_block in struct AcpiFadtDescriptorRev5_1 is not used for ARM now, if we use build_append_int_noprefix, we should add lots of build_append_int_noprefix(table, 0, 1/2/4/8). But if we use struct, we just need to care them when we define it, rather than every time we use. >>> We did this for some structures and I'm thinking it's a good direction >>> generally. >>> >> >> -- >> Shannon -- Shannon
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
On Tue, Jun 16, 2015 at 05:36:19PM -0700, Peter Crosthwaite wrote: > Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset > (this is true of real hardware) by default or selectable as the boot > processor. Hi Peter, I think it would be good if you could model at least a minimal way to release the R5s from reset the "real" way. The R5s are not covered by PSCI in real code and not all code uses PSCI, in particular not any R5 code. How would the R5s be useful with upstream with this version? Maybe I'm missing something. Cheers, Edgar > > Signed-off-by: Peter Crosthwaite > --- > changed since v2: > Add boot-cpu start-powered-off conditional > changed since v1: > s/rcpu/rpu-cpu/ > > hw/arm/xlnx-zynqmp.c | 34 ++ > include/hw/arm/xlnx-zynqmp.h | 2 ++ > 2 files changed, 36 insertions(+) > > diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c > index 0c966da..5e72078 100644 > --- a/hw/arm/xlnx-zynqmp.c > +++ b/hw/arm/xlnx-zynqmp.c > @@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) >&error_abort); > } > > +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { > +object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), > + "cortex-r5-" TYPE_ARM_CPU); > +object_property_add_child(obj, "rpu-cpu[*]", OBJECT(&s->rpu_cpu[i]), > + &error_abort); > +} > + > object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); > qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); > > @@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error > **errp) > qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); > } > > +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { > +char *name; > + > +name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); > +if (strcmp(name, boot_cpu)) { > +/* Secondary CPUs start in PSCI powered-down state */ > +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, > + "start-powered-off", &error_abort); > +} else { > +s->boot_cpu_ptr = &s->rpu_cpu[i]; > +} > + > +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, > "reset-hivecs", > + &err); > +if (err != NULL) { > +error_propagate(errp, err); > +return; > +} > + > +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "realized", > + &err); > +if (err) { > +error_propagate((errp), (err)); > +return; > +} > +} > + > if (!s->boot_cpu_ptr) { > error_setg(errp, "ZynqMP Boot cpu %s not found\n", boot_cpu); > return; > diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h > index 4f14a22..c379632 100644 > --- a/include/hw/arm/xlnx-zynqmp.h > +++ b/include/hw/arm/xlnx-zynqmp.h > @@ -28,6 +28,7 @@ > TYPE_XLNX_ZYNQMP) > > #define XLNX_ZYNQMP_NUM_APU_CPUS 4 > +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2 > #define XLNX_ZYNQMP_NUM_GEMS 4 > #define XLNX_ZYNQMP_NUM_UARTS 2 > > @@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState { > > /*< public >*/ > ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS]; > +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS]; > GICState gic; > MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; > CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; > -- > 2.4.3.3.g905f831 >
Re: [Qemu-devel] [PATCH 3/9] runstate: Add runstate store
"Denis V. Lunev" wrote: > On 14/05/15 19:28, Juan Quintela wrote: >> This allows us to store the current state to send it through migration. >> >> Signed-off-by: Juan Quintela >> --- >> include/sysemu/sysemu.h | 1 + >> vl.c| 11 +++ >> 2 files changed, 12 insertions(+) >> >> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h >> index 8a52934..c1a403e 100644 >> --- a/include/sysemu/sysemu.h >> +++ b/include/sysemu/sysemu.h >> @@ -28,6 +28,7 @@ bool runstate_check(RunState state); >> void runstate_set(RunState new_state); >> int runstate_is_running(void); >> bool runstate_needs_reset(void); >> +int runstate_store(char *str, int size); >> typedef struct vm_change_state_entry VMChangeStateEntry; >> typedef void VMChangeStateHandler(void *opaque, int running, RunState >> state); >> >> diff --git a/vl.c b/vl.c >> index 15bccc4..7dca13f 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -609,6 +609,17 @@ bool runstate_check(RunState state) >> return current_run_state == state; >> } >> >> +int runstate_store(char *str, int size) >> +{ >> +const char *state = RunState_lookup[current_run_state]; >> + >> +if (strlen(state)+1 > size) { >> +return -1; >> +} >> +strncpy(str, state, strlen(state)+1); >> +return 0; >> +} >> + >> static void runstate_init(void) >> { >> const RunStateTransition *p; >> > > minor. why to call strlen() twice? > > if you have the length in hand it would be better to call > memcpy to copy data. Done, thanks.
Re: [Qemu-devel] [PATCH 4/9] runstate: create runstate_index function
"Dr. David Alan Gilbert" wrote: > * Juan Quintela (quint...@redhat.com) wrote: >> Given a string state, we need a way to get the RunState for that string. >> >> Signed-off-by: Juan Quintela >> --- >> include/sysemu/sysemu.h | 1 + >> vl.c| 13 + >> 2 files changed, 14 insertions(+) >> >> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h >> index c1a403e..e5fff07 100644 >> --- a/include/sysemu/sysemu.h >> +++ b/include/sysemu/sysemu.h >> @@ -29,6 +29,7 @@ void runstate_set(RunState new_state); >> int runstate_is_running(void); >> bool runstate_needs_reset(void); >> int runstate_store(char *str, int size); >> +RunState runstate_index(char *str); >> typedef struct vm_change_state_entry VMChangeStateEntry; >> typedef void VMChangeStateHandler(void *opaque, int running, RunState >> state); >> >> diff --git a/vl.c b/vl.c >> index 7dca13f..ea4319d 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -620,6 +620,19 @@ int runstate_store(char *str, int size) >> return 0; >> } >> >> +RunState runstate_index(char *str) >> +{ >> +RunState i = 0; >> + >> +while (i != RUN_STATE_MAX) { >> +if (strcmp(str, RunState_lookup[i]) == 0) { >> +return i; >> +} >> +i++; >> +} >> +return -1; > > It doesn't seem right to return -1 for the value of an enum > (which is otherwise used as an index into an array of strings). > > Make it return a bool and pass the RunState* as a parameter ? > > Dave > >> +} >> + >> static void runstate_init(void) >> { >> const RunStateTransition *p; >> -- >> 2.4.0 >> >> > -- > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK Dropped, see Eric suggestion. Thanks, Juan.
[Qemu-devel] linux-user crashes on clone(2) when run on ppc host
Hi, I'm having trouble running a simple multithreaded program on a PowerPC host machine. The machine I'm using is a ppc VM--I think it's running under KVM (I'm using OVH's RunAbove Power8 service): admin@adsf:~/qemu$ uname -a Linux adsf 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:27:09 UTC 2014 ppc64le ppc64le ppc64le GNU/Linux The original program I tried was doing pthread_create, and it was segfaulting. Then I distilled it to a simpler test program taken from https://lists.gnu.org/archive/html/qemu-devel/2005-10/msg00251.html , which is simply doing a clone(2): /* gcc -O0 -g -o foo foo.c -pthread -static */ #define _GNU_SOURCE #include #include #include #include int thread_main(void *arg) { printf("child: Hello world!\n"); while(1) ; return 0; } unsigned long stack[8192]; int main() { int pid; printf("About to clone: thread_main=%p\n", thread_main); pid = clone(thread_main, stack+4096, CLONE_VM, NULL); if(pid == -1) { perror("clone"); return 1; } printf("parent: clone successful; child pid is %d\n", pid); printf("parent: sleeping a bit\n"); sleep(2); printf("parent: killing process\n"); kill(pid, SIGTERM); return 0; } Doesn't work (linux-user on ppc64le host): - x86_64 static binary, compiled natively - ppc static binary, cross-compiled from x86 host - ppc64le static binary, compiled natively on the ppc64le host - ppc64le binary (i.e. non-static), compiled natively on the ppc64le host - ppc64 binary, compiled natively on ppc64 host (running ppc64-linux-user) Works: - Any of the above running on x86_64 host (linux-user or native) - ppc64le binary running natively on ppc64le host The current HEAD of the tree is: commit 93f6d1c16036aaf34055d16f54ea770fb8d6d280 Merge: 4316536 7a4dfd1 Author: Peter Maydell Date: Tue Jun 16 10:35:43 2015 +0100 I've tried older versions of qemu (e.g. v2.0, v1.7) and they don't work either. The segfault for the ppc64le static binary is as follows: admin@adsf:~/qemu$ ppc64le-linux-user/qemu-ppc64le foo About to clone: thread_main=0x18f0 Invalid data memory access: 0x3fffa2f8a720 NIP 0040009aeec8 LR 1660 CTR 0040009aee68 XER CPU#1 MSR 82806001 HID0 HF 02806001 idx 0 TB GPR00 0078 10019030 004000a52800 GPR04 10019030 0027 0001 GPR08 0001 0007 GPR12 0040009aee68 004000a57b60 GPR16 GPR20 GPR24 00400084be10 GPR28 00400084c148 0100 18f0 CR 42000884 [ G E - - - L L G ] RES FPR00 FPR04 FPR08 FPR12 FPR16 FPR20 FPR24 FPR28 FPSCR Invalid segfault errno (4200) NIP 0040009aeec8 LR 1660 CTR 0040009aee68 XER CPU#1 MSR 82806001 HID0 HF 02806001 idx 0 TB GPR00 0078 10019030 004000a52800 GPR04 10019030 0027 0001 GPR08 0001 0007 GPR12 0040009aee68 004000a57b60 GPR16 GPR20 GPR24 00400084be10 GPR28 00400084c148 0100 18f0 CR 42000884 [ G E - - - L L G ] RES FPR00 FPR04 FPR08 FPR12 FPR16 FPR20 FPR24
[Qemu-devel] [PATCH target-arm v3 6/7] arm: xlnx-zynqmp: Add boot-cpu property
Add a string property that specifies the primary boot cpu. All CPUs except the one selected will start-powered-off. This allows for elf boots on any CPU, which prepares support for booting R5 elfs directly on the R5 processors. Signed-off-by: Peter Crosthwaite --- hw/arm/xlnx-ep108.c | 2 +- hw/arm/xlnx-zynqmp.c | 19 ++- include/hw/arm/xlnx-zynqmp.h | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c index 7a98dd6..f94da86 100644 --- a/hw/arm/xlnx-ep108.c +++ b/hw/arm/xlnx-ep108.c @@ -65,7 +65,7 @@ static void xlnx_ep108_init(MachineState *machine) xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline; xlnx_ep108_binfo.initrd_filename = machine->initrd_filename; xlnx_ep108_binfo.loader_start = 0; -arm_load_kernel(&s->soc.apu_cpu[0], &xlnx_ep108_binfo); +arm_load_kernel(s->soc.boot_cpu_ptr, &xlnx_ep108_binfo); } static QEMUMachine xlnx_ep108_machine = { diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 353ecad..0c966da 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -90,6 +90,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) XlnxZynqMPState *s = XLNX_ZYNQMP(dev); MemoryRegion *system_memory = get_system_memory(); uint8_t i; +const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]"; qemu_irq gic_spi[GIC_NUM_SPI_INTR]; Error *err = NULL; @@ -123,13 +124,18 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) { qemu_irq irq; +char *name; object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC, "psci-conduit", &error_abort); -if (i > 0) { + +name = object_get_canonical_path_component(OBJECT(&s->apu_cpu[i])); +if (strcmp(name, boot_cpu)) { /* Secondary CPUs start in PSCI powered-down state */ object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "start-powered-off", &error_abort); +} else { +s->boot_cpu_ptr = &s->apu_cpu[i]; } object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR, @@ -157,6 +163,11 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); } +if (!s->boot_cpu_ptr) { +error_setg(errp, "ZynqMP Boot cpu %s not found\n", boot_cpu); +return; +} + for (i = 0; i < GIC_NUM_SPI_INTR; i++) { gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); } @@ -190,10 +201,16 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) } } +static Property xlnx_zynqmp_props[] = { +DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu), +DEFINE_PROP_END_OF_LIST() +}; + static void xlnx_zynqmp_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); +dc->props = xlnx_zynqmp_props; dc->realize = xlnx_zynqmp_realize; } diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index d042df1..4f14a22 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -52,6 +52,9 @@ typedef struct XlnxZynqMPState { MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS]; + +char *boot_cpu; +ARMCPU *boot_cpu_ptr; } XlnxZynqMPState; #define XLNX_ZYNQMP_H -- 2.4.3.3.g905f831
[Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset (this is true of real hardware) by default or selectable as the boot processor. Signed-off-by: Peter Crosthwaite --- changed since v2: Add boot-cpu start-powered-off conditional changed since v1: s/rcpu/rpu-cpu/ hw/arm/xlnx-zynqmp.c | 34 ++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 0c966da..5e72078 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) &error_abort); } +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { +object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), + "cortex-r5-" TYPE_ARM_CPU); +object_property_add_child(obj, "rpu-cpu[*]", OBJECT(&s->rpu_cpu[i]), + &error_abort); +} + object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); @@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); } +for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) { +char *name; + +name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); +if (strcmp(name, boot_cpu)) { +/* Secondary CPUs start in PSCI powered-down state */ +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, + "start-powered-off", &error_abort); +} else { +s->boot_cpu_ptr = &s->rpu_cpu[i]; +} + +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "reset-hivecs", + &err); +if (err != NULL) { +error_propagate(errp, err); +return; +} + +object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "realized", + &err); +if (err) { +error_propagate((errp), (err)); +return; +} +} + if (!s->boot_cpu_ptr) { error_setg(errp, "ZynqMP Boot cpu %s not found\n", boot_cpu); return; diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 4f14a22..c379632 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -28,6 +28,7 @@ TYPE_XLNX_ZYNQMP) #define XLNX_ZYNQMP_NUM_APU_CPUS 4 +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2 #define XLNX_ZYNQMP_NUM_GEMS 4 #define XLNX_ZYNQMP_NUM_UARTS 2 @@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState { /*< public >*/ ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS]; +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS]; GICState gic; MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; -- 2.4.3.3.g905f831
[Qemu-devel] [PATCH target-arm v3 5/7] arm: xlnx-zynqmp: Preface CPU variables with "apu"
The CPUs currently supported by zynqmp are the APU (application processing unit) CPUs. There are other CPUs in Zynqmp so unqualified "cpus" in ambiguous. Preface the variables with "APU" accordingly, to prepare support adding the RPU (realtime processing unit) processors. Signed-off-by: Peter Crosthwaite --- changed since v1: s/acpu/apu-cpu/ hw/arm/xlnx-ep108.c | 2 +- hw/arm/xlnx-zynqmp.c | 26 ++ include/hw/arm/xlnx-zynqmp.h | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c index b924f5e..7a98dd6 100644 --- a/hw/arm/xlnx-ep108.c +++ b/hw/arm/xlnx-ep108.c @@ -65,7 +65,7 @@ static void xlnx_ep108_init(MachineState *machine) xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline; xlnx_ep108_binfo.initrd_filename = machine->initrd_filename; xlnx_ep108_binfo.loader_start = 0; -arm_load_kernel(&s->soc.cpu[0], &xlnx_ep108_binfo); +arm_load_kernel(&s->soc.apu_cpu[0], &xlnx_ep108_binfo); } static QEMUMachine xlnx_ep108_machine = { diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 6b01965..353ecad 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -64,10 +64,10 @@ static void xlnx_zynqmp_init(Object *obj) XlnxZynqMPState *s = XLNX_ZYNQMP(obj); int i; -for (i = 0; i < XLNX_ZYNQMP_NUM_CPUS; i++) { -object_initialize(&s->cpu[i], sizeof(s->cpu[i]), +for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) { +object_initialize(&s->apu_cpu[i], sizeof(s->apu_cpu[i]), "cortex-a53-" TYPE_ARM_CPU); -object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpu[i]), +object_property_add_child(obj, "apu-cpu[*]", OBJECT(&s->apu_cpu[i]), &error_abort); } @@ -95,7 +95,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32); qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2); -qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_CPUS); +qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_APU_CPUS); object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); if (err) { error_propagate((errp), (err)); @@ -121,38 +121,40 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) } } -for (i = 0; i < XLNX_ZYNQMP_NUM_CPUS; i++) { +for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) { qemu_irq irq; -object_property_set_int(OBJECT(&s->cpu[i]), QEMU_PSCI_CONDUIT_SMC, +object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC, "psci-conduit", &error_abort); if (i > 0) { /* Secondary CPUs start in PSCI powered-down state */ -object_property_set_bool(OBJECT(&s->cpu[i]), true, +object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "start-powered-off", &error_abort); } -object_property_set_int(OBJECT(&s->cpu[i]), GIC_BASE_ADDR, +object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR, "reset-cbar", &err); if (err) { error_propagate((errp), (err)); return; } -object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); +object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized", + &err); if (err) { error_propagate((errp), (err)); return; } sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i, - qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ)); + qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]), +ARM_CPU_IRQ)); irq = qdev_get_gpio_in(DEVICE(&s->gic), arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI)); -qdev_connect_gpio_out(DEVICE(&s->cpu[i]), 0, irq); +qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 0, irq); irq = qdev_get_gpio_in(DEVICE(&s->gic), arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI)); -qdev_connect_gpio_out(DEVICE(&s->cpu[i]), 1, irq); +qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); } for (i = 0; i < GIC_NUM_SPI_INTR; i++) { diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 79c2b0b..d042df1 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -27,7 +27,7 @@ #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ TYPE_XLNX_ZYNQMP) -#define XLNX_ZYNQMP_NUM_CPUS 4 +#define XLNX_ZYNQMP_NUM_APU_CPUS 4 #define XLNX_ZYNQMP_NUM_GEMS 4 #define XLNX_ZYNQMP_NUM_UARTS 2 @@ -47,7 +47,7 @@ typedef struct Xlnx
[Qemu-devel] [PATCH target-arm v3 1/7] target-arm/helper.c: define MPUIR register
Define the MPUIR register for MPU supporting ARMv6 and onwards. Currently we only support unified MPU. The size of the unified MPU is defined via the number of "dregions". So just a single config is added to specify this size. (When split MPU is implemented we will add an extra iregions config). Signed-off-by: Peter Crosthwaite --- changed since v2 (PMM review): Fix commit message wording issues. change assertion to realize error. allow 0 regions. raise error of >255 memory regions. changed since v1: Add #regions configuration conditionalize MPUIR existence target-arm/cpu-qom.h | 2 ++ target-arm/cpu.c | 18 ++ target-arm/helper.c | 10 ++ 3 files changed, 30 insertions(+) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 072aa9b..3cbc4a0 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -105,6 +105,8 @@ typedef struct ARMCPU { /* CPU has memory protection unit */ bool has_mpu; +/* PMSAv7 MPU number of supported regions */ +uint32_t pmsav7_dregion; /* PSCI conduit used to invoke PSCI methods * 0 - disabled, 1 - smc, 2 - hvc diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 7496983..a3d702f 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -457,6 +457,9 @@ static Property arm_cpu_has_el3_property = static Property arm_cpu_has_mpu_property = DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); +static Property arm_cpu_pmsav7_dregion_property = +DEFINE_PROP_UINT32("pmsav7-dregion", ARMCPU, pmsav7_dregion, 16); + static void arm_cpu_post_init(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); @@ -488,6 +491,11 @@ static void arm_cpu_post_init(Object *obj) if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) { qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, &error_abort); +if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { +qdev_property_add_static(DEVICE(obj), + &arm_cpu_pmsav7_dregion_property, + &error_abort); +} } } @@ -580,6 +588,16 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) unset_feature(env, ARM_FEATURE_MPU); } +if (arm_feature(env, ARM_FEATURE_MPU) && +arm_feature(env, ARM_FEATURE_V7)) { +uint32_t nr = cpu->pmsav7_dregion; + +if (nr > 0xff) { +error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32 "\n", nr); +return; +} +} + register_cp_regs_for_features(cpu); arm_cpu_register_gdb_regs_for_features(cpu); diff --git a/target-arm/helper.c b/target-arm/helper.c index 00509b1..685f972 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3465,6 +3465,13 @@ void register_cp_regs_for_features(ARMCPU *cpu) .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0, }; +/* MPUIR is specific to PMSA V6+ */ +ARMCPRegInfo id_mpuir_reginfo = { + .name = "MPUIR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmsav7_dregion << 8 +}; ARMCPRegInfo crn0_wi_reginfo = { .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, @@ -3487,6 +3494,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) r->access = PL1_RW; } id_tlbtr_reginfo.access = PL1_RW; +id_tlbtr_reginfo.access = PL1_RW; } if (arm_feature(env, ARM_FEATURE_V8)) { define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo); @@ -3496,6 +3504,8 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_arm_cp_regs(cpu, id_cp_reginfo); if (!arm_feature(env, ARM_FEATURE_MPU)) { define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo); +} else if (arm_feature(env, ARM_FEATURE_V7)) { +define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); } } -- 2.4.3.3.g905f831
[Qemu-devel] [PATCH target-arm v3 4/7] target-arm: Add support for Cortex-R5
Introduce a CPU model for the Cortex R5 processor. ARMv7 with MPU, and both thumb and ARM div instructions. Also implement dummy ATCM and BTCM. These CPs are defined for R5 but don't have a lot of meaning in QEMU yet. Raz them so the guest can proceed if they are read. The TCM registers will return a size of 0, indicating no TCM. Reviewed-by: Peter Maydell Signed-off-by: Peter Crosthwaite --- Based loosely on an old patch of Andreas' for the cortex-r4. changed since v1: Squashed in R5 specific CP regs patch Reordered to be after supporting patches set mp_is_up target-arm/cpu.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 4010d81..dce91bb 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -847,6 +847,43 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; } +static const ARMCPRegInfo cortexr5_cp_reginfo[] = { +/* Dummy the TCM region regs for the moment */ +{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST }, +{ .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST }, +REGINFO_SENTINEL +}; + +static void cortex_r5_initfn(Object *obj) +{ +ARMCPU *cpu = ARM_CPU(obj); + +set_feature(&cpu->env, ARM_FEATURE_V7); +set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV); +set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); +set_feature(&cpu->env, ARM_FEATURE_V7MP); +set_feature(&cpu->env, ARM_FEATURE_MPU); +cpu->midr = 0x411fc153; /* r1p3 */ +cpu->id_pfr0 = 0x0131; +cpu->id_pfr1 = 0x001; +cpu->id_dfr0 = 0x010400; +cpu->id_afr0 = 0x0; +cpu->id_mmfr0 = 0x0210030; +cpu->id_mmfr1 = 0x; +cpu->id_mmfr2 = 0x0120; +cpu->id_mmfr3 = 0x0211; +cpu->id_isar0 = 0x210; +cpu->id_isar1 = 0x13112111; +cpu->id_isar2 = 0x21232141; +cpu->id_isar3 = 0x01112131; +cpu->id_isar4 = 0x0010142; +cpu->id_isar5 = 0x0; +cpu->mp_is_up = true; +define_arm_cp_regs(cpu, cortexr5_cp_reginfo); +} + static const ARMCPRegInfo cortexa8_cp_reginfo[] = { { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, @@ -1238,6 +1275,7 @@ static const ARMCPUInfo arm_cpus[] = { { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, { .name = "cortex-m3", .initfn = cortex_m3_initfn, .class_init = arm_v7m_class_init }, +{ .name = "cortex-r5", .initfn = cortex_r5_initfn }, { .name = "cortex-a8", .initfn = cortex_a8_initfn }, { .name = "cortex-a9", .initfn = cortex_a9_initfn }, { .name = "cortex-a15", .initfn = cortex_a15_initfn }, -- 2.4.3.3.g905f831
[Qemu-devel] [PATCH target-arm v3 2/7] target-arm: Add registers for PMSAv7
Define the arm CP registers for PMSAv7 and their accessor functions. RGNR serves as a shared index that indexes into arrays storing the DRBAR, DRSR and DRACR registers. DRBAR and friends have to be VMSDd separately from the CP interface using a new PMSA specific VMSD subsection. Reviewed-by: Peter Maydell Signed-off-by: Peter Crosthwaite --- changed since v2 (PMM review): conditionalise pointer allocation on non-zero regions Handle 0 regions in CP accessors Tweak RGNR GUEST_ERROR message with s/>/>= Resolve conflict with VSMD subsection.needed refactor changed since v1 (PMM review): Use raw_ptr Implement reset as memset Implement VMSD support Add out-of-bounds guard or rgnr_write Dynamically allocate registers Move arrays out of cp15 struct into dedicated substruct target-arm/cpu.c | 6 target-arm/cpu.h | 10 ++ target-arm/helper.c | 90 target-arm/machine.c | 34 4 files changed, 133 insertions(+), 7 deletions(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index a3d702f..4010d81 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -596,6 +596,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32 "\n", nr); return; } + +if (nr) { +env->pmsav7.drbar = g_new0(uint32_t, nr); +env->pmsav7.drsr = g_new0(uint32_t, nr); +env->pmsav7.dracr = g_new0(uint32_t, nr); +} } register_cp_regs_for_features(cpu); diff --git a/target-arm/cpu.h b/target-arm/cpu.h index c9d2330..6e82893 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -284,6 +284,9 @@ typedef struct CPUARMState { }; uint64_t par_el[4]; }; + +uint32_t c6_rgnr; + uint32_t c9_insn; /* Cache lockdown registers. */ uint32_t c9_data; uint64_t c9_pmcr; /* performance monitor control register */ @@ -482,6 +485,13 @@ typedef struct CPUARMState { /* Internal CPU feature flags. */ uint64_t features; +/* PMSAv7 MPU */ +struct { +uint32_t *drbar; +uint32_t *drsr; +uint32_t *dracr; +} pmsav7; + void *nvic; const struct arm_boot_info *boot_info; } CPUARMState; diff --git a/target-arm/helper.c b/target-arm/helper.c index 685f972..0384c79 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1710,6 +1710,81 @@ static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri) return simple_mpu_ap_bits(env->cp15.pmsav5_insn_ap); } +static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ +uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); + +if (!u32p) { +return 0; +} + +u32p += env->cp15.c6_rgnr; +return *u32p; +} + +static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +ARMCPU *cpu = arm_env_get_cpu(env); +uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); + +if (!u32p) { +return; +} + +u32p += env->cp15.c6_rgnr; +tlb_flush(CPU(cpu), 1); /* Mappings may have changed - purge! */ +*u32p = value; +} + +static void pmsav7_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ +ARMCPU *cpu = arm_env_get_cpu(env); +uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); + +if (!u32p) { +return; +} + +memset(u32p, 0, sizeof(*u32p) * cpu->pmsav7_dregion); +} + +static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +ARMCPU *cpu = arm_env_get_cpu(env); +uint32_t nrgs = cpu->pmsav7_dregion; + +if (value >= nrgs) { +qemu_log_mask(LOG_GUEST_ERROR, + "PMSAv7 RGNR write >= # supported regions, %" PRIu32 + " > %" PRIu32 "\n", (uint32_t)value, nrgs); +return; +} + +raw_write(env, ri, value); +} + +static const ARMCPRegInfo pmsav7_cp_reginfo[] = { +{ .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), + .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, +{ .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.drsr), + .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, +{ .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.dracr), + .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, +{ .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMStat
[Qemu-devel] [PATCH target-arm v3 0/7] ARM Cortex R5 Support
Hi Peter and all, This patch series adds ARM Cortex R5 processor support. The PMSAv7 MPU is implemented. Two R5s are added to the Xilinx ZynqMP SoC. Changed since v2: Rebased (early patches merged) Added boot CPU selection. Addressed PMM review (see indiv. patches) Changed since v1: Addressed PMM and Alistair reviews (see indiv. patches) Adding prepatory refactorings to target-arm (new patches) - TLBTR VMSA conditional (1) - V7MP CP regs VMSA conditional (2) - Refactor get_phys_addr FSR return path (4) - Add MPUIR.U config (5) - Improved cpu configurability around MPUs (6-7) Regards, Peter Peter Crosthwaite (7): target-arm/helper.c: define MPUIR register target-arm: Add registers for PMSAv7 target-arm: Implement PMSAv7 MPU target-arm: Add support for Cortex-R5 arm: xlnx-zynqmp: Preface CPU variables with "apu" arm: xlnx-zynqmp: Add boot-cpu property arm: xlnx-zynqmp: Add 2xCortexR5 CPUs hw/arm/xlnx-ep108.c | 2 +- hw/arm/xlnx-zynqmp.c | 79 +++-- include/hw/arm/xlnx-zynqmp.h | 9 +- target-arm/cpu-qom.h | 2 + target-arm/cpu.c | 62 ++ target-arm/cpu.h | 11 ++ target-arm/helper.c | 274 +-- target-arm/machine.c | 34 ++ 8 files changed, 449 insertions(+), 24 deletions(-) -- 2.4.3.3.g905f831
[Qemu-devel] [PATCH target-arm v3 3/7] target-arm: Implement PMSAv7 MPU
Unified MPU only. Uses ARM architecture major revision to switch between PMSAv5 and v7 when ARM_FEATURE_MPU is set. PMSA v6 remains unsupported and is asserted against. Reviewed-by: Peter Maydell Signed-off-by: Peter Crosthwaite --- changed since v2 Add missing -1 on initialiser Use default if dregions == 0 Drop unneeded else changed since v1 (PMM review): Add comment about PMSAv6 non-support Fix case where MPU is completely disabled Ignore regions with 0 size. GUEST_ERROR invalid base address alignments UNIMP regions that are smaller than TARGET_PAGE_SIZE use extract32 to get SR disable bits Fixed up DRACR AP bit error message. Correct bullet point about MPU FSR format Rebased against new FSR return system removed *prot switch-case target-arm/cpu.h| 1 + target-arm/helper.c | 174 +++- 2 files changed, 174 insertions(+), 1 deletion(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 6e82893..16fd1aa 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -560,6 +560,7 @@ void pmccntr_sync(CPUARMState *env); #define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */ #define SCTLR_nTWI(1U << 16) /* v8 onward */ #define SCTLR_HA (1U << 17) +#define SCTLR_BR (1U << 17) /* PMSA only */ #define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */ #define SCTLR_nTWE(1U << 18) /* v8 onward */ #define SCTLR_WXN (1U << 19) diff --git a/target-arm/helper.c b/target-arm/helper.c index 0384c79..8663f80 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -5845,6 +5845,167 @@ do_fault: return true; } +static inline void get_phys_addr_pmsav7_default(CPUARMState *env, +ARMMMUIdx mmu_idx, +int32_t address, int *prot) +{ +*prot = PAGE_READ | PAGE_WRITE; +switch (address) { +case 0xF000 ... 0x: +if (regime_sctlr(env, mmu_idx) & SCTLR_V) { /* hivecs execing is ok */ +*prot |= PAGE_EXEC; +} +break; +case 0x ... 0x7FFF: +*prot |= PAGE_EXEC; +break; +} + +} + +static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, int *prot, uint32_t *fsr) +{ +ARMCPU *cpu = arm_env_get_cpu(env); +int n; +bool is_user = regime_is_user(env, mmu_idx); + +*phys_ptr = address; +*prot = 0; + +if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ +get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); +} else { /* MPU enabled */ +for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { +/* region search */ +uint32_t base = env->pmsav7.drbar[n]; +uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5); +uint32_t rmask; +bool srdis = false; + +if (!(env->pmsav7.drsr[n] & 0x1)) { +continue; +} + +if (!rsize) { +qemu_log_mask(LOG_GUEST_ERROR, "DRSR.Rsize field can not be 0"); +continue; +} +rsize++; +rmask = (1ull << rsize) - 1; + +if (base & rmask) { +qemu_log_mask(LOG_GUEST_ERROR, "DRBAR %" PRIx32 " misaligned " + "to DRSR region size, mask = %" PRIx32, + base, rmask); +continue; +} + +if (address < base || address > base + rmask) { +continue; +} + +/* Region matched */ + +if (rsize >= 8) { /* no subregions for regions < 256 bytes */ +int i, snd; +uint32_t srdis_mask; + +rsize -= 3; /* sub region size (power of 2) */ +snd = ((address - base) >> rsize) & 0x7; +srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1); + +srdis_mask = srdis ? 0x3 : 0x0; +for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) { +/* This will check in groups of 2, 4 and then 8, whether + * the subregion bits are consistent. rsize is incremented + * back up to give the region size, considering consistent + * adjacent subregions as one region. Stop testing if rsize + * is already big enough for an entire QEMU page. + */ +int snd_rounded = snd & ~(i - 1); +uint32_t srdis_multi = extract32(env->pmsav7.drsr[n], + snd_rounded + 8, i); +if (srdis_mask ^ srdis_multi) { +break; +} +srdis_mask = (srdis_mask << i) | srdis_mask; +
Re: [Qemu-devel] [PATCH 4/9] runstate: create runstate_index function
Eric Blake wrote: D> On 05/18/2015 03:58 AM, Dr. David Alan Gilbert wrote: >> * Juan Quintela (quint...@redhat.com) wrote: >>> Given a string state, we need a way to get the RunState for that string. >>> >>> Signed-off-by: Juan Quintela >>> --- >>> include/sysemu/sysemu.h | 1 + >>> vl.c| 13 + >>> 2 files changed, 14 insertions(+) >>> > >>> >>> +RunState runstate_index(char *str) >>> +{ >>> +RunState i = 0; >>> + >>> +while (i != RUN_STATE_MAX) { >>> +if (strcmp(str, RunState_lookup[i]) == 0) { >>> +return i; >>> +} >>> +i++; >>> +} >>> +return -1; >> >> It doesn't seem right to return -1 for the value of an enum >> (which is otherwise used as an index into an array of strings). >> >> Make it return a bool and pass the RunState* as a parameter ? > > Why open-code this, when we already have qapi_enum_parse() in > qapi/qapi-util.c? Didn't knew about this function. Thanks, Juan.
Re: [Qemu-devel] [PATCH 3/9] runstate: Add runstate store
"Dr. David Alan Gilbert" wrote: > * Juan Quintela (quint...@redhat.com) wrote: >> This allows us to store the current state to send it through migration. >> >> Signed-off-by: Juan Quintela >> --- >> include/sysemu/sysemu.h | 1 + >> vl.c| 11 +++ >> 2 files changed, 12 insertions(+) >> >> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h >> index 8a52934..c1a403e 100644 >> --- a/include/sysemu/sysemu.h >> +++ b/include/sysemu/sysemu.h >> @@ -28,6 +28,7 @@ bool runstate_check(RunState state); >> void runstate_set(RunState new_state); >> int runstate_is_running(void); >> bool runstate_needs_reset(void); >> +int runstate_store(char *str, int size); >> typedef struct vm_change_state_entry VMChangeStateEntry; >> typedef void VMChangeStateHandler(void *opaque, int running, RunState >> state); >> >> diff --git a/vl.c b/vl.c >> index 15bccc4..7dca13f 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -609,6 +609,17 @@ bool runstate_check(RunState state) >> return current_run_state == state; >> } >> >> +int runstate_store(char *str, int size) >> +{ > > size_t size > > and perhaps a bool for the return type? ack > >> +const char *state = RunState_lookup[current_run_state]; >> + >> +if (strlen(state)+1 > size) { >> +return -1; >> +} >> +strncpy(str, state, strlen(state)+1); > > Why not a plain strcpy? asked for memcpy, I don't really cared one way or another, it is a really small string. Thanks, Juan.
Re: [Qemu-devel] [RFC] generic-gpio-led & stm32-gpio-led
On Tue, Jun 16, 2015 at 3:25 PM, Liviu Ionescu wrote: > >> On 16 Jun 2015, at 19:10, Peter Crosthwaite >> wrote: >> >> ... In my proposal the machine model would do this. >> >> qdev_connect_gpio_out_named(mcu, "name", index, qdev_get_gpio_in(gpio_dev, >> 0)); >> >> Or something like that. > > connecting a gpio_out to a gpio_in seems not possible, gpio_in irqs are > parented to the device and parenting them to the gpio_out fail with the > parent != 0 assertion. > This should work. Can I see the backtrace of that abort? Regards. Peter > however I was able to connect_gpio_out for standalone irqs. > > the actual connection sequence is: > > qemu_irq irq = GENERIC_GPIO_LED_STATE(led)->irq; > > qdev_connect_gpio_out(DEVICE(object_resolve_path("/machine/stm32/gpio[c]", > NULL)), 12, irq); > > I'm not very happy with it, since it is quite long. > > any suggestions how to make it more readable? > >> E.g. if the SoC define "bank A" gpios, then a >> suitable string name would be "bank-A". This should match the SoC >> level, not the board level so it wouldn't be names like "green-led". > > this is still too tricky for me. > > since the default names were unusable (like device[7], etc), I created two > containers (cortexm and stm32) and placed the peripherals inside, with names > like /cortexm/nvic, cortexm/itm, stm32/rcc, stm32/gpio[%c], etc. > > I used calls like: > > state->container = container_get(qdev_get_machine(), "/stm32"); > > object_property_add_child(state->container, "rcc", OBJECT(state->rcc), > NULL); > > > would this be acceptable? > > > regards, > > Liviu > > > > >
Re: [Qemu-devel] [PATCH 2/3] migration: create migration event
Eric Blake wrote: > On 05/20/2015 09:35 AM, Juan Quintela wrote: >> We have one argument that tells us what event has happened. >> >> Signed-off-by: Juan Quintela >> --- >> docs/qmp/qmp-events.txt | 16 >> migration/migration.c | 12 >> qapi/event.json | 14 ++ >> 3 files changed, 42 insertions(+) >> >> diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt >> index 4c13d48..3797709 100644 >> --- a/docs/qmp/qmp-events.txt >> +++ b/docs/qmp/qmp-events.txt >> @@ -473,6 +473,22 @@ Example: >> { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, >>"event": "SPICE_MIGRATE_COMPLETED" } >> >> +MIGRATION >> +- >> + >> +Emitted when a migration event happens >> + >> +Data: None. >> + >> + - "status": migration status >> + "": error has been ignored > > Uggh. Looking for an empty string is awkward. We are using MigrationStatus from qapi-schema.json, add the comment stating that. > >> + "report": error has been reported to the device >> + "stop": the VM is going to stop because of the error >> + >> +Example: >> + >> +{"timestamp": {"seconds": 1432121972, "microseconds": 744001}, >> + "event": "MIGRATION", "data": {"status": "completed"}} > > The example lists "completed", but the documentation does not mention > it. Might be good to expand the docs to mention all states, and/or point > to the enum definition. See above. > > >> +++ b/qapi/event.json >> @@ -243,6 +243,20 @@ >> { 'event': 'SPICE_MIGRATE_COMPLETED' } >> >> ## >> +# @MIGRATION >> +# >> +# Emitted when a migration event happens >> +# >> +# @status: @MigrationStatus describing the current migration status. >> +# If this field is not returned, no migration process >> +# has been initiated > > Rather than returning an empty string,... > >> +# >> +# Since: 2.4 >> +## >> +{ 'event': 'MIGRATION', >> + 'data': {'status': 'MigrationStatus'}} > > ...this field should be marked optional, as in '*status'. Then in your > callers, you'll have to pass true or false for has_status, so that you > can omit status when there is none. But really, when will this event > ever be omitted if migration has not been initiated? Maybe it is just > bogus documentation that you can return an empty string, as I didn't see > any addition of a call to qapi_event_send_migration() that would pass an > empty string on the wire. So it sounds to me like the interface is > okay, but the documentation is wrong. It is wrong documentation, sorry for the inconvenience. Later, Juan.
Re: [Qemu-devel] [PATCH 2/3] migration: create migration event
Jiri Denemark wrote: > On Wed, May 20, 2015 at 17:35:23 +0200, Juan Quintela wrote: >> We have one argument that tells us what event has happened. >> >> Signed-off-by: Juan Quintela >> --- >> docs/qmp/qmp-events.txt | 16 >> migration/migration.c | 12 >> qapi/event.json | 14 ++ >> 3 files changed, 42 insertions(+) > > Hi Juan, > > I patched libvirt to be able to consume this event and it all seems to > work fine except for events sent after migrate_cancel command: > > {"execute":"migrate_cancel","id":"libvirt-33"} > {"timestamp": {"seconds": 1432899178, "microseconds": 844907}, "event": > "MIGRATION", "data": {"status": "cancelling"}} > {"return": {}, "id": "libvirt-33"} > {"timestamp": {"seconds": 1432899178, "microseconds": 845625}, "event": > "MIGRATION", "data": {"status": "failed"}} > {"timestamp": {"seconds": 1432899178, "microseconds": 846432}, "event": > "MIGRATION", "data": {"status": "cancelled"}} > > In other words, the status first changes to "failed" and then it changes > correctly "cancelled". Can you fix this weird behavior in QEMU or do we > have to work around it in libvirt? > > Jirka Found root cause of this, basically we had the code: migrate_set_state(FOO, MIGRATION_STATUS_FAILED); qapi_send_event(, MIGRATION_STATUS_FAILED); But the first call only change the state if the current state is FOO. So, changed the event to inside migrate_set_state() and only sent it when we change the state. See new patch series, basically we were using incorrectly atomic_cmpxchg() and that made things ... interesting. Later, Juan.
Re: [Qemu-devel] [PATCH V16 4/4] tests: add a unit test for the vmgenid device
On Tue, 16 Jun 2015 17:11:03 +0300 Gal Hammer wrote: > Signed-off-by: Gal Hammer > --- > tests/Makefile | 2 ++ > tests/vmgenid-test.c | 44 > 2 files changed, 46 > insertions(+) create mode 100644 tests/vmgenid-test.c > > diff --git a/tests/Makefile b/tests/Makefile > index c5e4744..3608068 100644 > --- a/tests/Makefile > +++ b/tests/Makefile > @@ -177,6 +177,7 @@ check-qtest-i386-y += tests/pc-cpu-test$(EXESUF) > check-qtest-i386-y += tests/q35-test$(EXESUF) > gcov-files-i386-y += hw/pci-host/q35.c > check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF) > +check-qtest-i386-y += tests/vmgenid-test$(EXESUF) > check-qtest-x86_64-y = $(check-qtest-i386-y) > gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c > gcov-files-x86_64-y = $(subst > i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) @@ -396,6 +397,7 > @@ tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o > qemu-char.o qemu-timer.o > tests/qemu-iotests/socket_scm_helper$(EXESUF): > tests/qemu-iotests/socket_scm_helper.o tests/test-qemu-opts$(EXESUF): > tests/test-qemu-opts.o libqemuutil.a libqemustub.a > tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o > $(block-obj-y) libqemuutil.a libqemustub.a > +tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o ifeq > ($(CONFIG_POSIX),y) LIBS += -lutil diff --git a/tests/vmgenid-test.c > b/tests/vmgenid-test.c new file mode 100644 index 000..dad1f1b > --- /dev/null > +++ b/tests/vmgenid-test.c > @@ -0,0 +1,44 @@ > +/* > + * QTest testcase for VM Generation ID > + * > + * Copyright (c) 2015 Red Hat, Inc. > + * > + * 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 > +#include "libqtest.h" > + > +static void vmgenid_test(void) > +{ > +static const uint8_t expected[16] = { > +0x32, 0x4e, 0x6e, 0xaf, 0xd1, 0xd1, 0x4b, 0xf6, > +0xbf, 0x41, 0xb9, 0xbb, 0x6c, 0x91, 0xfb, 0x87 > +}; > +uint8_t guid[16]; > +uint32_t i; > + > +/* Skip the ACPI ADDR method and read the GUID directly from > memory. */ > +for (i = 0; i < 16; i++) { > +guid[i] = readb(0xfedf + i); get address from vmgidid.addr property > +} > + > +g_assert_cmpuint(sizeof(guid), ==, sizeof(expected)); > +g_assert(memcmp(guid, expected, sizeof(guid)) == 0); > +} > + > +int main(int argc, char **argv) > +{ > +int ret; > + > +g_test_init(&argc, &argv, NULL); > +qtest_add_func("/vmgenid/vmgenid", vmgenid_test); > + > +qtest_start("-device > vmgenid,uuid=324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"); add case for non default addr value, BTW if board would use default mapping addr then it should also set vmgenid.addr to it so that introspection tools would see actual mapped addr. > +ret = g_test_run(); > + > +qtest_end(); > + > +return ret; > +}
Re: [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device
On Tue, 16 Jun 2015 17:11:02 +0300 Gal Hammer wrote: > Based on Microsoft's specifications (paper can be downloaded from > http://go.microsoft.com/fwlink/?LinkId=260709), add a device > description to the SSDT ACPI table and its implementation. > > The GUID is set using a global "vmgenid.uuid" parameter. > > Signed-off-by: Gal Hammer > --- > default-configs/i386-softmmu.mak | 1 + > default-configs/x86_64-softmmu.mak | 1 + > hw/i386/acpi-build.c | 32 + > hw/misc/Makefile.objs | 1 + > hw/misc/vmgenid.c | 140 > + > include/hw/i386/pc.h | 3 + 6 files changed, 178 > insertions(+) create mode 100644 hw/misc/vmgenid.c > > diff --git a/default-configs/i386-softmmu.mak > b/default-configs/i386-softmmu.mak index 91d602c..3c2fda8 100644 > --- a/default-configs/i386-softmmu.mak > +++ b/default-configs/i386-softmmu.mak > @@ -48,3 +48,4 @@ CONFIG_MEM_HOTPLUG=y > CONFIG_XIO3130=y > CONFIG_IOH3420=y > CONFIG_I82801B11=y > +CONFIG_VMGENID=y > diff --git a/default-configs/x86_64-softmmu.mak > b/default-configs/x86_64-softmmu.mak index 62575eb..36e654d 100644 > --- a/default-configs/x86_64-softmmu.mak > +++ b/default-configs/x86_64-softmmu.mak > @@ -49,3 +49,4 @@ CONFIG_MEM_HOTPLUG=y > CONFIG_XIO3130=y > CONFIG_IOH3420=y > CONFIG_I82801B11=y > +CONFIG_VMGENID=y > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c > index b71e942..784e23d 100644 > --- a/hw/i386/acpi-build.c > +++ b/hw/i386/acpi-build.c > @@ -112,6 +112,7 @@ typedef struct AcpiMiscInfo { > unsigned dsdt_size; > uint16_t pvpanic_port; > uint16_t applesmc_io_base; > +uint64_t vm_generation_addr; > } AcpiMiscInfo; > > typedef struct AcpiBuildPciBusHotplugState { > @@ -238,6 +239,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info) > info->tpm_version = tpm_get_version(); > info->pvpanic_port = pvpanic_port(); > info->applesmc_io_base = applesmc_port(); > +info->vm_generation_addr = vm_generation_addr(); > } > > /* > @@ -1128,6 +1130,36 @@ build_ssdt(GArray *table_data, GArray *linker, > } > > sb_scope = aml_scope("\\_SB"); > + > +if (misc->vm_generation_addr) { > +dev = aml_device("VMGI"); > +aml_append(dev, aml_name_decl("_HID", > aml_string("QEMU0002"))); > +aml_append(dev, > +aml_name_decl("_CID", aml_string("VM_Gen_Counter"))); > +aml_append(dev, > +aml_name_decl("_DDN", aml_string("VM_Gen_Counter"))); > + > +method = aml_method("ADDR", 0); > +pkg = aml_package(2); > +aml_append(pkg, aml_int(misc->vm_generation_addr & > 0x)); > +aml_append(pkg, aml_int(misc->vm_generation_addr >> 32)); > +aml_append(method, aml_store(pkg, aml_local(0))); > +aml_append(method, aml_return(aml_local(0))); > +aml_append(dev, method); > + > +aml_append(sb_scope, dev); > +aml_append(ssdt, sb_scope); > + > +scope = aml_scope("\\_GPE"); > + > +method = aml_method("_E00", 0); > +aml_append(method, > +aml_notify(aml_name("\\_SB.VMGI"), aml_int(0x80))); > + > +aml_append(scope, method); > +aml_append(ssdt, scope); > +} > + > { > /* create PCI0.PRES device and its _CRS to reserve CPU > hotplug MMIO */ dev = aml_device("PCI0." > stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); diff --git > a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index > 4aa76ff..3db11de 100644 --- a/hw/misc/Makefile.objs > +++ b/hw/misc/Makefile.objs > @@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o > > obj-$(CONFIG_PVPANIC) += pvpanic.o > obj-$(CONFIG_EDU) += edu.o > +obj-$(CONFIG_VMGENID) += vmgenid.o > diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c > new file mode 100644 > index 000..4484952 > --- /dev/null > +++ b/hw/misc/vmgenid.c > @@ -0,0 +1,140 @@ > +/* > + * Virtual Machine Generation ID Device > + * > + * Copyright (C) 2015 Red Hat Inc. > + * > + * Authors: Gal Hammer > + * > + * 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 "hw/i386/pc.h" > +#include "hw/acpi/acpi_dev_interface.h" > + > +#define VMGENID_DEVICE "vmgenid" > + > +/* Use the memory address which follows HPET for no special reason. > */ +#define VMGENID_DEFAULT_ADDRESS 0xfedf should be somwhere in target specific in header, I'd suggest i386/pc.h [...] > + > +vmstate_register_ram(&s->iomem, DEVICE(s)); with MMIO it ^^^ won't be needed > +memory_region_add_subregion(get_system_memory(), s->addr, > &s->iomem); +} that should be in pc_machine_device_plug_cb() along the lines: } else if (object_dynamic_cast(OBJECT(dev), TYPE_VMGENID_DEVICE)) { VMGENID_DEVICE_CLASS *dc = GET_FOO_CLASS(dev) addr = get_property(dev, "addr"); memory_region_add_subregion(get_system_memory(),
Re: [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method
On Tue, 16 Jun 2015 17:11:01 +0300 Gal Hammer wrote: > Add a new method to the AcpiDeviceIfClass interface. The new > method sends an ACPI notfication when the VM generation id is > changed. > > Signed-off-by: Gal Hammer > --- > hw/acpi/core.c | 8 > hw/acpi/ich9.c | 8 > hw/acpi/piix4.c | 8 > hw/isa/lpc_ich9.c| 1 + > include/hw/acpi/acpi.h | 2 ++ > include/hw/acpi/acpi_dev_interface.h | 4 > include/hw/acpi/ich9.h | 2 ++ > 7 files changed, 33 insertions(+) > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c > index 0f201d8..3c8d1eb 100644 > --- a/hw/acpi/core.c > +++ b/hw/acpi/core.c > @@ -29,6 +29,8 @@ > #include "qapi-visit.h" > #include "qapi-event.h" > > +#define ACPI_VM_GENERATION_ID_CHANGED_STATUS 1 nowadays this should be a part of AcpiGPEStatusBits enum > + > struct acpi_table_header { > uint16_t _length; /* our length, not actual part of the > hdr */ /* allows easier parsing for fw_cfg clients */ > @@ -703,3 +705,9 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq) > (regs->pm1.evt.en & > ACPI_BITMASK_TIMER_ENABLE) && !(pm1a_sts & > ACPI_BITMASK_TIMER_STATUS)); } > + > +void acpi_vm_generation_id_changed(ACPIREGS *acpi_regs, qemu_irq irq) > +{ > +acpi_regs->gpe.sts[0] |= ACPI_VM_GENERATION_ID_CHANGED_STATUS; > +acpi_update_sci(acpi_regs, irq); replace above 2 with acpi_send_gpe_event() > +} > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c > index 8a64ffb..cab1af7 100644 > --- a/hw/acpi/ich9.c > +++ b/hw/acpi/ich9.c > @@ -429,3 +429,11 @@ void ich9_pm_ospm_status(AcpiDeviceIf *adev, > ACPIOSTInfoList ***list) > acpi_memory_ospm_status(&s->pm.acpi_memory_hotplug, list); > } > + > +void ich9_vm_generation_id_changed(AcpiDeviceIf *adev) > +{ > +ICH9LPCState *s = ICH9_LPC_DEVICE(adev); > +ICH9LPCPMRegs *pm = &s->pm; > + > +acpi_vm_generation_id_changed(&pm->acpi_regs, pm->irq); > +} > diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c > index 3bd1d5a..101a13a 100644 > --- a/hw/acpi/piix4.c > +++ b/hw/acpi/piix4.c > @@ -580,6 +580,13 @@ static void piix4_ospm_status(AcpiDeviceIf > *adev, ACPIOSTInfoList ***list) > acpi_memory_ospm_status(&s->acpi_memory_hotplug, list); } > > +static void piix4_vm_generation_id_changed(AcpiDeviceIf *adev) > +{ > +PIIX4PMState *s = PIIX4_PM(adev); > + > +acpi_vm_generation_id_changed(&s->ar, s->irq); > +} > + > static Property piix4_pm_properties[] = { > DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), > DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, > disable_s3, 0), @@ -618,6 +625,7 @@ static void > piix4_pm_class_init(ObjectClass *klass, void *data) > hc->unplug_request = piix4_device_unplug_request_cb; hc->unplug = > piix4_device_unplug_cb; adevc->ospm_status = piix4_ospm_status; > +adevc->vm_generation_id_changed = piix4_vm_generation_id_changed; > } > > static const TypeInfo piix4_pm_info = { > diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c > index b3e0b1f..f240a3a 100644 > --- a/hw/isa/lpc_ich9.c > +++ b/hw/isa/lpc_ich9.c > @@ -702,6 +702,7 @@ static void ich9_lpc_class_init(ObjectClass > *klass, void *data) hc->unplug_request = > ich9_device_unplug_request_cb; hc->unplug = ich9_device_unplug_cb; > adevc->ospm_status = ich9_pm_ospm_status; > +adevc->vm_generation_id_changed = ich9_vm_generation_id_changed; > } > > static const TypeInfo ich9_lpc_info = { > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h > index b20bd55..1a4caf2 100644 > --- a/include/hw/acpi/acpi.h > +++ b/include/hw/acpi/acpi.h > @@ -196,4 +196,6 @@ unsigned acpi_table_len(void *current); > void acpi_table_add(const QemuOpts *opts, Error **errp); > void acpi_table_add_builtin(const QemuOpts *opts, Error **errp); > > +void acpi_vm_generation_id_changed(ACPIREGS *acpi_regs, qemu_irq > irq); + > #endif /* !QEMU_HW_ACPI_H */ > diff --git a/include/hw/acpi/acpi_dev_interface.h > b/include/hw/acpi/acpi_dev_interface.h index f245f8d..757ce60 100644 > --- a/include/hw/acpi/acpi_dev_interface.h > +++ b/include/hw/acpi/acpi_dev_interface.h > @@ -28,6 +28,9 @@ typedef struct AcpiDeviceIf { > * ospm_status: returns status of ACPI device objects, reported > * via _OST method if device supports it. > * > + * vm_generation_id_changed: notify the guest that it generation > + * id was changed. > + * > * Interface is designed for providing unified interface > * to generic ACPI functionality that could be used without > * knowledge about internals of actual device that implements > @@ -39,5 +42,6 @@ typedef struct AcpiDeviceIfClass { > > /* */ > void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); > +void (*vm_generation_id_changed)(AcpiDeviceIf *adev); > } AcpiDeviceIfClass; > #endif > diff --git a/include/hw/acpi/ich9.h b/incl
Re: [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device
On Tue, 16 Jun 2015 17:11:02 +0300 Gal Hammer wrote: > Based on Microsoft's specifications (paper can be downloaded from > http://go.microsoft.com/fwlink/?LinkId=260709), add a device > description to the SSDT ACPI table and its implementation. > > The GUID is set using a global "vmgenid.uuid" parameter. -device vmgenid,uuid=FOO or some QMP FOO > > Signed-off-by: Gal Hammer > --- > default-configs/i386-softmmu.mak | 1 + > default-configs/x86_64-softmmu.mak | 1 + > hw/i386/acpi-build.c | 32 + > hw/misc/Makefile.objs | 1 + > hw/misc/vmgenid.c | 140 > + > include/hw/i386/pc.h | 3 + 6 files changed, 178 > insertions(+) create mode 100644 hw/misc/vmgenid.c > > diff --git a/default-configs/i386-softmmu.mak > b/default-configs/i386-softmmu.mak index 91d602c..3c2fda8 100644 > --- a/default-configs/i386-softmmu.mak > +++ b/default-configs/i386-softmmu.mak > @@ -48,3 +48,4 @@ CONFIG_MEM_HOTPLUG=y > CONFIG_XIO3130=y > CONFIG_IOH3420=y > CONFIG_I82801B11=y > +CONFIG_VMGENID=y > diff --git a/default-configs/x86_64-softmmu.mak > b/default-configs/x86_64-softmmu.mak index 62575eb..36e654d 100644 > --- a/default-configs/x86_64-softmmu.mak > +++ b/default-configs/x86_64-softmmu.mak > @@ -49,3 +49,4 @@ CONFIG_MEM_HOTPLUG=y > CONFIG_XIO3130=y > CONFIG_IOH3420=y > CONFIG_I82801B11=y > +CONFIG_VMGENID=y > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c > index b71e942..784e23d 100644 > --- a/hw/i386/acpi-build.c > +++ b/hw/i386/acpi-build.c > @@ -112,6 +112,7 @@ typedef struct AcpiMiscInfo { > unsigned dsdt_size; > uint16_t pvpanic_port; > uint16_t applesmc_io_base; > +uint64_t vm_generation_addr; > } AcpiMiscInfo; > > typedef struct AcpiBuildPciBusHotplugState { > @@ -238,6 +239,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info) > info->tpm_version = tpm_get_version(); > info->pvpanic_port = pvpanic_port(); > info->applesmc_io_base = applesmc_port(); > +info->vm_generation_addr = vm_generation_addr(); > } > > /* > @@ -1128,6 +1130,36 @@ build_ssdt(GArray *table_data, GArray *linker, > } > > sb_scope = aml_scope("\\_SB"); move ^^ inside of if(misc->vm_generation_addr) block > +if (misc->vm_generation_addr) { like this: + sb_scope = aml_scope("\\_SB"); // <= scope comes > +dev = aml_device("VMGI"); ... > + > +aml_append(sb_scope, dev); > +aml_append(ssdt, sb_scope); ^^^ scope goes away here you've added sb_scope to ssdt and later it continues to be extended with PCI0.PRES and other devices. it most likely will cause a mess in the table. Try to verify by running "make check" to see what changes you've added. > + > +scope = aml_scope("\\_GPE"); > + > +method = aml_method("_E00", 0); > +aml_append(method, > +aml_notify(aml_name("\\_SB.VMGI"), aml_int(0x80))); > + > +aml_append(scope, method); > +aml_append(ssdt, scope); > +} leave original line as it was: sb_scope = aml_scope("\\_SB"); > { > /* create PCI0.PRES device and its _CRS to reserve CPU > hotplug MMIO */ dev = aml_device("PCI0." > stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); diff --git > a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index > 4aa76ff..3db11de 100644 --- a/hw/misc/Makefile.objs > +++ b/hw/misc/Makefile.objs > @@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o > > obj-$(CONFIG_PVPANIC) += pvpanic.o > obj-$(CONFIG_EDU) += edu.o > +obj-$(CONFIG_VMGENID) += vmgenid.o > diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c > new file mode 100644 > index 000..4484952 > --- /dev/null > +++ b/hw/misc/vmgenid.c > @@ -0,0 +1,140 @@ > +/* > + * Virtual Machine Generation ID Device > + * > + * Copyright (C) 2015 Red Hat Inc. > + * > + * Authors: Gal Hammer > + * > + * 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 "hw/i386/pc.h" > +#include "hw/acpi/acpi_dev_interface.h" > + > +#define VMGENID_DEVICE "vmgenid" > + > +/* Use the memory address which follows HPET for no special reason. > */ +#define VMGENID_DEFAULT_ADDRESS 0xfedf > + > +#define PROPERTY_ADDR "addr" > +#define PROPERTY_UUID "uuid" > + > +#define VMGENID(obj) OBJECT_CHECK(VmGenIdState, (obj), > VMGENID_DEVICE) + > +typedef struct VmGenIdState { > +DeviceState parent_obj; > +MemoryRegion iomem; > +uint64_t addr; > +uint8_t guid[16]; > +bool guid_set; > +} VmGenIdState; > + > +uint64_t vm_generation_addr(void) > +{ > +Object *obj = object_resolve_path_type("", VMGENID_DEVICE, NULL); > +VmGenIdState *s = VMGENID(obj); > + > +if (!obj) { > +return 0; > +} > +return s->addr; > +} > + > +static void update_guest(VmGenIdState *s, bool notify) > +{ > +void *ptr = memory_region_get_
Re: [Qemu-devel] [RFC] generic-gpio-led & stm32-gpio-led
> On 16 Jun 2015, at 19:10, Peter Crosthwaite > wrote: > > ... In my proposal the machine model would do this. > > qdev_connect_gpio_out_named(mcu, "name", index, qdev_get_gpio_in(gpio_dev, > 0)); > > Or something like that. connecting a gpio_out to a gpio_in seems not possible, gpio_in irqs are parented to the device and parenting them to the gpio_out fail with the parent != 0 assertion. however I was able to connect_gpio_out for standalone irqs. the actual connection sequence is: qemu_irq irq = GENERIC_GPIO_LED_STATE(led)->irq; qdev_connect_gpio_out(DEVICE(object_resolve_path("/machine/stm32/gpio[c]", NULL)), 12, irq); I'm not very happy with it, since it is quite long. any suggestions how to make it more readable? > E.g. if the SoC define "bank A" gpios, then a > suitable string name would be "bank-A". This should match the SoC > level, not the board level so it wouldn't be names like "green-led". this is still too tricky for me. since the default names were unusable (like device[7], etc), I created two containers (cortexm and stm32) and placed the peripherals inside, with names like /cortexm/nvic, cortexm/itm, stm32/rcc, stm32/gpio[%c], etc. I used calls like: state->container = container_get(qdev_get_machine(), "/stm32"); object_property_add_child(state->container, "rcc", OBJECT(state->rcc), NULL); would this be acceptable? regards, Liviu
[Qemu-devel] GSoC 2015 (Mac OS 9 support) report, week 7
[This Week] - Fix ppc: mem_claim() and mmu_claim() - Remove extraneous "interrupts" property from /pci/mac-io - I'm having trouble tracking down where the property is actually being set. The mac-io devices are defined in drivers/pci_database.c, but the pci_dev_t struct (drivers/pci_database.h) doesn't appear to have an interrupts field. Much of the mac-io related functionality is defined in drivers/macio.c, but there's no mention of interrupts there so I'm kind of at a loss. - This originates from the PCI device's announcement of an IRQ pin which really shouldn't be there - This only requires minimal changes, so the patch is ready. Just has to be tested before submission. - Initial patch version has been submitted to the qemu-devel mailing list. - Review requires v2, need to follow up with that now - Test and debug boot script loader - We're going to shrink the scope of the patch for a less complex solution -- just a different method of measuring script length. - Trace virtual memory maps for rom-virt and figure out why copying the rom there doesn't work - Verify that the carriage return / newline problem is related to stack corruption - Try to run the boot script without RELEASE-LOAD-AREA [Next Week] - Enable debugging in MOL - The installation is now broken after a failed make. Tried reinstalling from Zypper but it couldn't find the config files -- do they have to be added manually? - The config files are at a different location when you compile manually, but I don't remember where everything was :). Just run mol with strace, it will tell you where it's looking for things. The current ones should be somewhere in /etc. [Long Term] - Progress past quiesce() client interface call - At the moment, this function simply closes all USB devices (`usb_exit()`) and sets the Instruction and Data Address Translation bits in the MSR (@agraf: does this cause any side effects?). The stack diagram shows no arguments or return values, and none of the other `ciface` functions make any modifications to the stack other than their arguments or return values. - Looks like `quiesce` either hangs on `mtmsr` or makes a jump out of the function. - MSR.IR and MSR.DR enable paging for instructions and data respectively. IIRC we disable paging when quiesce gets called because it's the last call that Linux runs before it executes non-OF aware code IIRC. - Try to run qemu with -d in_asm,cpu,int -D log and check where the code execution hangs :). There's a good chance we're already in the Mac OS 9 kernel. - It would appear that execution has branched off into invalid memory. invalid/unsupported opcode: 00 - 00 - 00 () 00f03000 0 IN: 0x00f03000: .long 0x0 - Awesome. What code gets executed before that? Maybe we shouldn't turn off IR/DR? - Actually looking at the code, the MSR IR/DR part is surround by a #if 0 ... #endif pair... maybe something in usb_exit() is breaking things? Possibly try removing it temporarily? - usb_exit() doesn't appear to be causing any issues. - This is probably where things go wrong. At 0x0740 I can't see a ToolboxImage: ToolboxImage current logical address = 0x0740, ToolboxImage final physical address = 0x00C0. - Is it just the virt<->phys map that is missing, i.e. can you see if the toolbox image is present in physical memory using the QEMU monitor "xp" command? In that case it might be that we need to mark a region as free in the virtual memory properties in order to allow the mapping to succeed. A DEBUG_CIF enabled log would help here. - IIRC we're just using a 1:1 map for almost everything, so I doubt that it's an MMU problem. From a small glimpse it almost looked like the binary simply never got loaded to the address it thought it would be loaded at. - Continue updating project log - Create and send patches - [ ] Patch: Boot script loader - [ ] ROM node - Patch: RTAS node - Patch has been sent in and is awaiting review. [Done] - Finals ヽ(o`皿′o)ノ - Test all patches - Darwin, OpenBSD, and Ubuntu have been tested successfully. - Patch: Combined Adler-32 and copyright - This patch will be split into two separate ones as suggested by Mark. - Splitting in progress.
Re: [Qemu-devel] [PATCH] s390x: Switch to s390-ccw machine as default
Am 16.06.2015 um 23:08 schrieb Alexander Graf: > We now finally have TCG support for the basic set of instructions necessary > to run the s390-ccw machine. That means in any aspect possible that machine > type is now superior to the legacy s390-virtio machine. > > Switch over to the ccw machine as default. That way people don't get a halfway > broken machine with the s390x target. > > Signed-off-by: Alexander Graf It will certainly make life easier for kvm on s390. Acked-by: Christian Borntraeger > --- > blockdev.c | 2 +- > hw/s390x/s390-virtio-ccw.c | 1 + > hw/s390x/s390-virtio.c | 1 - > qdev-monitor.c | 6 +++--- > 4 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/blockdev.c b/blockdev.c > index 3aa1ae6..41d7e0f 100644 > --- a/blockdev.c > +++ b/blockdev.c > @@ -942,7 +942,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, > BlockInterfaceType block_default_type) > devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, > &error_abort); > if (arch_type == QEMU_ARCH_S390X) { > -qemu_opt_set(devopts, "driver", "virtio-blk-s390", &error_abort); > +qemu_opt_set(devopts, "driver", "virtio-blk-ccw", &error_abort); > } else { > qemu_opt_set(devopts, "driver", "virtio-blk-pci", &error_abort); > } > diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c > index 8a565f6..c574988 100644 > --- a/hw/s390x/s390-virtio-ccw.c > +++ b/hw/s390x/s390-virtio-ccw.c > @@ -216,6 +216,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void > *data) > mc->no_sdcard = 1; > mc->use_sclp = 1; > mc->max_cpus = 255; > +mc->is_default = 1; > nc->nmi_monitor_handler = s390_nmi; > } > > diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c > index 59750db..00ea793 100644 > --- a/hw/s390x/s390-virtio.c > +++ b/hw/s390x/s390-virtio.c > @@ -345,7 +345,6 @@ static void s390_machine_class_init(ObjectClass *oc, void > *data) > mc->no_floppy = 1; > mc->no_cdrom = 1; > mc->no_sdcard = 1; > -mc->is_default = 1; > nc->nmi_monitor_handler = s390_nmi; > } > > diff --git a/qdev-monitor.c b/qdev-monitor.c > index 7dd62dd..d71d1ee 100644 > --- a/qdev-monitor.c > +++ b/qdev-monitor.c > @@ -42,9 +42,9 @@ static const QDevAlias qdev_alias_table[] = { > { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X > }, > { "virtio-balloon-pci", "virtio-balloon", > QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, > -{ "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X }, > -{ "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X }, > -{ "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X }, > +{ "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X }, > +{ "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X }, > +{ "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X }, > { "lsi53c895a", "lsi" }, > { "ich9-ahci", "ahci" }, > { "kvm-pci-assign", "pci-assign" }, >
Re: [Qemu-devel] [PATCH] s390x: Switch to s390-ccw machine as default
On 2015-06-16 23:08, Alexander Graf wrote: > We now finally have TCG support for the basic set of instructions necessary > to run the s390-ccw machine. That means in any aspect possible that machine > type is now superior to the legacy s390-virtio machine. > > Switch over to the ccw machine as default. That way people don't get a halfway > broken machine with the s390x target. > > Signed-off-by: Alexander Graf \o/ Very good idea! Reviewed-by: Aurelien Jarno That said in the future it would be even better if we can automagically pass bootindex=1 to the first created drive when not declaring the device and the drive separately. That would allow to run an image with just: qemu-system-s390x -nographic -drive file=image.qcow2 Aurelien -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH RFC 3/3] block/nfs: switch to error_init_local
On Tue, Jun 16, 2015 at 09:08:16AM -0600, Eric Blake wrote: > On 06/16/2015 06:53 AM, Michael S. Tsirkin wrote: > > We probably should just switch everyone, this is > > just to demonstrate the API usage. > > > > Signed-off-by: Michael S. Tsirkin > > --- > > block/nfs.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > And indeed this is the reason things are still at RFC level. I like the > idea. It doesn't change anything for a bug-free program, but where we > DO have a bug, we now get a stacktrace that aborts as soon as possible > rather than delaying to the propagation point and losing some information. > > > > > diff --git a/block/nfs.c b/block/nfs.c > > index ca9e24e..de4b8c3 100644 > > --- a/block/nfs.c > > +++ b/block/nfs.c > > @@ -385,7 +385,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict > > *options, int flags, > > NFSClient *client = bs->opaque; > > int64_t ret; > > QemuOpts *opts; > > -Error *local_err = NULL; > > +Error *local_err = error_init_local(errp); > > Should be a fairly mechanical patch to catch all the spots; although > there are multiple spellings (not all callers name it local_err). I'll try to write an spatch to do this. > -- > Eric Blake eblake redhat com+1-919-301-3266 > Libvirt virtualization library http://libvirt.org >
[Qemu-devel] [PATCH] s390x: Switch to s390-ccw machine as default
We now finally have TCG support for the basic set of instructions necessary to run the s390-ccw machine. That means in any aspect possible that machine type is now superior to the legacy s390-virtio machine. Switch over to the ccw machine as default. That way people don't get a halfway broken machine with the s390x target. Signed-off-by: Alexander Graf --- blockdev.c | 2 +- hw/s390x/s390-virtio-ccw.c | 1 + hw/s390x/s390-virtio.c | 1 - qdev-monitor.c | 6 +++--- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blockdev.c b/blockdev.c index 3aa1ae6..41d7e0f 100644 --- a/blockdev.c +++ b/blockdev.c @@ -942,7 +942,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, &error_abort); if (arch_type == QEMU_ARCH_S390X) { -qemu_opt_set(devopts, "driver", "virtio-blk-s390", &error_abort); +qemu_opt_set(devopts, "driver", "virtio-blk-ccw", &error_abort); } else { qemu_opt_set(devopts, "driver", "virtio-blk-pci", &error_abort); } diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 8a565f6..c574988 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -216,6 +216,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) mc->no_sdcard = 1; mc->use_sclp = 1; mc->max_cpus = 255; +mc->is_default = 1; nc->nmi_monitor_handler = s390_nmi; } diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index 59750db..00ea793 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -345,7 +345,6 @@ static void s390_machine_class_init(ObjectClass *oc, void *data) mc->no_floppy = 1; mc->no_cdrom = 1; mc->no_sdcard = 1; -mc->is_default = 1; nc->nmi_monitor_handler = s390_nmi; } diff --git a/qdev-monitor.c b/qdev-monitor.c index 7dd62dd..d71d1ee 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -42,9 +42,9 @@ static const QDevAlias qdev_alias_table[] = { { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, { "virtio-balloon-pci", "virtio-balloon", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, -{ "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X }, -{ "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X }, -{ "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X }, +{ "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X }, +{ "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X }, +{ "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X }, { "lsi53c895a", "lsi" }, { "ich9-ahci", "ahci" }, { "kvm-pci-assign", "pci-assign" }, -- 1.7.12.4
[Qemu-devel] [PATCH] target-s390x: fix MOVE LONG instruction
The MOVE LONG instruction should pad the destination operand with the byte from bit positions 32-39 of the source length (r2 + 1), not with the same byte in the source address. Cc: Alexander Graf Cc: Richard Henderson Signed-off-by: Aurelien Jarno --- target-s390x/mem_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index 3ccbeb9..9f0eb1e 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -550,7 +550,7 @@ uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2) uint64_t dest = get_address_31fix(env, r1); uint64_t srclen = env->regs[r2 + 1] & 0xff; uint64_t src = get_address_31fix(env, r2); -uint8_t pad = src >> 24; +uint8_t pad = env->regs[r2 + 1] >> 24; uint8_t v; uint32_t cc; -- 2.1.4
Re: [Qemu-devel] [PATCH] Migration compatibility for serial
On Tue, Jun 16, 2015 at 07:54:09PM +0100, Dr. David Alan Gilbert (git) wrote: > From: "Dr. David Alan Gilbert" > > Older QEMUs dont understand the new (sub)sections that > may be generated in the serial device. Limit their generation > to newer machine types. > > Signed-off-by: Dr. David Alan Gilbert I don't see a problem with this, but the specific interface is unfortunate: this spreads versioning info around which we don't normally do. Instead, please add specific flags, e.g. serial_has_recv_fifo Also, is it really enough to just skip a bunch of stuff on load? For example, I notice that before 7385b275d9ae8bdf3c012bc4e2ae9779fcea6312 we used to generate interrupts on loadvm - isn't that needed in this compat mode? > --- > hw/char/serial.c | 19 +-- > hw/i386/pc_piix.c| 2 ++ > hw/i386/pc_q35.c | 2 ++ > hw/ppc/spapr.c | 2 ++ > include/hw/char/serial.h | 3 +++ > 5 files changed, 22 insertions(+), 6 deletions(-) > > diff --git a/hw/char/serial.c b/hw/char/serial.c > index 513d73c..ef31df3 100644 > --- a/hw/char/serial.c > +++ b/hw/char/serial.c > @@ -103,6 +103,9 @@ do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } > while (0) > do {} while (0) > #endif > > +/* Force migration compatibility of pre-2.2 machine types */ > +bool serial_migrate_pre_2_2; > + > static void serial_receive1(void *opaque, const uint8_t *buf, int size); > > static inline void recv_fifo_put(SerialState *s, uint8_t chr) > @@ -646,6 +649,10 @@ static bool serial_thr_ipending_needed(void *opaque) > { > SerialState *s = opaque; > > +if (serial_migrate_pre_2_2) { > +return false; > +} > + > if (s->ier & UART_IER_THRI) { > bool expected_value = ((s->iir & UART_IIR_ID) == UART_IIR_THRI); > return s->thr_ipending != expected_value; > @@ -672,7 +679,7 @@ static const VMStateDescription > vmstate_serial_thr_ipending = { > static bool serial_tsr_needed(void *opaque) > { > SerialState *s = (SerialState *)opaque; > -return s->tsr_retry != 0; > +return !serial_migrate_pre_2_2 && s->tsr_retry != 0; > } > > static const VMStateDescription vmstate_serial_tsr = { > @@ -691,7 +698,7 @@ static const VMStateDescription vmstate_serial_tsr = { > static bool serial_recv_fifo_needed(void *opaque) > { > SerialState *s = (SerialState *)opaque; > -return !fifo8_is_empty(&s->recv_fifo); > +return !serial_migrate_pre_2_2 && !fifo8_is_empty(&s->recv_fifo); > > } > > @@ -709,7 +716,7 @@ static const VMStateDescription vmstate_serial_recv_fifo > = { > static bool serial_xmit_fifo_needed(void *opaque) > { > SerialState *s = (SerialState *)opaque; > -return !fifo8_is_empty(&s->xmit_fifo); > +return !serial_migrate_pre_2_2 && !fifo8_is_empty(&s->xmit_fifo); > } > > static const VMStateDescription vmstate_serial_xmit_fifo = { > @@ -726,7 +733,7 @@ static const VMStateDescription vmstate_serial_xmit_fifo > = { > static bool serial_fifo_timeout_timer_needed(void *opaque) > { > SerialState *s = (SerialState *)opaque; > -return timer_pending(s->fifo_timeout_timer); > +return !serial_migrate_pre_2_2 && timer_pending(s->fifo_timeout_timer); > } > > static const VMStateDescription vmstate_serial_fifo_timeout_timer = { > @@ -743,7 +750,7 @@ static const VMStateDescription > vmstate_serial_fifo_timeout_timer = { > static bool serial_timeout_ipending_needed(void *opaque) > { > SerialState *s = (SerialState *)opaque; > -return s->timeout_ipending != 0; > +return !serial_migrate_pre_2_2 && s->timeout_ipending != 0; > } > > static const VMStateDescription vmstate_serial_timeout_ipending = { > @@ -760,7 +767,7 @@ static const VMStateDescription > vmstate_serial_timeout_ipending = { > static bool serial_poll_needed(void *opaque) > { > SerialState *s = (SerialState *)opaque; > -return s->poll_msl >= 0; > +return !serial_migrate_pre_2_2 && s->poll_msl >= 0; > } > > static const VMStateDescription vmstate_serial_poll = { > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c > index e142f75..d6d596c 100644 > --- a/hw/i386/pc_piix.c > +++ b/hw/i386/pc_piix.c > @@ -39,6 +39,7 @@ > #include "hw/kvm/clock.h" > #include "sysemu/sysemu.h" > #include "hw/sysbus.h" > +#include "hw/char/serial.h" > #include "hw/cpu/icc_bus.h" > #include "sysemu/arch_init.h" > #include "sysemu/block-backend.h" > @@ -344,6 +345,7 @@ static void pc_compat_2_1(MachineState *machine) > x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0); > x86_cpu_compat_kvm_no_autodisable(FEAT_8000_0001_ECX, CPUID_EXT3_SVM); > pcms->enforce_aligned_dimm = false; > +serial_migrate_pre_2_2 = true; > } > > static void pc_compat_2_0(MachineState *machine) > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c > index b68263d..a211f21 100644 > --- a/hw/i386/pc_q35.c > +++ b/hw/i386/pc_q35.c > @@ -32,6 +32,7 @@ > #include "sysemu/arch_
Re: [Qemu-devel] [RFC] generic-gpio-led & stm32-gpio-led
On Tue, Jun 16, 2015 at 12:22 PM, Liviu Ionescu wrote: > >> On 16 Jun 2015, at 21:19, Peter Crosthwaite >> wrote: >> >> Your autoformatter does a surprisingly good job of getting close to >> qemu coding style. Can the rules just be tweaked any maybe QEMU coding >> style can be added to eclipse? > > this is exactly what I did, I took the K&R and tweaked it where possible. > unfortunately the closing brace position is not configurable. > >> They are not really aliases, they are the GPIO names proper. >> qdev_[init|get|connect]_gpio_[in|out]_named are direct replacements >> for the non named variants. The non-human internal names should go >> away if you use them. The name of the GPIO should match something in >> the TRM for the device. E.g. if the SoC define "bank A" gpios, then a >> suitable string name would be "bank-A". This should match the SoC >> level, not the board level so it wouldn't be names like "green-led". >> Your new code handles that information. For your generic LED however, >> that is a QEMU invention which is why I propose a single unnamed GPIO >> in that case. > > oops... you lost me... I need to dig a bit to understand this. > >> I have to wonder though if the printfery is the right approach. > > blinking leds with printf() is just the first step, or the backup solution if > graphics are not available. the plan was to enable graphics, present a > picture of the board, and blink the led by painting a saturated square in the > led location. however I don't know yet how much effort this may take, and if > it is worth doing it, but it would definitely be a good marketing tool ;-) > >> Can >> eclipse use QEMUs existing GPIO introspection capabilites to get the >> LED states and do something with them? Then the LED definition is pure >> GPIO passing and these is no need for new devices at all. > > I do not know the QEMU introspection capabilities (hint?) but my Eclipse > plug-in can be extended to connect to any reasonable protocol. > qtest protocol I think. I would grep qdev_intercept_gpio_out and go from there. Regards, Peter > --- > > I'm currently reworking the (generic-)gpio-led to be standalone and > accommodate your suggestions, but it'll take me some time to figure out the > details of nodes naming. > > I also had a small problem with the objects tree. initially my gpio-led > object was not derived from SysBusDevice, since I considered it a separate > object. it was functional, but made 'info qtree' fail. I changed the node > parent to SysBusDevice but I'm not sure what would be the best topology for > my object tree. > That SysBus parenting will lead to a false topology anyways. The correct parent for the LED is TYPE_DEVICE. don't worry about the qtree, Andreas was working on a correct solution for the tree-dump that uses QOM rather than the legacy qbus tree (qtree). Regards, Peter > > regards, > > Liviu > >
Re: [Qemu-devel] [PATCH target-arm v2 10/13] target-arm: Implement PMSAv7 MPU
On Fri, Jun 12, 2015 at 12:10 PM, Peter Crosthwaite wrote: > Unified MPU only. Uses ARM architecture major revision to switch > between PMSAv5 and v7 when ARM_FEATURE_MPU is set. PMSA v6 remains > unsupported and is asserted against. > > Signed-off-by: Peter Crosthwaite > --- > changed since v1 (PMM review): > Add comment about PMSAv6 non-support > Fix case where MPU is completely disabled > Ignore regions with 0 size. > GUEST_ERROR invalid base address alignments > UNIMP regions that are smaller than TARGET_PAGE_SIZE > use extract32 to get SR disable bits > Fixed up DRACR AP bit error message. > Correct bullet point about MPU FSR format > Rebased against new FSR return system > removed *prot switch-case > > target-arm/cpu.h| 1 + > target-arm/helper.c | 173 > +++- > 2 files changed, 173 insertions(+), 1 deletion(-) > > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index 43c1f85..bfba377 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -561,6 +561,7 @@ void pmccntr_sync(CPUARMState *env); > #define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */ > #define SCTLR_nTWI(1U << 16) /* v8 onward */ > #define SCTLR_HA (1U << 17) > +#define SCTLR_BR (1U << 17) /* PMSA only */ > #define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */ > #define SCTLR_nTWE(1U << 18) /* v8 onward */ > #define SCTLR_WXN (1U << 19) > diff --git a/target-arm/helper.c b/target-arm/helper.c > index 588dbc9..6436c93 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -5827,6 +5827,166 @@ do_fault: > return true; > } > > +static inline void get_phys_addr_pmsav7_default(CPUARMState *env, > +ARMMMUIdx mmu_idx, > +int32_t address, int *prot) > +{ > +*prot = PAGE_READ | PAGE_WRITE; > +switch (address) { > +case 0xF000 ... 0x: > +if (regime_sctlr(env, mmu_idx) & SCTLR_V) { /* hivecs execing is ok > */ > +*prot |= PAGE_EXEC; > +} > +break; > +case 0x ... 0x7FFF: > +*prot |= PAGE_EXEC; > +break; > +} > + > +} > + > +static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, > + int access_type, ARMMMUIdx mmu_idx, > + hwaddr *phys_ptr, int *prot, uint32_t *fsr) > +{ > +ARMCPU *cpu = arm_env_get_cpu(env); > +int n; > +bool is_user = regime_is_user(env, mmu_idx); > + > +*phys_ptr = address; > +*prot = 0; > + > +if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ > +get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); > +} else { /* MPU enabled */ > +for (n = cpu->pmsav7_dregion; n >= 0; n--) { /* region search */ -1 on initialiser. I guess I have been getting lucky with 0s in the right place on my test guest. > +uint32_t base = env->pmsav7.drbar[n]; > +uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5); > +uint32_t rmask; > +bool srdis = false; > + > +if (!(env->pmsav7.drsr[n] & 0x1)) { > +continue; > +} > + > +if (!rsize) { > +qemu_log_mask(LOG_GUEST_ERROR, "DRSR.Rsize field can not be > 0"); > +continue; > +} > +rsize++; > +rmask = (1ull << rsize) - 1; > + > +if (base & rmask) { > +qemu_log_mask(LOG_GUEST_ERROR, "DRBAR %" PRIx32 " misaligned > " > + "to DRSR region size, mask = %" PRIx32, > + base, rmask); > +continue; > +} > + > +if (address < base || address > base + rmask) { > +continue; > +} > + > +/* Region matched */ > + > +if (rsize >= 8) { /* no subregions for regions < 256 bytes */ > +int i, snd; > +uint32_t srdis_mask; > + > +rsize -= 3; /* sub region size (power of 2) */ > +snd = ((address - base) >> rsize) & 0x7; > +srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1); > + > +srdis_mask = srdis ? 0x3 : 0x0; > +for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) { > +/* This will check in groups of 2, 4 and then 8, whether > + * the subregion bits are consistent. rsize is > incremented > + * back up to give the region size, considering > consistent > + * adjacent subregions as one region. Stop testing if > rsize > + * is already big enough for an entire QEMU page. > + */ > +int snd_rounded = snd & ~(i - 1); > +uint32_t srdis_multi = extract32(env->pms
Re: [Qemu-devel] [RFC] generic-gpio-led & stm32-gpio-led
> On 16 Jun 2015, at 21:19, Peter Crosthwaite > wrote: > > Your autoformatter does a surprisingly good job of getting close to > qemu coding style. Can the rules just be tweaked any maybe QEMU coding > style can be added to eclipse? this is exactly what I did, I took the K&R and tweaked it where possible. unfortunately the closing brace position is not configurable. > They are not really aliases, they are the GPIO names proper. > qdev_[init|get|connect]_gpio_[in|out]_named are direct replacements > for the non named variants. The non-human internal names should go > away if you use them. The name of the GPIO should match something in > the TRM for the device. E.g. if the SoC define "bank A" gpios, then a > suitable string name would be "bank-A". This should match the SoC > level, not the board level so it wouldn't be names like "green-led". > Your new code handles that information. For your generic LED however, > that is a QEMU invention which is why I propose a single unnamed GPIO > in that case. oops... you lost me... I need to dig a bit to understand this. > I have to wonder though if the printfery is the right approach. blinking leds with printf() is just the first step, or the backup solution if graphics are not available. the plan was to enable graphics, present a picture of the board, and blink the led by painting a saturated square in the led location. however I don't know yet how much effort this may take, and if it is worth doing it, but it would definitely be a good marketing tool ;-) > Can > eclipse use QEMUs existing GPIO introspection capabilites to get the > LED states and do something with them? Then the LED definition is pure > GPIO passing and these is no need for new devices at all. I do not know the QEMU introspection capabilities (hint?) but my Eclipse plug-in can be extended to connect to any reasonable protocol. --- I'm currently reworking the (generic-)gpio-led to be standalone and accommodate your suggestions, but it'll take me some time to figure out the details of nodes naming. I also had a small problem with the objects tree. initially my gpio-led object was not derived from SysBusDevice, since I considered it a separate object. it was functional, but made 'info qtree' fail. I changed the node parent to SysBusDevice but I'm not sure what would be the best topology for my object tree. regards, Liviu
Re: [Qemu-devel] [PATCH target-arm v2 07/13] target-arm/helper.c: define MPUIR register
On Mon, Jun 15, 2015 at 6:44 AM, Peter Maydell wrote: > On 12 June 2015 at 20:10, Peter Crosthwaite > wrote: >> Define the MPUIR register for MPU supporting systems V6 onwards. > > "(ARMv6 and onwards)". > >> Currently only support unified MPU. > > "we only" > >> The size of the unified MPU is supported via the number of "dregions". >> So just a single config as added to specify this size. (When split MPU >> is implemented iregions will accompany). > > Try: > > The size of the unified MPU is defined via the number of "dregions". > So just a single config is added to specify this size. (When split MPU > is implemented we will add an extra iregions config). > Fixed all. >> Signed-off-by: Peter Crosthwaite >> --- >> changed since v1: >> Add #regions configuration >> conditionalise MPUIR existence >> >> target-arm/cpu-qom.h | 2 ++ >> target-arm/cpu.c | 8 >> target-arm/helper.c | 10 ++ >> 3 files changed, 20 insertions(+) >> >> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h >> index 30832d9..05c33ac 100644 >> --- a/target-arm/cpu-qom.h >> +++ b/target-arm/cpu-qom.h >> @@ -105,6 +105,8 @@ typedef struct ARMCPU { >> >> /* CPU has memory protection unit */ >> bool has_mpu; >> +/* PMSAv7 MPU number of supported regions */ >> +uint32_t pmsav7_dregion; >> >> /* PSCI conduit used to invoke PSCI methods >> * 0 - disabled, 1 - smc, 2 - hvc >> diff --git a/target-arm/cpu.c b/target-arm/cpu.c >> index 82ac52d..c967763 100644 >> --- a/target-arm/cpu.c >> +++ b/target-arm/cpu.c >> @@ -445,6 +445,9 @@ static Property arm_cpu_has_el3_property = >> static Property arm_cpu_has_mpu_property = >> DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); >> >> +static Property arm_cpu_pmsav7_dregion_property = >> +DEFINE_PROP_UINT32("pmsav7-dregion", ARMCPU, pmsav7_dregion, >> 16); >> + >> static void arm_cpu_post_init(Object *obj) >> { >> ARMCPU *cpu = ARM_CPU(obj); >> @@ -476,6 +479,11 @@ static void arm_cpu_post_init(Object *obj) >> if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) { >> qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, >> &error_abort); >> +if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { >> +qdev_property_add_static(DEVICE(obj), >> + &arm_cpu_pmsav7_dregion_property, >> + &error_abort); >> +} >> } > > > Worth making bogus values (<0, >255, at least) a realize error, > I think, especially since we start allocating memory based on > the number of regions later on. > Added realize error. So it occurs to me that 0 itself is valid for #dregions. I have patched the memory allocation to not happen in 0 case and added null guards to the pointer accessors. This means that a PMSA with 0 regions can be configured which will still call get_phys_addr_pmsav7 and get the default behaviour. Regards, Peter > Otherwise OK. > > -- PMM >
Re: [Qemu-devel] [PATCH v2 1/4] ahci: Do not ignore memory access read size
On 06/16/2015 12:25 PM, Eric Blake wrote: > On 06/16/2015 10:02 AM, John Snow wrote: >> The only guidance the AHCI specification gives on memory access >> is: "Register accesses shall have a maximum size of 64-bits; >> 64-bit access must not cross an 8-byte alignment boundary." >> >> I interpret this to mean that aligned or unaligned 1, 2 and 4 >> byte accesses should work, as well as aligned 8 byte accesses. >> >> In practice, a real Q35/ICH9 responds to 1, 2, 4 and 8 byte >> reads regardless of alignment. Windows 7 can be observed making 1 >> byte reads to the middle of 32 bit registers to fetch error >> codes. >> >> Introduce a wrapper to support unaligned accesses to AHCI. This >> wrapper will support aligned 8 byte reads, but will make no >> effort to support unaligned 8 byte reads, which although they >> will work on real hardware, are not guaranteed to work and do not >> appear to be used by either Windows or Linux. >> >> Signed-off-by: John Snow --- hw/ide/ahci.c | >> 27 +-- 1 file changed, 25 insertions(+), >> 2 deletions(-) >> > >> +/** + * AHCI 1.3 section 3 ("HBA Memory Registers") + * Support >> unaligned 8/16/32 bit reads, and 64 bit aligned reads. + * Caller >> is responsible for masking unwanted higher order bytes. + */ >> +static uint64_t ahci_mem_read(void *opaque, hwaddr addr, >> unsigned size) +{ +hwaddr aligned = addr & ~0x3; > > This actually supports 4-byte aligned 8-byte reads (which is an > unaligned 8-byte read). Doesn't matter; no guest should be relying > on it. > > Reviewed-by: Eric Blake > Easier to say "indeterminate" than rely on wonko behavior, even if it sometimes accidentally works :) Thanks.
[Qemu-devel] [PATCH] Migration compatibility for serial
From: "Dr. David Alan Gilbert" Older QEMUs dont understand the new (sub)sections that may be generated in the serial device. Limit their generation to newer machine types. Signed-off-by: Dr. David Alan Gilbert --- hw/char/serial.c | 19 +-- hw/i386/pc_piix.c| 2 ++ hw/i386/pc_q35.c | 2 ++ hw/ppc/spapr.c | 2 ++ include/hw/char/serial.h | 3 +++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 513d73c..ef31df3 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -103,6 +103,9 @@ do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } while (0) do {} while (0) #endif +/* Force migration compatibility of pre-2.2 machine types */ +bool serial_migrate_pre_2_2; + static void serial_receive1(void *opaque, const uint8_t *buf, int size); static inline void recv_fifo_put(SerialState *s, uint8_t chr) @@ -646,6 +649,10 @@ static bool serial_thr_ipending_needed(void *opaque) { SerialState *s = opaque; +if (serial_migrate_pre_2_2) { +return false; +} + if (s->ier & UART_IER_THRI) { bool expected_value = ((s->iir & UART_IIR_ID) == UART_IIR_THRI); return s->thr_ipending != expected_value; @@ -672,7 +679,7 @@ static const VMStateDescription vmstate_serial_thr_ipending = { static bool serial_tsr_needed(void *opaque) { SerialState *s = (SerialState *)opaque; -return s->tsr_retry != 0; +return !serial_migrate_pre_2_2 && s->tsr_retry != 0; } static const VMStateDescription vmstate_serial_tsr = { @@ -691,7 +698,7 @@ static const VMStateDescription vmstate_serial_tsr = { static bool serial_recv_fifo_needed(void *opaque) { SerialState *s = (SerialState *)opaque; -return !fifo8_is_empty(&s->recv_fifo); +return !serial_migrate_pre_2_2 && !fifo8_is_empty(&s->recv_fifo); } @@ -709,7 +716,7 @@ static const VMStateDescription vmstate_serial_recv_fifo = { static bool serial_xmit_fifo_needed(void *opaque) { SerialState *s = (SerialState *)opaque; -return !fifo8_is_empty(&s->xmit_fifo); +return !serial_migrate_pre_2_2 && !fifo8_is_empty(&s->xmit_fifo); } static const VMStateDescription vmstate_serial_xmit_fifo = { @@ -726,7 +733,7 @@ static const VMStateDescription vmstate_serial_xmit_fifo = { static bool serial_fifo_timeout_timer_needed(void *opaque) { SerialState *s = (SerialState *)opaque; -return timer_pending(s->fifo_timeout_timer); +return !serial_migrate_pre_2_2 && timer_pending(s->fifo_timeout_timer); } static const VMStateDescription vmstate_serial_fifo_timeout_timer = { @@ -743,7 +750,7 @@ static const VMStateDescription vmstate_serial_fifo_timeout_timer = { static bool serial_timeout_ipending_needed(void *opaque) { SerialState *s = (SerialState *)opaque; -return s->timeout_ipending != 0; +return !serial_migrate_pre_2_2 && s->timeout_ipending != 0; } static const VMStateDescription vmstate_serial_timeout_ipending = { @@ -760,7 +767,7 @@ static const VMStateDescription vmstate_serial_timeout_ipending = { static bool serial_poll_needed(void *opaque) { SerialState *s = (SerialState *)opaque; -return s->poll_msl >= 0; +return !serial_migrate_pre_2_2 && s->poll_msl >= 0; } static const VMStateDescription vmstate_serial_poll = { diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e142f75..d6d596c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,6 +39,7 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" +#include "hw/char/serial.h" #include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" @@ -344,6 +345,7 @@ static void pc_compat_2_1(MachineState *machine) x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0); x86_cpu_compat_kvm_no_autodisable(FEAT_8000_0001_ECX, CPUID_EXT3_SVM); pcms->enforce_aligned_dimm = false; +serial_migrate_pre_2_2 = true; } static void pc_compat_2_0(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index b68263d..a211f21 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -32,6 +32,7 @@ #include "sysemu/arch_init.h" #include "hw/i2c/smbus.h" #include "hw/boards.h" +#include "hw/char/serial.h" #include "hw/timer/mc146818rtc.h" #include "hw/xen/xen.h" #include "sysemu/kvm.h" @@ -328,6 +329,7 @@ static void pc_compat_2_1(MachineState *machine) x86_cpu_compat_set_features("coreduo", FEAT_1_ECX, CPUID_EXT_VMX, 0); x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0); x86_cpu_compat_kvm_no_autodisable(FEAT_8000_0001_ECX, CPUID_EXT3_SVM); +serial_migrate_pre_2_2 = true; } static void pc_compat_2_0(MachineState *machine) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 01f8da8..f2673da 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -39,6 +39,7 @@ #include "qom/cpu.h" #include "hw/boards.h" +#include "hw/char/serial.h" #inc
[Qemu-devel] [PATCH v5 4/4] hw/pci-bridge: format SeaBIOS-compliant OFW device node for PXB
SeaBIOS expects OpenFirmware device paths in the "bootorder" fw_cfg file to follow the pattern /pci-root@N/pci@i0cf8/... for devices that live behind an extra root bus. The extra root bus in question is the N'th among the extra root bridges. (In other words, N gives the position of the affected extra root bus relative to the other extra root buses, in bus_nr order.) N starts at 1, and is formatted in hex. The "pci@i0cf8" node text is hardcoded in SeaBIOS (see the macro FW_PCI_DOMAIN). Cc: Kevin O'Connor Cc: Marcel Apfelbaum Cc: Michael S. Tsirkin Signed-off-by: Laszlo Ersek Tested-by: Marcel Apfelbaum Reviewed-by: Marcel Apfelbaum --- Notes: v5: - constify parameter and local variables of pxb_host_ofw_unit_address(), in accord with the previous patch v4: - new in v4 hw/pci-bridge/pci_expander_bridge.c | 39 - 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index c7a085d..ee249b7 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -42,6 +42,8 @@ typedef struct PXBDev { uint16_t numa_node; } PXBDev; +static GList *pxb_dev_list; + #define TYPE_PXB_HOST "pxb-host" static int pxb_bus_num(PCIBus *bus) @@ -88,12 +90,29 @@ static const char *pxb_host_root_bus_path(PCIHostState *host_bridge, return bus->bus_path; } +static char *pxb_host_ofw_unit_address(const SysBusDevice *dev) +{ +const PCIHostState *host = PCI_HOST_BRIDGE(dev); +const PCIBus *bus; +const PXBDev *pxb; +int position; + +bus = host->bus; +pxb = PXB_DEV(bus->parent_dev); +position = g_list_index(pxb_dev_list, pxb); +assert(position >= 0); + +return g_strdup_printf("%x/pci@i0cf8", position + 1); +} + static void pxb_host_class_init(ObjectClass *class, void *data) { DeviceClass *dc = DEVICE_CLASS(class); +SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(class); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class); -dc->fw_name = "pci"; +dc->fw_name = "pci-root"; +sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address; hc->root_bus_path = pxb_host_root_bus_path; } @@ -148,6 +167,15 @@ static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin) return pin - PCI_SLOT(pxb->devfn); } +static gint pxb_compare(gconstpointer a, gconstpointer b) +{ +const PXBDev *pxb_a = a, *pxb_b = b; + +return pxb_a->bus_nr < pxb_b->bus_nr ? -1 : + pxb_a->bus_nr > pxb_b->bus_nr ? 1 : + 0; +} + static int pxb_dev_initfn(PCIDevice *dev) { PXBDev *pxb = PXB_DEV(dev); @@ -190,9 +218,17 @@ static int pxb_dev_initfn(PCIDevice *dev) PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST); +pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare); return 0; } +static void pxb_dev_exitfn(PCIDevice *pci_dev) +{ +PXBDev *pxb = PXB_DEV(pci_dev); + +pxb_dev_list = g_list_remove(pxb_dev_list, pxb); +} + static Property pxb_dev_properties[] = { /* Note: 0 is not a legal a PXB bus number. */ DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0), @@ -206,6 +242,7 @@ static void pxb_dev_class_init(ObjectClass *klass, void *data) PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); k->init = pxb_dev_initfn; +k->exit = pxb_dev_exitfn; k->vendor_id = PCI_VENDOR_ID_REDHAT; k->device_id = PCI_DEVICE_ID_REDHAT_PXB; k->class_id = PCI_CLASS_BRIDGE_HOST; -- 1.8.3.1
[Qemu-devel] [PATCH v5 2/4] hw/core: rebase sysbus_get_fw_dev_path() to g_strdup_printf()
This is done mainly for improving readability, and in preparation for the next patch, but Markus pointed out another bonus for the string being returned: "No arbitrary length limit. Before the patch, it's 39 characters, and the code breaks catastrophically when qdev_fw_name() is longer: the second snprintf() is called with its first argument pointing beyond path[], and its second argument underflowing to a huge size." Cc: Markus Armbruster Cc: Marcel Apfelbaum Cc: Michael S. Tsirkin Signed-off-by: Laszlo Ersek Tested-by: Marcel Apfelbaum Reviewed-by: Marcel Apfelbaum Reviewed-by: Markus Armbruster --- Notes: v5: - separate "%s@" from TARGET_FMT_plx with a space [Markus] - copied Markus's note about "no arbitrary length limit" on the retval into the commit message v4: - unchanged v3: - new in v3 hw/core/sysbus.c | 16 ++-- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index b53c351..92eced9 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -281,19 +281,15 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) static char *sysbus_get_fw_dev_path(DeviceState *dev) { SysBusDevice *s = SYS_BUS_DEVICE(dev); -char path[40]; -int off; - -off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev)); if (s->num_mmio) { -snprintf(path + off, sizeof(path) - off, "@"TARGET_FMT_plx, - s->mmio[0].addr); -} else if (s->num_pio) { -snprintf(path + off, sizeof(path) - off, "@i%04x", s->pio[0]); +return g_strdup_printf("%s@" TARGET_FMT_plx, qdev_fw_name(dev), + s->mmio[0].addr); } - -return g_strdup(path); +if (s->num_pio) { +return g_strdup_printf("%s@i%04x", qdev_fw_name(dev), s->pio[0]); +} +return g_strdup(qdev_fw_name(dev)); } void sysbus_add_io(SysBusDevice *dev, hwaddr addr, -- 1.8.3.1
[Qemu-devel] [PATCH v5 3/4] hw/core: explicit OFW unit address callback for SysBusDeviceClass
The sysbus_get_fw_dev_path() function formats OpenFirmware device path nodes ("driver-name@unit-address") for sysbus devices. The first choice for "unit-address" is the base address of the device's first MMIO region. The second choice is its first IO port. However, if two sysbus devices with the same "driver-name" lack both MMIO and PIO resources, then there is no good way to distinguish them based on their OFW nodes, because in this case unit-address is omitted completely for both devices. An example is TYPE_PXB_HOST ("pxb-host"). For the sake of such devices, introduce the explicit_ofw_unit_address() "virtual member function". With this function, each sysbus device in the same SysBusDeviceClass can state its own address. Cc: Markus Armbruster Cc: Marcel Apfelbaum Cc: Michael S. Tsirkin Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Tested-by: Marcel Apfelbaum Reviewed-by: Markus Armbruster --- Notes: v5: - mention "pxb-host" as an example device in the commit message [Markus] - reword documentation on explicit_ofw_unit_address(), specifying headline, preconditions / goal, side effects, retval, errors separately. [Markus] - constify parameter of explicit_ofw_unit_address(), after focusing on side effects [Markus] - move declaration of "addr" and "fw_dev_path" to the top level block in sysbus_get_fw_dev_path() [Markus] - no functional changes, add / keep Markus's R-b v4: - Yet another approach. Instead of allowing the creator of the device to set a string property statically, introduce a class level callback. v3: - new in v3 - new approach include/hw/sysbus.h | 17 + hw/core/sysbus.c| 11 +++ 2 files changed, 28 insertions(+) diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index d1f3f00..34f93c3 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -41,6 +41,23 @@ typedef struct SysBusDeviceClass { /*< public >*/ int (*init)(SysBusDevice *dev); + +/* + * Let the sysbus device format its own non-PIO, non-MMIO unit address. + * + * Sometimes a class of SysBusDevices has neither MMIO nor PIO resources, + * yet instances of it would like to distinguish themselves, in + * OpenFirmware device paths, from other instances of the same class on the + * sysbus. For that end we expose this callback. + * + * The implementation is not supposed to change *@dev, or incur other + * observable change. + * + * The function returns a dynamically allocated string. On error, NULL + * should be returned; the unit address portion of the OFW node will be + * omitted then. (This is not considered a fatal error.) + */ +char *(*explicit_ofw_unit_address)(const SysBusDevice *dev); } SysBusDeviceClass; struct SysBusDevice { diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 92eced9..278a2d1 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -281,6 +281,9 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) static char *sysbus_get_fw_dev_path(DeviceState *dev) { SysBusDevice *s = SYS_BUS_DEVICE(dev); +SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(s); +/* for the explicit unit address fallback case: */ +char *addr, *fw_dev_path; if (s->num_mmio) { return g_strdup_printf("%s@" TARGET_FMT_plx, qdev_fw_name(dev), @@ -289,6 +292,14 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) if (s->num_pio) { return g_strdup_printf("%s@i%04x", qdev_fw_name(dev), s->pio[0]); } +if (sbc->explicit_ofw_unit_address) { +addr = sbc->explicit_ofw_unit_address(s); +if (addr) { +fw_dev_path = g_strdup_printf("%s@%s", qdev_fw_name(dev), addr); +g_free(addr); +return fw_dev_path; +} +} return g_strdup(qdev_fw_name(dev)); } -- 1.8.3.1
[Qemu-devel] [PATCH v5 0/4] PXB changes
No functional changes whatsoever; addressing commit message, code comment, and coding style remarks from Markus. Those updates are listed individually per patch. I added / preserved all Tested-by and Reviewed-by tags I got for v4. Cc: Marcel Apfelbaum Cc: Michael S. Tsirkin Cc: Markus Armbruster Cc: Kevin O'Connor Thanks Laszlo Laszlo Ersek (4): hw/pci-bridge: create interrupt-less, hotplug-less bridge for PXB hw/core: rebase sysbus_get_fw_dev_path() to g_strdup_printf() hw/core: explicit OFW unit address callback for SysBusDeviceClass hw/pci-bridge: format SeaBIOS-compliant OFW device node for PXB hw/pci-bridge/Makefile.objs | 1 + include/hw/pci/pci.h | 1 + include/hw/sysbus.h | 17 + hw/core/sysbus.c | 27 +--- hw/pci-bridge/pci_basic_bridge_dev.c | 124 +++ hw/pci-bridge/pci_expander_bridge.c | 41 +++- 6 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 hw/pci-bridge/pci_basic_bridge_dev.c -- 1.8.3.1
[Qemu-devel] [PATCH v5 1/4] hw/pci-bridge: create interrupt-less, hotplug-less bridge for PXB
OVMF downloads the ACPI linker/loader script from QEMU when the edk2 PCI Bus driver globally signals the firmware that PCI enumeration and resource allocation have completed. At this point QEMU regenerates the ACPI payload in an fw_cfg read callback, and this is when the PXB's _CRS gets populated. Unfortunately, when this happens, the PCI_COMMAND_MEMORY bit is clear in the root bus's command register, *unlike* under SeaBIOS. The consequences unfold as follows: - When build_crs() fetches dev->io_regions[i].addr, it is all-bits-one, because pci_update_mappings() --> pci_bar_address() calculated it as PCI_BAR_UNMAPPED, due to the PCI_COMMAND_MEMORY bit being clear. - Consequently, the SHPC MMIO BAR (bar 0) of the bridge is not added to the _CRS, *despite* having been programmed in PCI config space. - Similarly, the SHPC MMIO BAR of the PXB is not removed from the main root bus's DWordMemory descriptor. - Guest OSes (Linux and Windows alike) notice the pre-programmed SHPC BAR within the PXB's config space, and notice that it conflicts with the main root bus's memory resource descriptors. Linux reports pci :04:00.0: BAR 0: can't assign mem (size 0x100) pci :04:00.0: BAR 0: trying firmware assignment [mem 0x8820-0x882000ff 64bit] pci :04:00.0: BAR 0: [mem 0x8820-0x882000ff 64bit] conflicts with PCI Bus :00 [mem 0x8820-0xfebf] While Windows Server 2012 R2 reports https://technet.microsoft.com/en-us/library/cc732199%28v=ws.10%29.aspx This device cannot find enough free resources that it can use. If you want to use this device, you will need to disable one of the other devices on this system. (Code 12) This issue was apparently encountered earlier, see the "hack" in: https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg02983.html and the current hole-punching logic in build_crs() and build_ssdt() is probably supposed to remedy exactly that problem -- however, for OVMF they don't work, because at the end of the PCI enumeration and resource allocation, which cues the ACPI linker/loader client, the command register is clear. It has been suggested to implement the above "hack" more cleanly and permanently. Unfortunately, we can't just disable the SHPC bar of TYPE_PCI_BRIDGE_DEV based on a new property (or flag), because said device model has a fixed (non-conditional) SHPC_VMSTATE() field, which would crash outgoing migration without a preceding shpc_init() call. (And the new property (or flag) would eliminate the shpc_init() call.) Changing SHPC_VMSTATE() into an optional subsection, in order to prevent the crash, would in turn break incoming migration from older hosts. Therefore implement a separate, more basic bridge device type, to be used by PXB, that has no SHPC / hotplug support at all, and consequently (see commit c008ac0c), no need for an interrupt / MSI either. The new device model is a stripped-down copy of "pci-bridge"; it is very small and simple, and shouldn't cause a significant maintenance burden. Suggested-by: Marcel Apfelbaum Cc: Marcel Apfelbaum Cc: Michael S. Tsirkin Cc: Markus Armbruster Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Tested-by: Marcel Apfelbaum --- Notes: v5: - Describe in both the commit message and a code comment how "pci-basic-bridge" relates to "pci-bridge" [Markus]. No functional changes. v4: - unchanged - unlike in v2 and v3, in v4 I'm formatting this as any other patch, without "--find-copies-harder" etc. That formatting was visible (for the exact same patch) in v3 and v4, so let's format the patch now in its "genuine glory" :) It shows that the patch is quite small. v3: - unchanged, added Marcel's R-b v2: - Replaced the corresponding v1 patch with a new approach. Instead of considering the PXB's disabled SHPC BAR in the PXB's _CRS (and correspondingly, punching it out of the main _CRS), this patch creates a separate device model that lacks the SHPC functionality completely. I already know from IRC that Michael doesn't like this, but that's okay: I'm formatting this with "-C35% --find-copies-harder", so that the differences are obvious against the clone origin, and Michael can pinpoint the locations where and how I should use a new device property instead, in the original device model. (That said, I did test this code, with both Windows and Linux, and compared the dumped / decompiled SSDTs too.) hw/pci-bridge/Makefile.objs | 1 + include/hw/pci/pci.h | 1 + hw/pci-bridge/pci_basic_bridge_dev.c | 124 +++ hw/pci-bridge/pci_expander_bridge.c | 2 +- 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 hw/pci-bridge/pci_basic_bridge_dev.c diff --git a/hw/
Re: [Qemu-devel] [RFC] generic-gpio-led & stm32-gpio-led
On Tue, Jun 16, 2015 at 10:16 AM, Liviu Ionescu wrote: > >> On 16 Jun 2015, at 19:10, Peter Crosthwaite >> wrote: >> >>> +bool use_stderr; >> >> Why do you want to switch between stderr and stdout? > > I wasn't sure which one is more appropriate, I first used stdout then tried > stderr. > >> I think stderr is more correct, > > yes, that was my conclusion too. I'll make it default. > >> or should at least be forced in >> nographic QEMU where stdout may be owned by a terminal mux. Otherwise >> you should probably talk to the monitor. > > most of my use cases are running with semihosting active, and the application > may printf() whatever it likes, so it is not realistic to expect no traffic > on stdout. > > but I got your point. > >>> +} GenericGPIOLEDClass; >> >> Drop the "Generic" > > from the typedef or from the string type name? what about the file name? > All. Generic is implicit from the fact there is no specifics. >>> +switch (level) { >>> +case 0: >>> +fprintf(file, "%s", >>> +info->active_low ? info->on_message : info->off_message); >>> +break; >>> + >>> +case 1: >>> +fprintf(file, "%s", >>> +info->active_low ? info->off_message : info->on_message); >>> +break; >> >> Can you do an ^ or != between level and active low to remove dup? > > yes, but code readability decreases. > >>> +static void generic_gpio_led_construct_callback(Object *obj, >>> +GenericGPIOLEDInfo* info, DeviceState *mcu) >>> +{ >>> +qemu_log_function_name(); >> >> Function call after QOM casts. > > could you be more explicit? > Just the C99 thing. >> >>> + >>> +GenericGPIOLEDState *state = GENERIC_GPIO_LED_STATE(obj); >>> +GenericGPIOLEDClass *klass = GENERIC_GPIO_LED_GET_CLASS(state); >>> + >> >> As we don't strictly forbid C99 decls but try and avoid them. > > come on, we're in 2015, 16 years were not enough to get used to C99? ;-) > Don't shoot the messenger :) It is not a hard rule, but you need a solid reason to break it (#ifdeffery being the only one I can think of). >>> +/* >>> + * Connect the LED interrupt to the originating GPIO pin. >>> + * This will finally create a link inside the STM32 GPIO device. >>> + */ >>> +qdev_connect_gpio_out(gpio_dev, info->port_bit, state->irq); >> >> I think this is where the big QOM issue is. You are creating your own >> GPIO connection mechanism on the abstract device level. Why can't you >> do the GPIO connections on the machine level? Instead, this would be a >> call to qdev_init_gpio_in() and you can remove all the refs to >> gpio_dev. > > I'll try to see how the code looks like. > > the main idea was to automate all these connection details. > > but if it is just a single additional line, I can live with it. > >>> +static Property generic_gpio_led_properties[] = { >>> +DEFINE_PROP_GENERIC_GPIO_LED_PTR("info", GenericGPIOLEDState, >>> info), >>> +DEFINE_PROP_DEVICE_STATE_PTR("mcu", GenericGPIOLEDState, mcu), >> >> With my proposal to remove connectivity info from the struct, the >> struct simple enough to just list out the remaining props one-by-one >> rather than having to QOMify a struct for parameters. > > right, just that it requires some extra typing... > Wont a machine level table parse make this a one-liner. >>> +.class_size = sizeof(GenericGPIOLEDClass) }; >> >> newline before } > > unfortunately this is way too complicated to fix. I'm not doing any > formatting manually, I use the Eclipse auto formatter, which generally is ok, > but when asked to do the antiquated R&K formatting, it uses this peculiar > closing brace syntax. (except for QEMU, in my all other sources I use the GNU > formatting style, which is ok in Eclipse). > > so manually fixing this is useless, since I auto-format after entering every > few lines and the manual formatting would be lost. > Your autoformatter does a surprisingly good job of getting close to qemu coding style. Can the rules just be tweaked any maybe QEMU coding style can be added to eclipse? To check your coding style, commit your work to git and: git show | ./scripts/checkpatch.pl - >> >> In my proposal the machine model would do this. >> >> qdev_connect_gpio_out_named(mcu, "name", index, qdev_get_gpio_in(gpio_dev, >> 0)); >> >> Or something like that. > > aha! I saw some examples where such names were used, but had no idea where > the names came from. > > what names do you suggest to use for GPIOs? I guess some nice aliases, since > the internal names are not for humans. could you give me a hint how these > aliases should be defined and used? > They are not really aliases, they are the GPIO names proper. qdev_[init|get|connect]_gpio_[in|out]_named are direct replacements for the non named variants. The non-human internal names should go away if you use them. The name of the GPIO should match something in the TRM for the device. E.g. if the SoC define "bank A" gpios, then a suitab
Re: [Qemu-devel] [PATCH 00/15] target-s390x: add Program-Event Recording feature
On 13.06.15 00:45, Aurelien Jarno wrote: > This patch set adds support for the Program-Event Recording (PER) > feature. It implements all the PER functionalities except the > following ones: > - zero-address-detection event (part of the zero-address-detection > facility) > - transaction-end event (we don't implement transactional memory) > > There are also a few limitations to the storage-alteration event, as it > doesn't support per ASC enablement, nor it doesn't correctly provide the > ASC used for a storage event in the PER AI field. > > With this patch set, it's possible to fully use GDB in a s390x guest, > including stepping, breakpoints and watchpoints. Thanks, applied all to s390-next. Alex
Re: [Qemu-devel] [PATCH 15/15] target-s390x: PER: add Breaking-Event-Address register
On 16.06.15 19:44, Aurelien Jarno wrote: > On 2015-06-16 18:44, Alexander Graf wrote: >> On 06/13/15 00:46, Aurelien Jarno wrote: >>> This patch adds support for PER Breaking-Event-Address register. Like >>> real hardware, it save the current PSW address when the PSW address is >>> changed by an instruction. We have to take care of optimizations QEMU >>> does, a branch to the next instruction is still a branch. >>> >>> This register is copied to low core memory when a program exception >>> happens. >>> >>> Cc: Richard Henderson >>> Cc: Alexander Graf >>> Signed-off-by: Aurelien Jarno >>> --- >>> target-s390x/cpu.c | 6 ++ >>> target-s390x/cpu.h | 12 +++- >>> target-s390x/helper.c| 1 + >>> target-s390x/translate.c | 29 +++-- >>> 4 files changed, 37 insertions(+), 11 deletions(-) >>> >>> diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c >>> index 67579e7..98d2081 100644 >>> --- a/target-s390x/cpu.c >>> +++ b/target-s390x/cpu.c >>> @@ -116,6 +116,9 @@ static void s390_cpu_initial_reset(CPUState *s) >>> env->cregs[0] = CR0_RESET; >>> env->cregs[14] = CR14_RESET; >>> +/* architectured initial value for Breaking-Event-Address register */ >>> +env->gbea = 1; >>> + >>> env->pfault_token = -1UL; >>> /* tininess for underflow is detected before rounding */ >>> @@ -145,6 +148,9 @@ static void s390_cpu_full_reset(CPUState *s) >>> env->cregs[0] = CR0_RESET; >>> env->cregs[14] = CR14_RESET; >>> +/* architectured initial value for Breaking-Event-Address register */ >>> +env->gbea = 1; >>> + >>> env->pfault_token = -1UL; >>> /* tininess for underflow is detected before rounding */ >>> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h >>> index 61cc5b4..519cef9 100644 >>> --- a/target-s390x/cpu.h >>> +++ b/target-s390x/cpu.h >>> @@ -788,14 +788,16 @@ typedef struct LowCore >>> uint8_t pad5[0xf4-0xf0]; /* 0x0f0 */ >>> uint32_texternal_damage_code; /* 0x0f4 */ >>> uint64_tfailing_storage_address; /* 0x0f8 */ >>> -uint8_t pad6[0x120-0x100];/* 0x100 */ >>> +uint8_t pad6[0x110-0x100];/* 0x100 */ >>> +uint64_tper_breaking_event_addr; /* 0x110 */ >>> +uint8_t pad7[0x120-0x118];/* 0x118 */ >>> PSW restart_old_psw; /* 0x120 */ >>> PSW external_old_psw; /* 0x130 */ >>> PSW svc_old_psw; /* 0x140 */ >>> PSW program_old_psw; /* 0x150 */ >>> PSW mcck_old_psw; /* 0x160 */ >>> PSW io_old_psw; /* 0x170 */ >>> -uint8_t pad7[0x1a0-0x180];/* 0x180 */ >>> +uint8_t pad8[0x1a0-0x180];/* 0x180 */ >>> PSW restart_new_psw; /* 0x1a0 */ >>> PSW external_new_psw; /* 0x1b0 */ >>> PSW svc_new_psw; /* 0x1c0 */ >>> @@ -813,10 +815,10 @@ typedef struct LowCore >>> uint64_tlast_update_clock;/* 0x280 */ >>> uint64_tsteal_clock; /* 0x288 */ >>> PSW return_mcck_psw; /* 0x290 */ >>> -uint8_t pad8[0xc00-0x2a0];/* 0x2a0 */ >>> +uint8_t pad9[0xc00-0x2a0];/* 0x2a0 */ >>> /* System info area */ >>> uint64_tsave_area[16];/* 0xc00 */ >>> -uint8_t pad9[0xd40-0xc80];/* 0xc80 */ >>> +uint8_t pad10[0xd40-0xc80]; /* 0xc80 */ >>> uint64_tkernel_stack; /* 0xd40 */ >>> uint64_tthread_info; /* 0xd48 */ >>> uint64_tasync_stack; /* 0xd50 */ >>> @@ -824,7 +826,7 @@ typedef struct LowCore >>> uint64_tuser_asce;/* 0xd60 */ >>> uint64_tpanic_stack; /* 0xd68 */ >>> uint64_tuser_exec_asce; /* 0xd70 */ >>> -uint8_t pad10[0xdc0-0xd78]; /* 0xd78 */ >>> +uint8_t pad11[0xdc0-0xd78]; /* 0xd78 */ >>> /* SMP info area: defined by DJB */ >>> uint64_tclock_comparator; /* 0xdc0 */ >>> diff --git a/target-s390x/helper.c b/target-s390x/helper.c >>> index 615cccf..d887006 100644 >>> --- a/target-s390x/helper.c >>> +++ b/target-s390x/helper.c >>> @@ -293,6 +293,7 @@ static void do_program_interrupt(CPUS390XState *env) >>> lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr); >>> mask = be64_to_cpu(lowcore->program_new_psw.mask); >>> addr = be64_to_cpu(lowcore->program_new_psw.addr); >>> +lowcore->per_breaking_event_addr = cpu_to_be64(env->gbea); >>> cpu_unmap_lowcore(lowcore); >>> diff --git a/target-s390x/translate.c b/target-s390x/translate.c >>> index 98e8224..2fde815 100644 >>> --- a/target-s390x/translate.c >>> +++ b/target-s390x/translate.c >>>
Re: [Qemu-devel] [PATCH] dma/rc4030: do multiple calls to address_space_rw when doing DMA transfers
On 2015-06-15 22:44, Hervé Poussineau wrote: > Hi Aurelien, > > Le 12/06/2015 01:30, Aurelien Jarno a écrit : > >On 2015-06-11 22:30, Hervé Poussineau wrote: > >>This workarounds a bug in memory management. > >> > >>To reproduce the problem, try to start the Windows NT 4.0/MIPS installer. > >>After loading some files, you should see a screen saying > >>"To set up Windows NT now, press ENTER." > >>However, you're welcomed with an IRQL_NOT_LESS_OR_EQUAL bugcheck or an > >>Unknown Hard Error c221. > >> > >>Signed-off-by: Hervé Poussineau > >>--- > >> hw/dma/rc4030.c | 15 +++ > >> 1 file changed, 15 insertions(+) > >> > >>diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c > >>index 3efa6de..d265d6c 100644 > >>--- a/hw/dma/rc4030.c > >>+++ b/hw/dma/rc4030.c > >>@@ -681,6 +681,7 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t > >>*buf, int len, int is_wri > >> rc4030State *s = opaque; > >> hwaddr dma_addr; > >> int dev_to_mem; > >>+int i; > >> > >> s->dma_regs[n][DMA_REG_ENABLE] &= ~(DMA_FLAG_TC_INTR | > >> DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR); > >> > >>@@ -699,8 +700,22 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t > >>*buf, int len, int is_wri > >> dma_addr = s->dma_regs[n][DMA_REG_ADDRESS]; > >> > >> /* Read/write data at right place */ > >>+#if 1 /* workaround for a bug in memory management */ > >>+for (i = 0; i < len; ) { > >>+int ncpy = DMA_PAGESIZE - (dma_addr & (DMA_PAGESIZE - 1)); > >>+if (ncpy > len - i) { > >>+ncpy = len - i; > >>+} > >>+address_space_rw(&s->dma_as, dma_addr, MEMTXATTRS_UNSPECIFIED, > >>+ buf + i, ncpy, is_write); > >>+ > >>+dma_addr += ncpy; > >>+i += ncpy; > >>+} > >>+#else > >> address_space_rw(&s->dma_as, dma_addr, MEMTXATTRS_UNSPECIFIED, > >> buf, len, is_write); > >>+#endif > > > >Hmm, basically your code splits the transfers so that they don't cross > >DMA page boundaries. It seems that your DMA memory region is actually > >made of small subregions of size DMA_PAGESIZE aliased to the RAM. > > Yes, that's the case. I have lots of DMA_PAGESIZE memory region aliases in > the DMA memory region. > > >Now looking at the address_space_rw function, it seems it optimizes the > >write to RAM case by calling address_space_translate() and then doing a > >memcpy() of the whole region. It doesn't work given the memory region is > >not linear. > > > >That said address_space_translate is supposed to adjust the length if > >needed, but does so only if iommu_ops is defined. > > Then, the problem lies here. > If you can use address_space_rw only on an address range which is linear in > underlying memory region, or if underlying memory region is a iommu, then > you have a big problem. As you can't query if that's the case, your only bet > is to use address_space_rw with only 1 byte quantities... > Adding Paolo, as he may have an idea. > The code assumes that if you don't have an IOMMU, the address range in the underlying memory region is linear. One fix would be to adjust the length even without IOMMU. That would have some performance impact though, so maybe we want to make this assumption clear and always use an IOMMU in that case. > > I therefore wonder if > >you therefore shouldn't model this DMA translation tables by using IOMMU > >ops instead of subregions. > > > No, in my opinion, that's an implementation detail. Paolo said that it was OK: > "Both are okay. The IOMMU makes address space changes faster; your > scheme is basically a form of caching, it trades update performance for > improved translation performance." > http://lists.gnu.org/archive/html/qemu-devel/2015-03/msg05486.html It seems wrong with the current code. And if we fix the bug by adjusting the length, the above sentence about the performances might becomes wrong Aurelien. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH 15/15] target-s390x: PER: add Breaking-Event-Address register
On 2015-06-16 18:44, Alexander Graf wrote: > On 06/13/15 00:46, Aurelien Jarno wrote: > >This patch adds support for PER Breaking-Event-Address register. Like > >real hardware, it save the current PSW address when the PSW address is > >changed by an instruction. We have to take care of optimizations QEMU > >does, a branch to the next instruction is still a branch. > > > >This register is copied to low core memory when a program exception > >happens. > > > >Cc: Richard Henderson > >Cc: Alexander Graf > >Signed-off-by: Aurelien Jarno > >--- > > target-s390x/cpu.c | 6 ++ > > target-s390x/cpu.h | 12 +++- > > target-s390x/helper.c| 1 + > > target-s390x/translate.c | 29 +++-- > > 4 files changed, 37 insertions(+), 11 deletions(-) > > > >diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c > >index 67579e7..98d2081 100644 > >--- a/target-s390x/cpu.c > >+++ b/target-s390x/cpu.c > >@@ -116,6 +116,9 @@ static void s390_cpu_initial_reset(CPUState *s) > > env->cregs[0] = CR0_RESET; > > env->cregs[14] = CR14_RESET; > >+/* architectured initial value for Breaking-Event-Address register */ > >+env->gbea = 1; > >+ > > env->pfault_token = -1UL; > > /* tininess for underflow is detected before rounding */ > >@@ -145,6 +148,9 @@ static void s390_cpu_full_reset(CPUState *s) > > env->cregs[0] = CR0_RESET; > > env->cregs[14] = CR14_RESET; > >+/* architectured initial value for Breaking-Event-Address register */ > >+env->gbea = 1; > >+ > > env->pfault_token = -1UL; > > /* tininess for underflow is detected before rounding */ > >diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h > >index 61cc5b4..519cef9 100644 > >--- a/target-s390x/cpu.h > >+++ b/target-s390x/cpu.h > >@@ -788,14 +788,16 @@ typedef struct LowCore > > uint8_t pad5[0xf4-0xf0]; /* 0x0f0 */ > > uint32_texternal_damage_code; /* 0x0f4 */ > > uint64_tfailing_storage_address; /* 0x0f8 */ > >-uint8_t pad6[0x120-0x100];/* 0x100 */ > >+uint8_t pad6[0x110-0x100];/* 0x100 */ > >+uint64_tper_breaking_event_addr; /* 0x110 */ > >+uint8_t pad7[0x120-0x118];/* 0x118 */ > > PSW restart_old_psw; /* 0x120 */ > > PSW external_old_psw; /* 0x130 */ > > PSW svc_old_psw; /* 0x140 */ > > PSW program_old_psw; /* 0x150 */ > > PSW mcck_old_psw; /* 0x160 */ > > PSW io_old_psw; /* 0x170 */ > >-uint8_t pad7[0x1a0-0x180];/* 0x180 */ > >+uint8_t pad8[0x1a0-0x180];/* 0x180 */ > > PSW restart_new_psw; /* 0x1a0 */ > > PSW external_new_psw; /* 0x1b0 */ > > PSW svc_new_psw; /* 0x1c0 */ > >@@ -813,10 +815,10 @@ typedef struct LowCore > > uint64_tlast_update_clock;/* 0x280 */ > > uint64_tsteal_clock; /* 0x288 */ > > PSW return_mcck_psw; /* 0x290 */ > >-uint8_t pad8[0xc00-0x2a0];/* 0x2a0 */ > >+uint8_t pad9[0xc00-0x2a0];/* 0x2a0 */ > > /* System info area */ > > uint64_tsave_area[16];/* 0xc00 */ > >-uint8_t pad9[0xd40-0xc80];/* 0xc80 */ > >+uint8_t pad10[0xd40-0xc80]; /* 0xc80 */ > > uint64_tkernel_stack; /* 0xd40 */ > > uint64_tthread_info; /* 0xd48 */ > > uint64_tasync_stack; /* 0xd50 */ > >@@ -824,7 +826,7 @@ typedef struct LowCore > > uint64_tuser_asce;/* 0xd60 */ > > uint64_tpanic_stack; /* 0xd68 */ > > uint64_tuser_exec_asce; /* 0xd70 */ > >-uint8_t pad10[0xdc0-0xd78]; /* 0xd78 */ > >+uint8_t pad11[0xdc0-0xd78]; /* 0xd78 */ > > /* SMP info area: defined by DJB */ > > uint64_tclock_comparator; /* 0xdc0 */ > >diff --git a/target-s390x/helper.c b/target-s390x/helper.c > >index 615cccf..d887006 100644 > >--- a/target-s390x/helper.c > >+++ b/target-s390x/helper.c > >@@ -293,6 +293,7 @@ static void do_program_interrupt(CPUS390XState *env) > > lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr); > > mask = be64_to_cpu(lowcore->program_new_psw.mask); > > addr = be64_to_cpu(lowcore->program_new_psw.addr); > >+lowcore->per_breaking_event_addr = cpu_to_be64(env->gbea); > > cpu_unmap_lowcore(lowcore); > >diff --git a/target-s390x/translate.c b/target-s390x/translate.c > >index 98e8224..2fde815 100644 > >--- a/target-s390x/translate.c > >+++ b/target-s390x/translate.c > >@@ -150,6 +150,7 @@ void s390_cpu_dump_state(CPUState *cs, FILE *f, > >fprintf_function cpu_fprin
Re: [Qemu-devel] [PATCH 0/2] target-i386: "custom" CPU model + script to dump existing CPU models
Ping? Any feedback? I want to get this into 2.4. On Mon, Jun 08, 2015 at 04:07:38PM -0300, Eduardo Habkost wrote: > The problem: > > The existing libvirt APIs assume that if a given CPU model is runnable in a > host kernel+hardware combination, it will be always runnable on that host even > if the machine-type changes. > > That assumption is implied in some of libvirt interfaces, for example, at: > > 1) Host capabilities, which let callers know the set of CPU models >that can run in a host: >https://libvirt.org/formatcaps.html#elementHost > >"virsh capabilities" returns a CPU model name + CPU feature list, assuming >that a CPU model name has a meaning that's independent from the >machine-type. > > 2) The function that checks if a given CPU model definition >is compatible with a host (virConnectCompareCPU()), >which does not take the machine-type as argument: >http://libvirt.org/html/libvirt-libvirt-host.html#virConnectCompareCPU > > But that assumption is not true, as QEMU changes CPU models in new > machine-types when fixing bugs, or when new features (previously unsupported > by > QEMU, TCG or KVM) get implemented. > > The solution: > > libvirt can solve this problem partially by making sure every feature in a CPU > model is explicitly configured, instead of (incorrectly) expecting that a > named > CPU model will never change in QEMU. But this doesn't solve the problem > completely, because it is still possible that new features unknown to libvirt > get enabled in the default CPU model in future machine-types (that's very > likely to happen when we introduce new KVM features, for example). > > So, to make sure no new feature will be ever enabled without the knowledge of > libvirt, add a "-cpu custom" mode, where no CPU model data is loaded at all, > and everything needs to be configured explicitly using CPU properties. That > means no CPU features will ever change depending on machine-type or > accelerator > capabilities when using "-cpu custom". > > * * * > > I know that this is basically the opposite of what we were aiming at in the > last few month^Wyears, where we were struggling to implement probing > interfaces > to expose machine-type-dependent data for libvirt. But, at least the fact that > we could implement the new approach using a 9-line patch means we were still > going in the right direction. :) > > To help libvirt in the transition, a x86-cpu-model-dump script is provided, > that will generate a config file that can be loaded using -readconfig, based > on > the -cpu and -machine options provided in the command-line. > > * * * > > This is basically the same version I sent as an RFC in April. A git tree is > available at: > > git://github.com/ehabkost/qemu-hacks.git work/x86-cpu-custom-model > > Eduardo Habkost (2): > target-i386: Introduce "-cpu custom" > scripts: x86-cpu-model-dump script > > scripts/x86-cpu-model-dump | 322 > + > target-i386/cpu.c | 10 +- > 2 files changed, 331 insertions(+), 1 deletion(-) > create mode 100755 scripts/x86-cpu-model-dump > > -- > 2.1.0 > > -- Eduardo
Re: [Qemu-devel] [RFC] generic-gpio-led & stm32-gpio-led
> On 16 Jun 2015, at 19:10, Peter Crosthwaite > wrote: > >> +bool use_stderr; > > Why do you want to switch between stderr and stdout? I wasn't sure which one is more appropriate, I first used stdout then tried stderr. > I think stderr is more correct, yes, that was my conclusion too. I'll make it default. > or should at least be forced in > nographic QEMU where stdout may be owned by a terminal mux. Otherwise > you should probably talk to the monitor. most of my use cases are running with semihosting active, and the application may printf() whatever it likes, so it is not realistic to expect no traffic on stdout. but I got your point. >> +} GenericGPIOLEDClass; > > Drop the "Generic" from the typedef or from the string type name? what about the file name? >> +switch (level) { >> +case 0: >> +fprintf(file, "%s", >> +info->active_low ? info->on_message : info->off_message); >> +break; >> + >> +case 1: >> +fprintf(file, "%s", >> +info->active_low ? info->off_message : info->on_message); >> +break; > > Can you do an ^ or != between level and active low to remove dup? yes, but code readability decreases. >> +static void generic_gpio_led_construct_callback(Object *obj, >> +GenericGPIOLEDInfo* info, DeviceState *mcu) >> +{ >> +qemu_log_function_name(); > > Function call after QOM casts. could you be more explicit? > >> + >> +GenericGPIOLEDState *state = GENERIC_GPIO_LED_STATE(obj); >> +GenericGPIOLEDClass *klass = GENERIC_GPIO_LED_GET_CLASS(state); >> + > > As we don't strictly forbid C99 decls but try and avoid them. come on, we're in 2015, 16 years were not enough to get used to C99? ;-) >> +/* >> + * Connect the LED interrupt to the originating GPIO pin. >> + * This will finally create a link inside the STM32 GPIO device. >> + */ >> +qdev_connect_gpio_out(gpio_dev, info->port_bit, state->irq); > > I think this is where the big QOM issue is. You are creating your own > GPIO connection mechanism on the abstract device level. Why can't you > do the GPIO connections on the machine level? Instead, this would be a > call to qdev_init_gpio_in() and you can remove all the refs to > gpio_dev. I'll try to see how the code looks like. the main idea was to automate all these connection details. but if it is just a single additional line, I can live with it. >> +static Property generic_gpio_led_properties[] = { >> +DEFINE_PROP_GENERIC_GPIO_LED_PTR("info", GenericGPIOLEDState, info), >> +DEFINE_PROP_DEVICE_STATE_PTR("mcu", GenericGPIOLEDState, mcu), > > With my proposal to remove connectivity info from the struct, the > struct simple enough to just list out the remaining props one-by-one > rather than having to QOMify a struct for parameters. right, just that it requires some extra typing... >> +.class_size = sizeof(GenericGPIOLEDClass) }; > > newline before } unfortunately this is way too complicated to fix. I'm not doing any formatting manually, I use the Eclipse auto formatter, which generally is ok, but when asked to do the antiquated R&K formatting, it uses this peculiar closing brace syntax. (except for QEMU, in my all other sources I use the GNU formatting style, which is ok in Eclipse). so manually fixing this is useless, since I auto-format after entering every few lines and the manual formatting would be lost. > > In my proposal the machine model would do this. > > qdev_connect_gpio_out_named(mcu, "name", index, qdev_get_gpio_in(gpio_dev, > 0)); > > Or something like that. aha! I saw some examples where such names were used, but had no idea where the names came from. what names do you suggest to use for GPIOs? I guess some nice aliases, since the internal names are not for humans. could you give me a hint how these aliases should be defined and used? > As you are trying to create a large number of machines, SoC and GPIO > messages you may want to do some tabulation of these connections and > rip through it in a loop. The same table may contain the on/off > messages and drive the creation of the GPIOs (and you may need to > parse the table multiple times if there are construction pass > inter-deps). I'm using tables and loop type creation when defining MCUs (for example about a dozen STM32 MCUs are created like this), but for machines things are not as uniform, and are anyway grouped by board vendor, so not all boards are in a file. >> +static void stm_gpio_led_construct_callback(Object *obj, >> +GenericGPIOLEDInfo* info, DeviceState *mcu) >> +{ >> +qemu_log_function_name(); >> + > > What would you want to put here? >> +/* Explicitly call the parent constructor. */ >> +GENERIC_GPIO_LED_GET_CLASS(obj)->construct(obj, info, mcu); in this case nothing, because the derived class just implements a base abstract. but the constructor was kept to call the parent constructor, like usual. thank you,
Re: [Qemu-devel] [PATCH 15/15] target-s390x: PER: add Breaking-Event-Address register
On 06/13/15 00:46, Aurelien Jarno wrote: This patch adds support for PER Breaking-Event-Address register. Like real hardware, it save the current PSW address when the PSW address is changed by an instruction. We have to take care of optimizations QEMU does, a branch to the next instruction is still a branch. This register is copied to low core memory when a program exception happens. Cc: Richard Henderson Cc: Alexander Graf Signed-off-by: Aurelien Jarno --- target-s390x/cpu.c | 6 ++ target-s390x/cpu.h | 12 +++- target-s390x/helper.c| 1 + target-s390x/translate.c | 29 +++-- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 67579e7..98d2081 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -116,6 +116,9 @@ static void s390_cpu_initial_reset(CPUState *s) env->cregs[0] = CR0_RESET; env->cregs[14] = CR14_RESET; +/* architectured initial value for Breaking-Event-Address register */ +env->gbea = 1; + env->pfault_token = -1UL; /* tininess for underflow is detected before rounding */ @@ -145,6 +148,9 @@ static void s390_cpu_full_reset(CPUState *s) env->cregs[0] = CR0_RESET; env->cregs[14] = CR14_RESET; +/* architectured initial value for Breaking-Event-Address register */ +env->gbea = 1; + env->pfault_token = -1UL; /* tininess for underflow is detected before rounding */ diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 61cc5b4..519cef9 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -788,14 +788,16 @@ typedef struct LowCore uint8_t pad5[0xf4-0xf0]; /* 0x0f0 */ uint32_texternal_damage_code; /* 0x0f4 */ uint64_tfailing_storage_address; /* 0x0f8 */ -uint8_t pad6[0x120-0x100];/* 0x100 */ +uint8_t pad6[0x110-0x100];/* 0x100 */ +uint64_tper_breaking_event_addr; /* 0x110 */ +uint8_t pad7[0x120-0x118];/* 0x118 */ PSW restart_old_psw; /* 0x120 */ PSW external_old_psw; /* 0x130 */ PSW svc_old_psw; /* 0x140 */ PSW program_old_psw; /* 0x150 */ PSW mcck_old_psw; /* 0x160 */ PSW io_old_psw; /* 0x170 */ -uint8_t pad7[0x1a0-0x180];/* 0x180 */ +uint8_t pad8[0x1a0-0x180];/* 0x180 */ PSW restart_new_psw; /* 0x1a0 */ PSW external_new_psw; /* 0x1b0 */ PSW svc_new_psw; /* 0x1c0 */ @@ -813,10 +815,10 @@ typedef struct LowCore uint64_tlast_update_clock;/* 0x280 */ uint64_tsteal_clock; /* 0x288 */ PSW return_mcck_psw; /* 0x290 */ -uint8_t pad8[0xc00-0x2a0];/* 0x2a0 */ +uint8_t pad9[0xc00-0x2a0];/* 0x2a0 */ /* System info area */ uint64_tsave_area[16];/* 0xc00 */ -uint8_t pad9[0xd40-0xc80];/* 0xc80 */ +uint8_t pad10[0xd40-0xc80]; /* 0xc80 */ uint64_tkernel_stack; /* 0xd40 */ uint64_tthread_info; /* 0xd48 */ uint64_tasync_stack; /* 0xd50 */ @@ -824,7 +826,7 @@ typedef struct LowCore uint64_tuser_asce;/* 0xd60 */ uint64_tpanic_stack; /* 0xd68 */ uint64_tuser_exec_asce; /* 0xd70 */ -uint8_t pad10[0xdc0-0xd78]; /* 0xd78 */ +uint8_t pad11[0xdc0-0xd78]; /* 0xd78 */ /* SMP info area: defined by DJB */ uint64_tclock_comparator; /* 0xdc0 */ diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 615cccf..d887006 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -293,6 +293,7 @@ static void do_program_interrupt(CPUS390XState *env) lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr); mask = be64_to_cpu(lowcore->program_new_psw.mask); addr = be64_to_cpu(lowcore->program_new_psw.addr); +lowcore->per_breaking_event_addr = cpu_to_be64(env->gbea); cpu_unmap_lowcore(lowcore); diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 98e8224..2fde815 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -150,6 +150,7 @@ void s390_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, static TCGv_i64 psw_addr; static TCGv_i64 psw_mask; +static TCGv_i64 gbea; static TCGv_i32 cc_op; static TCGv_i64 cc_src; @@ -173,6 +174,9 @@ void s390x_translate_init(void) psw_mask = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, p
Re: [Qemu-devel] [PATCH 0/4] qga: disk and volume info for Windows guest
On 16/06/15 17:37, Eric Blake wrote: On 06/16/2015 06:57 AM, Denis V. Lunev wrote: PING, 1 week till soft freeze. Michael, can you pls consider these patches? We have really small amount of time left. Regards, Den _PING_ I think Michael is on vacation until the end of this week. Stefan thank you for the update. This is really a problem for this set and for guest exec code to be merged into 2.4 OK, I'll get some patience if nobody other can help. Windows is not a favorite platform in this list :) If I understand soft freeze correctly, it's okay if your patches have been posted but not yet applied; a maintainer can still pick them up. It's not until hard freeze that we no longer take new features into the tree. I still hope to help review the interface side of pending qga patches before I go on vacation next week, but I'm not enough of an expert on Windows coding to review much beyond that. I think that it will have more sense if you will start from second patchset with guest exec, which really touch interfaces and your review will be very useful. Den
Re: [Qemu-devel] [PATCH v2 1/2] spapr_iommu: drop erroneous check in h_put_tce_indirect()
On Tue, 16 Jun 2015 18:26:47 +0200 Greg Kurz wrote: > The tce_list variable is not a TCE but the address to a TCE: we shouldn't > clear permission bits as we do now. And this is dead code anyway since we > check tce_list is 4K aligned a few lines above. > > This patch doesn't fix any bug, it is only code cleanup. > > Suggested-by: Alexey Kardashevskiy > Signed-off-by: Greg Kurz > --- > hw/ppc/spapr_iommu.c |4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > Of course, I did forget the changelog... v2: - suggested by aik - keep sPAPRTCEAccess, a translation helper is introduced in the next patch > diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c > index 8cd9dba9ac4d..ddd0ea5cd4dd 100644 > --- a/hw/ppc/spapr_iommu.c > +++ b/hw/ppc/spapr_iommu.c > @@ -267,9 +267,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu, > ioba &= page_mask; > > for (i = 0; i < npages; ++i, ioba += page_size) { > -target_ulong off = (tce_list & ~SPAPR_TCE_RW) + > -i * sizeof(target_ulong); > -tce = ldq_be_phys(cs->as, off); > +tce = ldq_be_phys(cs->as, tce_list + i * sizeof(target_ulong)); > > ret = put_tce_emu(tcet, ioba, tce); > if (ret) { > >