[Qemu-devel] [PATCH] net: Flush queued packets when guest resumes
Since commit 6e99c63 net/socket: Drop net_socket_can_send and friends, net queues need to be explicitly flushed after qemu_can_send_packet() returns false, because the netdev side will disable the polling of fd. This fixes the case of cont after stop (or migration), i.e. vm_running changes to true, by listening to vm state changes. Signed-off-by: Fam Zheng f...@redhat.com --- include/net/net.h | 2 ++ net/net.c | 14 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/net/net.h b/include/net/net.h index 6a6cbef..619a6e1 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -8,6 +8,7 @@ #include net/queue.h #include migration/vmstate.h #include qapi-types.h +#include sysemu/sysemu.h #define MAX_QUEUE_NUM 1024 @@ -92,6 +93,7 @@ struct NetClientState { NetClientDestructor *destructor; unsigned int queue_index; unsigned rxfilter_notify_enabled:1; +VMChangeStateEntry *vmcse; }; typedef struct NICState { diff --git a/net/net.c b/net/net.c index 6ff7fec..edfa6a0 100644 --- a/net/net.c +++ b/net/net.c @@ -43,7 +43,6 @@ #include qapi-visit.h #include qapi/opts-visitor.h #include qapi/dealloc-visitor.h -#include sysemu/sysemu.h /* Net bridge is currently not supported for W32. */ #if !defined(_WIN32) @@ -263,6 +262,16 @@ static void qemu_net_client_destructor(NetClientState *nc) g_free(nc); } +static void qemu_net_client_handle_vmstate(void *opaque, + int running, + RunState state) +{ +NetClientState *nc = opaque; +if (running qemu_can_send_packet(nc) nc-peer) { +qemu_flush_queued_packets(nc-peer); +} +} + static void qemu_net_client_setup(NetClientState *nc, NetClientInfo *info, NetClientState *peer, @@ -287,6 +296,8 @@ static void qemu_net_client_setup(NetClientState *nc, nc-incoming_queue = qemu_new_net_queue(nc); nc-destructor = destructor; +nc-vmcse = qemu_add_vm_change_state_handler(qemu_net_client_handle_vmstate, + nc); } NetClientState *qemu_new_net_client(NetClientInfo *info, @@ -395,6 +406,7 @@ void qemu_del_net_client(NetClientState *nc) MAX_QUEUE_NUM); assert(queues != 0); +qemu_del_vm_change_state_handler(nc-vmcse); /* If there is a peer NIC, delete and cleanup client, but do not free. */ if (nc-peer nc-peer-info-type == NET_CLIENT_OPTIONS_KIND_NIC) { NICState *nic = qemu_get_nic(nc-peer); -- 2.4.3
Re: [Qemu-devel] [Bug 1469946] Re: guest can't get IP when create guest with bridge.
On Wed, 07/01 06:36, chao zhou wrote: after try the patch http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg07377.html with qemu.git commit(d2966f804d70a244f5dde395fc5d22a50ed3e74e) the guest can get IP, but after save/retore or live migration, the guest is alive, but ping or ssh guest's IP fail . Another fix is needed to handle stop/resume. I'm sending it now with you in the Cc list. Please test! Thanks, Fam -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1469946 Title: guest can't get IP when create guest with bridge. Status in QEMU: New Bug description: Environment: Host OS (ia32/ia32e/IA64):ia32e Guest OS (ia32/ia32e/IA64):ia32e Guest OS Type (Linux/Windows):linux kvm.git Commit:aefbef10e3ae6e2c6e3c54f906f10b34c73a2c66 qemu.git Commit:dc1e1350f8061021df765b396295329797d66933 Host Kernel Version:4.1.0 Hardware:Ivytown_EP, Haswell_EP Bug detailed description: -- when create guest with bridge, the guest can not get ip. note: 1. fail rate: 3/5 2. this is a qemu bug: kvm + qemu = result aefbef10 + dc1e1350= bad aefbef10 + a4ef02fd = good Reproduce steps: 1. create guest: qemu-system-x86_64 -enable-kvm -m 2G -smp 4 -device virtio-net-pci,netdev=net0,mac=$random_mac -netdev tap,id=net0,script=/etc/kvm/qemu-ifup rhel6u5.qcow Current result: guest can't get IP Expected result: guest can get ip Basic root-causing log: -- To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1469946/+subscriptions
Re: [Qemu-devel] [PATCH v2 0/2] avoid a hotplug operation leading migration's source side abort
Li Zhijian lizhij...@cn.fujitsu.com wrote: qemu migration's source side will exit unexpectedly when we hotplug a deivce during a migration is processing. we can reproduced it easily by following step 1. do something with dirty memory requently(like memtester) in guest 2. startup a background migration with '-d' option 3. hotplug a device(device_add e1000,id=mye1000) 4. stop step.1, let guest idle so that migration can complete fastly Applied, thanks. something unexpectedly occurs like below: *** Error in `/home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64': free(): invalid pointer: 0x7fff5c010b20 *** === Backtrace: = /lib64/libc.so.6(+0x7d1fd)[0x75ad41fd] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x1e29c2)[0x557369c2] /lib64/libglib-2.0.so.0(g_free+0xf)[0x76aaa5af] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x139454)[0x5568d454] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x13a232)[0x5568e232] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x13a2f1)[0x5568e2f1] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0xec914)[0x55640914] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0xc7e7e)[0x5561be7e] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0xc7f0f)[0x5561bf0f] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0xf01c9)[0x556441c9] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x3541d4)[0x558a81d4] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x3a5cf6)[0x558f9cf6] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x3b5809)[0x55909809] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x3a6067)[0x558fa067] /lib64/libglib-2.0.so.0(g_main_context_dispatch+0x15a)[0x76aa49ba] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x3b3c6f)[0x55907c6f] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x3b3d4c)[0x55907d4c] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x3b3e0b)[0x55907e0b] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x1df701)[0x55733701] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x1e6fed)[0x5573afed] /lib64/libc.so.6(__libc_start_main+0xf5)[0x75a78af5] /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64(+0x93729)[0x555e7729] === Memory map: 4000-55b04000 r-xp 08:04 14111744 /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64 55d03000-55dcc000 r--p 005af000 08:04 14111744 /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64 55dcc000-55e42000 rw-p 00678000 08:04 14111744 /home/lizj/workspace/qemu/x86_64-softmmu/qemu-system-x86_64 55e42000-5affc000 rw-p 00:00 0 [heap] snip... Changes from v1 do bitmap_set after bitmap_copy Li Zhijian (2): migration: protect migration_bitmap migration: extend migration_bitmap exec.c | 5 + include/exec/exec-all.h | 1 + migration/ram.c | 40 ++-- 3 files changed, 40 insertions(+), 6 deletions(-)
Re: [Qemu-devel] [PATCH v2 04/12] rdma typos
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com A couple of typo fixes. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reviewed-by: Juan Quintela quint...@redhat.com
Re: [Qemu-devel] [PATCH v2 05/12] Store block name in local blocks structure
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com In a later patch the block name will be used to match up two views of the block list. Keep a copy of the block name with the local block list. (At some point it could be argued that it would be best just to let migration see the innards of RAMBlock and avoid the need to use foreach). Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reviewed-by: Michael R. Hines mrhi...@us.ibm.com Reviewed-by: Juan Quintela quint...@redhat.com
Re: [Qemu-devel] [PATCH 07/10] block/backup: support block job transactions
On Tue, Jun 30, 2015 at 11:52:54AM -0400, John Snow wrote: On 06/30/2015 11:27 AM, Stefan Hajnoczi wrote: On Mon, Jun 29, 2015 at 06:39:08PM -0400, John Snow wrote: On 06/25/2015 08:12 AM, Stefan Hajnoczi wrote: @@ -537,6 +539,9 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target, job-sync_mode = sync_mode; job-sync_bitmap = sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP ? sync_bitmap : NULL; +if (job-sync_bitmap) { +block_job_txn_add_job(txn, job-common); +} Hmm, is this what we want? This will add backup jobs to a transaction only if they have a bitmap attached to the job. However, if we're doing a mixture of full and incremental backups, we may still want to roll back the incremental backups if the full backups failed as part of the transaction. The (admittedly more complicated) design I submitted will always add a job to the transactional group, whether it has a bitmap or not. The membership test was only if it was launched by the backup transaction action. The bitmap is only checked for purposes of refcounting and cleanup mechanics. Maybe that wasn't what we wanted either, but this is a difference in how our series will behave. The 'backup' operation was added to the QMP 'transaction' command in QEMU 1.6. If we add non-incremental backup commands to the transaction then behavior changes. Ugh, good point... Perhaps DriveBackup and BlockdevBackup QAPI structures should take an optional 'transaction' bool argument. That way the caller decides which behavior to use. The way my version operated only changed the cleanup behavior -- it didn't attempt to cancel other jobs if they failed or not. It naively let them finish, then performed cleanup based on the overall completion status. That let the old behavior continue working like it did, but changed how incrementals worked upon completion. (1) Perhaps we can change the forced cancellation aspect and just allow jobs to finish naturally even in the event of failure. It's wasteful, but it does allow us to maintain the existing behavior while getting the behavior we want for incremental transactions. (2) Or, yes, add some sort of all or nothing flag to transactions(?*) that users can toggle on/off. I had wondered in the past if it wouldn't be advantageous for libvirt to be able to choose this behavior, if managing state of partial completions was desirable in some cases to avoid re-running operations unnecessarily. *As a thought, perhaps cancel-all-on-error as a flag can be a property of the QMP transaction command itself. When set, actions that launch jobs can add the job to the TXN. An error can be raised if the flag is used in conjunction with an action that doesn't currently/won't ever support the do-or-die flag. Good, this is easy to add. pgpaYnFbw1UsQ.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v2 07/12] Rework ram_control_load_hook to hook during block load
Dr. David Alan Gilbert dgilb...@redhat.com wrote: * Michael R. Hines (mrhi...@linux.vnet.ibm.com) wrote: qemu_rdma_registration_handle_unregister_success(uint64_t chunk) % PRIu64 -qemu_rdma_registration_handle_wait(uint64_t flags) Waiting for next request % PRIu64 +qemu_rdma_registration_handle_wait(void) Are you using some kind of script to generate these trace prototypes? What happened to the message? =) The prototypes I added manually. You normally have the trace name in your tool so you don't need the text that gives you the same piece of information. So I get output like: 25988@1434041422.299944:qemu_rdma_registration_handle_ram_blocks without having to write anything in the text. (That's with the stderr trace backend, and the prefix being PID and time) Notice also that he removed the flags argument on the caller function, so nothing to print there, really. Dave qemu_rdma_registration_start(uint64_t flags) % PRIu64 qemu_rdma_registration_stop(uint64_t flags) % PRIu64 qemu_rdma_registration_stop_ram(void) -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
[Qemu-devel] [PATCH 03/12] 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 quint...@redhat.com --- include/migration/migration.h | 1 + migration/migration.c | 105 +++--- trace-events | 3 ++ vl.c | 1 + 4 files changed, 103 insertions(+), 7 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 c6ac08a..b4b6d69 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -26,6 +26,7 @@ #include qemu/thread.h #include qmp-commands.h #include trace.h +#include qapi/util.h #define MAX_THROTTLE (32 20) /* Migration speed throttling */ @@ -97,6 +98,83 @@ void migration_incoming_state_destroy(void) mis_current = NULL; } + +typedef struct { +uint32_t size; +uint8_t runstate[100]; +} GlobalState; + +static GlobalState global_state; + +static int global_state_store(void) +{ +if (!runstate_store((char *)global_state.runstate, +sizeof(global_state.runstate))) { +trace_migrate_state_too_big(); +return -EINVAL; +} +return 0; +} + +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; + +trace_migrate_global_state_post_load(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 -EINVAL; +} +ret = vm_stop_force_state(r); +} + + return ret; +} + +static void global_state_pre_save(void *opaque) +{ +GlobalState *s = opaque; + +trace_migrate_global_state_pre_save((char *)s-runstate); +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_UINT32(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 @@ -164,10 +242,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(); } @@ -793,10 +881,13 @@ static void *migration_thread(void *opaque) qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); old_vm_running = runstate_is_running(); -ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); -if (ret =
[Qemu-devel] [PATCH 04/12] 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 quint...@redhat.com --- 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 082cd93..26104ca 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 b4b6d69..0fd5962 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -100,6 +100,7 @@ void migration_incoming_state_destroy(void) typedef struct { +bool optional; uint32_t size; uint8_t runstate[100]; } GlobalState; @@ -121,6 +122,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; @@ -152,7 +180,6 @@ static void global_state_pre_save(void *opaque) trace_migrate_global_state_pre_save((char *)s-runstate); s-size = strlen((char *)s-runstate) + 1; -printf(saved state: %s\n, s-runstate); } static const VMStateDescription vmstate_globalstate = { @@ -161,6 +188,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_UINT32(size, GlobalState), VMSTATE_BUFFER(runstate, GlobalState), -- 2.4.3
[Qemu-devel] [PATCH v2 00/12] Migration events + optional sections
Hi At the end, Daved asked for a couple of things on previous series. [v2] - Ensure that we start in NONE even after failed/canceled migration - move printf's to traces - make sure that we can migrate the new states like guest-panicked (not sure if it is a good idea to enable migrate a guest-panicked, but it is not this series the place to forbid it) - address all comments from Dave and Eric. Please, review. [v1] 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 (12): 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: ensure we start in NONE state 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 | 157 ++ migration/savevm.c| 69 +++ migration/vmstate.c | 11 +++ qapi/event.json | 12 trace-events | 4 ++ vl.c | 21 +- 12 files changed, 283 insertions(+), 16 deletions(-) -- 2.4.3
[Qemu-devel] [PATCH 11/12] migration: create migration event
We have one argument that tells us what event has happened. Signed-off-by: Juan Quintela quint...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com --- docs/qmp/qmp-events.txt | 14 ++ migration/migration.c | 2 ++ qapi/event.json | 12 3 files changed, 28 insertions(+) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 4c13d48..d92cc48 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-schema.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 ef1e4a4..fee2186 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -27,6 +27,7 @@ #include qmp-commands.h #include trace.h #include qapi/util.h +#include qapi-event.h #define MAX_THROTTLE (32 20) /* Migration speed throttling */ @@ -509,6 +510,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..f0cef01 100644 --- a/qapi/event.json +++ b/qapi/event.json @@ -243,6 +243,18 @@ { 'event': 'SPICE_MIGRATE_COMPLETED' } ## +# @MIGRATION +# +# Emitted when a migration event happens +# +# @status: @MigrationStatus describing the current migration status. +# +# Since: 2.4 +## +{ 'event': 'MIGRATION', + 'data': {'status': 'MigrationStatus'}} + +## # @ACPI_DEVICE_OST # # Emitted when guest executes ACPI _OST method. -- 2.4.3
[Qemu-devel] [PATCH 08/12] migration: ensure we start in NONE state
Signed-off-by: Juan Quintela quint...@redhat.com --- migration/migration.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/migration/migration.c b/migration/migration.c index cfcc227..c5b778b 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -693,7 +693,6 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, error_setg(errp, QERR_MIGRATION_ACTIVE); return; } - if (runstate_check(RUN_STATE_INMIGRATE)) { error_setg(errp, Guest is waiting for an incoming migration); return; @@ -708,6 +707,12 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, return; } +/* We are starting a new migration, so we want to start in a clean + state. This change is only needed if previous migration + failed/was cancelled. We don't use migrate_set_state() because + we are setting the initial state, not changing it. */ +s-state = MIGRATION_STATUS_NONE; + s = migrate_init(params); if (strstart(uri, tcp:, p)) { -- 2.4.3
[Qemu-devel] [PATCH 12/12] 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 quint...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- migration/migration.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/migration/migration.c b/migration/migration.c index fee2186..8fe4e73 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -221,6 +221,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)) { @@ -249,7 +250,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); @@ -257,10 +258,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
Re: [Qemu-devel] [PATCH] net: Flush queued packets when guest resumes
On Wed, 07/01 16:23, Fam Zheng wrote: Since commit 6e99c63 net/socket: Drop net_socket_can_send and friends, net queues need to be explicitly flushed after qemu_can_send_packet() returns false, because the netdev side will disable the polling of fd. This fixes the case of cont after stop (or migration), i.e. vm_running changes to true, by listening to vm state changes. Signed-off-by: Fam Zheng f...@redhat.com Note that to fix virtio-net, this patch is also needed: http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg07377.html Fam
Re: [Qemu-devel] [PATCH v4 2/5] cpu-exec: introduce loop exit with restore function
On 06/29/2015 08:23 AM, Pavel Dovgalyuk wrote: This patch introduces loop exit function, which also restores guest CPU state according to the value of host program counter. Signed-off-by: Pavel Dovgalyukpavel.dovga...@ispras.ru --- cpu-exec.c |9 + include/exec/exec-all.h |1 + 2 files changed, 10 insertions(+), 0 deletions(-) Reviewed-by: Richard Henderson r...@twiddle.net r~
Re: [Qemu-devel] [PATCH v2 1/1] KVM s390 pci infrastructure modelling
On 7/1/2015 16:05, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 03:56:25PM +0800, Hong Bo Li wrote: On 7/1/2015 14:22, Michael S. Tsirkin wrote: On Tue, Jun 30, 2015 at 02:16:59PM +0800, Hong Bo Li wrote: On 6/29/2015 18:01, Michael S. Tsirkin wrote: On Mon, Jun 29, 2015 at 05:24:53PM +0800, Hong Bo Li wrote: This patch introduce a new facility(and bus) to hold devices representing information actually provided by s390 firmware and I/O configuration. usage example: -device s390-pcihost -device vfio-pci,host=:00:00.0,id=vpci1 -device zpci,fid=2,uid=5,pci_id=vpci1,id=zpci1 The first line will create a s390 pci host bridge and init the root bus. The second line will create a standard vfio pci device, and attach it to the root bus. These are similiar to the standard process to define a pci device on other platform. The third line will create a s390 pci device to store s390 specific information, and references the corresponding vfio pci device via device id. We create a s390 pci facility bus to hold all the zpci devices. Signed-off-by: Hong Bo Li lih...@linux.vnet.ibm.com It's mostly up to s390 maintainers, but I'd like to note one thing below --- hw/s390x/s390-pci-bus.c| 314 + hw/s390x/s390-pci-bus.h| 48 ++- hw/s390x/s390-pci-inst.c | 4 +- hw/s390x/s390-virtio-ccw.c | 5 +- 4 files changed, 283 insertions(+), 88 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 560b66a..d5e7b2e 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -32,8 +32,8 @@ int chsc_sei_nt2_get_event(void *res) PciCcdfErr *eccdf; int rc = 1; SeiContainer *sei_cont; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return rc; @@ -72,8 +72,8 @@ int chsc_sei_nt2_get_event(void *res) int chsc_sei_nt2_have_event(void) { -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return 0; @@ -82,20 +82,32 @@ int chsc_sei_nt2_have_event(void) return !QTAILQ_EMPTY(s-pending_sei); } +void s390_pci_device_enable(S390PCIBusDevice *zpci) +{ +zpci-fh = zpci-fh | 1 ENABLE_BIT_OFFSET; +} + +void s390_pci_device_disable(S390PCIBusDevice *zpci) +{ +zpci-fh = zpci-fh ~(1 ENABLE_BIT_OFFSET); +if (zpci-is_unplugged) +object_unparent(OBJECT(zpci)); +} + S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid) { S390PCIBusDevice *pbdev; -int i; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +BusChild *kid; +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return NULL; } -for (i = 0; i PCI_SLOT_MAX; i++) { -pbdev = s-pbdev[i]; -if ((pbdev-fh != 0) (pbdev-fid == fid)) { +QTAILQ_FOREACH(kid, s-fbus-qbus.children, sibling) { +pbdev = (S390PCIBusDevice *)kid-child; +if (pbdev-fid == fid) { return pbdev; } } @@ -126,39 +138,24 @@ void s390_pci_sclp_configure(int configure, SCCB *sccb) return; } -static uint32_t s390_pci_get_pfid(PCIDevice *pdev) -{ -return PCI_SLOT(pdev-devfn); -} - -static uint32_t s390_pci_get_pfh(PCIDevice *pdev) -{ -return PCI_SLOT(pdev-devfn) | FH_VIRT; -} - S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx) { S390PCIBusDevice *pbdev; -int i; -int j = 0; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +BusChild *kid; +int i = 0; +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return NULL; } -for (i = 0; i PCI_SLOT_MAX; i++) { -pbdev = s-pbdev[i]; - -if (pbdev-fh == 0) { -continue; -} - -if (j == idx) { +QTAILQ_FOREACH(kid, s-fbus-qbus.children, sibling) { +pbdev = (S390PCIBusDevice *)kid-child; +if (i == idx) { return pbdev; } -j++; +i++; } return NULL; This relies on the order of children on the qbus, that's wrong I think. Generally I'm not sure why do you convert all slot lookups to child lookups: more code to achieve the same effect? Thank you Michael. I do the change due to two reasons: 1. The old implement only supports one s390 pci root bus, and 32(PCI_SLOT_MAX) slots at most. So when it comes to multiple s390 pci root buses, the old code does not work. 2. Now the zpci device S390PCIBusDevice is only a structure to store s390
Re: [Qemu-devel] [PATCH 03/12] migration: create new section to store global state
* 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 quint...@redhat.com --- include/migration/migration.h | 1 + migration/migration.c | 105 +++--- trace-events | 3 ++ vl.c | 1 + 4 files changed, 103 insertions(+), 7 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 c6ac08a..b4b6d69 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -26,6 +26,7 @@ #include qemu/thread.h #include qmp-commands.h #include trace.h +#include qapi/util.h #define MAX_THROTTLE (32 20) /* Migration speed throttling */ @@ -97,6 +98,83 @@ void migration_incoming_state_destroy(void) mis_current = NULL; } + +typedef struct { +uint32_t size; +uint8_t runstate[100]; +} GlobalState; + +static GlobalState global_state; + +static int global_state_store(void) +{ +if (!runstate_store((char *)global_state.runstate, +sizeof(global_state.runstate))) { +trace_migrate_state_too_big(); Hmm ok, but that should have stayed as the error_report - the only problem with that in the previous version was a \n (error_report for errors, trace_ for debug) +return -EINVAL; +} +return 0; +} + +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; + +trace_migrate_global_state_post_load(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 -EINVAL; +} +ret = vm_stop_force_state(r); +} + + return ret; +} + +static void global_state_pre_save(void *opaque) +{ +GlobalState *s = opaque; + +trace_migrate_global_state_pre_save((char *)s-runstate); +s-size = strlen((char *)s-runstate) + 1; +printf(saved state: %s\n, s-runstate); Stray printf Other than that, Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com +} + +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_UINT32(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 @@ -164,10 +242,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
Re: [Qemu-devel] [PATCH 04/12] global_state: Make section optional
* 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. Signed-off-by: Juan Quintela quint...@redhat.com Note you should probably also fix Power (see my 'Fix for section footers for power') Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- 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 082cd93..26104ca 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 b4b6d69..0fd5962 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -100,6 +100,7 @@ void migration_incoming_state_destroy(void) typedef struct { +bool optional; uint32_t size; uint8_t runstate[100]; } GlobalState; @@ -121,6 +122,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; @@ -152,7 +180,6 @@ static void global_state_pre_save(void *opaque) trace_migrate_global_state_pre_save((char *)s-runstate); s-size = strlen((char *)s-runstate) + 1; -printf(saved state: %s\n, s-runstate); } static const VMStateDescription vmstate_globalstate = { @@ -161,6 +188,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_UINT32(size, GlobalState), VMSTATE_BUFFER(runstate, GlobalState), -- 2.4.3 -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
[Qemu-devel] [PATCH 1/1] s390x/migration: Introduce 2.4 machine
The section footer changes commit f68945d42bab (Add a protective section footer) and commit 37fb569c0198 (Disable section footers on older machine types) broke migration for any non-versioned machines. While one can argue that section footer should be enabled explicitely for new versions instead of disabled for old ones, this pinpoints to a problem of s390-ccw-machines: it needs to be versioned to be compatible with future changes in common code data structures such as section footers. Let's introduce a version scheme for s390-ccw-virtio machines. We will use the old s390-ccw-virtio name as alias to the latest version as all existing libvirt XML for the ccw type were expanded by libvirt to that name. The only downside of this patch is, that the old alias s390-ccw will no longer be available as machines can have only one alias, but it should not really matter. Cc: Dr. David Alan Gilbert dgilb...@redhat.com Cc: Juan Quintela quint...@redhat.com Cc: Boris Fiuczynski fiu...@linux.vnet.ibm.com Cc: Jason J. Herne jjhe...@linux.vnet.ibm.com Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com --- hw/s390x/s390-virtio-ccw.c | 22 ++ 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 47f323b..90bb159 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -159,9 +159,6 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); NMIClass *nc = NMI_CLASS(oc); -mc-name = s390-ccw-virtio; -mc-alias = s390-ccw; -mc-desc = VirtIO-ccw based S390 machine; mc-init = ccw_init; mc-block_default_type = IF_VIRTIO; mc-no_cdrom = 1; @@ -171,7 +168,6 @@ 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; mc-hot_add_cpu = ccw_hot_add_cpu; nc-nmi_monitor_handler = s390_nmi; } @@ -228,6 +224,7 @@ static inline void s390_machine_initfn(Object *obj) static const TypeInfo ccw_machine_info = { .name = TYPE_S390_CCW_MACHINE, .parent= TYPE_MACHINE, +.abstract = true, .instance_size = sizeof(S390CcwMachineState), .instance_init = s390_machine_initfn, .class_init= ccw_machine_class_init, @@ -237,9 +234,26 @@ static const TypeInfo ccw_machine_info = { }, }; +static void ccw_machine_2_4_class_init(ObjectClass *oc, void *data) +{ +MachineClass *mc = MACHINE_CLASS(oc); + +mc-name = s390-ccw-virtio-2.4; +mc-alias = s390-ccw-virtio; +mc-desc = VirtIO-ccw based S390 machine v2.4; +mc-is_default = 1; +} + +static const TypeInfo ccw_machine_2_4_info = { +.name = TYPE_S390_CCW_MACHINE 2.4, +.parent= TYPE_S390_CCW_MACHINE, +.class_init= ccw_machine_2_4_class_init, +}; + static void ccw_machine_register_types(void) { type_register_static(ccw_machine_info); +type_register_static(ccw_machine_2_4_info); } type_init(ccw_machine_register_types) -- 2.3.0
Re: [Qemu-devel] [Qemu-block] [PATCH COLO-Block v6 07/16] Add new block driver interface to connect/disconnect the remote target
On 07/01/2015 04:11 PM, Dr. David Alan Gilbert wrote: * Wen Congyang (we...@cn.fujitsu.com) wrote: On 07/01/2015 03:01 AM, Dr. David Alan Gilbert wrote: * Wen Congyang (we...@cn.fujitsu.com) wrote: On 06/27/2015 03:03 AM, Dr. David Alan Gilbert wrote: snip Ah, I hadn't realised you could do that; so do you just do: migrate_set_parameter colo on migrate -d -b tcp:otherhhost:port How does the secondary know to feed that data straight into the disk without recording all the old data into the hidden-disk ? hidden disk and active disk will be made empty when starting block replication. Hmm, yes - I think I need to update to your current world; in the version from the end of May, I get a 'error while loading state for instance 0x0 of device 'block'' if I try to use migrate -d -b (the bdrv_write fails) Can you give me both primary and secondary qemu's command? I think the command line is wrong, and disk migration fails. Primary: ./try/bin/qemu-system-x86_64 -enable-kvm -nographic \ -boot c -m 4096 -smp 4 -S \ -name debug-threads=on -trace events=trace-file \ -netdev tap,id=hn0,script=$PWD/ifup-prim,\ downscript=no,colo_script=$PWD/qemu/scripts/colo-proxy-script.sh,colo_nicname=em4 \ -device e1000,mac=9c:da:4d:1c:b5:89,id=net-pci0,netdev=hn0 \ -drive if=virtio,driver=quorum,read-pattern=fifo,no-connect=on,\ cache=none,aio=native,\ children.0.file.filename=./bugzilla.raw,\ children.0.driver=raw,\ children.1.file.driver=nbd,\ children.1.file.host=ibpair,\ children.1.file.port=8889,\ children.1.file.export=colo1,\ children.1.driver=replication,\ children.1.mode=primary,\ children.1.ignore-errors=on Add id=nbd_target1 to primary disk option, and try it. Disk migration needs the same id to sync the disk. Thanks Wen Congyang Secondary: ./try/bin/qemu-system-x86_64 -enable-kvm -nographic \ -boot c -m 4096 -smp 4 -S \ -name debug-threads=on -trace events=trace-file \ -netdev tap,id=hn0,script=$PWD/ifup-slave,\ downscript=no,colo_script=$PWD/qemu/scripts/colo-proxy-script.sh,colo_nicname=em4 \ -device e1000,mac=9c:da:4d:1c:b5:89,id=net-pci0,netdev=hn0 \ -drive if=none,driver=raw,file=bugzilla.raw,id=nbd_target1,cache=none,aio=native \ -drive if=virtio,driver=replication,mode=secondary,export=colo1,throttling.bps-total-max=7000,\ file.file.filename=/run/colo-active-disk.qcow2,\ file.driver=qcow2,\ file.backing_reference.drive_id=nbd_target1,\ file.backing_reference.hidden-disk.file.filename=/run/colo-hidden-disk.qcow2,\ file.backing_reference.hidden-disk.driver=qcow2,\ file.backing_reference.hidden-disk.allow-write-backing-file=on \ -incoming tcp:0: Thanks, Dave If the user uses mirror job, we don't cancel the mirror job now. It would be good to get it to work with mirror, that seems preferred these days to the old block migration. In normal migration, is mirror job created and cancelled by libvirt? Yes, I think so; you should be able to turn on full logging on libvirt and watch the qmp commands it sends. Supporting mirror job in my TODO list now. But I think we should focus the basci function now. Thanks Wen Congyang Dave -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK . -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK .
Re: [Qemu-devel] [PATCH] Only try and read a VMDescription if it should be there
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com The VMDescription section maybe after the EOF mark, the current code does a 'qemu_get_byte' and either gets the header byte identifying the description or an error (which it ignores). Doing the 'get' upsets RDMA which hangs on old machine types without the VMDescription. Just avoid reading the VMDescription if we wouldn't send it. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Applied.
Re: [Qemu-devel] [PATCH] RDMA: Missing free in (probably unreachable) error path
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com Coverity CID 1307773 Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Integrated gonglei patch for this, just moved the malloc. --- migration/rdma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/migration/rdma.c b/migration/rdma.c index 53e611e..2a9e0ce 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3395,6 +3395,7 @@ static void *qemu_fopen_rdma(RDMAContext *rdma, const char *mode) QEMUFileRDMA *r = g_malloc0(sizeof(QEMUFileRDMA)); if (qemu_file_mode_is_not_valid(mode)) { +g_free(r); return NULL; }
Re: [Qemu-devel] [PATCH v2 02/12] qemu_ram_foreach_block: pass up error value, and down the ramblock name
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com check the return value of the function it calls and error if it's non-0 Fixup qemu_rdma_init_one_block that is the only current caller, and rdma_add_block the only function it calls using it. Pass the name of the ramblock to the function; helps in debugging. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reviewed-by: David Gibson da...@gibson.dropbear.id.au Reviewed-by: Amit Shah amit.s...@redhat.com Reviewed-by: Michael R. Hines mrhi...@us.ibm.com Reviewed-by: Juan Quintela quint...@redhat.com
Re: [Qemu-devel] [PATCH v2 03/12] Remove unneeded memset
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reviewed-by: Michael R. Hines mrhi...@us.ibm.com Reviewed-by: Juan Quintela quint...@redhat.com
Re: [Qemu-devel] [PATCH 4/5] net/dump: Add dump option for netdev devices
On Tue, Jun 30, 2015 at 12:37:46PM +0200, Thomas Huth wrote: On Fri, 26 Jun 2015 10:44:59 +0100 Stefan Hajnoczi stefa...@gmail.com wrote: On Wed, Jun 24, 2015 at 05:56:20PM +0200, Thomas Huth wrote: diff --git a/net/net.c b/net/net.c index cc36c7b..8871b77 100644 --- a/net/net.c +++ b/net/net.c @@ -568,6 +568,12 @@ ssize_t qemu_deliver_packet(NetClientState *sender, return 0; } +if (nc-netdev_dump_enabled) { +net_dump_receive(nc, data, size); +} else if (sender-netdev_dump_enabled) { +net_dump_receive(sender, data, size); +} ... Perhaps dumping should happen after -receive() has returned size. If -receive() returns -1 the packet is discarded, and if it returns 0 the packet is queued (not delivered yet). If you dump unconditionally before -receive() you will see queued packets dumped multiple times (each time the queue gets flushed). I've now tried this, but then I suddenly get the packets in the wrong order in the dump file (when using slirp networking), e.g.: 1 0.00 10.0.2.2 - 255.255.255.255 DHCP 590 DHCP Offer 2 0.12 0.0.0.0 - 255.255.255.255 DHCP 342 DHCP Discover instead of: 1 0.00 0.0.0.0 - 255.255.255.255 DHCP 342 DHCP Discover 2 0.35 10.0.2.2 - 255.255.255.255 DHCP 590 DHCP Offer Looks like with slirp, the answer is already sent before the initial receive() function returns? Any idea how to avoid that issue? If not, I think I'll simply keep the dump hooks before calling the receive functions. I see. So either way the packet capture will be misleading. Please leave add a comment to the code mentioning that either queued packets are duplicated or slirp traffic is out-of-order. That way we won't forget why the code is the way it is. Stefan pgpmPTfMvtuvz.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v2 01/12] Rename RDMA structures to make destination clear
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com RDMA has two data types that are named confusingly; RDMALocalBlock (pointed to indirectly by local_ram_blocks) RDMARemoteBlock (pointed to by block in RDMAContext) RDMALocalBlocks, as the name suggests is a data strucuture that represents the RDMAable RAM Blocks on the current side of the migration whichever that is. RDMARemoteBlocks is always the shape of the RAMBlocks on the destination, even on the destination. Rename: RDMARemoteBlock - RDMADestBlock context-'block' - context-dest_blocks Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reviewed-by: Michael R. Hines mrhi...@us.ibm.com Reviewed-by: Juan Quintela quint...@redhat.com
Re: [Qemu-devel] [PATCH] more check for replaced node
On Thu, Jun 25, 2015 at 02:55:10PM +0800, Wen Congyang wrote: Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- block.c | 5 +++-- block/mirror.c| 3 ++- blockdev.c| 2 +- include/block/block.h | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) This patch is missing a commit description. What is the justification for this change? Leaving this patch to Jeff since I'm CC only but the email is to Jeff. diff --git a/block.c b/block.c index 7168575..70ee0f6 100644 --- a/block.c +++ b/block.c @@ -4033,7 +4033,8 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate) return false; } -BlockDriverState *check_to_replace_node(const char *node_name, Error **errp) +BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, +const char *node_name, Error **errp) { BlockDriverState *to_replace_bs = bdrv_find_node(node_name); AioContext *aio_context; @@ -4056,7 +4057,7 @@ BlockDriverState *check_to_replace_node(const char *node_name, Error **errp) * Another benefit is that this tests exclude backing files which are * blocked by the backing blockers. */ -if (!bdrv_is_first_non_filter(to_replace_bs)) { +if (!bdrv_recurse_is_first_non_filter(parent_bs, to_replace_bs)) { error_setg(errp, Only top most non filter can be replaced); to_replace_bs = NULL; goto out; diff --git a/block/mirror.c b/block/mirror.c index 0d06cc2..f132f35 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -612,7 +612,8 @@ static void mirror_complete(BlockJob *job, Error **errp) if (s-replaces) { AioContext *replace_aio_context; -s-to_replace = check_to_replace_node(s-replaces, local_err); +s-to_replace = check_to_replace_node(s-common.bs, s-replaces, + local_err); if (!s-to_replace) { error_propagate(errp, local_err); return; diff --git a/blockdev.c b/blockdev.c index f3a3097..a0e13b0 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2756,7 +2756,7 @@ void qmp_drive_mirror(const char *device, const char *target, goto out; } -to_replace_bs = check_to_replace_node(replaces, local_err); +to_replace_bs = check_to_replace_node(bs, replaces, local_err); if (!to_replace_bs) { error_propagate(errp, local_err); diff --git a/include/block/block.h b/include/block/block.h index 07bb724..e0dad54 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -311,7 +311,8 @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, bool bdrv_is_first_non_filter(BlockDriverState *candidate); /* check if a named node can be replaced when doing drive-mirror */ -BlockDriverState *check_to_replace_node(const char *node_name, Error **errp); +BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, +const char *node_name, Error **errp); /* async block I/O */ typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector, pgpJ6OSFGJNHm.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v2 06/12] Translate offsets to destination address space
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com The 'offset' field in RDMACompress and 'current_addr' field in RDMARegister are commented as being offsets within a particular RAMBlock, however they appear to actually be offsets within the ram_addr_t space. The code currently assumes that the offsets on the source/destination match, this change removes the need for the assumption for these structures by translating the addresses into the ram_addr_t space of the destination host. Note: An alternative would be to change the fields to actually take the data they're commented for; this would potentially be simpler but would break stream compatibility for those cases that currently work. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reviewed-by: Juan Quintela quint...@redhat.com backwards compatibility, you will live with your errors forever +/* + * current_addr as passed in is an address in the local ram_addr_t + * space, we need to translate this for the destination + */ +reg-key.current_addr -= local_block-offset; +reg-key.current_addr += rdma-dest_blocks[reg-current_index].offset; I would add a function that is: rdma_adjust_offest() or something, but it needs three pointer parameters, not sure that it is any easier :-(
Re: [Qemu-devel] [PATCH] more check for replaced node
On 07/01/2015 04:39 PM, Stefan Hajnoczi wrote: On Thu, Jun 25, 2015 at 02:55:10PM +0800, Wen Congyang wrote: Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- block.c | 5 +++-- block/mirror.c| 3 ++- blockdev.c| 2 +- include/block/block.h | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) This patch is missing a commit description. What is the justification for this change? Sorry, I forgot to add commit messages.. Without this patch, the replace node can be any node, and it can be top BDS with BB, or another quorum's child. With this patch, the replace node must be this quorum's child. Thanks Wen Congyang Leaving this patch to Jeff since I'm CC only but the email is to Jeff. diff --git a/block.c b/block.c index 7168575..70ee0f6 100644 --- a/block.c +++ b/block.c @@ -4033,7 +4033,8 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate) return false; } -BlockDriverState *check_to_replace_node(const char *node_name, Error **errp) +BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, +const char *node_name, Error **errp) { BlockDriverState *to_replace_bs = bdrv_find_node(node_name); AioContext *aio_context; @@ -4056,7 +4057,7 @@ BlockDriverState *check_to_replace_node(const char *node_name, Error **errp) * Another benefit is that this tests exclude backing files which are * blocked by the backing blockers. */ -if (!bdrv_is_first_non_filter(to_replace_bs)) { +if (!bdrv_recurse_is_first_non_filter(parent_bs, to_replace_bs)) { error_setg(errp, Only top most non filter can be replaced); to_replace_bs = NULL; goto out; diff --git a/block/mirror.c b/block/mirror.c index 0d06cc2..f132f35 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -612,7 +612,8 @@ static void mirror_complete(BlockJob *job, Error **errp) if (s-replaces) { AioContext *replace_aio_context; -s-to_replace = check_to_replace_node(s-replaces, local_err); +s-to_replace = check_to_replace_node(s-common.bs, s-replaces, + local_err); if (!s-to_replace) { error_propagate(errp, local_err); return; diff --git a/blockdev.c b/blockdev.c index f3a3097..a0e13b0 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2756,7 +2756,7 @@ void qmp_drive_mirror(const char *device, const char *target, goto out; } -to_replace_bs = check_to_replace_node(replaces, local_err); +to_replace_bs = check_to_replace_node(bs, replaces, local_err); if (!to_replace_bs) { error_propagate(errp, local_err); diff --git a/include/block/block.h b/include/block/block.h index 07bb724..e0dad54 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -311,7 +311,8 @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, bool bdrv_is_first_non_filter(BlockDriverState *candidate); /* check if a named node can be replaced when doing drive-mirror */ -BlockDriverState *check_to_replace_node(const char *node_name, Error **errp); +BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, +const char *node_name, Error **errp); /* async block I/O */ typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
Re: [Qemu-devel] [PATCH v2 07/12] Rework ram_control_load_hook to hook during block load
Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com We need the names of RAMBlocks as they're loaded for RDMA, reuse a slightly modified ram_control_load_hook: a) Pass a 'data' parameter to use for the name in the block-reg case b) Only some hook types now require the presence of a hook function. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com @@ -1569,6 +1569,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) error_report_err(local_err); } } +ram_control_load_hook(f, RAM_CONTROL_BLOCK_REG, + block-idstr); break; } } @@ -1637,7 +1639,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) break; default: if (flags RAM_SAVE_FLAG_HOOK) { -ram_control_load_hook(f, flags); +ram_control_load_hook(f, RAM_CONTROL_HOOK, NULL); Using a function in only two places, and passing two additional parameters for that +static int rdma_load_hook(QEMUFile *f, void *opaque, uint64_t flags, void *data) +{ +switch (flags) { +case RAM_CONTROL_BLOCK_REG: +/* TODO A later patch */ +return 0; +break; + +case RAM_CONTROL_HOOK: +return qemu_rdma_registration_handle(f, opaque); + +default: +/* Shouldn't be called with any other values */ +abort(); +} And you are doing two completely different things depending of the flag Later, Juan.
Re: [Qemu-devel] [PATCH v2 07/12] Rework ram_control_load_hook to hook during block load
* Juan Quintela (quint...@redhat.com) wrote: Dr. David Alan Gilbert (git) dgilb...@redhat.com wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com We need the names of RAMBlocks as they're loaded for RDMA, reuse a slightly modified ram_control_load_hook: a) Pass a 'data' parameter to use for the name in the block-reg case b) Only some hook types now require the presence of a hook function. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com @@ -1569,6 +1569,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) error_report_err(local_err); } } +ram_control_load_hook(f, RAM_CONTROL_BLOCK_REG, + block-idstr); break; } } @@ -1637,7 +1639,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) break; default: if (flags RAM_SAVE_FLAG_HOOK) { -ram_control_load_hook(f, flags); +ram_control_load_hook(f, RAM_CONTROL_HOOK, NULL); Using a function in only two places, and passing two additional parameters for that +static int rdma_load_hook(QEMUFile *f, void *opaque, uint64_t flags, void *data) +{ +switch (flags) { +case RAM_CONTROL_BLOCK_REG: +/* TODO A later patch */ +return 0; +break; + +case RAM_CONTROL_HOOK: +return qemu_rdma_registration_handle(f, opaque); + +default: +/* Shouldn't be called with any other values */ +abort(); +} And you are doing two completely different things depending of the flag The other way would be to add a new function pointer to qemu_file and wire up the new pointer. It didn't seem any prettier. Dave Later, Juan. -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
[Qemu-devel] [PATCH 09/12] 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 quint...@redhat.com --- migration/migration.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index c5b778b..a8d2da5 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -548,7 +548,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); } @@ -633,7 +633,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); @@ -732,7 +732,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } else { error_setg(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 01/12] runstate: Add runstate store
This allows us to store the current state to send it through migration. Signed-off-by: Juan Quintela quint...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- 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 df80951..44570d1 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 69ad90c..fec7e93 100644 --- a/vl.c +++ b/vl.c @@ -634,6 +634,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
[Qemu-devel] [PATCH 02/12] 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 quint...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- vl.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vl.c b/vl.c index fec7e93..d4d9ca8 100644 --- a/vl.c +++ b/vl.c @@ -573,8 +573,14 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_DEBUG, RUN_STATE_RUNNING }, { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE }, -{ RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR }, +{ RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN }, +{ RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_WHATCHDOG }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, -- 2.4.3
[Qemu-devel] [PATCH 05/12] vmstate: Create optional sections
To make sections optional, we need to do it at the beggining of the code. Signed-off-by: Juan Quintela quint...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- 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 0695d7c..f51ff69 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -820,6 +820,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 9e0e286..8a15021 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -836,6 +836,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); @@ -949,6 +954,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 5d5cae2..8b85fbb 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 07/12] migration: Use cmpxchg correctly
cmpxchg returns the old value Signed-off-by: Juan Quintela quint...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- migration/migration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration/migration.c b/migration/migration.c index 0fd5962..cfcc227 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -508,7 +508,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/12] 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 quint...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- 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 26104ca..d00766e 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 8a15021..db8e943 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -246,11 +246,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, @@ -723,6 +767,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; @@ -1037,6 +1086,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 10/12] 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 quint...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- migration/migration.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index a8d2da5..ef1e4a4 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -549,7 +549,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); } @@ -634,7 +633,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
Re: [Qemu-devel] [PATCH v4 1/5] softmmu: add helper function to pass through retaddr
On 06/29/2015 08:23 AM, Pavel Dovgalyuk wrote: This patch introduces several helpers to pass return address which points to the TB. Correct return address allows correct restoring of the guest PC and icount. These functions should be used when helpers embedded into TB invoke memory operations. Signed-off-by: Pavel Dovgalyukpavel.dovga...@ispras.ru --- include/exec/cpu_ldst_template.h | 59 +- softmmu_template.h |6 tcg/tcg.h| 23 +++ 3 files changed, 74 insertions(+), 14 deletions(-) Reviewed-by: Richard Henderson r...@twiddle.net r~
[Qemu-devel] [PATCH v2 1/1] Add support for PCI Enhanced Allocation BARs
PCI Enhanced Allocation is a new method of allocating MMIO IO resources for PCI devices bridges. It can be used instead of the traditional PCI method of using BARs. EA entries are hardware-initialized to a fixed address. Unlike BARs, regions described by EA are cannot be moved. Because of this, only devices which are permanently connected to the PCI bus can use EA. A removable PCI card must not use EA. This patch enables any existing QEMU PCI model to use EA instead of BARs. It adds EA options to the PCI device parameters. The Enhanced Allocation ECN is publicly available here: https://www.pcisig.com/specifications/conventional/ECN_Enhanced_Allocation_23_Oct_2014_Final.pdf Signed-off-by: Sean O. Stalley sean.stal...@intel.com --- hw/pci/Makefile.objs| 2 +- hw/pci/pci.c| 95 +-- hw/pci/pci_ea.c | 202 include/hw/pci/pci.h| 6 ++ include/hw/pci/pci_ea.h | 42 ++ include/qemu/typedefs.h | 1 + 6 files changed, 324 insertions(+), 24 deletions(-) create mode 100644 hw/pci/pci_ea.c create mode 100644 include/hw/pci/pci_ea.h diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs index 9f905e6..e5d80cf 100644 --- a/hw/pci/Makefile.objs +++ b/hw/pci/Makefile.objs @@ -3,7 +3,7 @@ common-obj-$(CONFIG_PCI) += msix.o msi.o common-obj-$(CONFIG_PCI) += shpc.o common-obj-$(CONFIG_PCI) += slotid_cap.o common-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o -common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o +common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o pci_ea.o common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o common-obj-$(CONFIG_ALL) += pci-stub.o diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 2158043..f3b255a 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -23,6 +23,7 @@ */ #include hw/hw.h #include hw/pci/pci.h +#include hw/pci/pci_ea.h #include hw/pci/pci_bridge.h #include hw/pci/pci_bus.h #include hw/pci/pci_host.h @@ -58,6 +59,9 @@ static Property pci_props[] = { QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), DEFINE_PROP_BIT(command_serr_enable, PCIDevice, cap_present, QEMU_PCI_CAP_SERR_BITNR, true), +DEFINE_PROP_ARRAY(ea_addr, PCIDevice, ea_addr_len, ea_addr, + qdev_prop_uint64, hwaddr), + DEFINE_PROP_END_OF_LIST() }; @@ -955,43 +959,76 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, uint32_t addr; uint64_t wmask; pcibus_t size = memory_region_size(memory); +bool enhanced = (pci_dev-ea_addr_len 0); assert(region_num = 0); assert(region_num PCI_NUM_REGIONS); -if (size (size-1)) { + +/* TODO: these checks should be done earlier */ +if (!enhanced (size (size-1))) { fprintf(stderr, ERROR: PCI region size must be pow2 type=0x%x, size=0x%FMT_PCIBUS\n, type, size); exit(1); } +if (enhanced) { + +if (pci_dev-ea_addr_len = region_num) { +fprintf(stderr, ERROR: Address for EA entry %i not given\n, +region_num); +exit(1); +} + +if (pci_dev-ea_addr[region_num] == 0x0) { +fprintf(stderr, ERROR: Address for EA entry %i not set\n, +region_num); +exit(1); +} + +if (pci_ea_invalid_addr(pci_dev-ea_addr[region_num])) { +fprintf(stderr, ERROR: Address for EA entry %i not valid\n, +region_num); +exit(1); +} + +} + r = pci_dev-io_regions[region_num]; r-addr = PCI_BAR_UNMAPPED; r-size = size; r-type = type; -r-memory = NULL; - -wmask = ~(size - 1); -addr = pci_bar(pci_dev, region_num); -if (region_num == PCI_ROM_SLOT) { -/* ROM enable bit is writable */ -wmask |= PCI_ROM_ADDRESS_ENABLE; -} -pci_set_long(pci_dev-config + addr, type); -if (!(r-type PCI_BASE_ADDRESS_SPACE_IO) -r-type PCI_BASE_ADDRESS_MEM_TYPE_64) { -pci_set_quad(pci_dev-wmask + addr, wmask); -pci_set_quad(pci_dev-cmask + addr, ~0ULL); -} else { -pci_set_long(pci_dev-wmask + addr, wmask 0x); -pci_set_long(pci_dev-cmask + addr, 0x); +r-enhanced = enhanced; +r-memory = memory; +r-address_space = type PCI_BASE_ADDRESS_SPACE_IO ? +pci_dev-bus-address_space_io : pci_dev-bus-address_space_mem; + +if (!enhanced) { + +wmask = ~(size - 1); +addr = pci_bar(pci_dev, region_num); +if (region_num == PCI_ROM_SLOT) { +/* ROM enable bit is writable */ +wmask |= PCI_ROM_ADDRESS_ENABLE; +} +pci_set_long(pci_dev-config + addr, type); +if (!(r-type PCI_BASE_ADDRESS_SPACE_IO) +r-type PCI_BASE_ADDRESS_MEM_TYPE_64) { +pci_set_quad(pci_dev-wmask + addr, wmask); +pci_set_quad(pci_dev-cmask + addr, ~0ULL); +} else {
Re: [Qemu-devel] [PATCH RFC 4/6] xen: Print and use errno where applicable.
On Wed, Jul 01, 2015 at 02:01:07PM +0100, Stefano Stabellini wrote: On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: In Xen 4.6 commit cd2f100f0f61b3f333d52d1737dd73f02daee592 libxc: Fix do_memory_op to return negative value on errors made the libxc API less odd-ball: On errors, return value is -1 and error code is in errno. On success the return value is either 0 or an positive value. Since we could be running with an old toolstack in which the Exx value is in rc or the newer, we print both and return the -EXX depending on rc == -1 condition. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com --- xen-hvm.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xen-hvm.c b/xen-hvm.c index 0408462..a92bc14 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -345,11 +345,12 @@ go_physmap: unsigned long idx = pfn + i; xen_pfn_t gpfn = start_gpfn + i; +/* In Xen 4.6 rc is -1 and errno contains the error value. */ rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); if (rc) { DPRINTF(add_to_physmap MFN %PRI_xen_pfn to PFN % -PRI_xen_pfn failed: %d\n, idx, gpfn, rc); -return -rc; +PRI_xen_pfn failed: %d (errno: %d)\n, idx, gpfn, rc, errno); +return rc == -1 ? -errno : -rc; Printing both rc and errno is the right thing to do, but I am not sure changing return value depending on the libxc version is a good idea. Maybe we should be consistent and always return rc? In Xen 4.5 and earlier this function would return -EINVAL (say rc=EINVAL). With Xen 4.6 it would always return 1 on errors (rc is -1, and with --1 we get 1), while the errno would have EINVAL. To be consistent and have this function return an proper -Exx value we need that check to use errno in case rc == -1. I am uncomfortable with returning positive values as errors, which reminds me - I need to update the commit to mention the return 1 issue. } } @@ -422,11 +423,12 @@ static int xen_remove_from_physmap(XenIOState *state, xen_pfn_t idx = start_addr + i; xen_pfn_t gpfn = phys_offset + i; +/* In Xen 4.6 rc is -1 and errno contains the error value. */ rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); if (rc) { fprintf(stderr, add_to_physmap MFN %PRI_xen_pfn to PFN % -PRI_xen_pfn failed: %d\n, idx, gpfn, rc); -return -rc; +PRI_xen_pfn failed: %d (errno: %d)\n, idx, gpfn, rc, errno); +return rc == -1 ? -errno : -rc; } } -- 2.1.0
[Qemu-devel] [PATCH] qmp-shell: add documentation
I should probably document the changes that were made. Signed-off-by: John Snow js...@redhat.com --- scripts/qmp/qmp-shell | 35 +++ 1 file changed, 35 insertions(+) diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index 65280d2..fa39bf0 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -29,6 +29,41 @@ # (QEMU) device_add driver=e1000 id=net1 # {u'return': {}} # (QEMU) +# +# key=value pairs also support Python or JSON object literal subset notations, +# without spaces. Dictionaries/objects {} are supported as are arrays []. +# +#example-command arg-name1={'key':'value','obj'={'prop':value}} +# +# Both JSON and Python formatting should work, including both styles of +# string literal quotes. Both paradigms of literal values should work, +# including null/true/false for JSON and None/True/False for Python. +# +# +# Transactions have the following multi-line format: +# +#transaction( +#action-name1 [ arg-name1=arg1 ] ... [arg-nameN=argN ] +#... +#action-nameN [ arg-name1=arg1 ] ... [arg-nameN=argN ] +#) +# +# One line transactions are also supported: +# +#transaction( action-name1 ... ) +# +# For example: +# +# (QEMU) transaction( +# TRANS block-dirty-bitmap-add node=drive0 name=bitmap1 +# TRANS block-dirty-bitmap-clear node=drive0 name=bitmap0 +# TRANS ) +# {return: {}} +# (QEMU) +# +# Use the -v and -p options to activate the verbose and pretty-print options, +# which will echo back the properly formatted JSON-compliant QMP that is being +# sent to QEMU, which is useful for debugging and documentation generation. import qmp import json -- 2.1.0
Re: [Qemu-devel] [Qemu-block] [RFC] ide: fix bmdma underflow code
On 07/01/2015 01:10 PM, Stefan Hajnoczi wrote: On Wed, Jul 1, 2015 at 4:49 PM, John Snow js...@redhat.com wrote: On 07/01/2015 06:18 AM, Stefan Hajnoczi wrote: On Mon, Jun 29, 2015 at 04:16:06PM -0400, John Snow wrote: diff --git a/hw/ide/core.c b/hw/ide/core.c index 8c271cc..6bcf07c 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -716,8 +716,8 @@ static void ide_dma_cb(void *opaque, int ret) sector_num = ide_get_sector(s); if (n 0) { - assert(s-io_buffer_size == s-sg.size); - dma_buf_commit(s, s-io_buffer_size); +assert(s-nsector * 512 == s-sg.size); The short PRDT case: ...is handled first, lower down in this callback. The first call to ide_dma_cb occurs before we've prepared any bytes or set io_buffer_size. We'll cruise past these post-hoc checks because we didn't transfer anything. We'll hit the explicit too short check during that first call and will cease processing there. If the (n 0) conditionals fire off here, it's because we've already transferred data and we KNOW the PRDTs weren't too short for at least one iteration of the DMA loop* The case I described with nsector = 2 and PRDT having only 1 sector isn't handled before we hit the assertion failure: qemu-system-x86_64: hw/ide/core.c:719: ide_dma_cb: Assertion `s-nsector * 512 == s-sg.size' failed. GOTCHA, it's because the short PRDT check doesn't check to see if it's enough to satisfy the entire command, just at least one sector. I forgot. You're right. (*note that at present, AHCI only ever makes one DMA callback loop, because we fire off the entire transfer in one shot, though the loop is tolerant to multiple loops. Maybe other HBAs utilize that, but AHCI doesn't. Regardless, with this patch no qtests or iotests fail, so everything seems peachy.) I have sent an ide-test.c patch with the test case that triggers the assertion failure. It's a slightly different code path from the other short PRDT test case so it's useful to add it. Though I'm now realizing that what I really meant to write was assert(n * 512 == s-sg.size); Looks good.
[Qemu-devel] [PATCH v2 05/15] ahci: factor ncq_finish out of ncq_cb
When we add werror=stop or rerror=stop support to NCQ, we'll want to take a codepath where we don't actually complete the command, so factor that out into a new routine. Signed-off-by: John Snow js...@redhat.com --- hw/ide/ahci.c | 32 +++- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index b3a6a91..b0b9b41 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -933,23 +933,11 @@ static void ncq_err(NCQTransferState *ncq_tfs) ncq_tfs-drive-port_regs.scr_err |= (1 ncq_tfs-tag); } -static void ncq_cb(void *opaque, int ret) +static void ncq_finish(NCQTransferState *ncq_tfs) { -NCQTransferState *ncq_tfs = (NCQTransferState *)opaque; -IDEState *ide_state = ncq_tfs-drive-port.ifs[0]; - -if (ret == -ECANCELED) { -return; -} /* Clear bit for this tag in SActive */ ncq_tfs-drive-port_regs.scr_act = ~(1 ncq_tfs-tag); -if (ret 0) { -ncq_err(ncq_tfs); -} else { -ide_state-status = READY_STAT | SEEK_STAT; -} - ahci_write_fis_sdb(ncq_tfs-drive-hba, ncq_tfs-drive-port_no, (1 ncq_tfs-tag)); @@ -962,6 +950,24 @@ static void ncq_cb(void *opaque, int ret) ncq_tfs-used = 0; } +static void ncq_cb(void *opaque, int ret) +{ +NCQTransferState *ncq_tfs = (NCQTransferState *)opaque; +IDEState *ide_state = ncq_tfs-drive-port.ifs[0]; + +if (ret == -ECANCELED) { +return; +} + +if (ret 0) { +ncq_err(ncq_tfs); +} else { +ide_state-status = READY_STAT | SEEK_STAT; +} + +ncq_finish(ncq_tfs); +} + static int is_ncq(uint8_t ata_cmd) { /* Based on SATA 3.2 section 13.6.3.2 */ -- 2.1.0
[Qemu-devel] [PATCH v2 09/15] qtest/ahci: halted NCQ test
Signed-off-by: John Snow js...@redhat.com --- tests/ahci-test.c | 19 +++ 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/ahci-test.c b/tests/ahci-test.c index 3f06fd9..c30837b 100644 --- a/tests/ahci-test.c +++ b/tests/ahci-test.c @@ -1200,13 +1200,13 @@ static void test_migrate_ncq(void) } /** - * DMA Error Test + * Halted IO Error Test * * Simulate an error on first write, Try to write a pattern, * Confirm the VM has stopped, resume the VM, verify command * has completed, then read back the data and verify. */ -static void test_halted_dma(void) +static void ahci_halted_io_test(uint8_t cmd_read, uint8_t cmd_write) { AHCIQState *ahci; uint8_t port; @@ -1241,7 +1241,7 @@ static void test_halted_dma(void) memwrite(ptr, tx, bufsize); /* Attempt to write (and fail) */ -cmd = ahci_guest_io_halt(ahci, port, CMD_WRITE_DMA, +cmd = ahci_guest_io_halt(ahci, port, cmd_write, ptr, bufsize, 0); /* Attempt to resume the command */ @@ -1249,7 +1249,7 @@ static void test_halted_dma(void) ahci_free(ahci, ptr); /* Read back and verify */ -ahci_io(ahci, port, CMD_READ_DMA, rx, bufsize, 0); +ahci_io(ahci, port, cmd_read, rx, bufsize, 0); g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0); /* Cleanup and go home */ @@ -1258,6 +1258,16 @@ static void test_halted_dma(void) g_free(tx); } +static void test_halted_dma(void) +{ +ahci_halted_io_test(CMD_READ_DMA, CMD_WRITE_DMA); +} + +static void test_halted_ncq(void) +{ +ahci_halted_io_test(READ_FPDMA_QUEUED, WRITE_FPDMA_QUEUED); +} + /** * DMA Error Migration Test * @@ -1677,6 +1687,7 @@ int main(int argc, char **argv) qtest_add_func(/ahci/io/ncq/simple, test_ncq_simple); qtest_add_func(/ahci/migrate/ncq/simple, test_migrate_ncq); +qtest_add_func(/ahci/io/ncq/retry, test_halted_ncq); ret = g_test_run(); -- 2.1.0
Re: [Qemu-devel] [PATCH v3 2/3] target-mips: improve exceptions handling
On 2015-06-29 09:57, Pavel Dovgaluk wrote: From: Aurelien Jarno [mailto:aurel...@aurel32.net] On 2015-06-18 16:28, Pavel Dovgalyuk wrote: This patch improves exception handling in MIPS. Instructions generate several types of exceptions. When exception is generated, it breaks the execution of the current translation block. Implementation of the exceptions handling does not correctly restore icount for the instruction which caused the exception. In most cases icount will be decreased by the value equal to the size of TB. This patch passes pointer to the translation block internals to the exception handler. It allows correct restoring of the icount value. v3 changes: This patch stops translation when instruction which always generates exception is translated. This improves the performance of the patched version compared to original one. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- target-mips/cpu.h| 28 +++ target-mips/helper.h |1 target-mips/msa_helper.c |5 - target-mips/op_helper.c | 183 ++ target-mips/translate.c | 379 ++ 5 files changed, 302 insertions(+), 294 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index f9d2b4c..70ba39a 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -1015,4 +1015,32 @@ static inline void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val) } #endif +static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, +uint32_t exception, +int error_code, +uintptr_t pc) +{ +CPUState *cs = CPU(mips_env_get_cpu(env)); + +if (exception EXCP_SC) { +qemu_log(%s: %d %d\n, __func__, exception, error_code); +} +cs-exception_index = exception; +env-error_code = error_code; + +if (pc) { +/* now we have a real cpu fault */ +cpu_restore_state(cs, pc); +} + +cpu_loop_exit(cs); What about creating a cpu_loop_exit_restore(cs, pc) (maybe with a better name?) in the common code, if we now have to repeat this pattern for every target? Ok. diff --git a/target-mips/translate.c b/target-mips/translate.c index fd063a2..f87d5ac 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1677,15 +1677,21 @@ generate_exception_err (DisasContext *ctx, int excp, int err) gen_helper_raise_exception_err(cpu_env, texcp, terr); tcg_temp_free_i32(terr); tcg_temp_free_i32(texcp); +ctx-bstate = BS_STOP; } static inline void generate_exception (DisasContext *ctx, int excp) { -save_cpu_state(ctx, 1); gen_helper_0e0i(raise_exception, excp); } +static inline void +generate_exception_end(DisasContext *ctx, int excp) +{ +generate_exception_err(ctx, excp, 0); +} + This sets error_code to 0, which is different than leaving it unchanged. This might be ok, but have you checked there is no side effect? Previous version called do_raise_exception, which passes 0 as error_code. Ok, it's all fine then. /* Addresses computation */ static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) { @@ -1731,7 +1737,7 @@ static inline void check_cp1_enabled(DisasContext *ctx) static inline void check_cop1x(DisasContext *ctx) { if (unlikely(!(ctx-hflags MIPS_HFLAG_COP1X))) -generate_exception(ctx, EXCP_RI); +generate_exception_end(ctx, EXCP_RI); I don't think it is correct. Before triggering such an exception, we were saving the CPU state, and not going through retranslation. With this change, we don't save the CPU state, but we don't go through retranslation either. The rule is to either go through retranslation, or to save the CPU state before a possible exception. generate_exception_end saves CPU state and stops the translation through calling of generate_exception_err function. I missed that. Thanks for pointing me to that. That looks fine then. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
[Qemu-devel] [PATCH v2 02/15] ahci: stash ncq command
For migration and werror=stop/rerror=stop resume purposes, it will be convenient to have the command handy inside of ncq_tfs. Eventually, we'd like to avoid reading from the FIS entirely after the initial read, so this is a byte (hah!) sized step in that direction. Signed-off-by: John Snow js...@redhat.com --- hw/ide/ahci.c | 3 ++- hw/ide/ahci.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index de1759a..9540a64 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -996,6 +996,7 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis, ncq_tfs-used = 1; ncq_tfs-drive = ad; ncq_tfs-slot = slot; +ncq_tfs-cmd = ncq_fis-command; ncq_tfs-lba = ((uint64_t)ncq_fis-lba5 40) | ((uint64_t)ncq_fis-lba4 32) | ((uint64_t)ncq_fis-lba3 24) | @@ -1047,7 +1048,7 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis, ncq_tfs-lba, ncq_tfs-lba + ncq_tfs-sector_count - 1, ide_state-nb_sectors - 1); -switch(ncq_fis-command) { +switch (ncq_tfs-cmd) { case READ_FPDMA_QUEUED: DPRINTF(port, NCQ reading %d sectors from LBA %PRId64, tag %d\n, diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h index b8872a4..33607d7 100644 --- a/hw/ide/ahci.h +++ b/hw/ide/ahci.h @@ -259,6 +259,7 @@ typedef struct NCQTransferState { uint16_t sector_count; uint64_t lba; uint8_t tag; +uint8_t cmd; int slot; int used; } NCQTransferState; -- 2.1.0
[Qemu-devel] [PATCH v2 15/15] ahci: fix sdb fis semantics
There are two things to fix here: The first one is subtle: the PxSACT register in the AHCI HBA has different semantics from the field it is shadowing, the ACT field in the Set Device Bits FIS. In the HBA register, PxSACT acts as a bitfield indicating outstanding NCQ commands where a set bit indicates a pending NCQ operation. The FIS field however operates as an RWC register update to PxSACT, where a set bit indicates a *successfully* completed command. Correct the FIS semantics. At the same time, move the clear finished action to the SDB FIS generation instead of the register read to mimick how the other shadow registers work, which always just report the last reported value from a FIS, and not the most current values which may not have been reported by a FIS yet. Lastly and more simply, SATA 3.2 section 13.6.4.2 (and later sections) all specify that the Interrupt bit for the SDB FIS should always be set to one for NCQ commands. That's currently the only time we generate this FIS, so set it on all the time. Signed-off-by: John Snow js...@redhat.com --- hw/ide/ahci.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index eadd8b3..bb6a92f 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -106,8 +106,6 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int offset) val = pr-scr_err; break; case PORT_SCR_ACT: -pr-scr_act = ~s-dev[port].finished; -s-dev[port].finished = 0; val = pr-scr_act; break; case PORT_CMD_ISSUE: @@ -666,14 +664,14 @@ static void ahci_unmap_clb_address(AHCIDevice *ad) ad-lst = NULL; } -static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished) +static void ahci_write_fis_sdb(AHCIState *s, NCQTransferState *ncq_tfs) { -AHCIDevice *ad = s-dev[port]; +AHCIDevice *ad = ncq_tfs-drive; AHCIPortRegs *pr = ad-port_regs; IDEState *ide_state; SDBFIS *sdb_fis; -if (!s-dev[port].res_fis || +if (!ad-res_fis || !(pr-cmd PORT_CMD_FIS_RX)) { return; } @@ -683,19 +681,23 @@ static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished) sdb_fis-type = SATA_FIS_TYPE_SDB; /* Interrupt pending Notification bit */ -sdb_fis-flags = (ad-hba-control_regs.irqstatus ? (1 6) : 0); +sdb_fis-flags = 0x40; /* Interrupt bit, always 1 for NCQ */ sdb_fis-status = ide_state-status 0x77; sdb_fis-error = ide_state-error; /* update SAct field in SDB_FIS */ -s-dev[port].finished |= finished; sdb_fis-payload = cpu_to_le32(ad-finished); /* Update shadow registers (except BSY 0x80 and DRQ 0x08) */ pr-tfdata = (ad-port.ifs[0].error 8) | (ad-port.ifs[0].status 0x77) | (pr-tfdata 0x88); +pr-scr_act = ~ad-finished; +ad-finished = 0; -ahci_trigger_irq(s, ad, PORT_IRQ_SDB_FIS); +/* Trigger IRQ if interrupt bit is set (which currently, it always is) */ +if (sdb_fis-flags 0x40) { +ahci_trigger_irq(s, ad, PORT_IRQ_SDB_FIS); +} } static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len) @@ -895,11 +897,14 @@ static void ncq_err(NCQTransferState *ncq_tfs) static void ncq_finish(NCQTransferState *ncq_tfs) { -/* Clear bit for this tag in SActive */ -ncq_tfs-drive-port_regs.scr_act = ~(1 ncq_tfs-tag); +/* If we didn't error out, set our finished bit. Errored commands + * do not get a bit set for the SDB FIS ACT register, nor do they + * clear the outstanding bit in scr_act (PxSACT). */ +if (!(ncq_tfs-drive-port_regs.scr_err (1 ncq_tfs-tag))) { +ncq_tfs-drive-finished |= (1 ncq_tfs-tag); +} -ahci_write_fis_sdb(ncq_tfs-drive-hba, ncq_tfs-drive-port_no, - (1 ncq_tfs-tag)); +ahci_write_fis_sdb(ncq_tfs-drive-hba, ncq_tfs); DPRINTF(ncq_tfs-drive-port_no, NCQ transfer tag %d finished\n, ncq_tfs-tag); -- 2.1.0
Re: [Qemu-devel] [Qemu-block] [PATCH] block.c: fix real cdrom detection
On Wed, Jul 1, 2015 at 4:35 PM, Programmingkid programmingk...@gmail.com wrote: On Jun 26, 2015, at 4:01 PM, Stefan Hajnoczi wrote: On Fri, Jun 26, 2015 at 4:50 PM, Programmingkid programmingk...@gmail.com wrote: On Jun 26, 2015, at 5:34 AM, Stefan Hajnoczi wrote: On Thu, Jun 25, 2015 at 11:11:24AM -0400, Programmingkid wrote: On Jun 25, 2015, at 9:31 AM, Stefan Hajnoczi wrote: On Tue, Jun 23, 2015 at 02:26:51PM -0400, Programmingkid wrote: On Jun 23, 2015, at 2:06 PM, John Snow wrote: So what's the issue that this patch attempts to fix and how did you determine that the fix was needed here? It doesn't look like it respects proper abstraction at a glance. Without the patch, QEMU would just quit when the -cdrom /dev/cdrom option is given. Why does it quit? Because of a bug. This is what it prints: Could not read image for determining its format: Invalid argument. The bdrv_pread() failure is what need you need to investigate. In the other sub-thread there have been hints about adding CD-ROM passthrough support on Mac OS X by filling in the missing parts in block/raw-posix.c. That should help you get to the bottom of the problem. This message seems to indicate that QEMU thinks the real cdrom drive is an image file. If the -drive format= option is not given, QEMU will try to detect the image format. That's the purpose of the find_image_format() function. QEMU does not make a distinction between image files and block devices because there are valid use cases where a block device uses an image format. For example, a disk or partition can contain qcow2 data (there is no partition table or file system, just qcow2). So what you are saying is if the user enters -cdrom /dev/cdrom, QEMU is suppose to call find_image_format. If everything goes right, the first if statement should be skipped. Then the bdrv_pread() function should succeed and so should the bdrv_probe_all() function. Is that how it is suppose to work? Exactly. bdrv_pread() will grab some data from the start of the CD-ROM. No qcow2, vmdk, etc header will be found (there is probably an ISO file system there), so QEMU will default to the raw format and everything will work as expected. This is also how CD-ROM passthrough works on Linux and FreeBSD. I need some help. In the function bdrv_co_io_em(), the co argument's ret field is changed to -22. Would you know where exactly it is set? That question again is where is the co.ret variable set? I have tried stepping thru the function, but the change always escapes me. Please keep qemu-devel@nongnu.org CCed so others can participate in the discussion. The return value comes from: acb = bs-drv-bdrv_aio_readv(bs, sector_num, iov, nb_sectors, bdrv_co_io_em_complete, co); When the read request completes it invokes the callback. In this case it's bdrv_co_io_em_complete(). That function fills in co.ret. You'll probably find that -bdrv_aio_readv() points to block/raw-posix.c:raw_aio_readv(). This is the block driver for raw image files on POSIX systems (Mac OS, Linux, etc). The function doing the actual preadv(2) system call is handle_aiocb_rw() and its children. Hope this helps. Stefan
Re: [Qemu-devel] [PATCH v4 2/5] cpu-exec: introduce loop exit with restore function
On 2015-06-29 10:23, Pavel Dovgalyuk wrote: This patch introduces loop exit function, which also restores guest CPU state according to the value of host program counter. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- cpu-exec.c |9 + include/exec/exec-all.h |1 + 2 files changed, 10 insertions(+), 0 deletions(-) Thanks for this patch. Reviewed-by: Aurelien Jarno aurel...@aurel32.net -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH v4 3/5] target-mips: improve exceptions handling
On 2015-06-29 10:23, Pavel Dovgalyuk wrote: This patch improves exception handling in MIPS. Instructions generate several types of exceptions. When exception is generated, it breaks the execution of the current translation block. Implementation of the exceptions handling does not correctly restore icount for the instruction which caused the exception. In most cases icount will be decreased by the value equal to the size of TB. This patch passes pointer to the translation block internals to the exception handler. It allows correct restoring of the icount value. v3 changes: This patch stops translation when instruction which always generates exception is translated. This improves the performance of the patched version compared to original one. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- target-mips/cpu.h| 23 +++ target-mips/helper.h |1 target-mips/msa_helper.c | 158 +++- target-mips/op_helper.c | 179 ++ target-mips/translate.c | 372 ++ 5 files changed, 368 insertions(+), 365 deletions(-) [ snip ] diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 73a8e45..b562384 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c [ snip ] @@ -72,21 +54,21 @@ void helper_raise_exception(CPUMIPSState *env, uint32_t exception) #if defined(CONFIG_USER_ONLY) #define HELPER_LD(name, insn, type) \ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \ - int mem_idx) \ + int mem_idx, uintptr_t retaddr)\ { \ -return (type) cpu_##insn##_data(env, addr); \ +return (type) cpu_##insn##_data_ra(env, addr, retaddr); \ } You changed this, but as already said, your first patch doesn't providee the cpu_##insn##_data_ra function. Also you forgot to update the caller of this function, so it doesn't compile. #else #define HELPER_LD(name, insn, type) \ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \ - int mem_idx) \ + int mem_idx, uintptr_t retaddr)\ { \ switch (mem_idx)\ { \ -case 0: return (type) cpu_##insn##_kernel(env, addr); break;\ -case 1: return (type) cpu_##insn##_super(env, addr); break; \ +case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ +case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr);\ default:\ -case 2: return (type) cpu_##insn##_user(env, addr); break; \ +case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \ } \ } #endif @@ -106,14 +88,14 @@ static inline void do_##name(CPUMIPSState *env, target_ulong addr, \ #else #define HELPER_ST(name, insn, type) \ static inline void do_##name(CPUMIPSState *env, target_ulong addr, \ - type val, int mem_idx) \ + type val, int mem_idx, uintptr_t retaddr) \ { \ switch (mem_idx)\ { \ -case 0: cpu_##insn##_kernel(env, addr, val); break; \ -case 1: cpu_##insn##_super(env, addr, val); break; \ +case 0: cpu_##insn##_kernel_ra(env, addr, val, retaddr); break; \ +case 1: cpu_##insn##_super_ra(env, addr, val, retaddr); break; \ default:\ -case 2: cpu_##insn##_user(env, addr, val); break; \ +case 2: cpu_##insn##_user_ra(env, addr, val, retaddr); break; \ } \ } #endif [ snip ] diff --git a/target-mips/translate.c b/target-mips/translate.c index fd063a2..85d374c 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1677,15 +1677,21 @@ generate_exception_err (DisasContext *ctx, int excp, int err) gen_helper_raise_exception_err(cpu_env, texcp, terr); tcg_temp_free_i32(terr); tcg_temp_free_i32(texcp); +ctx-bstate =
Re: [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers
On 30/06/2015 13:33, Denis V. Lunev wrote: +static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host) +{ + struct kvm_hv *hv = vcpu-kvm-arch.hyperv; + + if (host) + hv-hv_crash_ctl = data; + You need to check against HV_X64_MSR_CRASH_CTL_CONTENTS here (or HV_X64_MSR_CRASH_CTL_NOTIFY) here. Paolo
Re: [Qemu-devel] [PATCH for-2.3] Revert seccomp tests that allow it to be used on non-x86 architectures
On Wednesday, July 01, 2015 02:07:49 PM Andrew Jones wrote: On Tue, Jun 30, 2015 at 01:18:49PM -0400, Paul Moore wrote: On Tuesday, June 30, 2015 06:07:40 PM Peter Maydell wrote: On 30 June 2015 at 18:01, Paul Moore pmo...@redhat.com wrote: I'm starting to wonder if the 32-bit ARM build system didn't have __NR_cacheflush defined in the system headers; that might explain some of the behavior. Could you check your system to see if it has __NR_cacheflush defined (try /usr/include/asm/unistd.h)? The constant name is __ARM_NR_cacheflush, not __NR_cacheflush (all the ARM-specific syscalls are __ARM_NR_*). See http://lxr.free-electrons.com/source/arch/arm/include/uapi/asm/unistd.h# L418 /me smacks his forehead Of course it is. We already work around that in arch-syscall-validate. D'oh! Good news though, I think we just found the bug ;) I'm currently trying to put out another fire in a different project; as soon as I've got that done I'll fix this. However, if somebody wants to play, I'm always happy to accept patches :) Sent: https://groups.google.com/forum/#!topic/libseccomp/RD9RTmc2Lxo Applied, thanks. I'll send the patch for qemu to add cacheflush to the whitelist shortly. -- paul moore security @ redhat
[Qemu-devel] [PATCH v4 10/10] ui: convert VNC to use generic cipher API
Switch the VNC server over to use the generic cipher API, this allows it to use the pluggable DES implementations, instead of being hardcoded to use QEMU's built-in impl. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- ui/vnc.c | 52 +--- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 7d844f7..94e4f19 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -49,7 +49,7 @@ static const struct timeval VNC_REFRESH_STATS = { 0, 50 }; static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 }; #include vnc_keysym.h -#include crypto/desrfb.h +#include crypto/cipher.h static QTAILQ_HEAD(, VncDisplay) vnc_displays = QTAILQ_HEAD_INITIALIZER(vnc_displays); @@ -2517,9 +2517,11 @@ static void make_challenge(VncState *vs) static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) { unsigned char response[VNC_AUTH_CHALLENGE_SIZE]; -int i, j, pwlen; +size_t i, pwlen; unsigned char key[8]; time_t now = time(NULL); +QCryptoCipher *cipher; +Error *err = NULL; if (!vs-vd-password) { VNC_DEBUG(No password configured on server); @@ -2536,9 +2538,29 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) pwlen = strlen(vs-vd-password); for (i=0; isizeof(key); i++) key[i] = ipwlen ? vs-vd-password[i] : 0; -deskey(key, EN0); -for (j = 0; j VNC_AUTH_CHALLENGE_SIZE; j += 8) -des(response+j, response+j); + +cipher = qcrypto_cipher_new( +QCRYPTO_CIPHER_ALG_DES_RFB, +QCRYPTO_CIPHER_MODE_ECB, +key, G_N_ELEMENTS(key), +err); +if (!cipher) { +VNC_DEBUG(Cannot initialize cipher %s, + error_get_pretty(err)); +error_free(err); +goto reject; +} + +if (qcrypto_cipher_decrypt(cipher, + vs-challenge, + response, + VNC_AUTH_CHALLENGE_SIZE, + err) 0) { +VNC_DEBUG(Cannot encrypt challenge %s, + error_get_pretty(err)); +error_free(err); +goto reject; +} /* Compare expected vs actual challenge response */ if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) { @@ -3484,12 +3506,20 @@ void vnc_display_open(const char *id, Error **errp) } password = qemu_opt_get_bool(opts, password, false); -if (password fips_get_state()) { -error_setg(errp, - VNC password auth disabled due to FIPS mode, - consider using the VeNCrypt or SASL authentication - methods as an alternative); -goto fail; +if (password) { +if (fips_get_state()) { +error_setg(errp, + VNC password auth disabled due to FIPS mode, + consider using the VeNCrypt or SASL authentication + methods as an alternative); +goto fail; +} +if (!qcrypto_cipher_supports( +QCRYPTO_CIPHER_ALG_DES_RFB)) { +error_setg(errp, + Cipher backend does not support DES RFB algorithm); +goto fail; +} } reverse = qemu_opt_get_bool(opts, reverse, false); -- 2.4.3
Re: [Qemu-devel] [PATCH] linux-user: Avoid compilation error with --disable-guest-base
Le 01/07/2015 15:15, Aurelien Jarno a écrit : On 2015-07-01 01:58, Laurent Vivier wrote: Le 30/06/2015 19:20, Peter Maydell a écrit : On 30 June 2015 at 18:13, Laurent Vivier laur...@vivier.eu wrote: Le 30/06/2015 18:45, Peter Maydell a écrit : On 30 June 2015 at 17:19, Laurent Vivier laur...@vivier.eu wrote: When guest base is disabled, RESERVED_VA is 0, and (__guest RESERVED_VA) is always false as __guest is unsigned. With -Werror=type-limits, this triggers an error: include/exec/cpu_ldst.h:60:31: error: comparison of unsigned expression 0 is always false [-Werror=type-limits] (!RESERVED_VA || (__guest RESERVED_VA)); \ This patch removes this comparison when guest base is disabled. Is there a useful reason to compile with --disable-guest-base (ie why we should retain the !CONFIG_USE_GUEST_BASE code in QEMU at all) ? It was originally optional because we didn't support it in all our TCG hosts, but we fixed that back in 2012... TCG generates less code, so performance is better (well, it is what I guess). I've compiled a kernel with and without guest base in a chrooted linux-user-qemu. Without guest base it is ~1 minute less for a 13 minutes build. I can do more tests if you want. Hmm. That's a fair chunk of speedup. On the downside: * you only get this if you're willing to build QEMU from source with funny options * it won't work for all guest/host combinations (sometimes the guest really wants to be able to map at low addresses the host won't permit) * it's an extra configuration to maintain which we're clearly not testing at all upstream I'd still favour removing it completely, personally... In fact, I have made more measurements, it saves only ~10 seconds on a 13 minutes build. my test is: make -j 4 vmlinux (target: m68k, host: x86_64, 4 cores x 2 threads) Note that on x86_64, guest base is implemented by using the gs segment register. That explains why the impact should be relatively low, as your test shows. I did a similar test on a PowerPC host, It is 2 seconds MORE on an 1m27s build WITH --disable-guest-base. So, definitively, I think the option can be dropped. Laurent
Re: [Qemu-devel] [PATCH v2] thread-win32: fix GetThreadContext() permanently fails
Am 01.07.2015 um 18:49 schrieb Paolo Bonzini: On 01/07/2015 17:48, Zavadovsky Yan wrote: Ping. Stefan, are you merging this? Paolo I can do so, but as the current code seems to fix the problems with multi-processor systems, too (even if it is unclear why), it does not look urgent. Fabien, you suggested extensive tests. Do you think that patch v2 is fine, or are you still waiting for test results? Stefan
Re: [Qemu-devel] [PATCH v3] pci : Add pba_offset PCI quirk for Chelsio T5 devices
What you are suggesting is: If table_offset is not as expected, then check if it's a chelsio device. If it's not, then print a message. On the other hand, if it's a chelsio device, then let msix_init() catch the error. Why ? And if we are sure that msix_init will error out, what's the purpose of the table_offset check ? The test needs only to check the pba_offset and reduced as following is enough ... /* * Test the size of the pba_offset variable and catch if it extends outside * of the specified BAR. If it is the case, we need to apply a hardware * specific quirk if the device is known or we have a broken configuration. */ if (vdev-msix-pba_offset = vdev-bars[vdev-msix-pba_bar].region.size) { PCIDevice *pdev = vdev-pdev; uint16_t vendor = pci_get_word(pdev-config + PCI_VENDOR_ID); uint16_t device = pci_get_word(pdev-config + PCI_DEVICE_ID); /* * Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5 * adapters. The T5 hardware returns an incorrect value of 0x8000 for * the VF PBA offset while the BAR itself is only 8k. The correct value * is 0x1000, so we hard code that here. */ if (vendor == PCI_VENDOR_ID_CHELSIO (device 0xff00) == 0x5800) { vdev-msix-pba_offset = 0x1000; } else { error_report(vfio: Hardware reports invalid configuration, MSIX data outside of specified BAR); return -EINVAL; } } ... As the hardware problem is only related with the pba_offset and the purpose of the quirk is to correct the known hardware error. The table_offset has never been seen as wrong. Therefore the msix_init() sanity check should take care of a rare potential error as you mentioned. This time I'll wait for ACKs from your side before submitting a new version :) Gabriel -Original Message- From: Bandan Das [mailto:b...@redhat.com] Sent: Tuesday, June 30, 2015 6:48 PM To: Gabriel Laupre Cc: jb-gnumli...@wisemo.com; Casey Leedom; m...@redhat.com; qemu-devel@nongnu.org; Anish Bhatt; Michael Boksanyi; alex.william...@redhat.com; b...@makefile.in Subject: Re: [Qemu-devel] [PATCH v3] pci : Add pba_offset PCI quirk for Chelsio T5 devices Gabriel Laupre glau...@chelsio.com writes: @ Bandan ... + + /* Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5 + * adapters. The T5 hardware returns an incorrect value of 0x8000 for + * the VF PBA offset. The correct value is 0x1000, so we hard code that + * here. */ + if (vendor == PCI_VENDOR_ID_CHELSIO (device 0xff00) == 0x5800) { + vdev-msix-pba_offset = 0x1000; For the rare case where table_offset is wrong for the device being checked for above and pba_offset is actually correct, shouldn't we fail ? I don't know if it is relevant to do all the tests here because in the function msix_init() all size are checked. I would prefer keeping this test as this to simplify the quirk, i.e. just testing the device first, and if another size than the pba_offset is wrong, then the sanity check in the function msix_init() will catch the error. Ok, here's the excerpt: +/* Test the size of the pba variables and catch if they extend outside of + * the specified BAR. If it is the case, we have a broken configuration or + * we need to apply a hardware specific quirk. */ +if (vdev-msix-table_offset = +vdev-bars[vdev-msix-table_bar].region.size || +vdev-msix-pba_offset = +vdev-bars[vdev-msix-pba_bar].region.size) { + +PCIDevice *pdev = vdev-pdev; +uint16_t vendor = pci_get_word(pdev-config + PCI_VENDOR_ID); +uint16_t device = pci_get_word(pdev-config + PCI_DEVICE_ID); + +/* Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5 + * adapters. The T5 hardware returns an incorrect value of 0x8000 for + * the VF PBA offset. The correct value is 0x1000, so we hard code that + * here. */ +if (vendor == PCI_VENDOR_ID_CHELSIO (device 0xff00) == 0x5800) { +vdev-msix-pba_offset = 0x1000; +} else { +error_report(vfio: Hardware reports invalid configuration, +MSIX data outside of specified BAR); +return -EINVAL; +} +} What you are suggesting is: If table_offset is not as expected, then check if it's a chelsio device. If it's not, then print a message. On the other hand, if it's a chelsio device, then let msix_init() catch the error. Why ? And if we are sure that msix_init will error out, what's the purpose of the table_offset check ? @ Alex I corrected what you pointed out. I will send the patch v4 in a minute. Thanks you Gabriel
Re: [Qemu-devel] [PATCH v3] pci : Add pba_offset PCI quirk for Chelsio T5 devices
On Wed, 2015-07-01 at 18:10 +, Gabriel Laupre wrote: What you are suggesting is: If table_offset is not as expected, then check if it's a chelsio device. If it's not, then print a message. On the other hand, if it's a chelsio device, then let msix_init() catch the error. Why ? And if we are sure that msix_init will error out, what's the purpose of the table_offset check ? The test needs only to check the pba_offset and reduced as following is enough ... /* * Test the size of the pba_offset variable and catch if it extends outside * of the specified BAR. If it is the case, we need to apply a hardware * specific quirk if the device is known or we have a broken configuration. */ if (vdev-msix-pba_offset = vdev-bars[vdev-msix-pba_bar].region.size) { PCIDevice *pdev = vdev-pdev; uint16_t vendor = pci_get_word(pdev-config + PCI_VENDOR_ID); uint16_t device = pci_get_word(pdev-config + PCI_DEVICE_ID); /* * Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5 * adapters. The T5 hardware returns an incorrect value of 0x8000 for * the VF PBA offset while the BAR itself is only 8k. The correct value * is 0x1000, so we hard code that here. */ if (vendor == PCI_VENDOR_ID_CHELSIO (device 0xff00) == 0x5800) { vdev-msix-pba_offset = 0x1000; } else { error_report(vfio: Hardware reports invalid configuration, MSIX data outside of specified BAR); return -EINVAL; } } ... As the hardware problem is only related with the pba_offset and the purpose of the quirk is to correct the known hardware error. The table_offset has never been seen as wrong. Therefore the msix_init() sanity check should take care of a rare potential error as you mentioned. This time I'll wait for ACKs from your side before submitting a new version :) I would s/data/PBA/ in the error_report text for this version. Thanks, Alex -Original Message- From: Bandan Das [mailto:b...@redhat.com] Sent: Tuesday, June 30, 2015 6:48 PM To: Gabriel Laupre Cc: jb-gnumli...@wisemo.com; Casey Leedom; m...@redhat.com; qemu-devel@nongnu.org; Anish Bhatt; Michael Boksanyi; alex.william...@redhat.com; b...@makefile.in Subject: Re: [Qemu-devel] [PATCH v3] pci : Add pba_offset PCI quirk for Chelsio T5 devices Gabriel Laupre glau...@chelsio.com writes: @ Bandan ... + + /* Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5 + * adapters. The T5 hardware returns an incorrect value of 0x8000 for + * the VF PBA offset. The correct value is 0x1000, so we hard code that + * here. */ + if (vendor == PCI_VENDOR_ID_CHELSIO (device 0xff00) == 0x5800) { + vdev-msix-pba_offset = 0x1000; For the rare case where table_offset is wrong for the device being checked for above and pba_offset is actually correct, shouldn't we fail ? I don't know if it is relevant to do all the tests here because in the function msix_init() all size are checked. I would prefer keeping this test as this to simplify the quirk, i.e. just testing the device first, and if another size than the pba_offset is wrong, then the sanity check in the function msix_init() will catch the error. Ok, here's the excerpt: +/* Test the size of the pba variables and catch if they extend outside of + * the specified BAR. If it is the case, we have a broken configuration or + * we need to apply a hardware specific quirk. */ +if (vdev-msix-table_offset = +vdev-bars[vdev-msix-table_bar].region.size || +vdev-msix-pba_offset = +vdev-bars[vdev-msix-pba_bar].region.size) { + +PCIDevice *pdev = vdev-pdev; +uint16_t vendor = pci_get_word(pdev-config + PCI_VENDOR_ID); +uint16_t device = pci_get_word(pdev-config + PCI_DEVICE_ID); + +/* Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5 + * adapters. The T5 hardware returns an incorrect value of 0x8000 for + * the VF PBA offset. The correct value is 0x1000, so we hard code that + * here. */ +if (vendor == PCI_VENDOR_ID_CHELSIO (device 0xff00) == 0x5800) { +vdev-msix-pba_offset = 0x1000; +} else { +error_report(vfio: Hardware reports invalid configuration, +MSIX data outside of specified BAR); +return -EINVAL; +} +} What you are suggesting is: If table_offset is not as expected, then check if it's a chelsio device. If it's not, then print a message. On the other hand, if it's a chelsio device, then let msix_init() catch the error. Why ? And if we are sure that msix_init will error out, what's the purpose of the table_offset check ? @ Alex I corrected what you pointed out. I will send the patch
[Qemu-devel] [PATCH v2 0/1] Add support for PCI Enhanced Allocation BARs
Changes from v1: - added a cover letter with a change log - made spelling fixes throughout patch - no longer add unnecessary whitespace - removed brackets in return calls - only add 1 PCI device parameter instead of 2 - don't add definitions to imported include/hw/pci/pci_regs.h Sean O. Stalley (1): Add support for PCI Enhanced Allocation BARs hw/pci/Makefile.objs| 2 +- hw/pci/pci.c| 95 +-- hw/pci/pci_ea.c | 202 include/hw/pci/pci.h| 6 ++ include/hw/pci/pci_ea.h | 42 ++ include/qemu/typedefs.h | 1 + 6 files changed, 324 insertions(+), 24 deletions(-) create mode 100644 hw/pci/pci_ea.c create mode 100644 include/hw/pci/pci_ea.h -- 1.9.1
Re: [Qemu-devel] [PATCH v3] pci : Add pba_offset PCI quirk for Chelsio T5 devices
Alex Williamson alex.william...@redhat.com writes: ... */ if (vendor == PCI_VENDOR_ID_CHELSIO (device 0xff00) == 0x5800) { vdev-msix-pba_offset = 0x1000; } else { error_report(vfio: Hardware reports invalid configuration, MSIX data outside of specified BAR); return -EINVAL; } } ... As the hardware problem is only related with the pba_offset and the purpose of the quirk is to correct the known hardware error. The table_offset has never been seen as wrong. Therefore the msix_init() sanity check should take care of a rare potential error as you mentioned. This time I'll wait for ACKs from your side before submitting a new version :) I would s/data/PBA/ in the error_report text for this version. Thanks, Looks good to me, Gabriel + what Alex mentioned above. Thanks, Bandan
Re: [Qemu-devel] [PATCH] qtest/ide: add another short PRDT test flavor
On 07/01/2015 01:09 PM, Stefan Hajnoczi wrote: The existing short PRDT test case does not transfer any data because the first PRD is less than 1 sector. This patch adds another short PRDT test case where the first sector can be read but the PRDT is still smaller than the requested number of sectors. This exercises a different code path in ide_dma_cb(). Cc: John Snow js...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- tests/ide-test.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/tests/ide-test.c b/tests/ide-test.c index 78382e9..4a07e3a 100644 --- a/tests/ide-test.c +++ b/tests/ide-test.c @@ -339,6 +339,31 @@ static void test_bmdma_short_prdt(void) assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR); } +static void test_bmdma_one_sector_short_prdt(void) +{ +uint8_t status; + +/* Read 2 sectors but only give 1 sector in PRDT */ +PrdtEntry prdt[] = { +{ +.addr = 0, +.size = cpu_to_le32(0x200 | PRDT_EOT), +}, +}; + +/* Normal request */ +status = send_dma_request(CMD_READ_DMA, 0, 2, + prdt, ARRAY_SIZE(prdt)); +g_assert_cmphex(status, ==, 0); +assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR); + +/* Abort the request before it completes */ +status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 2, + prdt, ARRAY_SIZE(prdt)); +g_assert_cmphex(status, ==, 0); +assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR); +} + static void test_bmdma_long_prdt(void) { uint8_t status; @@ -592,6 +617,8 @@ int main(int argc, char **argv) qtest_add_func(/ide/bmdma/setup, test_bmdma_setup); qtest_add_func(/ide/bmdma/simple_rw, test_bmdma_simple_rw); qtest_add_func(/ide/bmdma/short_prdt, test_bmdma_short_prdt); +qtest_add_func(/ide/bmdma/one_sector_short_prdt, + test_bmdma_one_sector_short_prdt); qtest_add_func(/ide/bmdma/long_prdt, test_bmdma_long_prdt); qtest_add_func(/ide/bmdma/no_busmaster, test_bmdma_no_busmaster); qtest_add_func(/ide/bmdma/teardown, test_bmdma_teardown); köszönöm! Reviewed-by: John Snow js...@redhat.com
Re: [Qemu-devel] [Qemu-block] [PATCH COLO-Block v6 07/16] Add new block driver interface to connect/disconnect the remote target
* Wen Congyang (we...@cn.fujitsu.com) wrote: On 07/01/2015 04:11 PM, Dr. David Alan Gilbert wrote: * Wen Congyang (we...@cn.fujitsu.com) wrote: On 07/01/2015 03:01 AM, Dr. David Alan Gilbert wrote: * Wen Congyang (we...@cn.fujitsu.com) wrote: On 06/27/2015 03:03 AM, Dr. David Alan Gilbert wrote: snip Ah, I hadn't realised you could do that; so do you just do: migrate_set_parameter colo on migrate -d -b tcp:otherhhost:port How does the secondary know to feed that data straight into the disk without recording all the old data into the hidden-disk ? hidden disk and active disk will be made empty when starting block replication. Hmm, yes - I think I need to update to your current world; in the version from the end of May, I get a 'error while loading state for instance 0x0 of device 'block'' if I try to use migrate -d -b (the bdrv_write fails) Can you give me both primary and secondary qemu's command? I think the command line is wrong, and disk migration fails. Primary: ./try/bin/qemu-system-x86_64 -enable-kvm -nographic \ -boot c -m 4096 -smp 4 -S \ -name debug-threads=on -trace events=trace-file \ -netdev tap,id=hn0,script=$PWD/ifup-prim,\ downscript=no,colo_script=$PWD/qemu/scripts/colo-proxy-script.sh,colo_nicname=em4 \ -device e1000,mac=9c:da:4d:1c:b5:89,id=net-pci0,netdev=hn0 \ -drive if=virtio,driver=quorum,read-pattern=fifo,no-connect=on,\ cache=none,aio=native,\ children.0.file.filename=./bugzilla.raw,\ children.0.driver=raw,\ children.1.file.driver=nbd,\ children.1.file.host=ibpair,\ children.1.file.port=8889,\ children.1.file.export=colo1,\ children.1.driver=replication,\ children.1.mode=primary,\ children.1.ignore-errors=on Add id=nbd_target1 to primary disk option, and try it. Disk migration needs the same id to sync the disk. Thank you! That worked nicely. The only odd thing was that the hidden disk on the secondary went upto ~2GB in size during the disk copy; (This is still on the version you posted at the end of may). I don't really understand why it was 2GB - the disk was 40GB, and qemu-img tells me that 2.6GB of it were used. Still, it would be good to avoid the overhead of going through the hidden disk on the secondary for the initial replication. Dave Thanks Wen Congyang Secondary: ./try/bin/qemu-system-x86_64 -enable-kvm -nographic \ -boot c -m 4096 -smp 4 -S \ -name debug-threads=on -trace events=trace-file \ -netdev tap,id=hn0,script=$PWD/ifup-slave,\ downscript=no,colo_script=$PWD/qemu/scripts/colo-proxy-script.sh,colo_nicname=em4 \ -device e1000,mac=9c:da:4d:1c:b5:89,id=net-pci0,netdev=hn0 \ -drive if=none,driver=raw,file=bugzilla.raw,id=nbd_target1,cache=none,aio=native \ -drive if=virtio,driver=replication,mode=secondary,export=colo1,throttling.bps-total-max=7000,\ file.file.filename=/run/colo-active-disk.qcow2,\ file.driver=qcow2,\ file.backing_reference.drive_id=nbd_target1,\ file.backing_reference.hidden-disk.file.filename=/run/colo-hidden-disk.qcow2,\ file.backing_reference.hidden-disk.driver=qcow2,\ file.backing_reference.hidden-disk.allow-write-backing-file=on \ -incoming tcp:0: Thanks, Dave If the user uses mirror job, we don't cancel the mirror job now. It would be good to get it to work with mirror, that seems preferred these days to the old block migration. In normal migration, is mirror job created and cancelled by libvirt? Yes, I think so; you should be able to turn on full logging on libvirt and watch the qmp commands it sends. Supporting mirror job in my TODO list now. But I think we should focus the basci function now. Thanks Wen Congyang Dave -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK . -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK . -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [Qemu-devel] [Qemu-discuss] GRO not happening in VM with VxLAN
Since the vxlan UDP header checksum is 0, udp_tunnel_gro_complete (called via vxlan_gro_complete) is setting SKB_GSO_UDP_TUNNEL in skb_shinfo(skb)-gso_type. Later when bridge interface tries to forward this packet to tap interface (br_dev_queue_push_xmit - __dev_queue_xmit - validate_xmit_skb) netif_needs_gso will succeed (skb_gso_ok returns 0) resulting in packet segmentation (which was earlier aggregated) as tap interface doesn't have this feature. Is there a way to enable tx-udp_tnl-segmentation for tap interface? # ethtool -K tap0 tx-udp_tnl-segmentation on Could not change any device features # ethtool -k tap0 | grep -i tnl tx-udp_tnl-segmentation: off [fixed] On Tue, Jun 30, 2015 at 12:24 PM, Santosh R skrasta...@gmail.com wrote: On Mon, Jun 29, 2015 at 9:24 PM, Santosh R skrasta...@gmail.com wrote: On Mon, Jun 29, 2015 at 9:04 PM, Vlad Yasevich vyase...@redhat.com wrote: On 06/29/2015 01:46 AM, Santosh R wrote: All, I am testing VxLAN performance in VM. For this I am using below command to bring up the VM. # qemu-system-x86_64 -m 4096 -smp 4 -boot c -device virtio-net-pci,netdev=tap0,mac=00:11:22:33:44:55 -netdev tap,id=tap0,script=no,vhost=on -drive file=/root/vdisk_rhel65.img This is resulting in lower throughput in VM. On looking further I found that GRO is not happing on the tap interface. Using tcpdump I could see GRO happeing in physcial nic, vxlan and bridge interface. but _not_ on tap interface. I don't think this is GRO. GRO only happens at the lowest possible layer. For packets coming from external sources, that happens just above the nic when the packet enters the host for the first time. From then on, the features of other devices determine if the large aggregated packet will be segmented again or not. So, I thought to use veth pair instead of the tap interface in VM. What is the command to do this? veth pair will not help with this. you need a tap or a macvtap to have VM talk to host. Also, 1. Why is rx-checksumming off for tap interface? because tap doesn't do checksum validation. it allows lower level devices or VM to do so. 2. Why is GRO not happening with tap interface? Again. I don't think it's GRO. Try capturing traffic at tap and see if you get large packets (more the 1 mtu long) on the tap. If not, then someone else is fragmenting packets and you need to find who. [Santosh]: Thanks for the reply. With VxLAN, aggregated packets are seen on physical, VxLAN and bridge interface but _not_ on the tap interface. Without VxLAN, I do see aggregated (GRO) packets all the way upto VM (i.e. physical, bridge and tap interface). As you rightly pointed, looks like VxLAN packets are getting fragmented. Any pointers to look for? By the way, I was referring below link for VxLAN testing and ran into the GRO issue. This mentions The veth0 is suppose to be connected to the VM, while the veth1 is connected to the Linux bridge. https://community.mellanox.com/docs/DOC-1473
Re: [Qemu-devel] [PATCH v2 1/1] KVM s390 pci infrastructure modelling
On 7/1/2015 17:22, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 05:13:11PM +0800, Hong Bo Li wrote: On 7/1/2015 16:05, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 03:56:25PM +0800, Hong Bo Li wrote: On 7/1/2015 14:22, Michael S. Tsirkin wrote: On Tue, Jun 30, 2015 at 02:16:59PM +0800, Hong Bo Li wrote: On 6/29/2015 18:01, Michael S. Tsirkin wrote: On Mon, Jun 29, 2015 at 05:24:53PM +0800, Hong Bo Li wrote: This patch introduce a new facility(and bus) to hold devices representing information actually provided by s390 firmware and I/O configuration. usage example: -device s390-pcihost -device vfio-pci,host=:00:00.0,id=vpci1 -device zpci,fid=2,uid=5,pci_id=vpci1,id=zpci1 The first line will create a s390 pci host bridge and init the root bus. The second line will create a standard vfio pci device, and attach it to the root bus. These are similiar to the standard process to define a pci device on other platform. The third line will create a s390 pci device to store s390 specific information, and references the corresponding vfio pci device via device id. We create a s390 pci facility bus to hold all the zpci devices. Signed-off-by: Hong Bo Li lih...@linux.vnet.ibm.com It's mostly up to s390 maintainers, but I'd like to note one thing below --- hw/s390x/s390-pci-bus.c| 314 + hw/s390x/s390-pci-bus.h| 48 ++- hw/s390x/s390-pci-inst.c | 4 +- hw/s390x/s390-virtio-ccw.c | 5 +- 4 files changed, 283 insertions(+), 88 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 560b66a..d5e7b2e 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -32,8 +32,8 @@ int chsc_sei_nt2_get_event(void *res) PciCcdfErr *eccdf; int rc = 1; SeiContainer *sei_cont; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return rc; @@ -72,8 +72,8 @@ int chsc_sei_nt2_get_event(void *res) int chsc_sei_nt2_have_event(void) { -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return 0; @@ -82,20 +82,32 @@ int chsc_sei_nt2_have_event(void) return !QTAILQ_EMPTY(s-pending_sei); } +void s390_pci_device_enable(S390PCIBusDevice *zpci) +{ +zpci-fh = zpci-fh | 1 ENABLE_BIT_OFFSET; +} + +void s390_pci_device_disable(S390PCIBusDevice *zpci) +{ +zpci-fh = zpci-fh ~(1 ENABLE_BIT_OFFSET); +if (zpci-is_unplugged) +object_unparent(OBJECT(zpci)); +} + S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid) { S390PCIBusDevice *pbdev; -int i; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +BusChild *kid; +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return NULL; } -for (i = 0; i PCI_SLOT_MAX; i++) { -pbdev = s-pbdev[i]; -if ((pbdev-fh != 0) (pbdev-fid == fid)) { +QTAILQ_FOREACH(kid, s-fbus-qbus.children, sibling) { +pbdev = (S390PCIBusDevice *)kid-child; +if (pbdev-fid == fid) { return pbdev; } } @@ -126,39 +138,24 @@ void s390_pci_sclp_configure(int configure, SCCB *sccb) return; } -static uint32_t s390_pci_get_pfid(PCIDevice *pdev) -{ -return PCI_SLOT(pdev-devfn); -} - -static uint32_t s390_pci_get_pfh(PCIDevice *pdev) -{ -return PCI_SLOT(pdev-devfn) | FH_VIRT; -} - S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx) { S390PCIBusDevice *pbdev; -int i; -int j = 0; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +BusChild *kid; +int i = 0; +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return NULL; } -for (i = 0; i PCI_SLOT_MAX; i++) { -pbdev = s-pbdev[i]; - -if (pbdev-fh == 0) { -continue; -} - -if (j == idx) { +QTAILQ_FOREACH(kid, s-fbus-qbus.children, sibling) { +pbdev = (S390PCIBusDevice *)kid-child; +if (i == idx) { return pbdev; } -j++; +i++; } return NULL; This relies on the order of children on the qbus, that's wrong I think. Generally I'm not sure why do you convert all slot lookups to child lookups: more code to achieve the same effect? Thank you Michael. I do the change due to two reasons: 1. The old implement only supports one s390 pci root bus, and 32(PCI_SLOT_MAX) slots at most. So when it comes to multiple s390 pci root
Re: [Qemu-devel] [PATCH 09/12] migration: Use always helper to set state
On 07/01/2015 04:51 PM, Juan Quintela wrote: There were three places that were not using the migrate_set_state() helper, just fix that. Signed-off-by: Juan Quintela quint...@redhat.com Reviewed-by: Yang Hongyang yan...@cn.fujitsu.com --- migration/migration.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index c5b778b..a8d2da5 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -548,7 +548,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); } @@ -633,7 +633,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); @@ -732,7 +732,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } else { error_setg(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; } -- Thanks, Yang.
Re: [Qemu-devel] [PATCH 1/1] s390x/migration: Introduce 2.4 machine
Am 01.07.2015 um 11:56 schrieb Juan Quintela: Christian Borntraeger borntrae...@de.ibm.com wrote: First of all Reviewed-by: Juan Quintela quint...@redhat.com For the patch. But one said that, I don't agree with the commint text. So let's just drop this sentence While one can argue that section footer should be enabled explicitely for new versions instead of disabled for old ones, And rephrase to This pinpoints to a problem of s390-ccw-machines: it needs to be versioned to allow common code changes to add compat handling. Conny, want me to resend or can you fixup the patch description when taking this patch? The section footer changes commit f68945d42bab (Add a protective section footer) and commit 37fb569c0198 (Disable section footers on older machine types) broke migration for any non-versioned machines. If broke migration for 2.4 - 2.3 for machines that don't care about compatibility. If they care, they are versioned O:-) Right now ppc x86. I guess that s390 and arm will follow in due curse. yes. That is what my 2nd sentence says: we are not versioned and that is the main issue to solve. this pinpoints to a problem of s390-ccw-machines: it needs to be versioned to be compatible with future changes in common code data structures such as section footers. It is done explicitely the other way around. New way is the default way. If we did it in a special way in the past, we add a switch. If at some point we remove the old machine type for any reason, we don't have to change anything on $latest. Basically the idea here is that (until now) only x86 cared about backwards compatibility, so when a migration changed happened because it was good for any reason, normal devices do changes, and then x86 try to fix the pieces after the fact. That is going to continue, just that now more architectures care, and then we should detect this kind of problems much earlier. Let's introduce a version scheme for s390-ccw-virtio machines. We will use the old s390-ccw-virtio name as alias to the latest version as all existing libvirt XML for the ccw type were expanded by libvirt to that name. The only downside of this patch is, that the old alias s390-ccw will no longer be available as machines can have only one alias, but it should not really matter. Should we change to a list? list of aliases? Why not, we would use it.
Re: [Qemu-devel] [PATCH RFC 0/4] vGICv3 support
On Fri, May 22, 2015 at 01:58:40PM +0300, Pavel Fedin wrote: This is my alternative to Ashok's vGICv3 patch (https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg03021.html), which i am currently working on. It addresses vGIC capability verification issue (kvm_irqchip_create() / kvm_arch_irqchip_create()), as well as offers better code structure (v3 code separated from v2). This patchset applies on top of this: https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg00943.html. Note that GIC type selection still relies on machine name (virt-v3 vs virt), and not on machine option. Since libvirt has recently introduced support for extra options, i have absolutely nothing against Ashok's approach. I just did not change this yet because it would affect my testing environment. The aim of this RFC is to focus on vGICv3 implementation and related changes. And yes, i agree that v2 and v3 now have some copypasted code, and this is TBD. This cover letter is not really helpful as it only describes the history and circumstances of how this patch came to be. It would be helpful if the beginning of this cover letter focuses on what the patch series does and which design decisions have been taken to shape the patches the way they are. I don't understand the whole background thing about libvirt and I don't at all understand the thing about copy-pasted code...?? A generally good approach to writing a cover letter is to follow this skeleton: --- This series implements...what We accomplish this by...design decisions [Optional] Patches 1-3 do something preliminary, patches 4-8 do something else... [Optional] Note something special, possibly historical Changes since vX: --- I think it would be good if you could re-spin this series based on Eric's comments on the code, my comments on the patch style, and Peter's advise on using machine properties for GICv3. Do you have cycles to continue working on this? -Christoffer Pavel Fedin (4): Add virt-v3 machine that uses GIC-500 Set kernel_irqchip_type for other ARM boards which use GIC First bits of vGICv3 support: Initial implementation of vGICv3. hw/arm/exynos4_boards.c | 1 + hw/arm/realview.c | 1 + hw/arm/vexpress.c | 1 + hw/arm/virt.c | 148 - hw/intc/Makefile.objs | 1 + hw/intc/arm_gicv3_kvm.c | 283 include/hw/boards.h | 1 + include/sysemu/kvm.h| 3 +- kvm-all.c | 2 +- stubs/kvm.c | 2 +- target-arm/kvm.c| 8 +- 11 files changed, 419 insertions(+), 32 deletions(-) create mode 100644 hw/intc/arm_gicv3_kvm.c -- 1.9.5.msysgit.0
[Qemu-devel] [PULL 10/26] Rework ram block hash
From: Dr. David Alan Gilbert dgilb...@redhat.com RDMA uses a hash from block offset-RAM Block; this isn't needed on the destination, and it becomes harder to maintain after the next patch in the series that sorts the block list. Split the hash so that it's only generated on the source. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Signed-off-by: Juan Quintela quint...@redhat.com --- migration/rdma.c | 32 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index 347d380..a652e67 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -534,23 +534,22 @@ static int rdma_add_block(RDMAContext *rdma, const char *block_name, ram_addr_t block_offset, uint64_t length) { RDMALocalBlocks *local = rdma-local_ram_blocks; -RDMALocalBlock *block = g_hash_table_lookup(rdma-blockmap, -(void *)(uintptr_t)block_offset); +RDMALocalBlock *block; RDMALocalBlock *old = local-block; -assert(block == NULL); - local-block = g_malloc0(sizeof(RDMALocalBlock) * (local-nb_blocks + 1)); if (local-nb_blocks) { int x; -for (x = 0; x local-nb_blocks; x++) { -g_hash_table_remove(rdma-blockmap, -(void *)(uintptr_t)old[x].offset); -g_hash_table_insert(rdma-blockmap, -(void *)(uintptr_t)old[x].offset, -local-block[x]); +if (rdma-blockmap) { +for (x = 0; x local-nb_blocks; x++) { +g_hash_table_remove(rdma-blockmap, +(void *)(uintptr_t)old[x].offset); +g_hash_table_insert(rdma-blockmap, +(void *)(uintptr_t)old[x].offset, +local-block[x]); +} } memcpy(local-block, old, sizeof(RDMALocalBlock) * local-nb_blocks); g_free(old); @@ -572,7 +571,9 @@ static int rdma_add_block(RDMAContext *rdma, const char *block_name, block-is_ram_block = local-init ? false : true; -g_hash_table_insert(rdma-blockmap, (void *) block_offset, block); +if (rdma-blockmap) { +g_hash_table_insert(rdma-blockmap, (void *) block_offset, block); +} trace_rdma_add_block(block_name, local-nb_blocks, (uintptr_t) block-local_host_addr, @@ -608,7 +609,6 @@ static int qemu_rdma_init_ram_blocks(RDMAContext *rdma) RDMALocalBlocks *local = rdma-local_ram_blocks; assert(rdma-blockmap == NULL); -rdma-blockmap = g_hash_table_new(g_direct_hash, g_direct_equal); memset(local, 0, sizeof *local); qemu_ram_foreach_block(qemu_rdma_init_one_block, rdma); trace_qemu_rdma_init_ram_blocks(local-nb_blocks); @@ -2300,6 +2300,14 @@ static int qemu_rdma_source_init(RDMAContext *rdma, Error **errp, bool pin_all) goto err_rdma_source_init; } +/* Build the hash that maps from offset to RAMBlock */ +rdma-blockmap = g_hash_table_new(g_direct_hash, g_direct_equal); +for (idx = 0; idx rdma-local_ram_blocks.nb_blocks; idx++) { +g_hash_table_insert(rdma-blockmap, +(void *)(uintptr_t)rdma-local_ram_blocks.block[idx].offset, +rdma-local_ram_blocks.block[idx]); +} + for (idx = 0; idx RDMA_WRID_MAX; idx++) { ret = qemu_rdma_reg_control(rdma, idx); if (ret) { -- 2.4.3
[Qemu-devel] [PULL 26/26] 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 quint...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- migration/migration.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/migration/migration.c b/migration/migration.c index d8415c4..c41779f 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -222,6 +222,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)) { @@ -250,7 +251,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); @@ -258,10 +259,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] [PULL 14/26] Fix older machine type compatibility on power with section footers
From: Dr. David Alan Gilbert dgilb...@redhat.com I forgot to add compatibility for Power when adding section footers. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Fixes: 37fb569c0198cba58e3e Signed-off-by: Juan Quintela quint...@redhat.com --- hw/ppc/spapr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f174e5a..01f8da8 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -34,6 +34,7 @@ #include sysemu/cpus.h #include sysemu/kvm.h #include kvm_ppc.h +#include migration/migration.h #include mmu-hash64.h #include qom/cpu.h @@ -1851,6 +1852,7 @@ static const TypeInfo spapr_machine_info = { static void spapr_compat_2_3(Object *obj) { +savevm_skip_section_footers(); } static void spapr_compat_2_2(Object *obj) -- 2.4.3
[Qemu-devel] [PULL 06/26] Store block name in local blocks structure
From: Dr. David Alan Gilbert dgilb...@redhat.com In a later patch the block name will be used to match up two views of the block list. Keep a copy of the block name with the local block list. (At some point it could be argued that it would be best just to let migration see the innards of RAMBlock and avoid the need to use foreach). Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reviewed-by: Michael R. Hines mrhi...@us.ibm.com Signed-off-by: Juan Quintela quint...@redhat.com --- migration/rdma.c | 35 +-- trace-events | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index fc6b81c..6fa9601 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -215,17 +215,18 @@ static void network_to_caps(RDMACapabilities *cap) * the information. It's small anyway, so a list is overkill. */ typedef struct RDMALocalBlock { -uint8_t *local_host_addr; /* local virtual address */ -uint64_t remote_host_addr; /* remote virtual address */ -uint64_t offset; -uint64_t length; -struct ibv_mr **pmr; /* MRs for chunk-level registration */ -struct ibv_mr *mr; /* MR for non-chunk-level registration */ -uint32_t *remote_keys; /* rkeys for chunk-level registration */ -uint32_t remote_rkey; /* rkeys for non-chunk-level registration */ -int index;/* which block are we */ -bool is_ram_block; -int nb_chunks; +char *block_name; +uint8_t *local_host_addr; /* local virtual address */ +uint64_t remote_host_addr; /* remote virtual address */ +uint64_t offset; +uint64_t length; +struct ibv_mr **pmr;/* MRs for chunk-level registration */ +struct ibv_mr *mr; /* MR for non-chunk-level registration */ +uint32_t *remote_keys; /* rkeys for chunk-level registration */ +uint32_t remote_rkey; /* rkeys for non-chunk-level registration */ +intindex; /* which block are we */ +bool is_ram_block; +intnb_chunks; unsigned long *transit_bitmap; unsigned long *unregister_bitmap; } RDMALocalBlock; @@ -511,7 +512,8 @@ static inline uint8_t *ram_chunk_end(const RDMALocalBlock *rdma_ram_block, return result; } -static int rdma_add_block(RDMAContext *rdma, void *host_addr, +static int rdma_add_block(RDMAContext *rdma, const char *block_name, + void *host_addr, ram_addr_t block_offset, uint64_t length) { RDMALocalBlocks *local = rdma-local_ram_blocks; @@ -539,6 +541,7 @@ static int rdma_add_block(RDMAContext *rdma, void *host_addr, block = local-block[local-nb_blocks]; +block-block_name = g_strdup(block_name); block-local_host_addr = host_addr; block-offset = block_offset; block-length = length; @@ -554,7 +557,8 @@ static int rdma_add_block(RDMAContext *rdma, void *host_addr, g_hash_table_insert(rdma-blockmap, (void *) block_offset, block); -trace_rdma_add_block(local-nb_blocks, (uintptr_t) block-local_host_addr, +trace_rdma_add_block(block_name, local-nb_blocks, + (uintptr_t) block-local_host_addr, block-offset, block-length, (uintptr_t) (block-local_host_addr + block-length), BITS_TO_LONGS(block-nb_chunks) * @@ -574,7 +578,7 @@ static int rdma_add_block(RDMAContext *rdma, void *host_addr, static int qemu_rdma_init_one_block(const char *block_name, void *host_addr, ram_addr_t block_offset, ram_addr_t length, void *opaque) { -return rdma_add_block(opaque, host_addr, block_offset, length); +return rdma_add_block(opaque, block_name, host_addr, block_offset, length); } /* @@ -636,6 +640,9 @@ static int rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset) g_free(block-remote_keys); block-remote_keys = NULL; +g_free(block-block_name); +block-block_name = NULL; + for (x = 0; x local-nb_blocks; x++) { g_hash_table_remove(rdma-blockmap, (void *)(uintptr_t)old[x].offset); } diff --git a/trace-events b/trace-events index 55c4272..c0b9105 100644 --- a/trace-events +++ b/trace-events @@ -1458,7 +1458,7 @@ qemu_rdma_write_one_recvregres(int mykey, int theirkey, uint64_t chunk) Receive qemu_rdma_write_one_sendreg(uint64_t chunk, int len, int index, int64_t offset) Sending registration request chunk % PRIu64 for %d bytes, index: %d, offset: % PRId64 qemu_rdma_write_one_top(uint64_t chunks, uint64_t size) Writing % PRIu64 chunks, (% PRIu64 MB) qemu_rdma_write_one_zero(uint64_t chunk, int len, int index, int64_t offset) Entire chunk is zero, sending compress: % PRIu64 for %d bytes, index: %d, offset: % PRId64 -rdma_add_block(int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int
Re: [Qemu-devel] [PATCH RFC 0/4] vGICv3 support
On Wed, Jul 01, 2015 at 02:14:55PM +0300, Pavel Fedin wrote: Hello! I think it would be good if you could re-spin this series based on Eric's comments on the code, my comments on the patch style, and Peter's advise on using machine properties for GICv3. There was a discussion about this, and i tried to add a machine property instead. This gave bad results: https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg04842.html Do you have cycles to continue working on this? Yes, i do. And i wish to work on this, since upstreaming this is a goal of my project. I know that descriptions were bad, and actually they were parts of ongoing discussions. Actually i am waiting for integration of Shlomo Pongratz' series: http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg01512.html. Posted as standalone, my series collide with Shlomo's series (it actually relies on some parts from there), so i prefer to respin on top of something clean. I thought the general sense here was that since emulating the full device is much more complicated than driving the KVM part, the integration with the virt board should go in via this series, and the emulation should build on top of that? Of course, if the full emulation series is almost ready to be merged that's a different story. It just felt like both patch series have stalled somehow, and I would like to see what we can do to get this stuff moving again. The first patch from the mentioned series is already in master; Peter told me that he doesn't want to add the complete GICv3 before qemu 2.4 is released: https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg04171.html So waiting... Fair enough. -Christoffer
[Qemu-devel] [PATCH v15 01/21] i386: partial revert of interrupt poll fix
Processing CPU_INTERRUPT_POLL requests in cpu_has_work functions break the determinism of cpu_exec. This patch is required to make interrupts processing deterministic. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- cpu-exec.c|6 ++ target-i386/cpu.c | 10 ++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 2ffeb6e..8f93df7 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -365,6 +365,12 @@ int cpu_exec(CPUArchState *env) volatile bool have_tb_lock = false; if (cpu-halted) { +#ifdef TARGET_I386 +if (cpu-interrupt_request CPU_INTERRUPT_POLL) { +apic_poll_irq(x86_cpu-apic_state); +cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL); +} +#endif if (!cpu_has_work(cpu)) { return EXCP_HALTED; } diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 36b07f9..8b57580 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3094,14 +3094,8 @@ static bool x86_cpu_has_work(CPUState *cs) X86CPU *cpu = X86_CPU(cs); CPUX86State *env = cpu-env; -#if !defined(CONFIG_USER_ONLY) -if (cs-interrupt_request CPU_INTERRUPT_POLL) { -apic_poll_irq(cpu-apic_state); -cpu_reset_interrupt(cs, CPU_INTERRUPT_POLL); -} -#endif - -return ((cs-interrupt_request CPU_INTERRUPT_HARD) +return ((cs-interrupt_request (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_POLL)) (env-eflags IF_MASK)) || (cs-interrupt_request (CPU_INTERRUPT_NMI | CPU_INTERRUPT_INIT |
[Qemu-devel] [PATCH 04/12] qga: rename 'path' to 'device_path'
'path' is already a global function, rename the variable since it's going to be in global scope in a later patch. Signed-off-by: Marc-André Lureau marcandre.lur...@gmail.com --- qga/main.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qga/main.c b/qga/main.c index 0c455f8..1c81575 100644 --- a/qga/main.c +++ b/qga/main.c @@ -944,7 +944,7 @@ static GList *split_list(gchar *str, const gchar separator) int main(int argc, char **argv) { const char *sopt = hVvdm:p:l:f:F::b:s:t:; -const char *method = NULL, *path = NULL; +const char *method = NULL, *device_path = NULL; const char *log_filepath = NULL; const char *pid_filepath; #ifdef CONFIG_FSFREEZE @@ -990,7 +990,7 @@ int main(int argc, char **argv) method = optarg; break; case 'p': -path = optarg; +device_path = optarg; break; case 'l': log_filepath = optarg; @@ -1040,7 +1040,8 @@ int main(int argc, char **argv) if (ga_install_vss_provider()) { exit(EXIT_FAILURE); } -if (ga_install_service(path, log_filepath, fixed_state_dir)) { +if (ga_install_service(device_path, log_filepath, + fixed_state_dir)) { exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); @@ -1185,7 +1186,7 @@ int main(int argc, char **argv) #endif s-main_loop = g_main_loop_new(NULL, false); -if (!channel_init(ga_state, method, path)) { +if (!channel_init(ga_state, method, device_path)) { g_critical(failed to initialize guest agent channel); goto out_bad; } -- 2.4.3
[Qemu-devel] [PATCH v15 17/21] typedef: add typedef for QemuOpts
This patch moves typedefs for QemuOpts and related types to qemu/typedefs.h file. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- include/qemu/option.h |5 + include/qemu/typedefs.h |3 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index 57e51c9..71f5f27 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -30,6 +30,7 @@ #include qemu/queue.h #include qapi/error.h #include qapi/qmp/qdict.h +#include qemu/typedefs.h const char *get_opt_name(char *buf, int buf_size, const char *p, char delim); const char *get_opt_value(char *buf, int buf_size, const char *p); @@ -44,10 +45,6 @@ void parse_option_size(const char *name, const char *value, bool has_help_option(const char *param); bool is_valid_option_list(const char *param); -typedef struct QemuOpt QemuOpt; -typedef struct QemuOpts QemuOpts; -typedef struct QemuOptsList QemuOptsList; - enum QemuOptType { QEMU_OPT_STRING = 0, /* no parsing (use string as-is) */ QEMU_OPT_BOOL,/* on/off */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 6fdcbcd..74e2c9c 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -66,6 +66,9 @@ typedef struct QEMUBH QEMUBH; typedef struct QemuConsole QemuConsole; typedef struct QEMUFile QEMUFile; typedef struct QEMUMachine QEMUMachine; +typedef struct QemuOpt QemuOpt; +typedef struct QemuOpts QemuOpts; +typedef struct QemuOptsList QemuOptsList; typedef struct QEMUSGList QEMUSGList; typedef struct QEMUSizedBuffer QEMUSizedBuffer; typedef struct QEMUTimerListGroup QEMUTimerListGroup;
[Qemu-devel] [PATCH v15 21/21] replay: recording of the user input
This records user input (keyboard and mouse events) in record mode and replays these input events in replay mode. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- include/ui/input.h |2 + replay/Makefile.objs |1 replay/replay-events.c | 31 + replay/replay-input.c| 159 ++ replay/replay-internal.h | 13 replay/replay.h |4 + ui/input.c | 27 +--- 7 files changed, 229 insertions(+), 8 deletions(-) create mode 100755 replay/replay-input.c diff --git a/include/ui/input.h b/include/ui/input.h index 5d5ac00..d06a12d 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -33,7 +33,9 @@ void qemu_input_handler_bind(QemuInputHandlerState *s, const char *device_id, int head, Error **errp); void qemu_input_event_send(QemuConsole *src, InputEvent *evt); +void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt); void qemu_input_event_sync(void); +void qemu_input_event_sync_impl(void); InputEvent *qemu_input_event_new_key(KeyValue *key, bool down); void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down); diff --git a/replay/Makefile.objs b/replay/Makefile.objs index 257c320..3936296 100755 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -2,3 +2,4 @@ obj-y += replay.o obj-y += replay-internal.o obj-y += replay-events.o obj-y += replay-time.o +obj-y += replay-input.o diff --git a/replay/replay-events.c b/replay/replay-events.c index 1e14cce..6cf13f2 100755 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -14,6 +14,7 @@ #include replay.h #include replay-internal.h #include block/aio.h +#include ui/input.h typedef struct Event { ReplayAsyncEventKind event_kind; @@ -39,6 +40,13 @@ static void replay_run_event(Event *event) case REPLAY_ASYNC_EVENT_PTIMER: aio_bh_call(event-opaque); break; +case REPLAY_ASYNC_EVENT_INPUT: +qemu_input_event_send_impl(NULL, (InputEvent *)event-opaque); +qapi_free_InputEvent((InputEvent *)event-opaque); +break; +case REPLAY_ASYNC_EVENT_INPUT_SYNC: +qemu_input_event_sync_impl(); +break; default: error_report(Replay: invalid async event ID (%d) in the queue, event-event_kind); @@ -132,6 +140,16 @@ void replay_add_ptimer_event(void *bh, uint64_t id) replay_add_event_internal(REPLAY_ASYNC_EVENT_PTIMER, bh, NULL, id); } +void replay_add_input_event(struct InputEvent *event) +{ +replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT, event, NULL, 0); +} + +void replay_add_input_sync_event(void) +{ +replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT_SYNC, NULL, NULL, 0); +} + static void replay_save_event(Event *event, int checkpoint) { if (replay_mode != REPLAY_MODE_PLAY) { @@ -145,6 +163,9 @@ static void replay_save_event(Event *event, int checkpoint) case REPLAY_ASYNC_EVENT_PTIMER: replay_put_qword(event-id); break; +case REPLAY_ASYNC_EVENT_INPUT: +replay_save_input_event(event-opaque); +break; } } } @@ -185,6 +206,16 @@ static Event *replay_read_event(int checkpoint) read_id = replay_get_qword(); } break; +case REPLAY_ASYNC_EVENT_INPUT: +event = g_malloc0(sizeof(Event)); +event-event_kind = read_event_kind; +event-opaque = replay_read_input_event(); +return event; +case REPLAY_ASYNC_EVENT_INPUT_SYNC: +event = g_malloc0(sizeof(Event)); +event-event_kind = read_event_kind; +event-opaque = 0; +return event; default: error_report(Unknown ID %d of replay event, read_event_kind); exit(1); diff --git a/replay/replay-input.c b/replay/replay-input.c new file mode 100755 index 000..54923b9 --- /dev/null +++ b/replay/replay-input.c @@ -0,0 +1,159 @@ +/* + * replay-input.c + * + * Copyright (c) 2010-2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include qemu-common.h +#include replay.h +#include replay-internal.h +#include ui/input.h +#include qapi/qmp-output-visitor.h +#include qapi/qmp-input-visitor.h +#include qapi-visit.h + +static InputEvent *qapi_clone_InputEvent(InputEvent *src) +{ +QmpOutputVisitor *qov; +QmpInputVisitor *qiv; +Visitor *ov, *iv; +QObject *obj; +InputEvent *dst = NULL; + +qov = qmp_output_visitor_new(); +ov = qmp_output_get_visitor(qov); +visit_type_InputEvent(ov, src, NULL, error_abort); +obj = qmp_output_get_qobject(qov); +qmp_output_visitor_cleanup(qov); +if (!obj) { +return NULL; +} + +qiv = qmp_input_visitor_new(obj); +iv =
[Qemu-devel] [PATCH v15 11/21] replay: asynchronous events infrastructure
This patch adds module for saving and replaying asynchronous events. These events include network packets, keyboard and mouse input, USB packets, thread pool and bottom halves callbacks. All events are stored in the queue to be processed at synchronization points such as beginning of TB execution, or checkpoint in the iothread. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- replay/Makefile.objs |1 replay/replay-events.c | 227 ++ replay/replay-internal.h | 31 ++ replay/replay.h |6 + 4 files changed, 265 insertions(+), 0 deletions(-) create mode 100755 replay/replay-events.c diff --git a/replay/Makefile.objs b/replay/Makefile.objs index 1148f45..56da09c 100755 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -1,2 +1,3 @@ obj-y += replay.o obj-y += replay-internal.o +obj-y += replay-events.o diff --git a/replay/replay-events.c b/replay/replay-events.c new file mode 100755 index 000..409c9ad --- /dev/null +++ b/replay/replay-events.c @@ -0,0 +1,227 @@ +/* + * replay-events.c + * + * Copyright (c) 2010-2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include qemu-common.h +#include qemu/error-report.h +#include replay.h +#include replay-internal.h + +typedef struct Event { +ReplayAsyncEventKind event_kind; +void *opaque; +void *opaque2; +uint64_t id; + +QTAILQ_ENTRY(Event) events; +} Event; + +static QTAILQ_HEAD(, Event) events_list = QTAILQ_HEAD_INITIALIZER(events_list); +static unsigned int read_event_kind = -1; +static uint64_t read_id = -1; +static int read_checkpoint = -1; + +static bool events_enabled = false; + +/* Functions */ + +static void replay_run_event(Event *event) +{ +switch (event-event_kind) { +default: +error_report(Replay: invalid async event ID (%d) in the queue, +event-event_kind); +exit(1); +break; +} +} + +void replay_enable_events(void) +{ +events_enabled = true; +} + +bool replay_has_events(void) +{ +return !QTAILQ_EMPTY(events_list); +} + +void replay_flush_events(void) +{ +replay_mutex_lock(); +while (!QTAILQ_EMPTY(events_list)) { +Event *event = QTAILQ_FIRST(events_list); +replay_mutex_unlock(); +replay_run_event(event); +replay_mutex_lock(); +QTAILQ_REMOVE(events_list, event, events); +g_free(event); +} +replay_mutex_unlock(); +} + +void replay_disable_events(void) +{ +if (replay_mode != REPLAY_MODE_NONE) { +events_enabled = false; +/* Flush events queue before waiting of completion */ +replay_flush_events(); +} +} + +void replay_clear_events(void) +{ +replay_mutex_lock(); +while (!QTAILQ_EMPTY(events_list)) { +Event *event = QTAILQ_FIRST(events_list); +QTAILQ_REMOVE(events_list, event, events); + +g_free(event); +} +replay_mutex_unlock(); +} + +static void replay_add_event_internal(ReplayAsyncEventKind event_kind, + void *opaque, + void *opaque2, uint64_t id) +{ +if (event_kind = REPLAY_ASYNC_COUNT) { +error_report(Replay: invalid async event ID (%d), event_kind); +exit(1); +} +if (!replay_file || replay_mode == REPLAY_MODE_NONE +|| !events_enabled) { +Event e; +e.event_kind = event_kind; +e.opaque = opaque; +e.opaque2 = opaque2; +e.id = id; +replay_run_event(e); +return; +} + +Event *event = g_malloc0(sizeof(Event)); +event-event_kind = event_kind; +event-opaque = opaque; +event-opaque2 = opaque2; +event-id = id; + +replay_mutex_lock(); +QTAILQ_INSERT_TAIL(events_list, event, events); +replay_mutex_unlock(); +} + +void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque) +{ +replay_add_event_internal(event_kind, opaque, NULL, 0); +} + +static void replay_save_event(Event *event, int checkpoint) +{ +if (replay_mode != REPLAY_MODE_PLAY) { +/* put the event into the file */ +replay_put_event(EVENT_ASYNC); +replay_put_byte(checkpoint); +replay_put_byte(event-event_kind); + +/* save event-specific data */ +switch (event-event_kind) { +} +} +} + +/* Called with replay mutex locked */ +void replay_save_events(int checkpoint) +{ +while (!QTAILQ_EMPTY(events_list)) { +Event *event = QTAILQ_FIRST(events_list); +replay_save_event(event, checkpoint); + +replay_mutex_unlock(); +replay_run_event(event); +replay_mutex_lock(); +QTAILQ_REMOVE(events_list, event, events); +g_free(event); +} +} + +static Event *replay_read_event(int
Re: [Qemu-devel] [PATCH RFC 4/6] xen: Print and use errno where applicable.
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: In Xen 4.6 commit cd2f100f0f61b3f333d52d1737dd73f02daee592 libxc: Fix do_memory_op to return negative value on errors made the libxc API less odd-ball: On errors, return value is -1 and error code is in errno. On success the return value is either 0 or an positive value. Since we could be running with an old toolstack in which the Exx value is in rc or the newer, we print both and return the -EXX depending on rc == -1 condition. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com --- xen-hvm.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xen-hvm.c b/xen-hvm.c index 0408462..a92bc14 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -345,11 +345,12 @@ go_physmap: unsigned long idx = pfn + i; xen_pfn_t gpfn = start_gpfn + i; +/* In Xen 4.6 rc is -1 and errno contains the error value. */ rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); if (rc) { DPRINTF(add_to_physmap MFN %PRI_xen_pfn to PFN % -PRI_xen_pfn failed: %d\n, idx, gpfn, rc); -return -rc; +PRI_xen_pfn failed: %d (errno: %d)\n, idx, gpfn, rc, errno); +return rc == -1 ? -errno : -rc; Printing both rc and errno is the right thing to do, but I am not sure changing return value depending on the libxc version is a good idea. Maybe we should be consistent and always return rc? } } @@ -422,11 +423,12 @@ static int xen_remove_from_physmap(XenIOState *state, xen_pfn_t idx = start_addr + i; xen_pfn_t gpfn = phys_offset + i; +/* In Xen 4.6 rc is -1 and errno contains the error value. */ rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); if (rc) { fprintf(stderr, add_to_physmap MFN %PRI_xen_pfn to PFN % -PRI_xen_pfn failed: %d\n, idx, gpfn, rc); -return -rc; +PRI_xen_pfn failed: %d (errno: %d)\n, idx, gpfn, rc, errno); +return rc == -1 ? -errno : -rc; } } -- 2.1.0
Re: [Qemu-devel] [PATCH RFC 6/6] xen: Add backtrace for serious issues.
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: When debugging issues that caused the emulator to kill itself or skipping certain operations (unable to write to host registers) an stack trace will most definitly aid in debugging the problem. As such this patch uses the most basic backtrace to print out details. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com I think it could be useful, but it cannot be done as a xen-hvm.c thing. It should be somewhere generic, maybe under util? Stefan, any suggestions? hw/xen/xen_pt.c | 3 +++ include/hw/xen/xen_common.h | 1 + xen-hvm.c | 16 3 files changed, 20 insertions(+) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index ea1ceda..1d256b9 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -407,6 +407,7 @@ out: if (rc 0) { XEN_PT_ERR(d, xen_host_pci_set_block failed. return value: %d.\n, rc); +xen_dump_stack(); } } } @@ -421,6 +422,7 @@ static uint64_t xen_pt_bar_read(void *o, hwaddr addr, * misconfiguration of the IOMMU. */ XEN_PT_ERR(d, Should not read BAR through QEMU. @0xTARGET_FMT_plx\n, addr); +xen_dump_stack(); return 0; } static void xen_pt_bar_write(void *o, hwaddr addr, uint64_t val, @@ -430,6 +432,7 @@ static void xen_pt_bar_write(void *o, hwaddr addr, uint64_t val, /* Same comment as xen_pt_bar_read function */ XEN_PT_ERR(d, Should not write BAR through QEMU. @0xTARGET_FMT_plx\n, addr); +xen_dump_stack(); } static const MemoryRegionOps ops = { diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 38f29fb..3983cfb 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -165,6 +165,7 @@ void destroy_hvm_domain(bool reboot); /* shutdown/destroy current domain because of an error */ void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +void xen_dump_stack(void); #ifdef HVM_PARAM_VMPORT_REGS_PFN static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, diff --git a/xen-hvm.c b/xen-hvm.c index a92bc14..8bf4a57 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -10,6 +10,7 @@ #include sys/mman.h +#include execinfo.h #include hw/pci/pci.h #include hw/i386/pc.h #include hw/xen/xen_common.h @@ -1328,6 +1329,20 @@ void xen_register_framebuffer(MemoryRegion *mr) framebuffer = mr; } +void xen_dump_stack(void) +{ +int nptrs; +#define SIZE 1024 +void *buffer[SIZE]; + +nptrs = backtrace(buffer, SIZE); +if (!nptrs) +return; + +backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO); +#undef SIZE +} + void xen_shutdown_fatal_error(const char *fmt, ...) { va_list ap; @@ -1335,6 +1350,7 @@ void xen_shutdown_fatal_error(const char *fmt, ...) va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); +xen_dump_stack(); fprintf(stderr, Will destroy the domain.\n); /* destroy the domain */ qemu_system_shutdown_request(); -- 2.1.0
Re: [Qemu-devel] [PATCH] linux-user: Avoid compilation error with --disable-guest-base
On 2015-07-01 01:58, Laurent Vivier wrote: Le 30/06/2015 19:20, Peter Maydell a écrit : On 30 June 2015 at 18:13, Laurent Vivier laur...@vivier.eu wrote: Le 30/06/2015 18:45, Peter Maydell a écrit : On 30 June 2015 at 17:19, Laurent Vivier laur...@vivier.eu wrote: When guest base is disabled, RESERVED_VA is 0, and (__guest RESERVED_VA) is always false as __guest is unsigned. With -Werror=type-limits, this triggers an error: include/exec/cpu_ldst.h:60:31: error: comparison of unsigned expression 0 is always false [-Werror=type-limits] (!RESERVED_VA || (__guest RESERVED_VA)); \ This patch removes this comparison when guest base is disabled. Is there a useful reason to compile with --disable-guest-base (ie why we should retain the !CONFIG_USE_GUEST_BASE code in QEMU at all) ? It was originally optional because we didn't support it in all our TCG hosts, but we fixed that back in 2012... TCG generates less code, so performance is better (well, it is what I guess). I've compiled a kernel with and without guest base in a chrooted linux-user-qemu. Without guest base it is ~1 minute less for a 13 minutes build. I can do more tests if you want. Hmm. That's a fair chunk of speedup. On the downside: * you only get this if you're willing to build QEMU from source with funny options * it won't work for all guest/host combinations (sometimes the guest really wants to be able to map at low addresses the host won't permit) * it's an extra configuration to maintain which we're clearly not testing at all upstream I'd still favour removing it completely, personally... In fact, I have made more measurements, it saves only ~10 seconds on a 13 minutes build. my test is: make -j 4 vmlinux (target: m68k, host: x86_64, 4 cores x 2 threads) Note that on x86_64, guest base is implemented by using the gs segment register. That explains why the impact should be relatively low, as your test shows. --enable-guest-base real13m26.134s13m28.712s 13m28.053s 13m28.875s user52m44.882s52m56.075s 52m49.223s 52m55.366s sys 0m33.452s 0m33.613s 0m33.013s 0m33.336s --disable-guest-base real13m20.412s13m17.773s 13m15.836s 13m13.278s user52m23.165s52m7.184s 52m1.547s 51m50.277s sys 0m33.427s 0m33.392s 0m32.954s 0m33.430s Laurent -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH pic32 v2 4/5] Two new processor variants: M4K and microAptivP.
On 2015-06-30 21:12, Serge Vakulenko wrote: Signed-off-by: Serge Vakulenko serge.vakule...@gmail.com --- target-mips/cpu.h| 2 ++ target-mips/translate_init.c | 46 2 files changed, 48 insertions(+) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index ab830ee..9f5890c 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -394,6 +394,7 @@ struct CPUMIPSState { #define CP0C0_M31 #define CP0C0_K23 28 #define CP0C0_KU 25 +#define CP0C0_SB 21 Bits in the range 16:24 are implementation specific, so I do wonder if we want to have this bit there. At least we should mark it as implementation specific. #define CP0C0_MDU 20 #define CP0C0_MM 17 #define CP0C0_BM 16 @@ -479,6 +480,7 @@ struct CPUMIPSState { #define CP0C5_NFExists 0 int32_t CP0_Config6; int32_t CP0_Config7; +#define CP0C7_WII31 Same as above, Config6 and Config7 are implementation dependent. /* XXX: Maybe make LLAddr per-TC? */ uint64_t lladdr; target_ulong llval; diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index ddfaff8..430a547 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -232,6 +232,52 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_FMT, }, { +/* Configuration for Microchip PIC32MX microcontroller. */ +.name = M4K, +.CP0_PRid = 0x00018765, +.CP0_Config0 = MIPS_CONFIG0 | (2 CP0C0_K23) | (2 CP0C0_KU) | + (1 CP0C0_SB) | (1 CP0C0_BM) | + (1 CP0C0_AR) | (MMU_TYPE_FMT CP0C0_MT), +.CP0_Config1 = (1U CP0C1_M) | (1 CP0C1_CA) | (1 CP0C1_EP), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = (1 CP0C3_VEIC) | (1 CP0C3_VInt), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 4, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x1258FF17, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MIPS16, +.mmu_type = MMU_TYPE_FMT, +}, +{ +/* Configuration for Microchip PIC32MZ microcontroller. */ +.name = microAptivP, +.CP0_PRid = 0x00019e28, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | +(MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (15 CP0C1_MMU) | (1 CP0C1_PC), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = (1 CP0C3_M) | (1 CP0C3_IPLW) | (1 CP0C3_MCU) | +(2 CP0C3_ISA) | (1 CP0C3_ULRI) | (1 CP0C3_RXI) | +(1 CP0C3_DSP2P) | (1 CP0C3_DSPP) | (1 CP0C3_VEIC) | +(1 CP0C3_VInt), DSP and DSPr2 are enabled here... +.CP0_Config4 = (1 CP0C4_M), +.CP0_Config5 = (1 CP0C5_NFExists), +.CP0_Config6 = 0, +.CP0_Config7 = (1 CP0C7_WII), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 4, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x1278FF17, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2, so I guess you want to enable ASE_DSP and ASE_DSPR2 here. +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = 24Kc, .CP0_PRid = 0x00019300, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | Otherwise it looks ok, though I haven't look at the PIC32 manual to check the values. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH] target-mips: fix MIPS64R6-generic configuration
On 01/07/2015 14:48, Aurelien Jarno wrote: On 2015-06-29 10:11, Yongbok Kim wrote: Fix core configuration for MIPS64R6-generic to make it as close as I6400. I6400 core has 48-bit of Virtual Address available (SEGBITS). MIPS SIMD Architecture is available. Rearrange order of bits to match the specification. Signed-off-by: Yongbok Kim yongbok@imgtec.com --- target-mips/mips-defs.h |2 +- target-mips/translate_init.c | 18 +- 2 files changed, 10 insertions(+), 10 deletions(-) Reviewed-by: Aurelien Jarno aurel...@aurel32.net That said given we are getting closer to the I6400 CPU model, shouldn't we try to directly model a I6400 core (even if we have to disable some features like IEEE 754-2008 FP) instead of a generic MIPS64R6 core? I fully agree with that but detailed specification of I6400 has not been published yet, therefore for the time being we will need to use the generic core name. However we could rename mips32r5-generic into P5600 with such restrictions - Hardware page table walk, Virtualization, EVA. What do you think? Regards, Yongbok
Re: [Qemu-devel] [PATCH RFC 1 7/8] xen/pt: Move bulk of xen_pt_unregister_device in its own routine.
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: This way we can call it if we fail during init. This code movement introduces no changes. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com Acked-by: Stefano Stabellini stefano.stabell...@eu.citrix.com hw/xen/xen_pt.c | 119 +--- 1 file changed, 62 insertions(+), 57 deletions(-) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index cda6a2d..589c6c6 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -686,6 +686,67 @@ static const MemoryListener xen_pt_io_listener = { .priority = 10, }; +/* destroy. */ +static void xen_pt_destroy(PCIDevice *d) { + +XenPCIPassthroughState *s = XEN_PT_DEVICE(d); +uint8_t machine_irq = s-machine_irq; +uint8_t intx; +int rc; + + /* Note that if xen_host_pci_device_put had closed config_fd, then + * intx value becomes 0xff. */ +intx = xen_pt_pci_intx(s); +if (machine_irq !xen_host_pci_device_closed(s-real_device)) { +rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq, + PT_IRQ_TYPE_PCI, + pci_bus_num(d-bus), + PCI_SLOT(s-dev.devfn), + intx, + 0 /* isa_irq */); +if (rc 0) { +XEN_PT_ERR(d, unbinding of interrupt INT%c failed. +(machine irq: %i, err: %d) +But bravely continuing on..\n, + 'a' + intx, machine_irq, errno); +} +} + +/* N.B. xen_pt_config_delete takes care of freeing them. */ +if (s-msi) { +xen_pt_msi_disable(s); +} +if (s-msix) { +xen_pt_msix_disable(s); +} + +if (machine_irq) { +xen_pt_mapped_machine_irq[machine_irq]--; + +if (xen_pt_mapped_machine_irq[machine_irq] == 0) { +rc = xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq); + +if (rc 0) { +XEN_PT_ERR(d, unmapping of interrupt %i failed. (err: %d) +But bravely continuing on..\n, + machine_irq, errno); +} +} +s-machine_irq = 0; +} + +/* delete all emulated config registers */ +xen_pt_config_delete(s); + +if (s-listener_set) { +memory_listener_unregister(s-memory_listener); +memory_listener_unregister(s-io_listener); +s-listener_set = false; +} +if (!xen_host_pci_device_closed(s-real_device)) { +xen_host_pci_device_put(s-real_device); +} +} /* init */ static int xen_pt_initfn(PCIDevice *d) @@ -820,63 +881,7 @@ out: static void xen_pt_unregister_device(PCIDevice *d) { -XenPCIPassthroughState *s = XEN_PT_DEVICE(d); -uint8_t machine_irq = s-machine_irq; -uint8_t intx; -int rc; - - /* Note that if xen_host_pci_device_put had closed config_fd, then - * intx value becomes 0xff. */ -intx = xen_pt_pci_intx(s); -if (machine_irq !xen_host_pci_device_closed(s-real_device)) { -rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq, - PT_IRQ_TYPE_PCI, - pci_bus_num(d-bus), - PCI_SLOT(s-dev.devfn), - intx, - 0 /* isa_irq */); -if (rc 0) { -XEN_PT_ERR(d, unbinding of interrupt INT%c failed. -(machine irq: %i, err: %d) -But bravely continuing on..\n, - 'a' + intx, machine_irq, errno); -} -} - -/* N.B. xen_pt_config_delete takes care of freeing them. */ -if (s-msi) { -xen_pt_msi_disable(s); -} -if (s-msix) { -xen_pt_msix_disable(s); -} - -if (machine_irq) { -xen_pt_mapped_machine_irq[machine_irq]--; - -if (xen_pt_mapped_machine_irq[machine_irq] == 0) { -rc = xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq); - -if (rc 0) { -XEN_PT_ERR(d, unmapping of interrupt %i failed. (err: %d) -But bravely continuing on..\n, - machine_irq, errno); -} -} -s-machine_irq = 0; -} - -/* delete all emulated config registers */ -xen_pt_config_delete(s); - -if (s-listener_set) { -memory_listener_unregister(s-memory_listener); -memory_listener_unregister(s-io_listener); -s-listener_set = false; -} -if (!xen_host_pci_device_closed(s-real_device)) { -xen_host_pci_device_put(s-real_device); -} +xen_pt_destroy(d); } static Property
Re: [Qemu-devel] [PATCH] target-mips: fix MIPS64R6-generic configuration
On 2015-07-01 14:57, Yongbok Kim wrote: On 01/07/2015 14:48, Aurelien Jarno wrote: On 2015-06-29 10:11, Yongbok Kim wrote: Fix core configuration for MIPS64R6-generic to make it as close as I6400. I6400 core has 48-bit of Virtual Address available (SEGBITS). MIPS SIMD Architecture is available. Rearrange order of bits to match the specification. Signed-off-by: Yongbok Kim yongbok@imgtec.com --- target-mips/mips-defs.h |2 +- target-mips/translate_init.c | 18 +- 2 files changed, 10 insertions(+), 10 deletions(-) Reviewed-by: Aurelien Jarno aurel...@aurel32.net That said given we are getting closer to the I6400 CPU model, shouldn't we try to directly model a I6400 core (even if we have to disable some features like IEEE 754-2008 FP) instead of a generic MIPS64R6 core? I fully agree with that but detailed specification of I6400 has not been published yet, therefore for the time being we will need to use the generic Oh ok. core name. However we could rename mips32r5-generic into P5600 with such restrictions - Hardware page table walk, Virtualization, EVA. What do you think? I think it's a good idea, as long as we keep the config register in sync with what is actually implemented. That also reminds me that we should look at implementing hardware page table walk. That should be relatively easy to implement, and provide a huge performance boost (exceptions cost a lot on QEMU). -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH] target-mips: fix MIPS64R6-generic configuration
On 2015-06-29 10:11, Yongbok Kim wrote: Fix core configuration for MIPS64R6-generic to make it as close as I6400. I6400 core has 48-bit of Virtual Address available (SEGBITS). MIPS SIMD Architecture is available. Rearrange order of bits to match the specification. Signed-off-by: Yongbok Kim yongbok@imgtec.com --- target-mips/mips-defs.h |2 +- target-mips/translate_init.c | 18 +- 2 files changed, 10 insertions(+), 10 deletions(-) Reviewed-by: Aurelien Jarno aurel...@aurel32.net That said given we are getting closer to the I6400 CPU model, shouldn't we try to directly model a I6400 core (even if we have to disable some features like IEEE 754-2008 FP) instead of a generic MIPS64R6 core? diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h index 20aa87c..53b185e 100644 --- a/target-mips/mips-defs.h +++ b/target-mips/mips-defs.h @@ -11,7 +11,7 @@ #if defined(TARGET_MIPS64) #define TARGET_LONG_BITS 64 #define TARGET_PHYS_ADDR_SPACE_BITS 48 -#define TARGET_VIRT_ADDR_SPACE_BITS 42 +#define TARGET_VIRT_ADDR_SPACE_BITS 48 #else #define TARGET_LONG_BITS 32 #define TARGET_PHYS_ADDR_SPACE_BITS 40 diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index ddfaff8..9304e74 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -655,14 +655,14 @@ static const mips_def_t mips_defs[] = (2 CP0C1_DS) | (4 CP0C1_DL) | (3 CP0C1_DA) | (0 CP0C1_PC) | (1 CP0C1_WR) | (1 CP0C1_EP), .CP0_Config2 = MIPS_CONFIG2, -.CP0_Config3 = MIPS_CONFIG3 | (1 CP0C3_RXI) | (1 CP0C3_BP) | - (1 CP0C3_BI) | (1 CP0C3_ULRI) | (1 CP0C3_LPA) | - (1U CP0C3_M), -.CP0_Config4 = MIPS_CONFIG4 | (0xfc CP0C4_KScrExist) | - (3 CP0C4_IE) | (1 CP0C4_M), +.CP0_Config3 = MIPS_CONFIG3 | (1U CP0C3_M) | (1 CP0C3_MSAP) | + (1 CP0C3_BP) | (1 CP0C3_BI) | (1 CP0C3_ULRI) | + (1 CP0C3_RXI) | (1 CP0C3_LPA), +.CP0_Config4 = MIPS_CONFIG4 | (1U CP0C4_M) | (3 CP0C4_IE) | + (0xfc CP0C4_KScrExist), .CP0_Config5 = MIPS_CONFIG5 | (1 CP0C5_LLB), -.CP0_Config5_rw_bitmask = (1 CP0C5_SBRI) | (1 CP0C5_FRE) | - (1 CP0C5_UFE), +.CP0_Config5_rw_bitmask = (1 CP0C5_MSAEn) | (1 CP0C5_SBRI) | + (1 CP0C5_FRE) | (1 CP0C5_UFE), .CP0_LLAddr_rw_bitmask = 0, .CP0_LLAddr_shift = 0, .SYNCI_Step = 32, @@ -674,9 +674,9 @@ static const mips_def_t mips_defs[] = .CP1_fcr0 = (1 FCR0_FREP) | (1 FCR0_F64) | (1 FCR0_L) | (1 FCR0_W) | (1 FCR0_D) | (1 FCR0_S) | (0x00 FCR0_PRID) | (0x0 FCR0_REV), -.SEGBITS = 42, +.SEGBITS = 48, .PABITS = 48, -.insn_flags = CPU_MIPS64R6, +.insn_flags = CPU_MIPS64R6 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, { -- 1.7.5.4 -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH RFC 1 3/8] xen/pt: Check if reg-init is past the reg-size
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: It should never happen, but in case it does we want to report. The code will only write up to reg-size so there is no runtime danger. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com --- hw/xen/xen_pt_config_init.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index 91c3a14..bc871c9 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -1901,9 +1901,13 @@ static int xen_pt_config_reg_init(XenPCIPassthroughState *s, } else val = data; +if (val size_mask) { +XEN_PT_ERR(s-dev,Offset 0x%04x:0x%04u expands past register size(%d)!\n, + offset, val, reg-size); should we return early? +} /* This could be just pci_set_long as we don't modify the bits - * past reg-size, but in case this routine is run in parallel - * we do not want to over-write other registers. */ + * past reg-size, but in case this routine is run in parallel or the + * init value is larger, we do not want to over-write registers. */ switch (reg-size) { case 1: pci_set_byte(s-dev.config + offset, (uint8_t)val); break; case 2: pci_set_word(s-dev.config + offset, (uint16_t)val); break; -- 2.1.0
[Qemu-devel] [Bug 1470481] [NEW] qemu-img converts large vhd files into only approx. 127GB raw file causing the VM to crash
Public bug reported: I have a VHD file for Windows 2014 server OS. I use the following command to convert VHD file (20GB) to a RAW file for KVM. qemu-img convert -f vpc -O raw WIN-SNRGCQV6O3O.VHD disk.img The output file is about 127GB. When install the VM and boot it up, the OS crashes with STOP error after the intial screen. I found on the internet that the file limit of 127GB is an existing bug. Kindly fix the problem. The workaround to use a Hyper-V to convert to fixed disk is not a feasible solution. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1470481 Title: qemu-img converts large vhd files into only approx. 127GB raw file causing the VM to crash Status in QEMU: New Bug description: I have a VHD file for Windows 2014 server OS. I use the following command to convert VHD file (20GB) to a RAW file for KVM. qemu-img convert -f vpc -O raw WIN-SNRGCQV6O3O.VHD disk.img The output file is about 127GB. When install the VM and boot it up, the OS crashes with STOP error after the intial screen. I found on the internet that the file limit of 127GB is an existing bug. Kindly fix the problem. The workaround to use a Hyper-V to convert to fixed disk is not a feasible solution. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1470481/+subscriptions
Re: [Qemu-devel] [PATCH v2 02/22] virtio: run drivers in 32bit mode
On Wed, Jul 01, 2015 at 03:50:50PM +0200, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 02:30:29PM +0200, Gerd Hoffmann wrote: On Mi, 2015-07-01 at 10:08 +0200, Michael S. Tsirkin wrote: On Tue, Jun 30, 2015 at 10:38:53AM +0200, Gerd Hoffmann wrote: virtio version 1.0 registers can (and actually do in the qemu implementation) live in mmio space. So we must run the blk and scsi virtio drivers in 32bit mode, otherwise we can't access them. This also allows to drop a bunch of GET_LOWFLAT calls from the virtio code in the following patches. Signed-off-by: Gerd Hoffmann kra...@redhat.com Is there an advantage to running them in a 16 bit mode? Not really any more. Switching from 32bit mode back to whatever-was-active-before used to be problematic before we had smm mode support. In theory. Because you can't save/restore the complete x86 processor state. In practice we had surprisingly few problems, appearently linux boot loaders simply don't play dirty tricks. cheers, Gerd Interesting. Might not be true for non-linux loaders :) Anyway we support SSM now so all should be well, right? Also a question: what's cheaper on kvm: use SMM to save/restore or access device through the config cap? -- MST
Re: [Qemu-devel] [PATCH RFC 1 5/8] xen/pt: Log xen_host_pci_get/set errors in MSI code.
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: We seem to only use these functions when de-activating the MSI - so just log errors. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com Reviewed-by: Stefano Stabellini stefano.stabell...@eu.citrix.com hw/xen/xen_pt_msi.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c index 5822df5..e3d7194 100644 --- a/hw/xen/xen_pt_msi.c +++ b/hw/xen/xen_pt_msi.c @@ -75,19 +75,29 @@ static int msi_msix_enable(XenPCIPassthroughState *s, bool enable) { uint16_t val = 0; +int rc; if (!address) { return -1; } -xen_host_pci_get_word(s-real_device, address, val); +rc = xen_host_pci_get_word(s-real_device, address, val); +if (rc) { +XEN_PT_ERR(s-dev, Failed to read MSI/MSI-X register (0x%x), rc:%d\n, + address, rc); +return rc; +} if (enable) { val |= flag; } else { val = ~flag; } -xen_host_pci_set_word(s-real_device, address, val); -return 0; +rc = xen_host_pci_set_word(s-real_device, address, val); +if (rc) { +XEN_PT_ERR(s-dev, Failed to write MSI/MSI-X register (0x%x), rc:%d\n, + address, rc); +} +return rc; } static int msi_msix_setup(XenPCIPassthroughState *s, @@ -276,7 +286,7 @@ void xen_pt_msi_disable(XenPCIPassthroughState *s) return; } -xen_pt_msi_set_enable(s, false); +(void)xen_pt_msi_set_enable(s, false); msi_msix_disable(s, msi_addr64(msi), msi-data, msi-pirq, false, msi-initialized); -- 2.1.0
Re: [Qemu-devel] [PATCH v8 3/3] ich9: implement strap SPKR pin logic
On Wed, Jul 01, 2015 at 03:18:41PM +0200, Paolo Bonzini wrote: On 28/06/2015 19:58, Paulo Alcantara wrote: If the signal is sampled high, this indicates that the system is strapped to the No Reboot mode (ICH9 will disable the TCO Timer system reboot feature). The status of this strap is readable via the NO_REBOOT bit (CC: offset 0x3410:bit 5). The NO_REBOOT bit is set when SPKR pin on ICH9 is sampled high. This bit may be set or cleared by software if the strap is sampled low but may not override the strap when it indicates No Reboot. This patch implements the logic where hardware has ability to set SPKR pin through a property named noreboot and it's sampled high by default. I know Michael suggested this, but I think default high is a worse default. It does not allow recovering from a hard lockup where you cannot process an NMI, unlike all other watchdogs implemented by QEMU. In fact, the Linux driver fails to start if the strap is high. My theory is that hardware manufacturers should only set the strap high if they want the firmware to have total control of the watchdog via SMIs (TCO_EN). If it is just a matter of being late in 2.4, just delay everything to 2.5. It doesn't require any more work from Paulo, as you can just flip the default yourself without adding a new machine type (in fact I'm still not sure why machine types for Q35 are versioned, since migration is not supported...). Paolo I don't think we should defer the whole series because of the argument about the default. I've merged these patches, I you like, pls send a one-line patch on top to flip the default with some info on how it was tested, and we can discuss it separately. Makes sense? BTW 2.4 makes qemu versioned because ahci finally supports migration so yes, we'll have to version from now on. Signed-off-by: Paulo Alcantara pca...@zytor.com --- v7 - v8: * change property name to noreboot * default noreboot property to high * define property in dc-props * update tco tests to support and exercise noreboot property --- hw/acpi/tco.c | 2 +- hw/isa/lpc_ich9.c | 6 ++ include/hw/i386/ich9.h | 5 + tests/tco-test.c | 18 -- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/hw/acpi/tco.c b/hw/acpi/tco.c index 1794a54..7a026c2 100644 --- a/hw/acpi/tco.c +++ b/hw/acpi/tco.c @@ -64,7 +64,7 @@ static void tco_timer_expired(void *opaque) tr-tco.sts2 |= TCO_BOOT_STS; tr-timeouts_no = 0; -if (!(gcs ICH9_CC_GCS_NO_REBOOT)) { +if (!lpc-pin_strap.spkr_hi !(gcs ICH9_CC_GCS_NO_REBOOT)) { watchdog_perform_action(); tco_timer_stop(tr); return; diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index b547002..3b460d4 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -688,6 +688,11 @@ static const VMStateDescription vmstate_ich9_lpc = { } }; +static Property ich9_lpc_properties[] = { +DEFINE_PROP_BOOL(noreboot, ICH9LPCState, pin_strap.spkr_hi, true), +DEFINE_PROP_END_OF_LIST(), +}; + static void ich9_lpc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -699,6 +704,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data) dc-reset = ich9_lpc_reset; k-init = ich9_lpc_init; dc-vmsd = vmstate_ich9_lpc; +dc-props = ich9_lpc_properties; k-config_write = ich9_lpc_config_write; dc-desc = ICH9 LPC bridge; k-vendor_id = PCI_VENDOR_ID_INTEL; diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index f5681a3..63c5cd8 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -46,6 +46,11 @@ typedef struct ICH9LPCState { ICH9LPCPMRegs pm; uint32_t sci_level; /* track sci level */ +/* 2.24 Pin Straps */ +struct { +bool spkr_hi; +} pin_strap; + /* 10.1 Chipset Configuration registers(Memory Space) which is pointed by RCBA */ uint8_t chip_config[ICH9_CC_SIZE]; diff --git a/tests/tco-test.c b/tests/tco-test.c index 1a2fe3d..6a48188 100644 --- a/tests/tco-test.c +++ b/tests/tco-test.c @@ -42,6 +42,7 @@ enum { typedef struct { const char *args; +bool noreboot; QPCIDevice *dev; void *lpc_base; void *tco_io_base; @@ -53,7 +54,9 @@ static void test_init(TestData *d) QTestState *qs; char *s; -s = g_strdup_printf(-machine q35 %s, !d-args ? : d-args); +s = g_strdup_printf(-machine q35 %s %s, +d-noreboot ? : -global ICH9-LPC.noreboot=false, +!d-args ? : d-args); qs = qtest_start(s); qtest_irq_intercept_in(qs, ioapic); g_free(s); @@ -135,6 +138,7 @@ static void test_tco_defaults(void) TestData d;
Re: [Qemu-devel] [PATCH RFC 1 4/8] xen/pt: Log xen_host_pci_get in two init functions
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: To help with troubleshooting in the field. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com Acked-by: Stefano Stabellini stefano.stabell...@eu.citrix.com hw/xen/xen_pt_config_init.c | 9 + 1 file changed, 9 insertions(+) diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index bc871c9..62b6a7b 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -1776,6 +1776,8 @@ static int xen_pt_ptr_reg_init(XenPCIPassthroughState *s, rc = xen_host_pci_get_byte(s-real_device, reg_field + PCI_CAP_LIST_ID, cap_id); if (rc) { +XEN_PT_ERR(s-dev, Failed to read capability @0x%x (rc:%d)\n, + reg_field + PCI_CAP_LIST_ID, rc); return rc; } if (xen_pt_emu_reg_grps[i].grp_id == cap_id) { @@ -1959,6 +1961,9 @@ int xen_pt_config_init(XenPCIPassthroughState *s) reg_grp_offset, reg_grp_entry-size); if (rc 0) { +XEN_PT_LOG(s-dev, Failed to initialize %d/%ld, type=0x%x, rc:%d\n, + i, ARRAY_SIZE(xen_pt_emu_reg_grps), + xen_pt_emu_reg_grps[i].grp_type, rc); xen_pt_config_delete(s); return rc; } @@ -1973,6 +1978,10 @@ int xen_pt_config_init(XenPCIPassthroughState *s) /* initialize capability register */ rc = xen_pt_config_reg_init(s, reg_grp_entry, regs); if (rc 0) { +XEN_PT_LOG(s-dev, Failed to initialize %d/%ld reg 0x%x in grp_type=0x%x (%d/%ld), rc=%d\n, + j, ARRAY_SIZE(xen_pt_emu_reg_grps[i].emu_regs), + regs-offset, xen_pt_emu_reg_grps[i].grp_type, + i, ARRAY_SIZE(xen_pt_emu_reg_grps), rc); xen_pt_config_delete(s); return rc; } -- 2.1.0
Re: [Qemu-devel] [PATCH v3 1/5] cpu: Provide vcpu throttling interface
On 25/06/2015 19:46, Jason J. Herne wrote: +static void cpu_throttle_thread(void *opaque) +{ +long sleeptime_ms = (long)(throttle_ratio * CPU_THROTTLE_TIMESLICE); + +qemu_mutex_unlock_iothread(); +g_usleep(sleeptime_ms * 1000); /* Convert ms to us for usleep call */ +qemu_mutex_lock_iothread(); + +timer_mod(throttle_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + + CPU_THROTTLE_TIMESLICE); The timer need not run while the VM is stopped. Please use QEMU_CLOCK_VIRTUAL_RT. +} + Are you sure you want each CPU to set the timer? I think this should be done in cpu_throttle_timer_pop, or it could use timer_mod_anticipate. +static void cpu_throttle_timer_pop(void *opaque) +{ +CPUState *cpu; + +/* Stop the timer if needed */ +if (throttle_timer_stop) { +timer_del(throttle_timer); timer_del is not needed in the timer callback. Paolo +timer_free(throttle_timer); +throttle_timer = NULL; +return; +} + +CPU_FOREACH(cpu) { +async_run_on_cpu(cpu, cpu_throttle_thread, NULL); +} +} +
[Qemu-devel] [PATCH] target-mips: fix ASID synchronisation for MIPS MT
When syncing the task ASID with EntryHi, correctly or the value instead of assigning it. Reported-by: Dr. David Alan Gilbert dgilb...@redhat.com Signed-off-by: Aurelien Jarno aurel...@aurel32.net Cc: Leon Alrae leon.al...@imgtec.com --- target-mips/op_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 2a9ddff..d457a29 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -661,7 +661,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, /* Sync the TASID with EntryHi. */ cpu-CP0_EntryHi = ~0xff; -cpu-CP0_EntryHi = tasid; +cpu-CP0_EntryHi |= tasid; compute_hflags(cpu); } -- 2.1.4
[Qemu-devel] [PATCH] target-xtensa: fix gdb register map construction
Due to different gdb overlay organization between windowed/call0 configurations core import script doesn't always work correctly. Simplify the script: always copy complete gdb register map from overlay, count registers at core registerstion time. Update existing cores. Signed-off-by: Max Filippov jcmvb...@gmail.com --- target-xtensa/core-dc232b.c | 2 +- target-xtensa/core-dc233c.c | 2 +- target-xtensa/core-fsf.c | 7 ++- target-xtensa/cpu.h | 1 + target-xtensa/helper.c | 14 ++ target-xtensa/import_core.sh | 6 ++ target-xtensa/overlay_tool.h | 2 ++ 7 files changed, 27 insertions(+), 7 deletions(-) diff --git a/target-xtensa/core-dc232b.c b/target-xtensa/core-dc232b.c index a3b914b..06826c0 100644 --- a/target-xtensa/core-dc232b.c +++ b/target-xtensa/core-dc232b.c @@ -33,7 +33,7 @@ #include core-dc232b/core-isa.h #include overlay_tool.h -static const XtensaConfig dc232b __attribute__((unused)) = { +static XtensaConfig dc232b __attribute__((unused)) = { .name = dc232b, .gdb_regmap = { .num_regs = 120, diff --git a/target-xtensa/core-dc233c.c b/target-xtensa/core-dc233c.c index ac745d1..8daf7d9 100644 --- a/target-xtensa/core-dc233c.c +++ b/target-xtensa/core-dc233c.c @@ -34,7 +34,7 @@ #include core-dc233c/core-isa.h #include overlay_tool.h -static const XtensaConfig dc233c __attribute__((unused)) = { +static XtensaConfig dc233c __attribute__((unused)) = { .name = dc233c, .gdb_regmap = { .num_regs = 121, diff --git a/target-xtensa/core-fsf.c b/target-xtensa/core-fsf.c index cfcc840..f6ea6b9 100644 --- a/target-xtensa/core-fsf.c +++ b/target-xtensa/core-fsf.c @@ -33,9 +33,14 @@ #include core-fsf/core-isa.h #include overlay_tool.h -static const XtensaConfig fsf __attribute__((unused)) = { +static XtensaConfig fsf __attribute__((unused)) = { .name = fsf, +.gdb_regmap = { /* GDB for this core is not supported currently */ +.reg = { +XTREG_END +}, +}, .clock_freq_khz = 1, DEFAULT_SECTIONS }; diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index b592efb..b89c602 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -400,6 +400,7 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model); void xtensa_translate_init(void); void xtensa_breakpoint_handler(CPUState *cs); int cpu_xtensa_exec(CPUXtensaState *s); +void xtensa_finalize_config(XtensaConfig *config); void xtensa_register_core(XtensaConfigList *node); void check_interrupts(CPUXtensaState *s); void xtensa_irq_init(CPUXtensaState *env); diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index d84d259..76be50d 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -51,6 +51,20 @@ static void xtensa_core_class_init(ObjectClass *oc, void *data) cc-gdb_num_core_regs = config-gdb_regmap.num_regs; } +void xtensa_finalize_config(XtensaConfig *config) +{ +unsigned i, n = 0; + +if (config-gdb_regmap.num_regs) { +return; +} + +for (i = 0; config-gdb_regmap.reg[i].targno = 0; ++i) { +n += (config-gdb_regmap.reg[i].type != 6); +} +config-gdb_regmap.num_regs = n; +} + void xtensa_register_core(XtensaConfigList *node) { TypeInfo type = { diff --git a/target-xtensa/import_core.sh b/target-xtensa/import_core.sh index 73791ec..351bee4 100755 --- a/target-xtensa/import_core.sh +++ b/target-xtensa/import_core.sh @@ -22,8 +22,7 @@ mkdir -p $TARGET tar -xf $OVERLAY -C $TARGET --strip-components=1 \ --xform='s/core/core-isa/' config/core.h tar -xf $OVERLAY -O gdb/xtensa-config.c | \ -sed -n '1,/*\//p;/pc/,/a15/p' $TARGET/gdb-config.c -NUM_REGS=$(grep XTREG $TARGET/gdb-config.c | wc -l) +sed -n '1,/*\//p;/XTREG/,/XTREG_END/p' $TARGET/gdb-config.c cat EOF ${TARGET}.c #include cpu.h @@ -34,10 +33,9 @@ cat EOF ${TARGET}.c #include core-$NAME/core-isa.h #include overlay_tool.h -static const XtensaConfig $NAME __attribute__((unused)) = { +static XtensaConfig $NAME __attribute__((unused)) = { .name = $NAME, .gdb_regmap = { -.num_regs = $NUM_REGS, .reg = { #include core-$NAME/gdb-config.c } diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h index f7b1510..eda03aa 100644 --- a/target-xtensa/overlay_tool.h +++ b/target-xtensa/overlay_tool.h @@ -28,6 +28,7 @@ #define XTREG(idx, ofs, bi, sz, al, no, flags, cp, typ, grp, name, \ a1, a2, a3, a4, a5, a6) \ { .targno = (no), .type = (typ), .group = (grp), .size = (sz) }, +#define XTREG_END { .targno = -1 }, #ifndef XCHAL_HAVE_DIV32 #define XCHAL_HAVE_DIV32 0 @@ -316,6 +317,7 @@ static XtensaConfigList node = { \ .config = core, \ }; \ +xtensa_finalize_config(core); \ xtensa_register_core(node); \ } #else -- 1.8.1.4
Re: [Qemu-devel] [PATCH RFC 1 8/8] xen/pt: Check for return values for xen_host_pci_[get|set] in init
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: and if we have failures we call xen_pt_destroy introduced in 'xen/pt: Move bulk of xen_pt_unregister_device in its own routine.' and free all of the allocated structures. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com Acked-by: Stefano Stabellini stefano.stabell...@eu.citrix.com hw/xen/xen_pt.c | 32 +--- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 589c6c6..ce202e9 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -779,10 +779,11 @@ static int xen_pt_initfn(PCIDevice *d) } /* Initialize virtualized PCI configuration (Extended 256 Bytes) */ -if (xen_host_pci_get_block(s-real_device, 0, d-config, - PCI_CONFIG_SPACE_SIZE) 0) { -xen_host_pci_device_put(s-real_device); -return -1; +rc = xen_host_pci_get_block(s-real_device, 0, d-config, +PCI_CONFIG_SPACE_SIZE); +if (rc 0) { +XEN_PT_ERR(d,Could not read PCI_CONFIG space! (rc:%d)\n, rc); +goto err_out; } s-memory_listener = xen_pt_memory_listener; @@ -792,17 +793,18 @@ static int xen_pt_initfn(PCIDevice *d) xen_pt_register_regions(s, cmd); /* reinitialize each config register to be emulated */ -if (xen_pt_config_init(s)) { +rc = xen_pt_config_init(s); +if (rc) { XEN_PT_ERR(d, PCI Config space initialisation failed.\n); -xen_host_pci_device_put(s-real_device); -return -1; +goto err_out; } /* Bind interrupt */ -if (xen_host_pci_get_byte(s-real_device, PCI_INTERRUPT_PIN, - machine_irq /* temp scratch */)) { +rc = xen_host_pci_get_byte(s-real_device, PCI_INTERRUPT_PIN, + machine_irq /* temp scratch */); +if (rc) { XEN_PT_ERR(d, Failed to read PCI_INTERRUPT_PIN! (rc:%d)\n, rc); -machine_irq = 0; +goto err_out; } if (!machine_irq) { XEN_PT_LOG(d, no pin interrupt\n); @@ -859,12 +861,15 @@ out: rc = xen_host_pci_get_word(s-real_device, PCI_COMMAND, val); if (rc) { XEN_PT_ERR(d, Failed to read PCI_COMMAND! (rc: %d)\n, rc); +goto err_out; } else { val |= cmd; -if (xen_host_pci_set_word(s-real_device, PCI_COMMAND, val)) { +rc = xen_host_pci_set_word(s-real_device, PCI_COMMAND, val); +if (rc) { XEN_PT_ERR(d, Failed to write PCI_COMMAND val=0x%x!(rc: %d)\n, val, rc); +goto err_out; } } } @@ -877,6 +882,11 @@ out: s-hostaddr.bus, s-hostaddr.slot, s-hostaddr.function); return 0; + +err_out: +xen_pt_destroy(d); +assert(rc); +return rc; } static void xen_pt_unregister_device(PCIDevice *d) -- 2.1.0
Re: [Qemu-devel] [PATCH v2 07/22] virtio: find version 1.0 virtio capabilities
Hi, Yes, seabios always allocates both mem and io. What if it can't? E.g. too many devices. First tries to move 64bit bars above 64g. Guess we better should exclude virtio devices here (like we do for xhci already). Failing that it'll panic. cheers, Gerd
Re: [Qemu-devel] [PATCH RFC 3/6] xen/pt: xen_host_pci_config_read returns -errno, not -1 on failure
On Mon, 29 Jun 2015, Konrad Rzeszutek Wilk wrote: However the init routines assume that on errors the return code is -1 (as the libxc API is) - while those xen_host_* routines follow another paradigm - negative errno on return, 0 on success. Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com Reviewed-by: Stefano Stabellini stefano.stabell...@eu.citrix.com hw/xen/xen_pt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 706e3d9..ea1ceda 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -716,7 +716,7 @@ static int xen_pt_initfn(PCIDevice *d) /* Initialize virtualized PCI configuration (Extended 256 Bytes) */ if (xen_host_pci_get_block(s-real_device, 0, d-config, - PCI_CONFIG_SPACE_SIZE) == -1) { + PCI_CONFIG_SPACE_SIZE) 0) { xen_host_pci_device_put(s-real_device); return -1; } -- 2.1.0
Re: [Qemu-devel] [PATCH v2 1/1] KVM s390 pci infrastructure modelling
On Wed, Jul 01, 2015 at 08:42:52PM +0800, Hong Bo Li wrote: On 7/1/2015 19:57, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 07:46:01PM +0800, Hong Bo Li wrote: On 7/1/2015 19:23, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 07:11:38PM +0800, Hong Bo Li wrote: On 7/1/2015 18:36, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 06:04:24PM +0800, Hong Bo Li wrote: On 7/1/2015 17:22, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 05:13:11PM +0800, Hong Bo Li wrote: On 7/1/2015 16:05, Michael S. Tsirkin wrote: On Wed, Jul 01, 2015 at 03:56:25PM +0800, Hong Bo Li wrote: On 7/1/2015 14:22, Michael S. Tsirkin wrote: On Tue, Jun 30, 2015 at 02:16:59PM +0800, Hong Bo Li wrote: On 6/29/2015 18:01, Michael S. Tsirkin wrote: On Mon, Jun 29, 2015 at 05:24:53PM +0800, Hong Bo Li wrote: This patch introduce a new facility(and bus) to hold devices representing information actually provided by s390 firmware and I/O configuration. usage example: -device s390-pcihost -device vfio-pci,host=:00:00.0,id=vpci1 -device zpci,fid=2,uid=5,pci_id=vpci1,id=zpci1 The first line will create a s390 pci host bridge and init the root bus. The second line will create a standard vfio pci device, and attach it to the root bus. These are similiar to the standard process to define a pci device on other platform. The third line will create a s390 pci device to store s390 specific information, and references the corresponding vfio pci device via device id. We create a s390 pci facility bus to hold all the zpci devices. Signed-off-by: Hong Bo Li lih...@linux.vnet.ibm.com It's mostly up to s390 maintainers, but I'd like to note one thing below --- hw/s390x/s390-pci-bus.c| 314 + hw/s390x/s390-pci-bus.h| 48 ++- hw/s390x/s390-pci-inst.c | 4 +- hw/s390x/s390-virtio-ccw.c | 5 +- 4 files changed, 283 insertions(+), 88 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 560b66a..d5e7b2e 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -32,8 +32,8 @@ int chsc_sei_nt2_get_event(void *res) PciCcdfErr *eccdf; int rc = 1; SeiContainer *sei_cont; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return rc; @@ -72,8 +72,8 @@ int chsc_sei_nt2_get_event(void *res) int chsc_sei_nt2_have_event(void) { -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return 0; @@ -82,20 +82,32 @@ int chsc_sei_nt2_have_event(void) return !QTAILQ_EMPTY(s-pending_sei); } +void s390_pci_device_enable(S390PCIBusDevice *zpci) +{ +zpci-fh = zpci-fh | 1 ENABLE_BIT_OFFSET; +} + +void s390_pci_device_disable(S390PCIBusDevice *zpci) +{ +zpci-fh = zpci-fh ~(1 ENABLE_BIT_OFFSET); +if (zpci-is_unplugged) +object_unparent(OBJECT(zpci)); +} + S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid) { S390PCIBusDevice *pbdev; -int i; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +BusChild *kid; +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return NULL; } -for (i = 0; i PCI_SLOT_MAX; i++) { -pbdev = s-pbdev[i]; -if ((pbdev-fh != 0) (pbdev-fid == fid)) { +QTAILQ_FOREACH(kid, s-fbus-qbus.children, sibling) { +pbdev = (S390PCIBusDevice *)kid-child; +if (pbdev-fid == fid) { return pbdev; } } @@ -126,39 +138,24 @@ void s390_pci_sclp_configure(int configure, SCCB *sccb) return; } -static uint32_t s390_pci_get_pfid(PCIDevice *pdev) -{ -return PCI_SLOT(pdev-devfn); -} - -static uint32_t s390_pci_get_pfh(PCIDevice *pdev) -{ -return PCI_SLOT(pdev-devfn) | FH_VIRT; -} - S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx) { S390PCIBusDevice *pbdev; -int i; -int j = 0; -S390pciState *s = S390_PCI_HOST_BRIDGE( -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL)); +BusChild *kid; +int i = 0; +S390PCIFacility *s = S390_PCI_FACILITY( +object_resolve_path(TYPE_S390_PCI_FACILITY, NULL)); if (!s) { return NULL; } -for (i = 0; i PCI_SLOT_MAX; i++) { -pbdev = s-pbdev[i]; - -if (pbdev-fh == 0) { -continue; -} - -if (j == idx) { +QTAILQ_FOREACH(kid, s-fbus-qbus.children, sibling) { +pbdev = (S390PCIBusDevice
Re: [Qemu-devel] [PATCH v8 3/3] ich9: implement strap SPKR pin logic
On 01/07/2015 15:31, Michael S. Tsirkin wrote: I don't think we should defer the whole series because of the argument about the default. I've merged these patches, I you like, pls send a one-line patch on top to flip the default with some info on how it was tested, and we can discuss it separately. Makes sense? Perfect. Paolo BTW 2.4 makes qemu versioned because ahci finally supports migration so yes, we'll have to version from now on.
Re: [Qemu-devel] [PATCH pic32 v2 5/5] Two new machine platforms: pic32mz7 and pic32mz.
On 2015-06-30 21:12, Serge Vakulenko wrote: Signed-off-by: Serge Vakulenko serge.vakule...@gmail.com --- hw/mips/Makefile.objs |3 + hw/mips/mips_pic32mx7.c | 1652 + hw/mips/mips_pic32mz.c | 2840 +++ hw/mips/pic32_ethernet.c| 557 + hw/mips/pic32_gpio.c| 39 + hw/mips/pic32_load_hex.c| 238 hw/mips/pic32_peripherals.h | 210 hw/mips/pic32_sdcard.c | 428 +++ hw/mips/pic32_spi.c | 121 ++ hw/mips/pic32_uart.c| 228 hw/mips/pic32mx.h | 1290 hw/mips/pic32mz.h | 2093 +++ 12 files changed, 9699 insertions(+) create mode 100644 hw/mips/mips_pic32mx7.c create mode 100644 hw/mips/mips_pic32mz.c create mode 100644 hw/mips/pic32_ethernet.c create mode 100644 hw/mips/pic32_gpio.c create mode 100644 hw/mips/pic32_load_hex.c create mode 100644 hw/mips/pic32_peripherals.h create mode 100644 hw/mips/pic32_sdcard.c create mode 100644 hw/mips/pic32_spi.c create mode 100644 hw/mips/pic32_uart.c create mode 100644 hw/mips/pic32mx.h create mode 100644 hw/mips/pic32mz.h This patch is huge, and needs to be splitted to ease the review. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net