Re: [Qemu-devel] [PATCH] Add qcow2 documentation
Am 09.03.2011 19:08, schrieb Dushyant Bansal: > On Tuesday 08 March 2011 05:17 PM, Kevin Wolf wrote: >> This adds a description of the qcow2 file format to the docs/ directory. >> Besides documenting what's there, which is never wrong, the document should >> provide a good basis for the discussion of format extensions (called "qcow3" >> in previous discussions) >> >> Signed-off-by: Kevin Wolf >> --- >> docs/specs/qcow2.txt | 228 >> ++ >> 1 files changed, 228 insertions(+), 0 deletions(-) >> create mode 100644 docs/specs/qcow2.txt >> >> diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt >> new file mode 100644 >> index 000..0e7bcda >> --- /dev/null >> +++ b/docs/specs/qcow2.txt >> @@ -0,0 +1,228 @@ >> +== Clusters == >> + >> +A qcow2 image file is organized in units of constant size, which are called >> +(host) clusters. A cluster is the unit in which all allocations are done, >> +both for actual guest data and for image metadata. >> + >> +Likewise, the virtual disk as seen by the guest is divided into (guest) >> +clusters of the same size. >> + >> + >> +== Header == >> + >> +The first cluster of a qcow2 image contains the file header: >> + >> +Byte 0 - 3: magic >> +QCOW magic string ("QFI\xfb") >> + >> + 4 - 7: version >> +Version number (only valid value is 2) >> + >> + 8 - 15: backing_file_offset >> +Offset into the image file at which the backing file >> name >> +is stored (NB: The string is not null terminated). 0 if >> the >> +image doesn't have a backing file. >> + >> + 16 - 19: backing_file_size >> +Length of the backing file name in bytes. Must not be >> +longer than 1023 bytes. Undefined if the image doesn't >> have >> +a backing file. >> + >> + 20 - 23: cluster_bits >> +Number of bits that are used for addressing an offset >> +within a cluster (1<< cluster_bits is the cluster size) >> + >> + 24 - 31: size >> +Virtual disk size in bytes >> + >> + 32 - 35: crypt_method >> +0 for no encryption >> +1 for AES encryption >> + >> + 36 - 39: l1_size >> +Number of entries in the active L1 table >> + >> + 40 - 47: l1_table_offset >> +Offset into the image file at which the active L1 table >> +starts. Must be aligned to a cluster boundary. >> + >> + 48 - 55: refcount_table_offset >> +Offset into the image file at which the refcount table >> +starts. Must be aligned to a cluster boundary. >> + >> + 56 - 59: refcount_table_clusters >> +Number of clusters that the refcount table occupies >> + >> + 60 - 63: nb_snapshots >> +Number of snapshots contained in the image >> + >> + 64 - 71: snapshots_offset >> +Offset into the image file at which the snapshot table >> +starts. Must be aligned to a cluster boundary. >> + >> +All numbers in qcow2 are stored in Big Endian byte order. >> + >> + >> +== Host cluster management == >> + >> +qcow2 manages the allocation of host clusters by maintaining a reference >> count >> +for each host cluster. A refcount of 0 means that the cluster is free, 1 >> means >> +that it is used, and>= 2 means that it is used and any write access must >> +perform a COW (copy on write) operation. >> + >> +The refcounts are managed in a two-level table. The first level is called >> +refcount table and has a variable size (which is stored in the header). The >> +refcount table can cover multiple clusters, however it needs to be >> contiguous >> +in the image file. >> + >> +It contains pointers to the second level structures which are called >> refcount >> +blocks and are exactly one cluster in size. >> + >> +Given a offset into the image file, the refcount of its cluster can be >> obtained >> +as follows: >> + >> +refcount_block_entries = (cluster_size / sizeof(uint16_t)) >> + >> +refcount_block_index = (offset / cluster_size) % refcount_table_entries >> +refcount_table_index = (offset / cluster_size) / refcount_table_entries >> + >> +refcount_block = load_cluster(refcount_table[refcount_table_index]); >> +return refcount_block[refcount_block_index]; >> + >> +Refcount table entry: >> + >> +Bit 0 - 8:Reserved (set to 0) >> + >> + 9 - 63:Bits 9-63 of the offset into the image file at which the >> +refcount block starts. Must be aligned to a cluster >> +boundary. >> + >> +If this is 0, the corresponding refcount block has not >> yet >> +been alloc
Re: [Qemu-devel] [PATCH 1/2][RESEND] vl: initialize all displaystates
Hello, On 3/10/11, andrzej zaborowski wrote: > On 4 March 2011 01:48, Dmitry Eremin-Solenikov wrote: >> Init not only first displaystate, but all. Otherwise machines with >> multiple display devices (e.g. tosa, as it exists now) will just >> segfault on ds switch. >> >> Signed-off-by: Dmitry Eremin-Solenikov >> --- >> vl.c | 104 >> +- >> 1 files changed, 52 insertions(+), 52 deletions(-) >> >> Basically this patch is equal to: >> @@ -3009,9 +3009,7 @@ int main(int argc, char **argv, char **envp) >> >> net_check_clients(); >> >> -/* just use the first displaystate for the moment */ >> -ds = get_displaystate(); >> - >> +for (ds = get_displaystate(); ds; ds = ds->next) { >> if (using_spice) >> display_remote++; >> if (display_type == DT_DEFAULT && !display_remote) { >> @@ -3077,7 +3075,9 @@ int main(int argc, char **argv, char **envp) >> nographic_timer = qemu_new_timer(rt_clock, nographic_update, >> NULL); >> qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock)); >> } >> -text_consoles_set_display(ds); >> +} >> + >> +text_consoles_set_display(get_displaystate()); >> >> if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) { >> fprintf(stderr, "qemu: could not open gdbserver on device >> '%s'\n", >> >> diff --git a/vl.c b/vl.c >> index 14255c4..b8cd455 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -3009,75 +3009,75 @@ int main(int argc, char **argv, char **envp) >> >> net_check_clients(); >> >> -/* just use the first displaystate for the moment */ >> -ds = get_displaystate(); >> - >> -if (using_spice) >> -display_remote++; >> -if (display_type == DT_DEFAULT && !display_remote) { >> +for (ds = get_displaystate(); ds; ds = ds->next) { >> +if (using_spice) >> +display_remote++; >> +if (display_type == DT_DEFAULT && !display_remote) { >> #if defined(CONFIG_SDL) || defined(CONFIG_COCOA) >> -display_type = DT_SDL; >> +display_type = DT_SDL; >> #else >> -vnc_display = "localhost:0,to=99"; >> -show_vnc_port = 1; >> +vnc_display = "localhost:0,to=99"; >> +show_vnc_port = 1; >> #endif >> -} >> - >> +} >> + >> >> -/* init local displays */ >> -switch (display_type) { >> -case DT_NOGRAPHIC: >> -break; >> +/* init local displays */ >> +switch (display_type) { >> +case DT_NOGRAPHIC: >> +break; >> #if defined(CONFIG_CURSES) >> -case DT_CURSES: >> -curses_display_init(ds, full_screen); >> -break; >> +case DT_CURSES: >> +curses_display_init(ds, full_screen); >> +break; >> #endif >> #if defined(CONFIG_SDL) >> -case DT_SDL: >> -sdl_display_init(ds, full_screen, no_frame); >> -break; >> +case DT_SDL: >> +sdl_display_init(ds, full_screen, no_frame); >> +break; >> #elif defined(CONFIG_COCOA) >> -case DT_SDL: >> -cocoa_display_init(ds, full_screen); >> -break; >> +case DT_SDL: >> +cocoa_display_init(ds, full_screen); >> +break; > > I'm not sure this will work as intended, I think we shouldn't call > curses/sdl/cocoa_display_init() for every display state, we should > just call register_displaychangelistener() etc. for each display > state. My assumption is that we want each ds to appear as a graphical > console in the same window, not open N SDL windows / VNC servers (for > curses that would break completely I think). I've not tested VNC/curses (will do this later), but for SDL this works as expected: on tosa, where qemu registers both PXA and TC6393xb displays, I've exactly one window. Moreover w/o this patch qemu crashes if I try to switch to secondary graphic console (tc6393). -- With best wishes Dmitry
[Qemu-devel] Re: [PULL (resend, rebase) 2/5] virtio-serial: Disallow generic ports at id 0
On (Thu) 10 Mar 2011 [11:39:16], Amit Shah wrote: > Port 0 is reserved for virtconsole devices for backward compatibility > with the old -virtioconsole (from qemu 0.12) device type. > > libvirt prior to commit 8e28c5d40200b4c5d483bd585d237b9d870372e5 used > port 0 for generic ports. libvirt will no longer do that, but disallow > instantiating generic ports at id 0 from qemu as well. > > Signed-off-by: Amit Shah Updated patch below, fixes a build break after rebase. The git tree in the pull request has been updated with this fix. >From 78f1d849a8d739fa7377b8a790a60ffc293aa786 Mon Sep 17 00:00:00 2001 Message-Id: <78f1d849a8d739fa7377b8a790a60ffc293aa786.1299745288.git.amit.s...@redhat.com> In-Reply-To: References: From: Amit Shah Date: Thu, 3 Feb 2011 13:05:07 +0530 Subject: [PULL (resend, rebase) 2/5] virtio-serial: Disallow generic ports at id 0 Port 0 is reserved for virtconsole devices for backward compatibility with the old -virtioconsole (from qemu 0.12) device type. libvirt prior to commit 8e28c5d40200b4c5d483bd585d237b9d870372e5 used port 0 for generic ports. libvirt will no longer do that, but disallow instantiating generic ports at id 0 from qemu as well. Signed-off-by: Amit Shah --- hw/virtio-console.c |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/hw/virtio-console.c b/hw/virtio-console.c index c235b27..4440784 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -11,6 +11,7 @@ */ #include "qemu-char.h" +#include "qemu-error.h" #include "virtio-serial.h" typedef struct VirtConsole { @@ -113,6 +114,14 @@ static int virtserialport_initfn(VirtIOSerialPort *port) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); +if (port->id == 0) { +/* + * Disallow a generic port at id 0, that's reserved for + * console ports. + */ +error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility."); +return -1; +} return generic_port_init(vcon, port); } -- 1.7.4 Amit
[Qemu-devel] [PATCH] Register only one qbus_reset_all_fn() for system bus
Currently reset handler is registered for System bus twice: once during bus creation and once in vl.c. Remove the second qemu_register_reset() invocation. Also while we are at it, remove incorrect check at qbus_create_inplace(): when system bus is created, main_system_bus is NULL (as it's not yet created, it cannot be set), so the check is just wrong. Signed-off-by: Dmitry Eremin-Solenikov --- hw/qdev.c |2 +- vl.c |3 --- 2 files changed, 1 insertions(+), 4 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 1aa1ea0..0a3c8ce 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -762,7 +762,7 @@ void qbus_create_inplace(BusState *bus, BusInfo *info, if (parent) { QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling); parent->num_child_bus++; -} else if (bus != main_system_bus) { +} else { /* TODO: once all bus devices are qdevified, only reset handler for main_system_bus should be registered here. */ qemu_register_reset(qbus_reset_all_fn, bus); diff --git a/vl.c b/vl.c index 91be92e..24923db 100644 --- a/vl.c +++ b/vl.c @@ -3120,9 +3120,6 @@ int main(int argc, char **argv, char **envp) exit(1); } -/* TODO: once all bus devices are qdevified, this should be done - * when bus is created by qdev.c */ -qemu_register_reset(qbus_reset_all_fn, sysbus_get_default()); qemu_run_machine_init_done_notifiers(); qemu_system_reset(); -- 1.7.2.3
[Qemu-devel] Re: RFC: emulation of system flash
On 03/10/2011 06:51 AM, Jordan Justen wrote: Hi all, I have documented a simple flash-like device which I think could be useful for qemu/kvm in some cases. (Particularly for allowing persistent UEFI non-volatile variables.) http://wiki.qemu.org/Features/System_Flash Let me know if you have any suggestions or concerns. Looks pretty nice. Two suggestions: - make the flash storage a standard qemu block device. This allows snapshotting, block-live-migration, and other nice features. - make the programming interface the same as an existing device -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] QMP: add snapshot_blkdev_sync command
On 03/09/11 18:03, Anthony Liguori wrote: > On 03/09/2011 10:01 AM, Kevin Wolf wrote: >>> I'm not sure blkdev is the right prefix. Kevin, what are your thoughts >>> here? Does 'blkdev' make sense for any command operating on a block >>> device (that is, a qdev device that happens to have a block drive, not >>> the same thing as -blockdev that we've discussed in the past). >> Doesn't this command work on a -blockdev style thing, i.e. >> BlockDriverState or DriveInfo? I don't think we have any commands that >> refer to qdev devices that happen to be block devices. You could >> probably argue that some of them should... > > 'device' is a device name though, right? Or is it a name associated > with a BlockDriverState that currently happens to be a qdev name? It is a device in the sense of what you get from 'info block' in the human monitor. > Would I be able to eventually pass a qdev path here? > > If the answer is that this is a bdrv_name, then should we at least use > blockdev instead of blkdev? I used blkdev in the human monitor command to reduce the length of the command name. Anyway, if you can decide what you want to call the command, I'll rename it accordingly. Cheers, Jes
Re: [Qemu-devel] [PATCH] QMP: add snapshot_blkdev_sync command
Am 09.03.2011 18:03, schrieb Anthony Liguori: > On 03/09/2011 10:01 AM, Kevin Wolf wrote: >> Am 09.03.2011 16:46, schrieb Anthony Liguori: >>> On 03/09/2011 09:37 AM, jes.soren...@redhat.com wrote: From: Jes Sorensen Add QMP bits for snapshot_blkdev_sync command. This is the same as snapshot_blkdev in the human monitor, but added _sync to the name to make it explicit that the command is synchronous and leave space for a future async version. Signed-off-by: Jes Sorensen --- qmp-commands.hx | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/qmp-commands.hx b/qmp-commands.hx index 9d3cc31..e32187e 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -667,6 +667,25 @@ Example: EQMP { +.name = "snapshot_blkdev_sync", +.args_type = "device:B,snapshot_file:s?,format:s?", +.params = "device [new-image-file] [format]", +.help = "initiates a live snapshot\n\t\t\t" + "of device. If a new image file is specified, the\n\t\t\t" + "new image file will become the new root image.\n\t\t\t" + "If format is specified, the snapshot file will\n\t\t\t" + "be created in that format. Otherwise the\n\t\t\t" + "snapshot will be internal! (currently unsupported)", +.user_print = monitor_user_noop, +.mhandler.cmd_new = do_snapshot_blkdev, +}, + +SQMP +Synchronous snapshot of block device, using snapshot file as target +if provided. >>> Please document the error semantics. >>> >>> The documentation in .help is discarded for QMP. You should put the >>> docs in the SQMP section. >>> >>> Also, QMP should use '-' instead of '_'. We should also try to follow >>> the form 'noun'-'verb' so the name would be better as 'blkdev-snapshot-sync' >>> >>> I'm not sure blkdev is the right prefix. Kevin, what are your thoughts >>> here? Does 'blkdev' make sense for any command operating on a block >>> device (that is, a qdev device that happens to have a block drive, not >>> the same thing as -blockdev that we've discussed in the past). >> Doesn't this command work on a -blockdev style thing, i.e. >> BlockDriverState or DriveInfo? I don't think we have any commands that >> refer to qdev devices that happen to be block devices. You could >> probably argue that some of them should... > > 'device' is a device name though, right? Or is it a name associated > with a BlockDriverState that currently happens to be a qdev name? > > Would I be able to eventually pass a qdev path here? > > If the answer is that this is a bdrv_name, then should we at least use > blockdev instead of blkdev? I think it's a drive name, like 'ide-hd0' or what they were called. I'm not completely sure if this is the same namespace as blockdev_add would use, but at first sight it would make some sense. Markus? Kevin
Re: [Qemu-devel] Issue with snapshot outside qcow2 disk - qemu 0.14.0
On Thu, Mar 10, 2011 at 1:51 AM, SAURAV LAHIRI wrote: > Scenario 1: > 1) I executed following with the vm in shutdown state. > "#qemu-img snapshot -c snap1 /home/user1/lucid-vm2" Here you are snapshotting the current disk image and storing the snapshot away as "snap1". > 2) Brought the VM Up. > > 3) Inside the vm create a file. > #touch samplefile Now you modified the current disk image but "snap1" remains unchanged. > 4) Shutdown the vm and copy the snapshot outside the original qcow2 > > #qemu-img convert -f qcow2 -O qcow2 -s snap1 /home/user1/lucid-vm2 > /home/lucid-vm2-snap1 > > Result : When I bring up the vm do not see the samplefile which is the > expected behaviour. Are you bringing up the VM with lucid-vm2 (which should have samplefile) or lucid-vm2-snap1 (which should not have samplefile)? > Scenario 2: > 1) I executed following with the vm in shutdown state. > "#qemu-img snapshot -c snap1 /home/user1/lucid-vm2" > > 2) Bring up the VM. > > 3) Inside the vm create a file. > #touch samplefile > > 4) VM is NOT Shutdown and copy the snapshot outside the original qcow2 > > #qemu-img convert -f qcow2 -O qcow2 -s snap1 /home/user1/lucid-vm2 > /home/lucid-vm2-snap1 > > Result : When I bring up the vm do not see the samplefile which is the > expected behaviour. > > > Is Scenario 2 safe where in the copying the snapshot outside the original > qcow2 is being executed with the VM running. This is because if this is safe > then this could be an approach as it would not require a long downtime for > the VM. There is no guarantee that qemu-img will work on an image file that is open by a running VM. I have CCed Jes who has been working on a live snapshot mechanism. He recently added the snapshot_blkdev monitor command that takes a snapshot of a block device while the VM is running. A new image file is created based off the original image file (which will no longer be modified), all new disk writes go to the new image file. It is safe to perform read-only access to the original image file. There currently is no support to merge the snapshot changes back into the original image while the VM is running, but I think that is the next planned step. If you can describe your snapshot use case at a higher level that might be useful. Stefan
Re: [Qemu-devel] Issue with snapshot outside qcow2 disk - qemu 0.14.0
On 03/10/11 10:27, Stefan Hajnoczi wrote: >> Is Scenario 2 safe where in the copying the snapshot outside the original >> qcow2 is being executed with the VM running. This is because if this is safe >> then this could be an approach as it would not require a long downtime for >> the VM. > > There is no guarantee that qemu-img will work on an image file that is > open by a running VM. I think the guarantee here is that you're guaranteed it will go horribly wrong if you try to do so. > I have CCed Jes who has been working on a live snapshot mechanism. He > recently added the snapshot_blkdev monitor command that takes a > snapshot of a block device while the VM is running. A new image file > is created based off the original image file (which will no longer be > modified), all new disk writes go to the new image file. It is safe > to perform read-only access to the original image file. There > currently is no support to merge the snapshot changes back into the > original image while the VM is running, but I think that is the next > planned step. Yes, keep in mind that the live snapshot is only for external snapshot files, it doesn't deal with internal snapshots. Cheers, Jes
[Qemu-devel] Re: RFC: emulation of system flash
On Wed, Mar 09, 2011 at 08:51:23PM -0800, Jordan Justen wrote: > Hi all, > > I have documented a simple flash-like device which I think could be > useful for qemu/kvm in some cases. (Particularly for allowing > persistent UEFI non-volatile variables.) > > http://wiki.qemu.org/Features/System_Flash > > Let me know if you have any suggestions or concerns. > Two things. First You suggest to replace -bios with -flash. This will make firmware upgrade painful process that will have to be performed from inside the guest since the same flash image will contain both firmware and whatever data was stored on a flash which presumably you want to reuse after upgrading a firmware. My suggestion is to extend -bios option like this: -bios bios.bin,flash=flash.bin,flash_base=addr flash.bin will be mapped at address flash_base, or, if flash_base is not present, just below bios.bin. Second. I asked how flash is programmed because interfaces like CFI where you write into flash memory address range to issue commands cannot be emulated efficiently in KVM. KVM supports either regular memory slots or IO memory, but in your proposal the same memory behaves as IO on write and regular memory on read. Better idea would be to present non-volatile flash as ISA virtio device. Should be simple to implement. -- Gleb.
Re: [Qemu-devel] Issue with snapshot outside qcow2 disk - qemu 0.14.0
On Thu, Mar 10, 2011 at 9:32 AM, Jes Sorensen wrote: > On 03/10/11 10:27, Stefan Hajnoczi wrote: >> I have CCed Jes who has been working on a live snapshot mechanism. He >> recently added the snapshot_blkdev monitor command that takes a >> snapshot of a block device while the VM is running. A new image file >> is created based off the original image file (which will no longer be >> modified), all new disk writes go to the new image file. It is safe >> to perform read-only access to the original image file. There >> currently is no support to merge the snapshot changes back into the >> original image while the VM is running, but I think that is the next >> planned step. > > Yes, keep in mind that the live snapshot is only for external snapshot > files, it doesn't deal with internal snapshots. Yep, that's why I'm interested in Saurav's use case. Many use cases work with either internal or external snapshot but it depends on the details. Stefan
Re: [Qemu-devel] Issue with snapshot outside qcow2 disk - qemu 0.14.0
On 03/10/11 10:58, Stefan Hajnoczi wrote: > On Thu, Mar 10, 2011 at 9:32 AM, Jes Sorensen wrote: >> On 03/10/11 10:27, Stefan Hajnoczi wrote: >>> I have CCed Jes who has been working on a live snapshot mechanism. He >>> recently added the snapshot_blkdev monitor command that takes a >>> snapshot of a block device while the VM is running. A new image file >>> is created based off the original image file (which will no longer be >>> modified), all new disk writes go to the new image file. It is safe >>> to perform read-only access to the original image file. There >>> currently is no support to merge the snapshot changes back into the >>> original image while the VM is running, but I think that is the next >>> planned step. >> >> Yes, keep in mind that the live snapshot is only for external snapshot >> files, it doesn't deal with internal snapshots. > > Yep, that's why I'm interested in Saurav's use case. Many use cases > work with either internal or external snapshot but it depends on the > details. Actually I think there's very little reason to keep internal snapshot support. It doesn't buy us much, but it adds unnecessary complexity. Cheers, Jes
[Qemu-devel] Re: [V8 PATCH 05/11] virtio-9p: Add support to open a file in chroot environment
On Wed, Mar 9, 2011 at 5:15 PM, M. Mohan Kumar wrote: > +/* Return opened file descriptor on success or -errno on error */ > +int v9fs_request(FsContext *fs_ctx, V9fsFileObjectRequest *request) > { > - (void)v9fs_receivefd; > - (void)v9fs_write_request; > + int fd, sock_error; > + qemu_mutex_lock(&fs_ctx->chroot_mutex); > + if (fs_ctx->chroot_ioerror) { > + fd = -EIO; > + goto unlock; > + } > + if (v9fs_write_request(fs_ctx->chroot_socket, request) < 0) { > + fs_ctx->chroot_ioerror = 1; > + fd = -EIO; > + goto unlock; > + } > + fd = v9fs_receivefd(fs_ctx->chroot_socket, &sock_error); > + if (fd < 0 && sock_error) { > + fs_ctx->chroot_ioerror = 1; > + } > +unlock: > + qemu_mutex_unlock(&fs_ctx->chroot_mutex); > + return fd; > } If the socket is broken why not just close it? Right now we're keeping the file descriptor and have an additional chroot_ioerror variable to keep track of the fact that we don't want to touch the socket. > +/* Helper routine to fill V9fsFileObjectRequest structure */ > +static int fill_fileobjectrequest(V9fsFileObjectRequest *request, > + const char *path, FsCred *credp) > +{ > + if (strlen(path) >= PATH_MAX) { > + return -ENAMETOOLONG; > + } > + memset(request, 0, sizeof(*request)); Perhaps remove this since request is a big struct (two PATH_MAX buffers) or is it necessary? > + strcpy(request->path.path, path); > + if (credp) { > + request->data.mode = credp->fc_mode; > + request->data.uid = credp->fc_uid; > + request->data.gid = credp->fc_gid; > + request->data.dev = credp->fc_rdev; > + } > + return 0; > +} > + > +static int passthrough_request(FsContext *fs_ctx, const char *old_path, > + const char *path, int flags, FsCred *credp, int type) > +{ > + V9fsFileObjectRequest request; > + int retval; > + > + retval = fill_fileobjectrequest(&request, path, credp); This function could also handle old_path, flags, and type. It seems to only fill half the request struct at the moment. > + if (retval < 0) { > + errno = -retval; > + return -1; > + } > + if (old_path) { > + if (strlen(old_path) >= PATH_MAX) { > + errno = -ENAMETOOLONG; errno = ENAMETOOLONG; Stefan
[Qemu-devel] Re: RFC: emulation of system flash
On 2011-03-10 10:47, Gleb Natapov wrote: > On Wed, Mar 09, 2011 at 08:51:23PM -0800, Jordan Justen wrote: >> Hi all, >> >> I have documented a simple flash-like device which I think could be >> useful for qemu/kvm in some cases. (Particularly for allowing >> persistent UEFI non-volatile variables.) >> >> http://wiki.qemu.org/Features/System_Flash >> >> Let me know if you have any suggestions or concerns. >> > > Two things. First You suggest to replace -bios with -flash. This will > make firmware upgrade painful process that will have to be performed > from inside the guest since the same flash image will contain both > firmware and whatever data was stored on a flash which presumably you > want to reuse after upgrading a firmware. My suggestion is to extend > -bios option like this: > > -bios bios.bin,flash=flash.bin,flash_base=addr > > flash.bin will be mapped at address flash_base, or, if flash_base is not > present, just below bios.bin. ...or define -flash in a way that allows mapping the bios image as an overlay to the otherwise guest-managed flash image. > > Second. I asked how flash is programmed because interfaces like CFI > where you write into flash memory address range to issue commands cannot > be emulated efficiently in KVM. KVM supports either regular memory slots > or IO memory, but in your proposal the same memory behaves as IO on > write and regular memory on read. Better idea would be to present > non-volatile flash as ISA virtio device. Should be simple to implement. Why not enhancing KVM memory slots to support direct read access while writes are trapped and forwarded to a user space device model? Virtio means that you have to patch the guest (which might be something else than flexible Linux...). Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH 5/9] vmstate: add VMSTATE_INT64_ARRAY
Signed-off-by: Juan Quintela --- hw/hw.h |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 0ed63c5..d801694 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -802,6 +802,12 @@ extern const VMStateDescription vmstate_usb_device; #define VMSTATE_UINT32_ARRAY(_f, _s, _n) \ VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0) +#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \ +VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t) + +#define VMSTATE_INT64_ARRAY(_f, _s, _n) \ +VMSTATE_INT64_ARRAY_V(_f, _s, _n, 0) + #define VMSTATE_BUFFER_V(_f, _s, _v) \ VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f))) -- 1.7.4
[Qemu-devel] [PATCH 0/9] VMState infrastructure
Hi This is the infrastructure that I pushed on my previous series. Anthony don't like 58 patches series (why? O:-) And then split the series in three. This are the infrastructure patches needed for the other two series. Anthony, please apply. Later, Juan. Juan Quintela (9): vmstate: add VMSTATE_UINT32_EQUAL vmstate: Fix varrays with uint8 indexes vmstate: add UINT32 VARRAYS vmstate: add VMSTATE_STRUCT_VARRAY_INT32 vmstate: add VMSTATE_INT64_ARRAY vmstate: add VMSTATE_STRUCT_VARRAY_UINT32 vmstate: Add a way to send a partial array vmstate: be able to store/save a pci device from a pointer vmstate: move timers to use test instead of version hw/hw.h | 78 ++ savevm.c | 25 2 files changed, 98 insertions(+), 5 deletions(-) -- 1.7.4
[Qemu-devel] [PATCH 1/9] vmstate: add VMSTATE_UINT32_EQUAL
Signed-off-by: Juan Quintela --- hw/hw.h |4 savevm.c | 21 + 2 files changed, 25 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 4e2d592..0299207 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -343,6 +343,7 @@ extern const VMStateInfo vmstate_info_int64; extern const VMStateInfo vmstate_info_uint8_equal; extern const VMStateInfo vmstate_info_uint16_equal; extern const VMStateInfo vmstate_info_int32_equal; +extern const VMStateInfo vmstate_info_uint32_equal; extern const VMStateInfo vmstate_info_int32_le; extern const VMStateInfo vmstate_info_uint8; @@ -704,6 +705,9 @@ extern const VMStateDescription vmstate_usb_device; #define VMSTATE_INT32_EQUAL(_f, _s) \ VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_equal, int32_t) +#define VMSTATE_UINT32_EQUAL(_f, _s) \ +VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint32_equal, uint32_t) + #define VMSTATE_INT32_LE(_f, _s) \ VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t) diff --git a/savevm.c b/savevm.c index a50fd31..ce063d1 100644 --- a/savevm.c +++ b/savevm.c @@ -882,6 +882,27 @@ const VMStateInfo vmstate_info_uint32 = { .put = put_uint32, }; +/* 32 bit uint. See that the received value is the same than the one + in the field */ + +static int get_uint32_equal(QEMUFile *f, void *pv, size_t size) +{ +uint32_t *v = pv; +uint32_t v2; +qemu_get_be32s(f, &v2); + +if (*v == v2) { +return 0; +} +return -EINVAL; +} + +const VMStateInfo vmstate_info_uint32_equal = { +.name = "uint32 equal", +.get = get_uint32_equal, +.put = put_uint32, +}; + /* 64 bit unsigned int */ static int get_uint64(QEMUFile *f, void *pv, size_t size) -- 1.7.4
[Qemu-devel] [PATCH 2/9] vmstate: Fix varrays with uint8 indexes
Signed-off-by: Juan Quintela --- hw/hw.h |5 +++-- savevm.c |2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 0299207..40c6396 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -298,6 +298,7 @@ enum VMStateFlags { VMS_VARRAY_UINT16= 0x080, /* Array with size in uint16_t field */ VMS_VBUFFER = 0x100, /* Buffer with size in int32_t field */ VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */ +VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/ }; typedef struct { @@ -489,11 +490,11 @@ extern const VMStateInfo vmstate_info_unused_buffer; #define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \ .name = (stringify(_field)), \ -.num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ +.num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ .version_id = (_version),\ .vmsd = &(_vmsd), \ .size = sizeof(_type), \ -.flags = VMS_STRUCT|VMS_VARRAY_INT32, \ +.flags = VMS_STRUCT|VMS_VARRAY_UINT8, \ .offset = offsetof(_state, _field), \ } diff --git a/savevm.c b/savevm.c index ce063d1..4db036b 100644 --- a/savevm.c +++ b/savevm.c @@ -1331,6 +1331,8 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, n_elems = *(int32_t *)(opaque+field->num_offset); } else if (field->flags & VMS_VARRAY_UINT16) { n_elems = *(uint16_t *)(opaque+field->num_offset); +} else if (field->flags & VMS_VARRAY_UINT8) { +n_elems = *(uint8_t *)(opaque+field->num_offset); } if (field->flags & VMS_POINTER) { base_addr = *(void **)base_addr + field->start; -- 1.7.4
[Qemu-devel] [PATCH 3/9] vmstate: add UINT32 VARRAYS
Signed-off-by: Juan Quintela --- hw/hw.h | 11 +++ savevm.c |2 ++ 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 40c6396..6e78fa9 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -299,6 +299,7 @@ enum VMStateFlags { VMS_VBUFFER = 0x100, /* Buffer with size in int32_t field */ VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */ VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/ +VMS_VARRAY_UINT32= 0x800, /* Array with size in uint32_t field*/ }; typedef struct { @@ -438,6 +439,16 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_pointer(_state, _field, _type), \ } +#define VMSTATE_VARRAY_UINT32(_field, _state, _field_num, _version, _info, _type) {\ +.name = (stringify(_field)), \ +.version_id = (_version),\ +.num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ +.info = &(_info), \ +.size = sizeof(_type), \ +.flags = VMS_VARRAY_UINT32|VMS_POINTER, \ +.offset = vmstate_offset_pointer(_state, _field, _type), \ +} + #define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version),\ diff --git a/savevm.c b/savevm.c index 4db036b..60d2f2a 100644 --- a/savevm.c +++ b/savevm.c @@ -1329,6 +1329,8 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, n_elems = field->num; } else if (field->flags & VMS_VARRAY_INT32) { n_elems = *(int32_t *)(opaque+field->num_offset); +} else if (field->flags & VMS_VARRAY_UINT32) { +n_elems = *(uint32_t *)(opaque+field->num_offset); } else if (field->flags & VMS_VARRAY_UINT16) { n_elems = *(uint16_t *)(opaque+field->num_offset); } else if (field->flags & VMS_VARRAY_UINT8) { -- 1.7.4
[Qemu-devel] [PATCH 9/9] vmstate: move timers to use test instead of version
Signed-off-by: Juan Quintela --- hw/hw.h | 15 --- 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 4e09f18..1b09039 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -399,6 +399,15 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_value(_state, _field, _type), \ } +#define VMSTATE_POINTER_TEST(_field, _state, _test, _info, _type) { \ +.name = (stringify(_field)), \ +.info = &(_info), \ +.field_exists = (_test), \ +.size = sizeof(_type), \ +.flags = VMS_SINGLE|VMS_POINTER,\ +.offset = vmstate_offset_value(_state, _field, _type), \ +} + #define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version),\ @@ -766,11 +775,11 @@ extern const VMStateDescription vmstate_usb_device; #define VMSTATE_UINT32_TEST(_f, _s, _t) \ VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t) -#define VMSTATE_TIMER_V(_f, _s, _v) \ -VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *) +#define VMSTATE_TIMER_TEST(_f, _s, _test) \ +VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *) #define VMSTATE_TIMER(_f, _s) \ -VMSTATE_TIMER_V(_f, _s, 0) +VMSTATE_TIMER_TEST(_f, _s, NULL) #define VMSTATE_TIMER_ARRAY(_f, _s, _n) \ VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *) -- 1.7.4
[Qemu-devel] [PATCH 6/9] vmstate: add VMSTATE_STRUCT_VARRAY_UINT32
Signed-off-by: Juan Quintela --- hw/hw.h | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index d801694..c198ce8 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -539,6 +539,16 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = offsetof(_state, _field), \ } +#define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \ +.name = (stringify(_field)), \ +.num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \ +.version_id = (_version),\ +.vmsd = &(_vmsd), \ +.size = sizeof(_type), \ +.flags = VMS_STRUCT|VMS_VARRAY_UINT32, \ +.offset = offsetof(_state, _field), \ +} + #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ -- 1.7.4
[Qemu-devel] [PATCH 8/9] vmstate: be able to store/save a pci device from a pointer
Signed-off-by: Juan Quintela --- hw/hw.h |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 9df1c2c..4e09f18 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -629,6 +629,14 @@ extern const VMStateDescription vmstate_pci_device; .offset = vmstate_offset_value(_state, _field, PCIDevice), \ } +#define VMSTATE_PCI_DEVICE_POINTER(_field, _state) { \ +.name = (stringify(_field)), \ +.size = sizeof(PCIDevice), \ +.vmsd = &vmstate_pci_device, \ +.flags = VMS_STRUCT|VMS_POINTER,\ +.offset = vmstate_offset_pointer(_state, _field, PCIDevice), \ +} + extern const VMStateDescription vmstate_pcie_device; #define VMSTATE_PCIE_DEVICE(_field, _state) {\ -- 1.7.4
[Qemu-devel] [PATCH 4/9] vmstate: add VMSTATE_STRUCT_VARRAY_INT32
Signed-off-by: Juan Quintela --- hw/hw.h | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 6e78fa9..0ed63c5 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -529,6 +529,16 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_pointer(_state, _field, _type), \ } +#define VMSTATE_STRUCT_VARRAY_INT32(_field, _state, _field_num, _version, _vmsd, _type) { \ +.name = (stringify(_field)), \ +.num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ +.version_id = (_version),\ +.vmsd = &(_vmsd), \ +.size = sizeof(_type), \ +.flags = VMS_STRUCT|VMS_VARRAY_INT32, \ +.offset = offsetof(_state, _field), \ +} + #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ -- 1.7.4
[Qemu-devel] [PATCH 7/9] vmstate: Add a way to send a partial array
Signed-off-by: Juan Quintela --- hw/hw.h |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index c198ce8..9df1c2c 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -429,6 +429,15 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \ } +#define VMSTATE_ARRAY_INT32_UNSAFE(_field, _state, _field_num, _info, _type) {\ +.name = (stringify(_field)), \ +.num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ +.info = &(_info), \ +.size = sizeof(_type), \ +.flags = VMS_VARRAY_INT32, \ +.offset = offsetof(_state, _field), \ +} + #define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version),\ -- 1.7.4
[Qemu-devel] Re: RFC: emulation of system flash
On 2011-03-10 12:27, Jan Kiszka wrote: > On 2011-03-10 10:47, Gleb Natapov wrote: >> On Wed, Mar 09, 2011 at 08:51:23PM -0800, Jordan Justen wrote: >>> Hi all, >>> >>> I have documented a simple flash-like device which I think could be >>> useful for qemu/kvm in some cases. (Particularly for allowing >>> persistent UEFI non-volatile variables.) >>> >>> http://wiki.qemu.org/Features/System_Flash >>> >>> Let me know if you have any suggestions or concerns. >>> >> >> Two things. First You suggest to replace -bios with -flash. This will >> make firmware upgrade painful process that will have to be performed >> from inside the guest since the same flash image will contain both >> firmware and whatever data was stored on a flash which presumably you >> want to reuse after upgrading a firmware. My suggestion is to extend >> -bios option like this: >> >> -bios bios.bin,flash=flash.bin,flash_base=addr >> >> flash.bin will be mapped at address flash_base, or, if flash_base is not >> present, just below bios.bin. > > ...or define -flash in a way that allows mapping the bios image as an > overlay to the otherwise guest-managed flash image. Better define flash chips as qdev devices and make the attributes qdev properties: -device flash,image=...,base=...,overlay=...,overlay_start=... Images should be addressed by block device IDs and created via '-drive' (likely requires a new interface type 'flash'). That way you could define the bios overlay as "snapshot" so that the guest could happily corrupt it, but restarting the VM would pick up a well-defined version again. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH 04/32] vmstate: port m48t59
Signed-off-by: Juan Quintela --- hw/m48t59.c | 36 +--- 1 files changed, 13 insertions(+), 23 deletions(-) diff --git a/hw/m48t59.c b/hw/m48t59.c index 2020487..82223c9 100644 --- a/hw/m48t59.c +++ b/hw/m48t59.c @@ -585,28 +585,18 @@ static CPUReadMemoryFunc * const nvram_read[] = { &nvram_readl, }; -static void m48t59_save(QEMUFile *f, void *opaque) -{ -M48t59State *s = opaque; - -qemu_put_8s(f, &s->lock); -qemu_put_be16s(f, &s->addr); -qemu_put_buffer(f, s->buffer, s->size); -} - -static int m48t59_load(QEMUFile *f, void *opaque, int version_id) -{ -M48t59State *s = opaque; - -if (version_id != 1) -return -EINVAL; - -qemu_get_8s(f, &s->lock); -qemu_get_be16s(f, &s->addr); -qemu_get_buffer(f, s->buffer, s->size); - -return 0; -} +static const VMStateDescription vmstate_m48t59 = { +.name = "m48t59", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT8(lock, M48t59State), +VMSTATE_UINT16(addr, M48t59State), +VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, 0, size), +VMSTATE_END_OF_LIST() +} +}; static void m48t59_reset_common(M48t59State *NVRAM) { @@ -696,7 +686,7 @@ static void m48t59_init_common(M48t59State *s) } qemu_get_timedate(&s->alarm, 0); -register_savevm(NULL, "m48t59", -1, 1, m48t59_save, m48t59_load, s); +vmstate_register(NULL, -1, &vmstate_m48t59, s); } static int m48t59_init_isa1(ISADevice *dev) -- 1.7.4
[Qemu-devel] [PATCH 03/32] vmstate: port ads7846
Signed-off-by: Juan Quintela --- hw/ads7846.c | 41 ++--- 1 files changed, 18 insertions(+), 23 deletions(-) diff --git a/hw/ads7846.c b/hw/ads7846.c index b3bbeaf..9c58a5f 100644 --- a/hw/ads7846.c +++ b/hw/ads7846.c @@ -105,35 +105,30 @@ static void ads7846_ts_event(void *opaque, } } -static void ads7846_save(QEMUFile *f, void *opaque) +static int ads7856_post_load(void *opaque, int version_id) { -ADS7846State *s = (ADS7846State *) opaque; -int i; - -for (i = 0; i < 8; i ++) -qemu_put_be32(f, s->input[i]); -qemu_put_be32(f, s->noise); -qemu_put_be32(f, s->cycle); -qemu_put_be32(f, s->output); -} - -static int ads7846_load(QEMUFile *f, void *opaque, int version_id) -{ -ADS7846State *s = (ADS7846State *) opaque; -int i; - -for (i = 0; i < 8; i ++) -s->input[i] = qemu_get_be32(f); -s->noise = qemu_get_be32(f); -s->cycle = qemu_get_be32(f); -s->output = qemu_get_be32(f); +ADS7846State *s = opaque; s->pressure = 0; ads7846_int_update(s); - return 0; } +static const VMStateDescription vmstate_ads7846 = { +.name = "ads7846", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.post_load = ads7856_post_load, +.fields = (VMStateField[]) { +VMSTATE_INT32_ARRAY(input, ADS7846State, 8), +VMSTATE_INT32(noise, ADS7846State), +VMSTATE_INT32(cycle, ADS7846State), +VMSTATE_INT32(output, ADS7846State), +VMSTATE_END_OF_LIST() +} +}; + static int ads7846_init(SSISlave *dev) { ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev); @@ -151,7 +146,7 @@ static int ads7846_init(SSISlave *dev) ads7846_int_update(s); -register_savevm(NULL, "ads7846", -1, 0, ads7846_save, ads7846_load, s); +vmstate_register(NULL, -1, &vmstate_ads7846, s); return 0; } -- 1.7.4
[Qemu-devel] Re: RFC: emulation of system flash
On Thu, Mar 10, 2011 at 12:27:55PM +0100, Jan Kiszka wrote: > On 2011-03-10 10:47, Gleb Natapov wrote: > > On Wed, Mar 09, 2011 at 08:51:23PM -0800, Jordan Justen wrote: > >> Hi all, > >> > >> I have documented a simple flash-like device which I think could be > >> useful for qemu/kvm in some cases. (Particularly for allowing > >> persistent UEFI non-volatile variables.) > >> > >> http://wiki.qemu.org/Features/System_Flash > >> > >> Let me know if you have any suggestions or concerns. > >> > > > > Two things. First You suggest to replace -bios with -flash. This will > > make firmware upgrade painful process that will have to be performed > > from inside the guest since the same flash image will contain both > > firmware and whatever data was stored on a flash which presumably you > > want to reuse after upgrading a firmware. My suggestion is to extend > > -bios option like this: > > > > -bios bios.bin,flash=flash.bin,flash_base=addr > > > > flash.bin will be mapped at address flash_base, or, if flash_base is not > > present, just below bios.bin. > > ...or define -flash in a way that allows mapping the bios image as an > overlay to the otherwise guest-managed flash image. > It is not much different from what I proposed. The result will be the same. Even option syntax will probably be the same :) > > > > Second. I asked how flash is programmed because interfaces like CFI > > where you write into flash memory address range to issue commands cannot > > be emulated efficiently in KVM. KVM supports either regular memory slots > > or IO memory, but in your proposal the same memory behaves as IO on > > write and regular memory on read. Better idea would be to present > > non-volatile flash as ISA virtio device. Should be simple to implement. > > Why not enhancing KVM memory slots to support direct read access while > writes are trapped and forwarded to a user space device model? Yes we can make memory slot that will be treated as memory on read and IO on write, but first relying on that will prevent using flash interface on older kernels and second it is not enough to implement the proposal. When magic value is written into an address, the address become IO for reading too, but KVM slot granularity is page, not byte, so KVM will have to remove the slot to make it IO, but KVM can't execute code from IO region (yet), so we will not be able to run firmware from flash and simultaneously write into the flash. > Virtio > means that you have to patch the guest (which might be something else > than flexible Linux...). > This intended to be used by firmware only and we control that. -- Gleb.
[Qemu-devel] [PATCH 00/32] VMState port of misc devices
Hi This are the devices that conversion was trivial. Series is on top of my previous series: [PATCH 0/9] VMState infrastructure All coments from Blue Swirl have been addressed (thanks for them). Change for PCI Device from Isazu was not implemented because I can test that it work. I like the change but would prefer it to be independent of this series Later, Juan. Juan Quintela (32): vmstate: port adb_kbd vmstate: port adb_mouse vmstate: port ads7846 vmstate: port m48t59 vmstate: port mipsnet vmstate: port arm sp804 vmstate: port arm_timer vmstate: port sysborg_timer vmstate: port pmtimer vmstate: port syborg_rtc vmstate: port pxa2xx_keypad vmstate: port pl011 vmstate: port armv7m nvic vmstate: port stellaris i2c vmstate: port stellaris ssi bus vmstate: port stellaris sys vmstate: port pl022 ssp vmstate: port heathrow_pic vmstate: port cuda vmstate: port stellaris gptm vmstate: port pxa2xx_i2s vmstate: port pxa2xx_cm vmstate: port pxa2xx_mm vmstate: port pxa2xx_pm vmstate: port ppce500_pci vmstate: port ppc4xx_pci vmstate: port syborg_pointer vmstate: port stellaris_adc vmstate: port syborg_serial vmstate: port syborg_keyboard vmstate: port stellaris gamepad vmstate: stellaris use unused for placeholder entries hw/adb.c | 83 +- hw/ads7846.c | 41 +++ hw/arm_timer.c | 66 --- hw/armv7m_nvic.c | 39 ++ hw/cuda.c| 116 +++--- hw/heathrow_pic.c| 62 -- hw/hw.h | 17 ++- hw/m48t59.c | 36 ++ hw/mipsnet.c | 53 +++-- hw/pl011.c | 76 hw/pl022.c | 84 ++ hw/ppc4xx_pci.c | 80 ++--- hw/ppce500_pci.c | 87 ++ hw/ptimer.c | 59 +++--- hw/pxa2xx.c | 158 + hw/pxa2xx_keypad.c | 53 +++-- hw/stellaris.c | 323 +- hw/stellaris_input.c | 50 hw/syborg_keyboard.c | 57 +++-- hw/syborg_pointer.c | 73 +--- hw/syborg_rtc.c | 34 ++ hw/syborg_serial.c | 60 +++--- hw/syborg_timer.c| 46 +++- qemu-timer.h |2 - 24 files changed, 654 insertions(+), 1101 deletions(-) -- 1.7.4
[Qemu-devel] [PATCH 09/32] vmstate: port pmtimer
It was a half conversion. Finish it. enabled can only get values of 0, 1 or 2, was declared as an int but sent as an unint8_t, change its type. Signed-off-by: Juan Quintela --- hw/hw.h | 17 ++- hw/ptimer.c | 59 +++-- qemu-timer.h |2 - 3 files changed, 27 insertions(+), 51 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 4e2d592..059ef06 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -630,6 +630,17 @@ extern const VMStateDescription vmstate_usb_device; .offset = vmstate_offset_macaddr(_state, _field),\ } +extern const VMStateDescription vmstate_ptimer; + +#define VMSTATE_PTIMER(_field, _state) { \ +.name = (stringify(_field)), \ +.version_id = (1), \ +.vmsd = &vmstate_ptimer, \ +.size = sizeof(ptimer_state *),\ +.flags = VMS_STRUCT|VMS_POINTER,\ +.offset = vmstate_offset_pointer(_state, _field, ptimer_state), \ +} + /* _f : field name _f_n : num of elements field_name _n : num of elements @@ -722,12 +733,6 @@ extern const VMStateDescription vmstate_usb_device; #define VMSTATE_TIMER_ARRAY(_f, _s, _n) \ VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *) -#define VMSTATE_PTIMER_V(_f, _s, _v) \ -VMSTATE_POINTER(_f, _s, _v, vmstate_info_ptimer, ptimer_state *) - -#define VMSTATE_PTIMER(_f, _s)\ -VMSTATE_PTIMER_V(_f, _s, 0) - #define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v) \ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool) diff --git a/hw/ptimer.c b/hw/ptimer.c index 4ddbc59..6b1f761 100644 --- a/hw/ptimer.c +++ b/hw/ptimer.c @@ -11,7 +11,7 @@ struct ptimer_state { -int enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */ +uint8_t enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */ uint64_t limit; uint64_t delta; uint32_t period_frac; @@ -188,49 +188,22 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload) } } -void qemu_put_ptimer(QEMUFile *f, ptimer_state *s) -{ -qemu_put_byte(f, s->enabled); -qemu_put_be64s(f, &s->limit); -qemu_put_be64s(f, &s->delta); -qemu_put_be32s(f, &s->period_frac); -qemu_put_sbe64s(f, &s->period); -qemu_put_sbe64s(f, &s->last_event); -qemu_put_sbe64s(f, &s->next_event); -qemu_put_timer(f, s->timer); -} - -void qemu_get_ptimer(QEMUFile *f, ptimer_state *s) -{ -s->enabled = qemu_get_byte(f); -qemu_get_be64s(f, &s->limit); -qemu_get_be64s(f, &s->delta); -qemu_get_be32s(f, &s->period_frac); -qemu_get_sbe64s(f, &s->period); -qemu_get_sbe64s(f, &s->last_event); -qemu_get_sbe64s(f, &s->next_event); -qemu_get_timer(f, s->timer); -} - -static int get_ptimer(QEMUFile *f, void *pv, size_t size) -{ -ptimer_state *v = pv; - -qemu_get_ptimer(f, v); -return 0; -} - -static void put_ptimer(QEMUFile *f, void *pv, size_t size) -{ -ptimer_state *v = pv; - -qemu_put_ptimer(f, v); -} - -const VMStateInfo vmstate_info_ptimer = { +const VMStateDescription vmstate_ptimer = { .name = "ptimer", -.get = get_ptimer, -.put = put_ptimer, +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT8(enabled, ptimer_state), +VMSTATE_UINT64(limit, ptimer_state), +VMSTATE_UINT64(delta, ptimer_state), +VMSTATE_UINT32(period_frac, ptimer_state), +VMSTATE_INT64(period, ptimer_state), +VMSTATE_INT64(last_event, ptimer_state), +VMSTATE_INT64(next_event, ptimer_state), +VMSTATE_TIMER(timer, ptimer_state), +VMSTATE_END_OF_LIST() +} }; ptimer_state *ptimer_init(QEMUBH *bh) diff --git a/qemu-timer.h b/qemu-timer.h index 8cd8f83..5c13ede 100644 --- a/qemu-timer.h +++ b/qemu-timer.h @@ -118,8 +118,6 @@ uint64_t ptimer_get_count(ptimer_state *s); void ptimer_set_count(ptimer_state *s, uint64_t count); void ptimer_run(ptimer_state *s, int oneshot); void ptimer_stop(ptimer_state *s); -void qemu_put_ptimer(QEMUFile *f, ptimer_state *s); -void qemu_get_ptimer(QEMUFile *f, ptimer_state *s); /* icount */ int64_t qemu_icount_round(int64_t count); -- 1.7.4
[Qemu-devel] [PATCH 06/32] vmstate: port arm sp804
Signed-off-by: Juan Quintela --- hw/arm_timer.c | 29 +++-- 1 files changed, 11 insertions(+), 18 deletions(-) diff --git a/hw/arm_timer.c b/hw/arm_timer.c index 82f05de..cfd1ebe 100644 --- a/hw/arm_timer.c +++ b/hw/arm_timer.c @@ -235,24 +235,17 @@ static CPUWriteMemoryFunc * const sp804_writefn[] = { sp804_write }; -static void sp804_save(QEMUFile *f, void *opaque) -{ -sp804_state *s = (sp804_state *)opaque; -qemu_put_be32(f, s->level[0]); -qemu_put_be32(f, s->level[1]); -} -static int sp804_load(QEMUFile *f, void *opaque, int version_id) -{ -sp804_state *s = (sp804_state *)opaque; - -if (version_id != 1) -return -EINVAL; - -s->level[0] = qemu_get_be32(f); -s->level[1] = qemu_get_be32(f); -return 0; -} +static const VMStateDescription vmstate_sp804 = { +.name = "sp804", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32_ARRAY(level, sp804_state, 2), +VMSTATE_END_OF_LIST() +} +}; static int sp804_init(SysBusDevice *dev) { @@ -271,7 +264,7 @@ static int sp804_init(SysBusDevice *dev) iomemtype = cpu_register_io_memory(sp804_readfn, sp804_writefn, s, DEVICE_NATIVE_ENDIAN); sysbus_init_mmio(dev, 0x1000, iomemtype); -register_savevm(&dev->qdev, "sp804", -1, 1, sp804_save, sp804_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_sp804, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 01/32] vmstate: port adb_kbd
Signed-off-by: Juan Quintela --- hw/adb.c | 40 ++-- 1 files changed, 14 insertions(+), 26 deletions(-) diff --git a/hw/adb.c b/hw/adb.c index 99b30f6..fbf5080 100644 --- a/hw/adb.c +++ b/hw/adb.c @@ -261,30 +261,19 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, return olen; } -static void adb_kbd_save(QEMUFile *f, void *opaque) -{ -KBDState *s = (KBDState *)opaque; - -qemu_put_buffer(f, s->data, sizeof(s->data)); -qemu_put_sbe32s(f, &s->rptr); -qemu_put_sbe32s(f, &s->wptr); -qemu_put_sbe32s(f, &s->count); -} - -static int adb_kbd_load(QEMUFile *f, void *opaque, int version_id) -{ -KBDState *s = (KBDState *)opaque; - -if (version_id != 1) -return -EINVAL; - -qemu_get_buffer(f, s->data, sizeof(s->data)); -qemu_get_sbe32s(f, &s->rptr); -qemu_get_sbe32s(f, &s->wptr); -qemu_get_sbe32s(f, &s->count); - -return 0; -} +static const VMStateDescription vmstate_adb_kbd = { +.name = "adb_kbd", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_BUFFER(data, KBDState), +VMSTATE_INT32(rptr, KBDState), +VMSTATE_INT32(wptr, KBDState), +VMSTATE_INT32(count, KBDState), +VMSTATE_END_OF_LIST() +} +}; static int adb_kbd_reset(ADBDevice *d) { @@ -305,8 +294,7 @@ void adb_kbd_init(ADBBusState *bus) d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, adb_kbd_reset, s); qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); -register_savevm(NULL, "adb_kbd", -1, 1, adb_kbd_save, -adb_kbd_load, s); +vmstate_register(NULL, -1, &vmstate_adb_kbd, s); } /***/ -- 1.7.4
[Qemu-devel] [PATCH 02/32] vmstate: port adb_mouse
Signed-off-by: Juan Quintela --- hw/adb.c | 43 +++ 1 files changed, 15 insertions(+), 28 deletions(-) diff --git a/hw/adb.c b/hw/adb.c index fbf5080..7499cdc 100644 --- a/hw/adb.c +++ b/hw/adb.c @@ -427,32 +427,20 @@ static int adb_mouse_reset(ADBDevice *d) return 0; } -static void adb_mouse_save(QEMUFile *f, void *opaque) -{ -MouseState *s = (MouseState *)opaque; - -qemu_put_sbe32s(f, &s->buttons_state); -qemu_put_sbe32s(f, &s->last_buttons_state); -qemu_put_sbe32s(f, &s->dx); -qemu_put_sbe32s(f, &s->dy); -qemu_put_sbe32s(f, &s->dz); -} - -static int adb_mouse_load(QEMUFile *f, void *opaque, int version_id) -{ -MouseState *s = (MouseState *)opaque; - -if (version_id != 1) -return -EINVAL; - -qemu_get_sbe32s(f, &s->buttons_state); -qemu_get_sbe32s(f, &s->last_buttons_state); -qemu_get_sbe32s(f, &s->dx); -qemu_get_sbe32s(f, &s->dy); -qemu_get_sbe32s(f, &s->dz); - -return 0; -} +static const VMStateDescription vmstate_adb_mouse = { +.name = "adb_mouse", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32(buttons_state, MouseState), +VMSTATE_INT32(last_buttons_state, MouseState), +VMSTATE_INT32(dx, MouseState), +VMSTATE_INT32(dy, MouseState), +VMSTATE_INT32(dz, MouseState), +VMSTATE_END_OF_LIST() +} +}; void adb_mouse_init(ADBBusState *bus) { @@ -463,6 +451,5 @@ void adb_mouse_init(ADBBusState *bus) d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, adb_mouse_reset, s); qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse"); -register_savevm(NULL, "adb_mouse", -1, 1, adb_mouse_save, -adb_mouse_load, s); +vmstate_register(NULL, -1, &vmstate_adb_mouse, s); } -- 1.7.4
[Qemu-devel] [PATCH 10/32] vmstate: port syborg_rtc
Signed-off-by: Juan Quintela --- hw/syborg_rtc.c | 34 -- 1 files changed, 12 insertions(+), 22 deletions(-) diff --git a/hw/syborg_rtc.c b/hw/syborg_rtc.c index 329aa42..4e24e52 100644 --- a/hw/syborg_rtc.c +++ b/hw/syborg_rtc.c @@ -102,26 +102,17 @@ static CPUWriteMemoryFunc * const syborg_rtc_writefn[] = { syborg_rtc_write }; -static void syborg_rtc_save(QEMUFile *f, void *opaque) -{ -SyborgRTCState *s = opaque; - -qemu_put_be64(f, s->offset); -qemu_put_be64(f, s->data); -} - -static int syborg_rtc_load(QEMUFile *f, void *opaque, int version_id) -{ -SyborgRTCState *s = opaque; - -if (version_id != 1) -return -EINVAL; - -s->offset = qemu_get_be64(f); -s->data = qemu_get_be64(f); - -return 0; -} +static const VMStateDescription vmstate_syborg_rtc = { +.name = "syborg_keyboard", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_INT64(offset, SyborgRTCState), +VMSTATE_INT64(data, SyborgRTCState), +VMSTATE_END_OF_LIST() +} +}; static int syborg_rtc_init(SysBusDevice *dev) { @@ -137,8 +128,7 @@ static int syborg_rtc_init(SysBusDevice *dev) qemu_get_timedate(&tm, 0); s->offset = (uint64_t)mktime(&tm) * 10; -register_savevm(&dev->qdev, "syborg_rtc", -1, 1, -syborg_rtc_save, syborg_rtc_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_syborg_rtc, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 17/32] vmstate: port pl022 ssp
Signed-off-by: Juan Quintela --- hw/pl022.c | 84 +-- 1 files changed, 36 insertions(+), 48 deletions(-) diff --git a/hw/pl022.c b/hw/pl022.c index ffe05ab..00e494a 100644 --- a/hw/pl022.c +++ b/hw/pl022.c @@ -239,54 +239,42 @@ static CPUWriteMemoryFunc * const pl022_writefn[] = { pl022_write }; -static void pl022_save(QEMUFile *f, void *opaque) -{ -pl022_state *s = (pl022_state *)opaque; -int i; - -qemu_put_be32(f, s->cr0); -qemu_put_be32(f, s->cr1); -qemu_put_be32(f, s->bitmask); -qemu_put_be32(f, s->sr); -qemu_put_be32(f, s->cpsr); -qemu_put_be32(f, s->is); -qemu_put_be32(f, s->im); -qemu_put_be32(f, s->tx_fifo_head); -qemu_put_be32(f, s->rx_fifo_head); -qemu_put_be32(f, s->tx_fifo_len); -qemu_put_be32(f, s->rx_fifo_len); -for (i = 0; i < 8; i++) { -qemu_put_be16(f, s->tx_fifo[i]); -qemu_put_be16(f, s->rx_fifo[i]); -} -} - -static int pl022_load(QEMUFile *f, void *opaque, int version_id) -{ -pl022_state *s = (pl022_state *)opaque; -int i; - -if (version_id != 1) -return -EINVAL; - -s->cr0 = qemu_get_be32(f); -s->cr1 = qemu_get_be32(f); -s->bitmask = qemu_get_be32(f); -s->sr = qemu_get_be32(f); -s->cpsr = qemu_get_be32(f); -s->is = qemu_get_be32(f); -s->im = qemu_get_be32(f); -s->tx_fifo_head = qemu_get_be32(f); -s->rx_fifo_head = qemu_get_be32(f); -s->tx_fifo_len = qemu_get_be32(f); -s->rx_fifo_len = qemu_get_be32(f); -for (i = 0; i < 8; i++) { -s->tx_fifo[i] = qemu_get_be16(f); -s->rx_fifo[i] = qemu_get_be16(f); +static const VMStateDescription vmstate_pl022 = { +.name = "pl022_ssp", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32(cr0, pl022_state), +VMSTATE_UINT32(cr1, pl022_state), +VMSTATE_UINT32(bitmask, pl022_state), +VMSTATE_UINT32(sr, pl022_state), +VMSTATE_UINT32(cpsr, pl022_state), +VMSTATE_UINT32(is, pl022_state), +VMSTATE_UINT32(im, pl022_state), +VMSTATE_INT32(tx_fifo_head, pl022_state), +VMSTATE_INT32(rx_fifo_head, pl022_state), +VMSTATE_INT32(tx_fifo_len, pl022_state), +VMSTATE_INT32(rx_fifo_len, pl022_state), +VMSTATE_UINT16(tx_fifo[0], pl022_state), +VMSTATE_UINT16(rx_fifo[0], pl022_state), +VMSTATE_UINT16(tx_fifo[1], pl022_state), +VMSTATE_UINT16(rx_fifo[1], pl022_state), +VMSTATE_UINT16(tx_fifo[2], pl022_state), +VMSTATE_UINT16(rx_fifo[2], pl022_state), +VMSTATE_UINT16(tx_fifo[3], pl022_state), +VMSTATE_UINT16(rx_fifo[3], pl022_state), +VMSTATE_UINT16(tx_fifo[4], pl022_state), +VMSTATE_UINT16(rx_fifo[4], pl022_state), +VMSTATE_UINT16(tx_fifo[5], pl022_state), +VMSTATE_UINT16(rx_fifo[5], pl022_state), +VMSTATE_UINT16(tx_fifo[6], pl022_state), +VMSTATE_UINT16(rx_fifo[6], pl022_state), +VMSTATE_UINT16(tx_fifo[7], pl022_state), +VMSTATE_UINT16(rx_fifo[7], pl022_state), +VMSTATE_END_OF_LIST() } - -return 0; -} +}; static int pl022_init(SysBusDevice *dev) { @@ -300,7 +288,7 @@ static int pl022_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); s->ssi = ssi_create_bus(&dev->qdev, "ssi"); pl022_reset(s); -register_savevm(&dev->qdev, "pl022_ssp", -1, 1, pl022_save, pl022_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_pl022, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 05/32] vmstate: port mipsnet
Signed-off-by: Juan Quintela --- hw/mipsnet.c | 53 +++-- 1 files changed, 19 insertions(+), 34 deletions(-) diff --git a/hw/mipsnet.c b/hw/mipsnet.c index c5e54ff..26aad51 100644 --- a/hw/mipsnet.c +++ b/hw/mipsnet.c @@ -202,44 +202,29 @@ static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -static void mipsnet_save(QEMUFile *f, void *opaque) -{ -MIPSnetState *s = opaque; - -qemu_put_be32s(f, &s->busy); -qemu_put_be32s(f, &s->rx_count); -qemu_put_be32s(f, &s->rx_read); -qemu_put_be32s(f, &s->tx_count); -qemu_put_be32s(f, &s->tx_written); -qemu_put_be32s(f, &s->intctl); -qemu_put_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE); -qemu_put_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE); -} - -static int mipsnet_load(QEMUFile *f, void *opaque, int version_id) -{ -MIPSnetState *s = opaque; - -if (version_id > 0) -return -EINVAL; - -qemu_get_be32s(f, &s->busy); -qemu_get_be32s(f, &s->rx_count); -qemu_get_be32s(f, &s->rx_read); -qemu_get_be32s(f, &s->tx_count); -qemu_get_be32s(f, &s->tx_written); -qemu_get_be32s(f, &s->intctl); -qemu_get_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE); -qemu_get_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE); - -return 0; -} +static const VMStateDescription vmstate_mipsnet = { +.name = "mipsnet", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32(busy, MIPSnetState), +VMSTATE_UINT32(rx_count, MIPSnetState), +VMSTATE_UINT32(rx_read, MIPSnetState), +VMSTATE_UINT32(tx_count, MIPSnetState), +VMSTATE_UINT32(tx_written, MIPSnetState), +VMSTATE_UINT32(intctl, MIPSnetState), +VMSTATE_BUFFER(rx_buffer, MIPSnetState), +VMSTATE_BUFFER(tx_buffer, MIPSnetState), +VMSTATE_END_OF_LIST() +} +}; static void mipsnet_cleanup(VLANClientState *nc) { MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque; -unregister_savevm(NULL, "mipsnet", s); +vmstate_unregister(NULL, &vmstate_mipsnet, s); isa_unassign_ioport(s->io_base, 36); @@ -284,5 +269,5 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd) } mipsnet_reset(s); -register_savevm(NULL, "mipsnet", 0, 0, mipsnet_save, mipsnet_load, s); +vmstate_register(NULL, 0, &vmstate_mipsnet, s); } -- 1.7.4
[Qemu-devel] [PATCH 07/32] vmstate: port arm_timer
Signed-off-by: Juan Quintela --- hw/arm_timer.c | 37 ++--- 1 files changed, 14 insertions(+), 23 deletions(-) diff --git a/hw/arm_timer.c b/hw/arm_timer.c index cfd1ebe..dac9e70 100644 --- a/hw/arm_timer.c +++ b/hw/arm_timer.c @@ -140,28 +140,19 @@ static void arm_timer_tick(void *opaque) arm_timer_update(s); } -static void arm_timer_save(QEMUFile *f, void *opaque) -{ -arm_timer_state *s = (arm_timer_state *)opaque; -qemu_put_be32(f, s->control); -qemu_put_be32(f, s->limit); -qemu_put_be32(f, s->int_level); -qemu_put_ptimer(f, s->timer); -} - -static int arm_timer_load(QEMUFile *f, void *opaque, int version_id) -{ -arm_timer_state *s = (arm_timer_state *)opaque; - -if (version_id != 1) -return -EINVAL; - -s->control = qemu_get_be32(f); -s->limit = qemu_get_be32(f); -s->int_level = qemu_get_be32(f); -qemu_get_ptimer(f, s->timer); -return 0; -} +static const VMStateDescription vmstate_arm_timer = { +.name = "arm_timer", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32(control, arm_timer_state), +VMSTATE_UINT32(limit, arm_timer_state), +VMSTATE_INT32(int_level, arm_timer_state), +VMSTATE_PTIMER(timer, arm_timer_state), +VMSTATE_END_OF_LIST() +} +}; static arm_timer_state *arm_timer_init(uint32_t freq) { @@ -174,7 +165,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq) bh = qemu_bh_new(arm_timer_tick, s); s->timer = ptimer_init(bh); -register_savevm(NULL, "arm_timer", -1, 1, arm_timer_save, arm_timer_load, s); +vmstate_register(NULL, -1, &vmstate_arm_timer, s); return s; } -- 1.7.4
[Qemu-devel] [PATCH 12/32] vmstate: port pl011
Signed-off-by: Juan Quintela --- hw/pl011.c | 76 +++ 1 files changed, 25 insertions(+), 51 deletions(-) diff --git a/hw/pl011.c b/hw/pl011.c index 77f0dbf..3b94b14 100644 --- a/hw/pl011.c +++ b/hw/pl011.c @@ -235,56 +235,30 @@ static CPUWriteMemoryFunc * const pl011_writefn[] = { pl011_write }; -static void pl011_save(QEMUFile *f, void *opaque) -{ -pl011_state *s = (pl011_state *)opaque; -int i; - -qemu_put_be32(f, s->readbuff); -qemu_put_be32(f, s->flags); -qemu_put_be32(f, s->lcr); -qemu_put_be32(f, s->cr); -qemu_put_be32(f, s->dmacr); -qemu_put_be32(f, s->int_enabled); -qemu_put_be32(f, s->int_level); -for (i = 0; i < 16; i++) -qemu_put_be32(f, s->read_fifo[i]); -qemu_put_be32(f, s->ilpr); -qemu_put_be32(f, s->ibrd); -qemu_put_be32(f, s->fbrd); -qemu_put_be32(f, s->ifl); -qemu_put_be32(f, s->read_pos); -qemu_put_be32(f, s->read_count); -qemu_put_be32(f, s->read_trigger); -} - -static int pl011_load(QEMUFile *f, void *opaque, int version_id) -{ -pl011_state *s = (pl011_state *)opaque; -int i; - -if (version_id != 1) -return -EINVAL; - -s->readbuff = qemu_get_be32(f); -s->flags = qemu_get_be32(f); -s->lcr = qemu_get_be32(f); -s->cr = qemu_get_be32(f); -s->dmacr = qemu_get_be32(f); -s->int_enabled = qemu_get_be32(f); -s->int_level = qemu_get_be32(f); -for (i = 0; i < 16; i++) -s->read_fifo[i] = qemu_get_be32(f); -s->ilpr = qemu_get_be32(f); -s->ibrd = qemu_get_be32(f); -s->fbrd = qemu_get_be32(f); -s->ifl = qemu_get_be32(f); -s->read_pos = qemu_get_be32(f); -s->read_count = qemu_get_be32(f); -s->read_trigger = qemu_get_be32(f); - -return 0; -} +static const VMStateDescription vmstate_pl011 = { +.name = "pl011", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32(readbuff, pl011_state), +VMSTATE_UINT32(flags, pl011_state), +VMSTATE_UINT32(lcr, pl011_state), +VMSTATE_UINT32(cr, pl011_state), +VMSTATE_UINT32(dmacr, pl011_state), +VMSTATE_UINT32(int_enabled, pl011_state), +VMSTATE_UINT32(int_level, pl011_state), +VMSTATE_UINT32_ARRAY(read_fifo, pl011_state, 16), +VMSTATE_UINT32(ilpr, pl011_state), +VMSTATE_UINT32(ibrd, pl011_state), +VMSTATE_UINT32(fbrd, pl011_state), +VMSTATE_UINT32(ifl, pl011_state), +VMSTATE_INT32(read_pos, pl011_state), +VMSTATE_INT32(read_count, pl011_state), +VMSTATE_INT32(read_trigger, pl011_state), +VMSTATE_END_OF_LIST() +} +}; static int pl011_init(SysBusDevice *dev, const unsigned char *id) { @@ -307,7 +281,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id) qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, pl011_event, s); } -register_savevm(&dev->qdev, "pl011_uart", -1, 1, pl011_save, pl011_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_pl011, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 27/32] vmstate: port syborg_pointer
Signed-off-by: Juan Quintela --- hw/syborg_pointer.c | 73 +++--- 1 files changed, 28 insertions(+), 45 deletions(-) diff --git a/hw/syborg_pointer.c b/hw/syborg_pointer.c index a886888..2f99707 100644 --- a/hw/syborg_pointer.c +++ b/hw/syborg_pointer.c @@ -152,52 +152,36 @@ static void syborg_pointer_event(void *opaque, int dx, int dy, int dz, syborg_pointer_update(s); } -static void syborg_pointer_save(QEMUFile *f, void *opaque) -{ -SyborgPointerState *s = (SyborgPointerState *)opaque; -int i; - -qemu_put_be32(f, s->fifo_size); -qemu_put_be32(f, s->absolute); -qemu_put_be32(f, s->int_enabled); -qemu_put_be32(f, s->read_pos); -qemu_put_be32(f, s->read_count); -for (i = 0; i < s->fifo_size; i++) { -qemu_put_be32(f, s->event_fifo[i].x); -qemu_put_be32(f, s->event_fifo[i].y); -qemu_put_be32(f, s->event_fifo[i].z); -qemu_put_be32(f, s->event_fifo[i].pointer_buttons); +static const VMStateDescription vmstate_event_data = { +.name = "dbma_channel", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_INT32(x, event_data), +VMSTATE_INT32(y, event_data), +VMSTATE_INT32(z, event_data), +VMSTATE_INT32(pointer_buttons, event_data), +VMSTATE_END_OF_LIST() } -} +}; -static int syborg_pointer_load(QEMUFile *f, void *opaque, int version_id) -{ -SyborgPointerState *s = (SyborgPointerState *)opaque; -uint32_t val; -int i; - -if (version_id != 1) -return -EINVAL; - -val = qemu_get_be32(f); -if (val != s->fifo_size) -return -EINVAL; - -val = qemu_get_be32(f); -if (val != s->absolute) -return -EINVAL; - -s->int_enabled = qemu_get_be32(f); -s->read_pos = qemu_get_be32(f); -s->read_count = qemu_get_be32(f); -for (i = 0; i < s->fifo_size; i++) { -s->event_fifo[i].x = qemu_get_be32(f); -s->event_fifo[i].y = qemu_get_be32(f); -s->event_fifo[i].z = qemu_get_be32(f); -s->event_fifo[i].pointer_buttons = qemu_get_be32(f); +static const VMStateDescription vmstate_syborg_pointer = { +.name = "syborg_pointer", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32_EQUAL(fifo_size, SyborgPointerState), +VMSTATE_UINT32_EQUAL(absolute, SyborgPointerState), +VMSTATE_INT32(int_enabled, SyborgPointerState), +VMSTATE_INT32(read_pos, SyborgPointerState), +VMSTATE_INT32(read_count, SyborgPointerState), +VMSTATE_STRUCT_VARRAY_UINT32(event_fifo, SyborgPointerState, fifo_size, + 1, vmstate_event_data, event_data), +VMSTATE_END_OF_LIST() } -return 0; -} +}; static int syborg_pointer_init(SysBusDevice *dev) { @@ -219,8 +203,7 @@ static int syborg_pointer_init(SysBusDevice *dev) qemu_add_mouse_event_handler(syborg_pointer_event, s, s->absolute, "Syborg Pointer"); -register_savevm(&dev->qdev, "syborg_pointer", -1, 1, -syborg_pointer_save, syborg_pointer_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_syborg_pointer, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 08/32] vmstate: port sysborg_timer
Signed-off-by: Juan Quintela --- hw/syborg_timer.c | 46 -- 1 files changed, 16 insertions(+), 30 deletions(-) diff --git a/hw/syborg_timer.c b/hw/syborg_timer.c index cedcd8e..50c813e 100644 --- a/hw/syborg_timer.c +++ b/hw/syborg_timer.c @@ -174,34 +174,21 @@ static CPUWriteMemoryFunc * const syborg_timer_writefn[] = { syborg_timer_write }; -static void syborg_timer_save(QEMUFile *f, void *opaque) -{ -SyborgTimerState *s = opaque; - -qemu_put_be32(f, s->running); -qemu_put_be32(f, s->oneshot); -qemu_put_be32(f, s->limit); -qemu_put_be32(f, s->int_level); -qemu_put_be32(f, s->int_enabled); -qemu_put_ptimer(f, s->timer); -} - -static int syborg_timer_load(QEMUFile *f, void *opaque, int version_id) -{ -SyborgTimerState *s = opaque; - -if (version_id != 1) -return -EINVAL; - -s->running = qemu_get_be32(f); -s->oneshot = qemu_get_be32(f); -s->limit = qemu_get_be32(f); -s->int_level = qemu_get_be32(f); -s->int_enabled = qemu_get_be32(f); -qemu_get_ptimer(f, s->timer); - -return 0; -} +static const VMStateDescription vmstate_syborg_timer = { +.name = "syborg_timer", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32(running, SyborgTimerState), +VMSTATE_INT32(oneshot, SyborgTimerState), +VMSTATE_UINT32(limit, SyborgTimerState), +VMSTATE_UINT32(int_level, SyborgTimerState), +VMSTATE_UINT32(int_enabled, SyborgTimerState), +VMSTATE_PTIMER(timer, SyborgTimerState), +VMSTATE_END_OF_LIST() +} +}; static int syborg_timer_init(SysBusDevice *dev) { @@ -222,8 +209,7 @@ static int syborg_timer_init(SysBusDevice *dev) bh = qemu_bh_new(syborg_timer_tick, s); s->timer = ptimer_init(bh); ptimer_set_freq(s->timer, s->freq); -register_savevm(&dev->qdev, "syborg_timer", -1, 1, -syborg_timer_save, syborg_timer_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_syborg_timer, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 13/32] vmstate: port armv7m nvic
Signed-off-by: Juan Quintela --- hw/armv7m_nvic.c | 39 ++- 1 files changed, 14 insertions(+), 25 deletions(-) diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c index 6c7ce01..397f5c9 100644 --- a/hw/armv7m_nvic.c +++ b/hw/armv7m_nvic.c @@ -365,30 +365,19 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) } } -static void nvic_save(QEMUFile *f, void *opaque) -{ -nvic_state *s = (nvic_state *)opaque; - -qemu_put_be32(f, s->systick.control); -qemu_put_be32(f, s->systick.reload); -qemu_put_be64(f, s->systick.tick); -qemu_put_timer(f, s->systick.timer); -} - -static int nvic_load(QEMUFile *f, void *opaque, int version_id) -{ -nvic_state *s = (nvic_state *)opaque; - -if (version_id != 1) -return -EINVAL; - -s->systick.control = qemu_get_be32(f); -s->systick.reload = qemu_get_be32(f); -s->systick.tick = qemu_get_be64(f); -qemu_get_timer(f, s->systick.timer); - -return 0; -} +static const VMStateDescription vmstate_nvic = { +.name = "armv7m_nvic", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32(systick.control, nvic_state), +VMSTATE_UINT32(systick.reload, nvic_state), +VMSTATE_INT64(systick.tick, nvic_state), +VMSTATE_TIMER(systick.timer, nvic_state), +VMSTATE_END_OF_LIST() +} +}; static int armv7m_nvic_init(SysBusDevice *dev) { @@ -397,7 +386,7 @@ static int armv7m_nvic_init(SysBusDevice *dev) gic_init(&s->gic); cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype); s->systick.timer = qemu_new_timer(vm_clock, systick_timer_tick, s); -register_savevm(&dev->qdev, "armv7m_nvic", -1, 1, nvic_save, nvic_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_nvic, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 26/32] vmstate: port ppc4xx_pci
Signed-off-by: Juan Quintela --- hw/ppc4xx_pci.c | 80 ++ 1 files changed, 39 insertions(+), 41 deletions(-) diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c index f62f1f9..299473c 100644 --- a/hw/ppc4xx_pci.c +++ b/hw/ppc4xx_pci.c @@ -285,50 +285,48 @@ static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pci_irqs[irq_num], level); } -static void ppc4xx_pci_save(QEMUFile *f, void *opaque) -{ -PPC4xxPCIState *controller = opaque; -int i; - -pci_device_save(controller->pci_dev, f); - -for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) { -qemu_put_be32s(f, &controller->pmm[i].la); -qemu_put_be32s(f, &controller->pmm[i].ma); -qemu_put_be32s(f, &controller->pmm[i].pcila); -qemu_put_be32s(f, &controller->pmm[i].pciha); -} - -for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) { -qemu_put_be32s(f, &controller->ptm[i].ms); -qemu_put_be32s(f, &controller->ptm[i].la); +static const VMStateDescription vmstate_pci_master_map = { +.name = "pci_master_map", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32(la, struct PCIMasterMap), +VMSTATE_UINT32(ma, struct PCIMasterMap), +VMSTATE_UINT32(pcila, struct PCIMasterMap), +VMSTATE_UINT32(pciha, struct PCIMasterMap), +VMSTATE_END_OF_LIST() } -} - -static int ppc4xx_pci_load(QEMUFile *f, void *opaque, int version_id) -{ -PPC4xxPCIState *controller = opaque; -int i; - -if (version_id != 1) -return -EINVAL; - -pci_device_load(controller->pci_dev, f); +}; -for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) { -qemu_get_be32s(f, &controller->pmm[i].la); -qemu_get_be32s(f, &controller->pmm[i].ma); -qemu_get_be32s(f, &controller->pmm[i].pcila); -qemu_get_be32s(f, &controller->pmm[i].pciha); +static const VMStateDescription vmstate_pci_target_map = { +.name = "pci_target_map", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32(ms, struct PCITargetMap), +VMSTATE_UINT32(la, struct PCITargetMap), +VMSTATE_END_OF_LIST() } +}; -for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) { -qemu_get_be32s(f, &controller->ptm[i].ms); -qemu_get_be32s(f, &controller->ptm[i].la); +static const VMStateDescription vmstate_ppc4xx_pci = { +.name = "ppc4xx_pci", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState), +VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1, + vmstate_pci_master_map, + struct PCIMasterMap), +VMSTATE_STRUCT_ARRAY(ptm, PPC4xxPCIState, PPC4xx_PCI_NR_PTMS, 1, + vmstate_pci_target_map, + struct PCITargetMap), +VMSTATE_END_OF_LIST() } - -return 0; -} +}; /* XXX Interrupt acknowledge cycles not supported. */ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], @@ -381,8 +379,8 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], qemu_register_reset(ppc4xx_pci_reset, controller); /* XXX load/save code not tested. */ -register_savevm(&controller->pci_dev->qdev, "ppc4xx_pci", ppc4xx_pci_id++, -1, ppc4xx_pci_save, ppc4xx_pci_load, controller); +vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++, + &vmstate_ppc4xx_pci, controller); return controller->pci_state.bus; -- 1.7.4
[Qemu-devel] [PATCH 14/32] vmstate: port stellaris i2c
Signed-off-by: Juan Quintela --- hw/stellaris.c | 49 + 1 files changed, 17 insertions(+), 32 deletions(-) diff --git a/hw/stellaris.c b/hw/stellaris.c index 5d8bd55..715e48c 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -844,36 +844,22 @@ static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = { stellaris_i2c_write }; -static void stellaris_i2c_save(QEMUFile *f, void *opaque) -{ -stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; - -qemu_put_be32(f, s->msa); -qemu_put_be32(f, s->mcs); -qemu_put_be32(f, s->mdr); -qemu_put_be32(f, s->mtpr); -qemu_put_be32(f, s->mimr); -qemu_put_be32(f, s->mris); -qemu_put_be32(f, s->mcr); -} - -static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id) -{ -stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; - -if (version_id != 1) -return -EINVAL; - -s->msa = qemu_get_be32(f); -s->mcs = qemu_get_be32(f); -s->mdr = qemu_get_be32(f); -s->mtpr = qemu_get_be32(f); -s->mimr = qemu_get_be32(f); -s->mris = qemu_get_be32(f); -s->mcr = qemu_get_be32(f); - -return 0; -} +static const VMStateDescription vmstate_stellaris_i2c = { +.name = "stellaris_i2c", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32(msa, stellaris_i2c_state), +VMSTATE_UINT32(mcs, stellaris_i2c_state), +VMSTATE_UINT32(mdr, stellaris_i2c_state), +VMSTATE_UINT32(mtpr, stellaris_i2c_state), +VMSTATE_UINT32(mimr, stellaris_i2c_state), +VMSTATE_UINT32(mris, stellaris_i2c_state), +VMSTATE_UINT32(mcr, stellaris_i2c_state), +VMSTATE_END_OF_LIST() +} +}; static int stellaris_i2c_init(SysBusDevice * dev) { @@ -891,8 +877,7 @@ static int stellaris_i2c_init(SysBusDevice * dev) sysbus_init_mmio(dev, 0x1000, iomemtype); /* ??? For now we only implement the master interface. */ stellaris_i2c_reset(s); -register_savevm(&dev->qdev, "stellaris_i2c", -1, 1, -stellaris_i2c_save, stellaris_i2c_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 19/32] vmstate: port cuda
Signed-off-by: Juan Quintela --- hw/cuda.c | 116 - 1 files changed, 46 insertions(+), 70 deletions(-) diff --git a/hw/cuda.c b/hw/cuda.c index e4c178d..f47dfab 100644 --- a/hw/cuda.c +++ b/hw/cuda.c @@ -644,80 +644,56 @@ static CPUReadMemoryFunc * const cuda_read[] = { &cuda_readl, }; -static void cuda_save_timer(QEMUFile *f, CUDATimer *s) +static bool cuda_timer_exist(void *opaque, int version_id) { -qemu_put_be16s(f, &s->latch); -qemu_put_be16s(f, &s->counter_value); -qemu_put_sbe64s(f, &s->load_time); -qemu_put_sbe64s(f, &s->next_irq_time); -if (s->timer) -qemu_put_timer(f, s->timer); -} - -static void cuda_save(QEMUFile *f, void *opaque) -{ -CUDAState *s = (CUDAState *)opaque; - -qemu_put_ubyte(f, s->b); -qemu_put_ubyte(f, s->a); -qemu_put_ubyte(f, s->dirb); -qemu_put_ubyte(f, s->dira); -qemu_put_ubyte(f, s->sr); -qemu_put_ubyte(f, s->acr); -qemu_put_ubyte(f, s->pcr); -qemu_put_ubyte(f, s->ifr); -qemu_put_ubyte(f, s->ier); -qemu_put_ubyte(f, s->anh); -qemu_put_sbe32s(f, &s->data_in_size); -qemu_put_sbe32s(f, &s->data_in_index); -qemu_put_sbe32s(f, &s->data_out_index); -qemu_put_ubyte(f, s->autopoll); -qemu_put_buffer(f, s->data_in, sizeof(s->data_in)); -qemu_put_buffer(f, s->data_out, sizeof(s->data_out)); -qemu_put_be32s(f, &s->tick_offset); -cuda_save_timer(f, &s->timers[0]); -cuda_save_timer(f, &s->timers[1]); -} +CUDATimer *s = opaque; -static void cuda_load_timer(QEMUFile *f, CUDATimer *s) -{ -qemu_get_be16s(f, &s->latch); -qemu_get_be16s(f, &s->counter_value); -qemu_get_sbe64s(f, &s->load_time); -qemu_get_sbe64s(f, &s->next_irq_time); -if (s->timer) -qemu_get_timer(f, s->timer); +return s->timer != NULL; } -static int cuda_load(QEMUFile *f, void *opaque, int version_id) -{ -CUDAState *s = (CUDAState *)opaque; - -if (version_id != 1) -return -EINVAL; - -s->b = qemu_get_ubyte(f); -s->a = qemu_get_ubyte(f); -s->dirb = qemu_get_ubyte(f); -s->dira = qemu_get_ubyte(f); -s->sr = qemu_get_ubyte(f); -s->acr = qemu_get_ubyte(f); -s->pcr = qemu_get_ubyte(f); -s->ifr = qemu_get_ubyte(f); -s->ier = qemu_get_ubyte(f); -s->anh = qemu_get_ubyte(f); -qemu_get_sbe32s(f, &s->data_in_size); -qemu_get_sbe32s(f, &s->data_in_index); -qemu_get_sbe32s(f, &s->data_out_index); -s->autopoll = qemu_get_ubyte(f); -qemu_get_buffer(f, s->data_in, sizeof(s->data_in)); -qemu_get_buffer(f, s->data_out, sizeof(s->data_out)); -qemu_get_be32s(f, &s->tick_offset); -cuda_load_timer(f, &s->timers[0]); -cuda_load_timer(f, &s->timers[1]); +static const VMStateDescription vmstate_cuda_timer = { +.name = "cuda_timer", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT16(latch, CUDATimer), +VMSTATE_UINT16(counter_value, CUDATimer), +VMSTATE_INT64(load_time, CUDATimer), +VMSTATE_INT64(next_irq_time, CUDATimer), +VMSTATE_TIMER_TEST(timer, CUDATimer, cuda_timer_exist), +VMSTATE_END_OF_LIST() +} +}; -return 0; -} +static const VMStateDescription vmstate_cuda = { +.name = "cuda", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT8(a, CUDAState), +VMSTATE_UINT8(b, CUDAState), +VMSTATE_UINT8(dira, CUDAState), +VMSTATE_UINT8(dirb, CUDAState), +VMSTATE_UINT8(sr, CUDAState), +VMSTATE_UINT8(acr, CUDAState), +VMSTATE_UINT8(pcr, CUDAState), +VMSTATE_UINT8(ifr, CUDAState), +VMSTATE_UINT8(ier, CUDAState), +VMSTATE_UINT8(anh, CUDAState), +VMSTATE_INT32(data_in_size, CUDAState), +VMSTATE_INT32(data_in_index, CUDAState), +VMSTATE_INT32(data_out_index, CUDAState), +VMSTATE_UINT8(autopoll, CUDAState), +VMSTATE_BUFFER(data_in, CUDAState), +VMSTATE_BUFFER(data_out, CUDAState), +VMSTATE_UINT32(tick_offset, CUDAState), +VMSTATE_STRUCT_ARRAY(timers, CUDAState, 2, 1, + vmstate_cuda_timer, CUDATimer), +VMSTATE_END_OF_LIST() +} +}; static void cuda_reset(void *opaque) { @@ -764,6 +740,6 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq) s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s, DEVICE_NATIVE_ENDIAN); -register_savevm(NULL, "cuda", -1, 1, cuda_save, cuda_load, s); +vmstate_register(NULL, -1, &vmstate_cuda, s); qemu_register_reset(cuda_reset, s); } -- 1.7.4
[Qemu-devel] Re: RFC: emulation of system flash
On 03/10/2011 12:46 PM, Jan Kiszka wrote: Better define flash chips as qdev devices and make the attributes qdev properties: -device flash,image=...,base=...,overlay=...,overlay_start=... Images should be addressed by block device IDs and created via '-drive' (likely requires a new interface type 'flash'). if=none will do. Paolo
[Qemu-devel] [PATCH 20/32] vmstate: port stellaris gptm
Signed-off-by: Juan Quintela --- hw/stellaris.c | 84 1 files changed, 24 insertions(+), 60 deletions(-) diff --git a/hw/stellaris.c b/hw/stellaris.c index b67f687..151b707 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -280,64 +280,29 @@ static CPUWriteMemoryFunc * const gptm_writefn[] = { gptm_write }; -static void gptm_save(QEMUFile *f, void *opaque) -{ -gptm_state *s = (gptm_state *)opaque; - -qemu_put_be32(f, s->config); -qemu_put_be32(f, s->mode[0]); -qemu_put_be32(f, s->mode[1]); -qemu_put_be32(f, s->control); -qemu_put_be32(f, s->state); -qemu_put_be32(f, s->mask); -qemu_put_be32(f, s->mode[0]); -qemu_put_be32(f, s->mode[0]); -qemu_put_be32(f, s->load[0]); -qemu_put_be32(f, s->load[1]); -qemu_put_be32(f, s->match[0]); -qemu_put_be32(f, s->match[1]); -qemu_put_be32(f, s->prescale[0]); -qemu_put_be32(f, s->prescale[1]); -qemu_put_be32(f, s->match_prescale[0]); -qemu_put_be32(f, s->match_prescale[1]); -qemu_put_be32(f, s->rtc); -qemu_put_be64(f, s->tick[0]); -qemu_put_be64(f, s->tick[1]); -qemu_put_timer(f, s->timer[0]); -qemu_put_timer(f, s->timer[1]); -} - -static int gptm_load(QEMUFile *f, void *opaque, int version_id) -{ -gptm_state *s = (gptm_state *)opaque; - -if (version_id != 1) -return -EINVAL; - -s->config = qemu_get_be32(f); -s->mode[0] = qemu_get_be32(f); -s->mode[1] = qemu_get_be32(f); -s->control = qemu_get_be32(f); -s->state = qemu_get_be32(f); -s->mask = qemu_get_be32(f); -s->mode[0] = qemu_get_be32(f); -s->mode[0] = qemu_get_be32(f); -s->load[0] = qemu_get_be32(f); -s->load[1] = qemu_get_be32(f); -s->match[0] = qemu_get_be32(f); -s->match[1] = qemu_get_be32(f); -s->prescale[0] = qemu_get_be32(f); -s->prescale[1] = qemu_get_be32(f); -s->match_prescale[0] = qemu_get_be32(f); -s->match_prescale[1] = qemu_get_be32(f); -s->rtc = qemu_get_be32(f); -s->tick[0] = qemu_get_be64(f); -s->tick[1] = qemu_get_be64(f); -qemu_get_timer(f, s->timer[0]); -qemu_get_timer(f, s->timer[1]); - -return 0; -} +static const VMStateDescription vmstate_stellaris_gptm = { +.name = "stellaris_gptm", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32(config, gptm_state), +VMSTATE_UINT32_ARRAY(mode, gptm_state, 2), +VMSTATE_UINT32(control, gptm_state), +VMSTATE_UINT32(state, gptm_state), +VMSTATE_UINT32(mask, gptm_state), +VMSTATE_UINT32(mode[0], gptm_state), +VMSTATE_UINT32(mode[0], gptm_state), +VMSTATE_UINT32_ARRAY(load, gptm_state, 2), +VMSTATE_UINT32_ARRAY(match, gptm_state, 2), +VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2), +VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2), +VMSTATE_UINT32(rtc, gptm_state), +VMSTATE_INT64_ARRAY(tick, gptm_state, 2), +VMSTATE_TIMER_ARRAY(timer, gptm_state, 2), +VMSTATE_END_OF_LIST() +} +}; static int stellaris_gptm_init(SysBusDevice *dev) { @@ -355,8 +320,7 @@ static int stellaris_gptm_init(SysBusDevice *dev) s->opaque[0] = s->opaque[1] = s; s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); -register_savevm(&dev->qdev, "stellaris_gptm", -1, 1, -gptm_save, gptm_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 18/32] vmstate: port heathrow_pic
Signed-off-by: Juan Quintela --- hw/heathrow_pic.c | 62 +--- 1 files changed, 25 insertions(+), 37 deletions(-) diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c index b19b754..5fd71a0 100644 --- a/hw/heathrow_pic.c +++ b/hw/heathrow_pic.c @@ -159,42 +159,31 @@ static void heathrow_pic_set_irq(void *opaque, int num, int level) heathrow_pic_update(s); } -static void heathrow_pic_save_one(QEMUFile *f, HeathrowPIC *s) -{ -qemu_put_be32s(f, &s->events); -qemu_put_be32s(f, &s->mask); -qemu_put_be32s(f, &s->levels); -qemu_put_be32s(f, &s->level_triggered); -} - -static void heathrow_pic_save(QEMUFile *f, void *opaque) -{ -HeathrowPICS *s = (HeathrowPICS *)opaque; - -heathrow_pic_save_one(f, &s->pics[0]); -heathrow_pic_save_one(f, &s->pics[1]); -} - -static void heathrow_pic_load_one(QEMUFile *f, HeathrowPIC *s) -{ -qemu_get_be32s(f, &s->events); -qemu_get_be32s(f, &s->mask); -qemu_get_be32s(f, &s->levels); -qemu_get_be32s(f, &s->level_triggered); -} - -static int heathrow_pic_load(QEMUFile *f, void *opaque, int version_id) -{ -HeathrowPICS *s = (HeathrowPICS *)opaque; - -if (version_id != 1) -return -EINVAL; - -heathrow_pic_load_one(f, &s->pics[0]); -heathrow_pic_load_one(f, &s->pics[1]); +static const VMStateDescription vmstate_heathrow_pic_one = { +.name = "heathrow_pic_one", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32(events, HeathrowPIC), +VMSTATE_UINT32(mask, HeathrowPIC), +VMSTATE_UINT32(levels, HeathrowPIC), +VMSTATE_UINT32(level_triggered, HeathrowPIC), +VMSTATE_END_OF_LIST() +} +}; -return 0; -} +static const VMStateDescription vmstate_heathrow_pic = { +.name = "heathrow_pic", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_STRUCT_ARRAY(pics, HeathrowPICS, 2, 1, + vmstate_heathrow_pic_one, HeathrowPIC), +VMSTATE_END_OF_LIST() +} +}; static void heathrow_pic_reset_one(HeathrowPIC *s) { @@ -223,8 +212,7 @@ qemu_irq *heathrow_pic_init(int *pmem_index, *pmem_index = cpu_register_io_memory(pic_read, pic_write, s, DEVICE_LITTLE_ENDIAN); -register_savevm(NULL, "heathrow_pic", -1, 1, heathrow_pic_save, -heathrow_pic_load, s); +vmstate_register(NULL, -1, &vmstate_heathrow_pic, s); qemu_register_reset(heathrow_pic_reset, s); return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64); } -- 1.7.4
[Qemu-devel] [PATCH 16/32] vmstate: port stellaris sys
Signed-off-by: Juan Quintela --- hw/stellaris.c | 71 +++ 1 files changed, 25 insertions(+), 46 deletions(-) diff --git a/hw/stellaris.c b/hw/stellaris.c index 9b83fb4..b67f687 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -605,58 +605,37 @@ static void ssys_reset(void *opaque) s->dcgc[0] = 1; } -static void ssys_save(QEMUFile *f, void *opaque) +static int stellaris_sys_post_load(void *opaque, int version_id) { -ssys_state *s = (ssys_state *)opaque; - -qemu_put_be32(f, s->pborctl); -qemu_put_be32(f, s->ldopctl); -qemu_put_be32(f, s->int_mask); -qemu_put_be32(f, s->int_status); -qemu_put_be32(f, s->resc); -qemu_put_be32(f, s->rcc); -qemu_put_be32(f, s->rcgc[0]); -qemu_put_be32(f, s->rcgc[1]); -qemu_put_be32(f, s->rcgc[2]); -qemu_put_be32(f, s->scgc[0]); -qemu_put_be32(f, s->scgc[1]); -qemu_put_be32(f, s->scgc[2]); -qemu_put_be32(f, s->dcgc[0]); -qemu_put_be32(f, s->dcgc[1]); -qemu_put_be32(f, s->dcgc[2]); -qemu_put_be32(f, s->clkvclr); -qemu_put_be32(f, s->ldoarst); -} - -static int ssys_load(QEMUFile *f, void *opaque, int version_id) -{ -ssys_state *s = (ssys_state *)opaque; - -if (version_id != 1) -return -EINVAL; +ssys_state *s = opaque; -s->pborctl = qemu_get_be32(f); -s->ldopctl = qemu_get_be32(f); -s->int_mask = qemu_get_be32(f); -s->int_status = qemu_get_be32(f); -s->resc = qemu_get_be32(f); -s->rcc = qemu_get_be32(f); -s->rcgc[0] = qemu_get_be32(f); -s->rcgc[1] = qemu_get_be32(f); -s->rcgc[2] = qemu_get_be32(f); -s->scgc[0] = qemu_get_be32(f); -s->scgc[1] = qemu_get_be32(f); -s->scgc[2] = qemu_get_be32(f); -s->dcgc[0] = qemu_get_be32(f); -s->dcgc[1] = qemu_get_be32(f); -s->dcgc[2] = qemu_get_be32(f); -s->clkvclr = qemu_get_be32(f); -s->ldoarst = qemu_get_be32(f); ssys_calculate_system_clock(s); return 0; } +static const VMStateDescription vmstate_stellaris_sys = { +.name = "stellaris_sys", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.post_load = stellaris_sys_post_load, +.fields = (VMStateField[]) { +VMSTATE_UINT32(pborctl, ssys_state), +VMSTATE_UINT32(ldopctl, ssys_state), +VMSTATE_UINT32(int_mask, ssys_state), +VMSTATE_UINT32(int_status, ssys_state), +VMSTATE_UINT32(resc, ssys_state), +VMSTATE_UINT32(rcc, ssys_state), +VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3), +VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3), +VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3), +VMSTATE_UINT32(clkvclr, ssys_state), +VMSTATE_UINT32(ldoarst, ssys_state), +VMSTATE_END_OF_LIST() +} +}; + static int stellaris_sys_init(uint32_t base, qemu_irq irq, stellaris_board_info * board, uint8_t *macaddr) @@ -676,7 +655,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(base, 0x1000, iomemtype); ssys_reset(s); -register_savevm(NULL, "stellaris_sys", -1, 1, ssys_save, ssys_load, s); +vmstate_register(NULL, -1, &vmstate_stellaris_sys, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 03/13] vmstate: port pxa2xx_lcd
Signed-off-by: Juan Quintela --- hw/pxa2xx_lcd.c | 110 +- 1 files changed, 43 insertions(+), 67 deletions(-) diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c index 55e95be..e524802 100644 --- a/hw/pxa2xx_lcd.c +++ b/hw/pxa2xx_lcd.c @@ -833,74 +833,26 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle) pxa2xx_lcdc_resize(s); } -static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque) -{ -PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; -int i; - -qemu_put_be32(f, s->irqlevel); -qemu_put_be32(f, s->transp); - -for (i = 0; i < 6; i ++) -qemu_put_be32s(f, &s->control[i]); -for (i = 0; i < 2; i ++) -qemu_put_be32s(f, &s->status[i]); -for (i = 0; i < 2; i ++) -qemu_put_be32s(f, &s->ovl1c[i]); -for (i = 0; i < 2; i ++) -qemu_put_be32s(f, &s->ovl2c[i]); -qemu_put_be32s(f, &s->ccr); -qemu_put_be32s(f, &s->cmdcr); -qemu_put_be32s(f, &s->trgbr); -qemu_put_be32s(f, &s->tcr); -qemu_put_be32s(f, &s->liidr); -qemu_put_8s(f, &s->bscntr); - -for (i = 0; i < 7; i ++) { -qemu_put_betl(f, s->dma_ch[i].branch); -qemu_put_byte(f, s->dma_ch[i].up); -qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); - -qemu_put_betl(f, s->dma_ch[i].descriptor); -qemu_put_betl(f, s->dma_ch[i].source); -qemu_put_be32s(f, &s->dma_ch[i].id); -qemu_put_be32s(f, &s->dma_ch[i].command); +static const VMStateDescription vmstate_dma_channel = { +.name = "dma_channel", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINTTL(branch, struct DMAChannel), +VMSTATE_UINT8(up, struct DMAChannel), +VMSTATE_BUFFER(pbuffer, struct DMAChannel), +VMSTATE_UINTTL(descriptor, struct DMAChannel), +VMSTATE_UINTTL(source, struct DMAChannel), +VMSTATE_UINT32(id, struct DMAChannel), +VMSTATE_UINT32(command, struct DMAChannel), +VMSTATE_END_OF_LIST() } -} +}; -static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id) +static int pxa2xx_lcdc_post_load(void *opaque, int version_id) { -PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; -int i; - -s->irqlevel = qemu_get_be32(f); -s->transp = qemu_get_be32(f); - -for (i = 0; i < 6; i ++) -qemu_get_be32s(f, &s->control[i]); -for (i = 0; i < 2; i ++) -qemu_get_be32s(f, &s->status[i]); -for (i = 0; i < 2; i ++) -qemu_get_be32s(f, &s->ovl1c[i]); -for (i = 0; i < 2; i ++) -qemu_get_be32s(f, &s->ovl2c[i]); -qemu_get_be32s(f, &s->ccr); -qemu_get_be32s(f, &s->cmdcr); -qemu_get_be32s(f, &s->trgbr); -qemu_get_be32s(f, &s->tcr); -qemu_get_be32s(f, &s->liidr); -qemu_get_8s(f, &s->bscntr); - -for (i = 0; i < 7; i ++) { -s->dma_ch[i].branch = qemu_get_betl(f); -s->dma_ch[i].up = qemu_get_byte(f); -qemu_get_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); - -s->dma_ch[i].descriptor = qemu_get_betl(f); -s->dma_ch[i].source = qemu_get_betl(f); -qemu_get_be32s(f, &s->dma_ch[i].id); -qemu_get_be32s(f, &s->dma_ch[i].command); -} +PXA2xxLCDState *s = opaque; s->bpp = LCCR3_BPP(s->control[3]); s->xres = s->yres = s->pal_for = -1; @@ -908,6 +860,31 @@ static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id) return 0; } +static const VMStateDescription vmstate_pxa2xx_lcdc = { +.name = "pxa2xx_lcdc", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.post_load = pxa2xx_lcdc_post_load, +.fields = (VMStateField[]) { +VMSTATE_INT32(irqlevel, PXA2xxLCDState), +VMSTATE_INT32(transp, PXA2xxLCDState), +VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6), +VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2), +VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2), +VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2), +VMSTATE_UINT32(ccr, PXA2xxLCDState), +VMSTATE_UINT32(cmdcr, PXA2xxLCDState), +VMSTATE_UINT32(trgbr, PXA2xxLCDState), +VMSTATE_UINT32(tcr, PXA2xxLCDState), +VMSTATE_UINT32(liidr, PXA2xxLCDState), +VMSTATE_UINT8(bscntr, PXA2xxLCDState), +VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0, + vmstate_dma_channel, struct DMAChannel), +VMSTATE_END_OF_LIST() +} +}; + #define BITS 8 #include "pxa2xx_template.h" #define BITS 15 @@ -972,8 +949,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq) exit(1); } -register_savevm(NULL, "pxa2xx_lcdc", 0, 0, -pxa2xx_lcdc_save, pxa2xx_lcdc_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s); return s; } -- 1.7.4
[Qemu-devel] [PATCH 23/32] vmstate: port pxa2xx_mm
Signed-off-by: Juan Quintela --- hw/pxa2xx.c | 33 - 1 files changed, 12 insertions(+), 21 deletions(-) diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index a3ba30a..0a9af4c 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -516,25 +516,16 @@ static CPUWriteMemoryFunc * const pxa2xx_mm_writefn[] = { pxa2xx_mm_write, }; -static void pxa2xx_mm_save(QEMUFile *f, void *opaque) -{ -PXA2xxState *s = (PXA2xxState *) opaque; -int i; - -for (i = 0; i < 0x1a; i ++) -qemu_put_be32s(f, &s->mm_regs[i]); -} - -static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id) -{ -PXA2xxState *s = (PXA2xxState *) opaque; -int i; - -for (i = 0; i < 0x1a; i ++) -qemu_get_be32s(f, &s->mm_regs[i]); - -return 0; -} +static const VMStateDescription vmstate_pxa2xx_mm = { +.name = "pxa2xx_mm", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a), +VMSTATE_END_OF_LIST() +} +}; /* Synchronous Serial Ports */ typedef struct { @@ -2171,7 +2162,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn, pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype); -register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s); s->pm_base = 0x40f0; iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn, @@ -2307,7 +2298,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn, pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype); -register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s); s->pm_base = 0x40f0; iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn, -- 1.7.4
[Qemu-devel] [PATCH 21/32] vmstate: port pxa2xx_i2s
Signed-off-by: Juan Quintela --- hw/pxa2xx.c | 53 ++--- 1 files changed, 18 insertions(+), 35 deletions(-) diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index 4c7b9e6..9bafe05 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -1748,39 +1748,23 @@ static CPUWriteMemoryFunc * const pxa2xx_i2s_writefn[] = { pxa2xx_i2s_write, }; -static void pxa2xx_i2s_save(QEMUFile *f, void *opaque) -{ -PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; - -qemu_put_be32s(f, &s->control[0]); -qemu_put_be32s(f, &s->control[1]); -qemu_put_be32s(f, &s->status); -qemu_put_be32s(f, &s->mask); -qemu_put_be32s(f, &s->clk); - -qemu_put_be32(f, s->enable); -qemu_put_be32(f, s->rx_len); -qemu_put_be32(f, s->tx_len); -qemu_put_be32(f, s->fifo_len); -} - -static int pxa2xx_i2s_load(QEMUFile *f, void *opaque, int version_id) -{ -PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; - -qemu_get_be32s(f, &s->control[0]); -qemu_get_be32s(f, &s->control[1]); -qemu_get_be32s(f, &s->status); -qemu_get_be32s(f, &s->mask); -qemu_get_be32s(f, &s->clk); - -s->enable = qemu_get_be32(f); -s->rx_len = qemu_get_be32(f); -s->tx_len = qemu_get_be32(f); -s->fifo_len = qemu_get_be32(f); - -return 0; -} +static const VMStateDescription vmstate_pxa2xx_i2s = { +.name = "pxa2xx_i2s", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2), +VMSTATE_UINT32(status, PXA2xxI2SState), +VMSTATE_UINT32(mask, PXA2xxI2SState), +VMSTATE_UINT32(clk, PXA2xxI2SState), +VMSTATE_INT32(enable, PXA2xxI2SState), +VMSTATE_INT32(rx_len, PXA2xxI2SState), +VMSTATE_INT32(tx_len, PXA2xxI2SState), +VMSTATE_INT32(fifo_len, PXA2xxI2SState), +VMSTATE_END_OF_LIST() +} +}; static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx) { @@ -1822,8 +1806,7 @@ static PXA2xxI2SState *pxa2xx_i2s_init(target_phys_addr_t base, pxa2xx_i2s_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(base, 0x10, iomemtype); -register_savevm(NULL, "pxa2xx_i2s", base, 0, -pxa2xx_i2s_save, pxa2xx_i2s_load, s); +vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s); return s; } -- 1.7.4
[Qemu-devel] [PATCH 22/32] vmstate: port pxa2xx_cm
Signed-off-by: Juan Quintela --- hw/pxa2xx.c | 39 ++- 1 files changed, 14 insertions(+), 25 deletions(-) diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index 9bafe05..a3ba30a 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -227,29 +227,18 @@ static CPUWriteMemoryFunc * const pxa2xx_cm_writefn[] = { pxa2xx_cm_write, }; -static void pxa2xx_cm_save(QEMUFile *f, void *opaque) -{ -PXA2xxState *s = (PXA2xxState *) opaque; -int i; - -for (i = 0; i < 4; i ++) -qemu_put_be32s(f, &s->cm_regs[i]); -qemu_put_be32s(f, &s->clkcfg); -qemu_put_be32s(f, &s->pmnc); -} - -static int pxa2xx_cm_load(QEMUFile *f, void *opaque, int version_id) -{ -PXA2xxState *s = (PXA2xxState *) opaque; -int i; - -for (i = 0; i < 4; i ++) -qemu_get_be32s(f, &s->cm_regs[i]); -qemu_get_be32s(f, &s->clkcfg); -qemu_get_be32s(f, &s->pmnc); - -return 0; -} +static const VMStateDescription vmstate_pxa2xx_cm = { +.name = "pxa2xx_cm", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4), +VMSTATE_UINT32(clkcfg, PXA2xxState), +VMSTATE_UINT32(pmnc, PXA2xxState), +VMSTATE_END_OF_LIST() +} +}; static uint32_t pxa2xx_clkpwr_read(void *opaque, int op2, int reg, int crm) { @@ -2171,7 +2160,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn, pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype); -register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); @@ -2307,7 +2296,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn, pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype); -register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); -- 1.7.4
[Qemu-devel] [PATCH 24/32] vmstate: port pxa2xx_pm
Signed-off-by: Juan Quintela --- hw/pxa2xx.c | 33 - 1 files changed, 12 insertions(+), 21 deletions(-) diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index 0a9af4c..aada093 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -146,25 +146,16 @@ static CPUWriteMemoryFunc * const pxa2xx_pm_writefn[] = { pxa2xx_pm_write, }; -static void pxa2xx_pm_save(QEMUFile *f, void *opaque) -{ -PXA2xxState *s = (PXA2xxState *) opaque; -int i; - -for (i = 0; i < 0x40; i ++) -qemu_put_be32s(f, &s->pm_regs[i]); -} - -static int pxa2xx_pm_load(QEMUFile *f, void *opaque, int version_id) -{ -PXA2xxState *s = (PXA2xxState *) opaque; -int i; - -for (i = 0; i < 0x40; i ++) -qemu_get_be32s(f, &s->pm_regs[i]); - -return 0; -} +static const VMStateDescription vmstate_pxa2xx_pm = { +.name = "pxa2xx_pm", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40), +VMSTATE_END_OF_LIST() +} +}; #define CCCR 0x00/* Core Clock Configuration register */ #define CKEN 0x04/* Clock Enable register */ @@ -2168,7 +2159,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn, pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(s->pm_base, 0x100, iomemtype); -register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s); for (i = 0; pxa27x_ssp[i].io_base; i ++); s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i); @@ -2304,7 +2295,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn, pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(s->pm_base, 0x100, iomemtype); -register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s); for (i = 0; pxa255_ssp[i].io_base; i ++); s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i); -- 1.7.4
[Qemu-devel] [PATCH 25/32] vmstate: port ppce500_pci
Signed-off-by: Juan Quintela --- hw/ppce500_pci.c | 87 +- 1 files changed, 40 insertions(+), 47 deletions(-) diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index 11edd03..132d8f7 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -216,56 +216,49 @@ static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } -static void ppce500_pci_save(QEMUFile *f, void *opaque) -{ -PPCE500PCIState *controller = opaque; -int i; - -pci_device_save(controller->pci_dev, f); - -for (i = 0; i < PPCE500_PCI_NR_POBS; i++) { -qemu_put_be32s(f, &controller->pob[i].potar); -qemu_put_be32s(f, &controller->pob[i].potear); -qemu_put_be32s(f, &controller->pob[i].powbar); -qemu_put_be32s(f, &controller->pob[i].powar); -} - -for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) { -qemu_put_be32s(f, &controller->pib[i].pitar); -qemu_put_be32s(f, &controller->pib[i].piwbar); -qemu_put_be32s(f, &controller->pib[i].piwbear); -qemu_put_be32s(f, &controller->pib[i].piwar); +static const VMStateDescription vmstate_pci_outbound = { +.name = "pci_outbound", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32(potar, struct pci_outbound), +VMSTATE_UINT32(potear, struct pci_outbound), +VMSTATE_UINT32(powbar, struct pci_outbound), +VMSTATE_UINT32(powar, struct pci_outbound), +VMSTATE_END_OF_LIST() } -qemu_put_be32s(f, &controller->gasket_time); -} - -static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id) -{ -PPCE500PCIState *controller = opaque; -int i; - -if (version_id != 1) -return -EINVAL; - -pci_device_load(controller->pci_dev, f); +}; -for (i = 0; i < PPCE500_PCI_NR_POBS; i++) { -qemu_get_be32s(f, &controller->pob[i].potar); -qemu_get_be32s(f, &controller->pob[i].potear); -qemu_get_be32s(f, &controller->pob[i].powbar); -qemu_get_be32s(f, &controller->pob[i].powar); +static const VMStateDescription vmstate_pci_inbound = { +.name = "pci_inbound", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32(pitar, struct pci_inbound), +VMSTATE_UINT32(piwbar, struct pci_inbound), +VMSTATE_UINT32(piwbear, struct pci_inbound), +VMSTATE_UINT32(piwar, struct pci_inbound), +VMSTATE_END_OF_LIST() } +}; -for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) { -qemu_get_be32s(f, &controller->pib[i].pitar); -qemu_get_be32s(f, &controller->pib[i].piwbar); -qemu_get_be32s(f, &controller->pib[i].piwbear); -qemu_get_be32s(f, &controller->pib[i].piwar); +static const VMStateDescription vmstate_ppce500_pci = { +.name = "ppce500_pci", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPCE500PCIState), +VMSTATE_STRUCT_ARRAY(pob, PPCE500PCIState, PPCE500_PCI_NR_POBS, 1, + vmstate_pci_outbound, struct pci_outbound), +VMSTATE_STRUCT_ARRAY(pib, PPCE500PCIState, PPCE500_PCI_NR_PIBS, 1, + vmstate_pci_outbound, struct pci_inbound), +VMSTATE_UINT32(gasket_time, PPCE500PCIState), +VMSTATE_END_OF_LIST() } -qemu_get_be32s(f, &controller->gasket_time); - -return 0; -} +}; PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers) { @@ -314,8 +307,8 @@ PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers) PCIE500_REG_SIZE, index); /* XXX load/save code not tested. */ -register_savevm(&d->qdev, "ppce500_pci", ppce500_pci_id++, -1, ppce500_pci_save, ppce500_pci_load, controller); +vmstate_register(&d->qdev, ppce500_pci_id++, &vmstate_ppce500_pci, + controller); return controller->pci_state.bus; -- 1.7.4
[Qemu-devel] [PATCH v2 0/3] really fix -icount with iothread
This is a "real" fix for -icount, real in the sense that it works in all cases including those that weren't fixed by my first attempt. Patch 1 is the three-line fix. With that in, patch 2 can revert the previous attempt(s). Finally, patch 3 makes the icount code clearer by finishing the bugfix/reorganization of qemu_next_deadline vs. qemu_next_alarm_deadline. v1->v2: reordered patches, renamed qemu_next_deadline Paolo Bonzini (3): really fix -icount in the iothread case Revert wrong fix for -icount in the iothread case qemu_next_deadline should not consider host-time timers cpus.c |5 +++- qemu-timer.c | 75 + qemu-timer.h |2 +- 3 files changed, 43 insertions(+), 39 deletions(-) -- 1.7.4
[Qemu-devel] [PATCH 28/32] vmstate: port stellaris_adc
Signed-off-by: Juan Quintela --- hw/stellaris.c | 89 +-- 1 files changed, 34 insertions(+), 55 deletions(-) diff --git a/hw/stellaris.c b/hw/stellaris.c index 151b707..6e31d89 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -1058,60 +1058,40 @@ static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = { stellaris_adc_write }; -static void stellaris_adc_save(QEMUFile *f, void *opaque) -{ -stellaris_adc_state *s = (stellaris_adc_state *)opaque; -int i; -int j; - -qemu_put_be32(f, s->actss); -qemu_put_be32(f, s->ris); -qemu_put_be32(f, s->im); -qemu_put_be32(f, s->emux); -qemu_put_be32(f, s->ostat); -qemu_put_be32(f, s->ustat); -qemu_put_be32(f, s->sspri); -qemu_put_be32(f, s->sac); -for (i = 0; i < 4; i++) { -qemu_put_be32(f, s->fifo[i].state); -for (j = 0; j < 16; j++) { -qemu_put_be32(f, s->fifo[i].data[j]); -} -qemu_put_be32(f, s->ssmux[i]); -qemu_put_be32(f, s->ssctl[i]); -} -qemu_put_be32(f, s->noise); -} - -static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) -{ -stellaris_adc_state *s = (stellaris_adc_state *)opaque; -int i; -int j; - -if (version_id != 1) -return -EINVAL; - -s->actss = qemu_get_be32(f); -s->ris = qemu_get_be32(f); -s->im = qemu_get_be32(f); -s->emux = qemu_get_be32(f); -s->ostat = qemu_get_be32(f); -s->ustat = qemu_get_be32(f); -s->sspri = qemu_get_be32(f); -s->sac = qemu_get_be32(f); -for (i = 0; i < 4; i++) { -s->fifo[i].state = qemu_get_be32(f); -for (j = 0; j < 16; j++) { -s->fifo[i].data[j] = qemu_get_be32(f); -} -s->ssmux[i] = qemu_get_be32(f); -s->ssctl[i] = qemu_get_be32(f); +static const VMStateDescription vmstate_stellaris_adc = { +.name = "stellaris_adc", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32(actss, stellaris_adc_state), +VMSTATE_UINT32(ris, stellaris_adc_state), +VMSTATE_UINT32(im, stellaris_adc_state), +VMSTATE_UINT32(emux, stellaris_adc_state), +VMSTATE_UINT32(ostat, stellaris_adc_state), +VMSTATE_UINT32(ustat, stellaris_adc_state), +VMSTATE_UINT32(sspri, stellaris_adc_state), +VMSTATE_UINT32(sac, stellaris_adc_state), +VMSTATE_UINT32(fifo[0].state, stellaris_adc_state), +VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16), +VMSTATE_UINT32(ssmux[0], stellaris_adc_state), +VMSTATE_UINT32(ssctl[0], stellaris_adc_state), +VMSTATE_UINT32(fifo[1].state, stellaris_adc_state), +VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16), +VMSTATE_UINT32(ssmux[1], stellaris_adc_state), +VMSTATE_UINT32(ssctl[1], stellaris_adc_state), +VMSTATE_UINT32(fifo[2].state, stellaris_adc_state), +VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16), +VMSTATE_UINT32(ssmux[2], stellaris_adc_state), +VMSTATE_UINT32(ssctl[2], stellaris_adc_state), +VMSTATE_UINT32(fifo[3].state, stellaris_adc_state), +VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16), +VMSTATE_UINT32(ssmux[3], stellaris_adc_state), +VMSTATE_UINT32(ssctl[3], stellaris_adc_state), +VMSTATE_UINT32(noise, stellaris_adc_state), +VMSTATE_END_OF_LIST() } -s->noise = qemu_get_be32(f); - -return 0; -} +}; static int stellaris_adc_init(SysBusDevice *dev) { @@ -1129,8 +1109,7 @@ static int stellaris_adc_init(SysBusDevice *dev) sysbus_init_mmio(dev, 0x1000, iomemtype); stellaris_adc_reset(s); qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1); -register_savevm(&dev->qdev, "stellaris_adc", -1, 1, -stellaris_adc_save, stellaris_adc_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s); return 0; } -- 1.7.4
[Qemu-devel] [PATCH 29/32] vmstate: port syborg_serial
Signed-off-by: Juan Quintela --- hw/syborg_serial.c | 60 +++ 1 files changed, 18 insertions(+), 42 deletions(-) diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c index 34ce076..df2950f 100644 --- a/hw/syborg_serial.c +++ b/hw/syborg_serial.c @@ -273,47 +273,24 @@ static CPUWriteMemoryFunc * const syborg_serial_writefn[] = { syborg_serial_write }; -static void syborg_serial_save(QEMUFile *f, void *opaque) -{ -SyborgSerialState *s = opaque; -int i; - -qemu_put_be32(f, s->fifo_size); -qemu_put_be32(f, s->int_enable); -qemu_put_be32(f, s->read_pos); -qemu_put_be32(f, s->read_count); -qemu_put_be32(f, s->dma_tx_ptr); -qemu_put_be32(f, s->dma_rx_ptr); -qemu_put_be32(f, s->dma_rx_size); -for (i = 0; i < s->fifo_size; i++) { -qemu_put_be32(f, s->read_fifo[i]); -} -} - -static int syborg_serial_load(QEMUFile *f, void *opaque, int version_id) -{ -SyborgSerialState *s = opaque; -int i; - -if (version_id != 1) -return -EINVAL; - -i = qemu_get_be32(f); -if (s->fifo_size != i) -return -EINVAL; - -s->int_enable = qemu_get_be32(f); -s->read_pos = qemu_get_be32(f); -s->read_count = qemu_get_be32(f); -s->dma_tx_ptr = qemu_get_be32(f); -s->dma_rx_ptr = qemu_get_be32(f); -s->dma_rx_size = qemu_get_be32(f); -for (i = 0; i < s->fifo_size; i++) { -s->read_fifo[i] = qemu_get_be32(f); +static const VMStateDescription vmstate_syborg_serial = { +.name = "syborg_serial", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32_EQUAL(fifo_size, SyborgSerialState), +VMSTATE_UINT32(int_enable, SyborgSerialState), +VMSTATE_INT32(read_pos, SyborgSerialState), +VMSTATE_INT32(read_count, SyborgSerialState), +VMSTATE_UINT32(dma_tx_ptr, SyborgSerialState), +VMSTATE_UINT32(dma_rx_ptr, SyborgSerialState), +VMSTATE_UINT32(dma_rx_size, SyborgSerialState), +VMSTATE_VARRAY_UINT32(read_fifo, SyborgSerialState, fifo_size, 1, + vmstate_info_uint32, uint32), +VMSTATE_END_OF_LIST() } - -return 0; -} +}; static int syborg_serial_init(SysBusDevice *dev) { @@ -336,8 +313,6 @@ static int syborg_serial_init(SysBusDevice *dev) } s->read_fifo = qemu_mallocz(s->fifo_size * sizeof(s->read_fifo[0])); -register_savevm(&dev->qdev, "syborg_serial", -1, 1, -syborg_serial_save, syborg_serial_load, s); return 0; } @@ -345,6 +320,7 @@ static SysBusDeviceInfo syborg_serial_info = { .init = syborg_serial_init, .qdev.name = "syborg,serial", .qdev.size = sizeof(SyborgSerialState), +.qdev.vmsd = &vmstate_syborg_serial, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("fifo-size", SyborgSerialState, fifo_size, 16), DEFINE_PROP_END_OF_LIST(), -- 1.7.4
[Qemu-devel] Re: [V8 PATCH 11/11] virtio-9p: Chroot environment for other functions
On Wed, Mar 9, 2011 at 5:16 PM, M. Mohan Kumar wrote: > Add chroot functionality for systemcalls that can operate on a file > using relative directory file descriptor. I suspect the relative directory approach is broken and escapes the chroot. Here's why: The request is local_chmod(fs_ctx, "/..", credp). dirname("/..") is "/" and basename("..") is "..". I'm not 100% sure of the semantics but I suspect that chmodat(dir_fd, "..", ...) does not honor the chroot since your current task is not inside the chroot. If so, then you can manipulate the parent directory of the chroot using some of the operations added in this patch. The safe solution is to perform all operations inside the chroot. This will require extending the chroot socket protocol. Stefan
[Qemu-devel] [PATCH 31/32] vmstate: port stellaris gamepad
Signed-off-by: Juan Quintela --- hw/stellaris_input.c | 50 -- 1 files changed, 24 insertions(+), 26 deletions(-) diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c index 16aae96..06c5f9d 100644 --- a/hw/stellaris_input.c +++ b/hw/stellaris_input.c @@ -13,7 +13,7 @@ typedef struct { qemu_irq irq; int keycode; -int pressed; +uint8_t pressed; } gamepad_button; typedef struct { @@ -47,30 +47,29 @@ static void stellaris_gamepad_put_key(void * opaque, int keycode) s->extension = 0; } -static void stellaris_gamepad_save(QEMUFile *f, void *opaque) -{ -gamepad_state *s = (gamepad_state *)opaque; -int i; - -qemu_put_be32(f, s->extension); -for (i = 0; i < s->num_buttons; i++) -qemu_put_byte(f, s->buttons[i].pressed); -} - -static int stellaris_gamepad_load(QEMUFile *f, void *opaque, int version_id) -{ -gamepad_state *s = (gamepad_state *)opaque; -int i; - -if (version_id != 1) -return -EINVAL; - -s->extension = qemu_get_be32(f); -for (i = 0; i < s->num_buttons; i++) -s->buttons[i].pressed = qemu_get_byte(f); +static const VMStateDescription vmstate_stellaris_button = { +.name = "stellaris_button", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT8(pressed, gamepad_button), +VMSTATE_END_OF_LIST() +} +}; -return 0; -} +static const VMStateDescription vmstate_stellaris_gamepad = { +.name = "stellaris_gamepad", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32(extension, gamepad_state), +VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0, + vmstate_stellaris_button, gamepad_button), +VMSTATE_END_OF_LIST() +} +}; /* Returns an array 5 ouput slots. */ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) @@ -86,6 +85,5 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) } s->num_buttons = n; qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s); -register_savevm(NULL, "stellaris_gamepad", -1, 1, -stellaris_gamepad_save, stellaris_gamepad_load, s); +vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s); } -- 1.7.4
[Qemu-devel] [PATCH 08/13] mac_nvram: size is a size, no need to be a target dependent type
Signed-off-by: Juan Quintela --- hw/mac_nvram.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c index c2a2fc2..64f0192 100644 --- a/hw/mac_nvram.c +++ b/hw/mac_nvram.c @@ -38,7 +38,7 @@ #endif struct MacIONVRAMState { -target_phys_addr_t size; +uint32_t size; int mem_index; unsigned int it_shift; uint8_t *data; -- 1.7.4
[Qemu-devel] [PATCH 00/13] VMState port more devices
Hi, This is the second half of devices that needed some change for vmstate conversion. Change was minimal. Fixed issues from previous sent. Again thanks to Blaw Swirl for the comments and review. This series apply on top of: [PATCH 0/9] VMState infrastructure [PATCH 00/32] VMState port of misc devices Later, Juan. Juan Quintela (13): pxa2xx_lcd: name anonymous struct pxa2xx_lcd: up field is used as a bool and migrated as an uint8_t vmstate: port pxa2xx_lcd max111x: input field is only used as uint8_t vmstate: port max111x nand: pin values are uint8_t vmstate: port nand mac_nvram: size is a size, no need to be a target dependent type vmstate: port mac_nvram piix4: create PIIX4State vmstate: port piix4 mac_dbdma: create DBDMAState instead of passing one array around vmstate: port mac_dbdma hw/flash.h |4 +- hw/mac_dbdma.c | 83 ++--- hw/mac_nvram.c | 32 + hw/max111x.c| 51 +++- hw/nand.c | 79 +--- hw/piix4.c | 44 + hw/pxa2xx_lcd.c | 138 +++ 7 files changed, 200 insertions(+), 231 deletions(-) -- 1.7.4
Re: [Qemu-devel] [PATCH 19/22] qapi: add QMP put-event command
On 03/09/2011 04:26 PM, Anthony Liguori wrote: On 03/09/2011 07:58 AM, Avi Kivity wrote: On 03/09/2011 03:48 PM, Anthony Liguori wrote: +[ 'put-event', {'tag': 'int'}, {}, 'none' ] Why is tag an int? +## It's a handle so the type doesn't matter as long as I can make sure values are unique. ints are easier to work with because they don't require memory allocation. I think it's nicer for the client to use a string. Instead of a global ID allocator, it can use unique IDs or unique prefixes + local IDs. Should also aid a little in debugging. handle's are opaque to clients. I don't have a huge objection to using strings and it may make sense to do a prefix like you're suggesting. I won't do that initially but since handles are opaque, we can make that change later. What I mean is that the client should specify the handle, like it does for everything else it gives a name (netdevs, blockdevs, SCM_RIGHT fds, etc). { execute: listen-event, arguments: { event: blah, id: blah1 } } { execute: unlisten-event arguments: { id: blah1 } } don't we use strings for command ids and similar? id's can be any valid JSON value. But a handle is not the same thing as an id. Why not? I hope handles are client-provided? No, they are generated by the server. It makes sense because really a handle is a marshalled version of a signal. The signal accessor looks something like this: { 'BLOCK_IO_ERROR': { 'device': 'str', 'action': 'str', 'operation': 'str' } } [ 'get-block-io-error-event': {}, 'BLOCK_IO_ERROR' } The way we marshal a 'BLOCK_IO_ERROR' type is by generating a unique handle and returning that. I don't follow at all. Where's the handle here? Why don't we return the BLOCK_IO_ERROR as an object, on the wire? While this looks like an int on the wire, at both the server and libqmp level, it looks like a BlockIoErrorEvent object. So in QEMU: BlockIoErrorEvent *qmp_get_block_io_error_event(Error **errp) { } And in libqmp: BlockIoErrorEvent *libqmp_get_block_io_error_event(QmpSession *sess, Error **errp) { } What would the wire exchange look like? Also could be better named, disconnect-event or unlisten-event. I was going for symmetry with the signal accessors which are typically in the format 'get-block-io-error-event'. Maybe it would be better to do 'connect-block-io-error-event' and 'disconnect-event'? Yes. But I'm confused, do we have a per-event command on the wire? Or just C stubs? Ignoring default events, you'll never see an event until you execute a signal accessor function. When you execute this function, you will start receiving the events and those events will carry a tag containing the handle returned by the signal accessor. A "signal accessor" is a command to start listening to a signal? So why not have the signal accessor provide the tag? Like execute: blah provides a tag? Within libqmp, any time you execute a signal accessor, a new signal object is created of the appropriate type. When that object is destroyed, you send a put-event to stop receiving the signal. When you connect to a signal object (via libqmp), you don't execute the signal accessor because the object is already receiving the signal. Default events (which exist to preserve compatibility) are a set of events that are automatically connected to after qmp_capabilities is executed. Because these connections are implicit, they arrive without a handle in the event object. At this point, libqmp just ignores default events. In the future, I'd like to add a command that can be executed before qmp_capabilities that will avoid connecting to default events. I'm really confused. Part of that is because the conversation mixes libqmp, server API, and wire protocol. I'd like to understand the wire protocol first, everything else follows from that. -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH 01/13] pxa2xx_lcd: name anonymous struct
Signed-off-by: Juan Quintela --- hw/pxa2xx_lcd.c | 28 +++- 1 files changed, 15 insertions(+), 13 deletions(-) diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c index 5b2b07e..9a19347 100644 --- a/hw/pxa2xx_lcd.c +++ b/hw/pxa2xx_lcd.c @@ -15,6 +15,20 @@ #include "sysemu.h" #include "framebuffer.h" +struct DMAChannel { +target_phys_addr_t branch; +int up; +uint8_t palette[1024]; +uint8_t pbuffer[1024]; +void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr, + int *miny, int *maxy); + +target_phys_addr_t descriptor; +target_phys_addr_t source; +uint32_t id; +uint32_t command; +}; + struct PXA2xxLCDState { qemu_irq irq; int irqlevel; @@ -50,19 +64,7 @@ struct PXA2xxLCDState { uint32_t liidr; uint8_t bscntr; -struct { -target_phys_addr_t branch; -int up; -uint8_t palette[1024]; -uint8_t pbuffer[1024]; -void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr, -int *miny, int *maxy); - -target_phys_addr_t descriptor; -target_phys_addr_t source; -uint32_t id; -uint32_t command; -} dma_ch[7]; +struct DMAChannel dma_ch[7]; qemu_irq vsync_cb; int orientation; -- 1.7.4
[Qemu-devel] [PATCH 12/13] mac_dbdma: create DBDMAState instead of passing one array around
Signed-off-by: Juan Quintela --- hw/mac_dbdma.c | 45 +++-- 1 files changed, 27 insertions(+), 18 deletions(-) diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index 5680fa9..c108aee 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -165,6 +165,10 @@ typedef struct DBDMA_channel { int processing; } DBDMA_channel; +typedef struct { +DBDMA_channel channels[DBDMA_CHANNELS]; +} DBDMAState; + #ifdef DEBUG_DBDMA static void dump_dbdma_cmd(dbdma_cmd *cmd) { @@ -617,31 +621,34 @@ static void channel_run(DBDMA_channel *ch) } } -static void DBDMA_run (DBDMA_channel *ch) +static void DBDMA_run(DBDMAState *s) { int channel; -for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) { -uint32_t status = ch->regs[DBDMA_STATUS]; -if (!ch->processing && (status & RUN) && (status & ACTIVE)) -channel_run(ch); +for (channel = 0; channel < DBDMA_CHANNELS; channel++) { +DBDMA_channel *ch = &s->channels[channel]; +uint32_t status = ch->regs[DBDMA_STATUS]; +if (!ch->processing && (status & RUN) && (status & ACTIVE)) { +channel_run(ch); +} } } static void DBDMA_run_bh(void *opaque) { -DBDMA_channel *ch = opaque; +DBDMAState *s = opaque; DBDMA_DPRINTF("DBDMA_run_bh\n"); -DBDMA_run(ch); +DBDMA_run(s); } void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, DBDMA_rw rw, DBDMA_flush flush, void *opaque) { -DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan; +DBDMAState *s = dbdma; +DBDMA_channel *ch = &s->channels[nchan]; DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan); @@ -700,7 +707,8 @@ static void dbdma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) { int channel = addr >> DBDMA_CHANNEL_SHIFT; -DBDMA_channel *ch = (DBDMA_channel *)opaque + channel; +DBDMAState *s = opaque; +DBDMA_channel *ch = &s->channels[channel]; int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value); @@ -749,7 +757,8 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr) { uint32_t value; int channel = addr >> DBDMA_CHANNEL_SHIFT; -DBDMA_channel *ch = (DBDMA_channel *)opaque + channel; +DBDMAState *s = opaque; +DBDMA_channel *ch = &s->channels[channel]; int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; value = ch->regs[reg]; @@ -803,17 +812,17 @@ static CPUReadMemoryFunc * const dbdma_read[] = { static void dbdma_save(QEMUFile *f, void *opaque) { -DBDMA_channel *s = opaque; +DBDMAState *s = opaque; unsigned int i, j; for (i = 0; i < DBDMA_CHANNELS; i++) for (j = 0; j < DBDMA_REGS; j++) -qemu_put_be32s(f, &s[i].regs[j]); +qemu_put_be32s(f, &s->channels[i].regs[j]); } static int dbdma_load(QEMUFile *f, void *opaque, int version_id) { -DBDMA_channel *s = opaque; +DBDMAState *s = opaque; unsigned int i, j; if (version_id != 2) @@ -821,25 +830,25 @@ static int dbdma_load(QEMUFile *f, void *opaque, int version_id) for (i = 0; i < DBDMA_CHANNELS; i++) for (j = 0; j < DBDMA_REGS; j++) -qemu_get_be32s(f, &s[i].regs[j]); +qemu_get_be32s(f, &s->channels[i].regs[j]); return 0; } static void dbdma_reset(void *opaque) { -DBDMA_channel *s = opaque; +DBDMAState *s = opaque; int i; for (i = 0; i < DBDMA_CHANNELS; i++) -memset(s[i].regs, 0, DBDMA_SIZE); +memset(s->channels[i].regs, 0, DBDMA_SIZE); } void* DBDMA_init (int *dbdma_mem_index) { -DBDMA_channel *s; +DBDMAState *s; -s = qemu_mallocz(sizeof(DBDMA_channel) * DBDMA_CHANNELS); +s = qemu_mallocz(sizeof(DBDMAState)); *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s, DEVICE_LITTLE_ENDIAN); -- 1.7.4
[Qemu-devel] [PATCH 02/13] pxa2xx_lcd: up field is used as a bool and migrated as an uint8_t
Signed-off-by: Juan Quintela --- hw/pxa2xx_lcd.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c index 9a19347..55e95be 100644 --- a/hw/pxa2xx_lcd.c +++ b/hw/pxa2xx_lcd.c @@ -17,7 +17,7 @@ struct DMAChannel { target_phys_addr_t branch; -int up; +uint8_t up; uint8_t palette[1024]; uint8_t pbuffer[1024]; void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr, -- 1.7.4
[Qemu-devel] [PATCH 04/13] max111x: input field is only used as uint8_t
Signed-off-by: Juan Quintela --- hw/max111x.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/max111x.c b/hw/max111x.c index 2844665..3adc3e4 100644 --- a/hw/max111x.c +++ b/hw/max111x.c @@ -15,7 +15,7 @@ typedef struct { uint8_t tb1, rb2, rb3; int cycle; -int input[8]; +uint8_t input[8]; int inputs, com; } MAX111xState; -- 1.7.4
[Qemu-devel] [PATCH 07/13] vmstate: port nand
Signed-off-by: Juan Quintela --- hw/nand.c | 73 1 files changed, 39 insertions(+), 34 deletions(-) diff --git a/hw/nand.c b/hw/nand.c index 9f978d8..37e51d7 100644 --- a/hw/nand.c +++ b/hw/nand.c @@ -66,6 +66,8 @@ struct NANDFlashState { void (*blk_write)(NANDFlashState *s); void (*blk_erase)(NANDFlashState *s); void (*blk_load)(NANDFlashState *s, uint32_t addr, int offset); + +uint32_t ioaddr_vmstate; }; # define NAND_NO_AUTOINCR 0x0001 @@ -281,48 +283,51 @@ static void nand_command(NANDFlashState *s) } } -static void nand_save(QEMUFile *f, void *opaque) +static void nand_pre_save(void *opaque) { -NANDFlashState *s = (NANDFlashState *) opaque; -qemu_put_byte(f, s->cle); -qemu_put_byte(f, s->ale); -qemu_put_byte(f, s->ce); -qemu_put_byte(f, s->wp); -qemu_put_byte(f, s->gnd); -qemu_put_buffer(f, s->io, sizeof(s->io)); -qemu_put_be32(f, s->ioaddr - s->io); -qemu_put_be32(f, s->iolen); - -qemu_put_be32s(f, &s->cmd); -qemu_put_be32s(f, &s->addr); -qemu_put_be32(f, s->addrlen); -qemu_put_be32(f, s->status); -qemu_put_be32(f, s->offset); -/* XXX: do we want to save s->storage too? */ +NANDFlashState *s = opaque; + +s->ioaddr_vmstate = s->ioaddr - s->io; } -static int nand_load(QEMUFile *f, void *opaque, int version_id) +static int nand_post_load(void *opaque, int version_id) { -NANDFlashState *s = (NANDFlashState *) opaque; -s->cle = qemu_get_byte(f); -s->ale = qemu_get_byte(f); -s->ce = qemu_get_byte(f); -s->wp = qemu_get_byte(f); -s->gnd = qemu_get_byte(f); -qemu_get_buffer(f, s->io, sizeof(s->io)); -s->ioaddr = s->io + qemu_get_be32(f); -s->iolen = qemu_get_be32(f); -if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io) +NANDFlashState *s = opaque; + +if (s->ioaddr_vmstate > sizeof(s->io)) { return -EINVAL; +} +s->ioaddr = s->io + s->ioaddr_vmstate; -qemu_get_be32s(f, &s->cmd); -qemu_get_be32s(f, &s->addr); -s->addrlen = qemu_get_be32(f); -s->status = qemu_get_be32(f); -s->offset = qemu_get_be32(f); return 0; } +static const VMStateDescription vmstate_nand = { +.name = "nand", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.pre_save = nand_pre_save, +.post_load = nand_post_load, +.fields = (VMStateField[]) { +VMSTATE_UINT8(cle, NANDFlashState), +VMSTATE_UINT8(ale, NANDFlashState), +VMSTATE_UINT8(ce, NANDFlashState), +VMSTATE_UINT8(wp, NANDFlashState), +VMSTATE_UINT8(gnd, NANDFlashState), +VMSTATE_BUFFER(io, NANDFlashState), +VMSTATE_UINT32(ioaddr_vmstate, NANDFlashState), +VMSTATE_INT32(iolen, NANDFlashState), +VMSTATE_UINT32(cmd, NANDFlashState), +VMSTATE_UINT32(addr, NANDFlashState), +VMSTATE_INT32(addrlen, NANDFlashState), +VMSTATE_INT32(status, NANDFlashState), +VMSTATE_INT32(offset, NANDFlashState), +/* XXX: do we want to save s->storage too? */ +VMSTATE_END_OF_LIST() +} +}; + /* * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins. Chip * outputs are R/B and eight I/O pins. @@ -502,7 +507,7 @@ NANDFlashState *nand_init(int manf_id, int chip_id) is used. */ s->ioaddr = s->io; -register_savevm(NULL, "nand", -1, 0, nand_save, nand_load, s); +vmstate_register(NULL, -1, &vmstate_nand, s); return s; } -- 1.7.4
[Qemu-devel] [PATCH v2 3/3] qemu_next_deadline should not consider host-time timers
It is purely for icount-based virtual timers. And now that we got the code right, rename the function to clarify the intended scope. Signed-off-by: Paolo Bonzini --- cpus.c |4 ++-- qemu-timer.c | 11 +++ qemu-timer.h |2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/cpus.c b/cpus.c index a953bac..d410f63 100644 --- a/cpus.c +++ b/cpus.c @@ -861,7 +861,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) while (1) { cpu_exec_all(); -if (use_icount && qemu_next_deadline() <= 0) { +if (use_icount && qemu_next_icount_deadline() <= 0) { qemu_notify_event(); } qemu_tcg_wait_io_event(); @@ -1059,7 +1059,7 @@ static int tcg_cpu_exec(CPUState *env) qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); env->icount_decr.u16.low = 0; env->icount_extra = 0; -count = qemu_icount_round (qemu_next_deadline()); +count = qemu_icount_round (qemu_next_icount_deadline()); qemu_icount += count; decr = (count > 0x) ? 0x : count; count -= decr; diff --git a/qemu-timer.c b/qemu-timer.c index 62dd504..c527844 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -688,21 +688,16 @@ static void host_alarm_handler(int host_signum) } } -int64_t qemu_next_deadline(void) +int64_t qemu_next_icount_deadline(void) { /* To avoid problems with overflow limit this to 2^32. */ int64_t delta = INT32_MAX; +assert(use_icount); if (active_timers[QEMU_CLOCK_VIRTUAL]) { delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time - qemu_get_clock_ns(vm_clock); } -if (active_timers[QEMU_CLOCK_HOST]) { -int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time - - qemu_get_clock_ns(host_clock); -if (hdelta < delta) -delta = hdelta; -} if (delta < 0) delta = 0; @@ -1096,7 +1091,7 @@ int qemu_calculate_timeout(void) } else { /* Wait for either IO to occur or the next timer event. */ -add = qemu_next_deadline(); +add = qemu_next_icount_deadline(); /* We advance the timer before checking for IO. Limit the amount we advance so that early IO activity won't get the guest too far ahead. */ diff --git a/qemu-timer.h b/qemu-timer.h index 8cd8f83..9c3e52f 100644 --- a/qemu-timer.h +++ b/qemu-timer.h @@ -46,7 +46,7 @@ int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time); void qemu_run_all_timers(void); int qemu_alarm_pending(void); -int64_t qemu_next_deadline(void); +int64_t qemu_next_icount_deadline(void); void configure_alarms(char const *opt); void configure_icount(const char *option); int qemu_calculate_timeout(void); -- 1.7.4
[Qemu-devel] [PATCH 09/13] vmstate: port mac_nvram
Signed-off-by: Juan Quintela --- hw/mac_nvram.c | 30 +++--- 1 files changed, 11 insertions(+), 19 deletions(-) diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c index 64f0192..61e53d2 100644 --- a/hw/mac_nvram.c +++ b/hw/mac_nvram.c @@ -105,24 +105,17 @@ static CPUReadMemoryFunc * const nvram_read[] = { &macio_nvram_readb, }; -static void macio_nvram_save(QEMUFile *f, void *opaque) -{ -MacIONVRAMState *s = (MacIONVRAMState *)opaque; - -qemu_put_buffer(f, s->data, s->size); -} - -static int macio_nvram_load(QEMUFile *f, void *opaque, int version_id) -{ -MacIONVRAMState *s = (MacIONVRAMState *)opaque; - -if (version_id != 1) -return -EINVAL; - -qemu_get_buffer(f, s->data, s->size); +static const VMStateDescription vmstate_macio_nvram = { +.name = "macio_nvram", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_VBUFFER_UINT32(data, MacIONVRAMState, 0, NULL, 0, size), +VMSTATE_END_OF_LIST() +} +}; -return 0; -} static void macio_nvram_reset(void *opaque) { @@ -141,8 +134,7 @@ MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size, s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s, DEVICE_NATIVE_ENDIAN); *mem_index = s->mem_index; -register_savevm(NULL, "macio_nvram", -1, 1, macio_nvram_save, -macio_nvram_load, s); +vmstate_register(NULL, -1, &vmstate_macio_nvram, s); qemu_register_reset(macio_nvram_reset, s); return s; -- 1.7.4
[Qemu-devel] [PATCH 10/13] piix4: create PIIX4State
It only contains a PCIDevice by know, but it makes easy to use migration code Signed-off-by: Juan Quintela --- hw/piix4.c | 29 + 1 files changed, 17 insertions(+), 12 deletions(-) diff --git a/hw/piix4.c b/hw/piix4.c index 72073cd..40cd91a 100644 --- a/hw/piix4.c +++ b/hw/piix4.c @@ -30,10 +30,14 @@ PCIDevice *piix4_dev; +typedef struct PIIX4State { +PCIDevice dev; +} PIIX4State; + static void piix4_reset(void *opaque) { -PCIDevice *d = opaque; -uint8_t *pci_conf = d->config; +PIIX4State *d = opaque; +uint8_t *pci_conf = d->dev.config; pci_conf[0x04] = 0x07; // master, memory and I/O pci_conf[0x05] = 0x00; @@ -70,31 +74,32 @@ static void piix4_reset(void *opaque) static void piix_save(QEMUFile* f, void *opaque) { -PCIDevice *d = opaque; -pci_device_save(d, f); +PIIX4State *d = opaque; +pci_device_save(&d->dev, f); } static int piix_load(QEMUFile* f, void *opaque, int version_id) { -PCIDevice *d = opaque; +PIIX4State *d = opaque; if (version_id != 2) return -EINVAL; -return pci_device_load(d, f); +return pci_device_load(&d->dev, f); } -static int piix4_initfn(PCIDevice *d) +static int piix4_initfn(PCIDevice *dev) { +PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev); uint8_t *pci_conf; -isa_bus_new(&d->qdev); -register_savevm(&d->qdev, "PIIX4", 0, 2, piix_save, piix_load, d); +isa_bus_new(&d->dev.qdev); +register_savevm(&d->dev.qdev, "PIIX4", 0, 2, piix_save, piix_load, d); -pci_conf = d->config; +pci_conf = d->dev.config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); -piix4_dev = d; +piix4_dev = &d->dev; qemu_register_reset(piix4_reset, d); return 0; } @@ -111,7 +116,7 @@ static PCIDeviceInfo piix4_info[] = { { .qdev.name= "PIIX4", .qdev.desc= "ISA bridge", -.qdev.size= sizeof(PCIDevice), +.qdev.size= sizeof(PIIX4State), .qdev.no_user = 1, .no_hotplug = 1, .init = piix4_initfn, -- 1.7.4
[Qemu-devel] [PATCH 15/32] vmstate: port stellaris ssi bus
Signed-off-by: Juan Quintela --- hw/stellaris.c | 31 +++ 1 files changed, 11 insertions(+), 20 deletions(-) diff --git a/hw/stellaris.c b/hw/stellaris.c index 715e48c..9b83fb4 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -1219,24 +1219,16 @@ static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val) return ssi_transfer(s->bus[s->current_dev], val); } -static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque) -{ -stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; - -qemu_put_be32(f, s->current_dev); -} - -static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id) -{ -stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; - -if (version_id != 1) -return -EINVAL; - -s->current_dev = qemu_get_be32(f); - -return 0; -} +static const VMStateDescription vmstate_stellaris_ssi_bus = { +.name = "stellaris_ssi_bus", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32(current_dev, stellaris_ssi_bus_state), +VMSTATE_END_OF_LIST() +} +}; static int stellaris_ssi_bus_init(SSISlave *dev) { @@ -1246,8 +1238,7 @@ static int stellaris_ssi_bus_init(SSISlave *dev) s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1"); qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1); -register_savevm(&dev->qdev, "stellaris_ssi_bus", -1, 1, -stellaris_ssi_bus_save, stellaris_ssi_bus_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s); return 0; } -- 1.7.4
Re: [Qemu-devel] [PATCH 14/22] qapi: add query-version QMP command
On 03/10/2011 02:41 PM, Avi Kivity wrote: I don't think I want to make this sort of change just yet. Also note that the schema that will be exposed over the wire is not directly related to the schema we use for code generation. Right, we have to nail down the format for the former, though. btw. Back in the day when json was proposed vs. a custom text-line oriented protocol, it beat established RPCs because they were all so cumbersome with IDLs and code generation and general heavyweightness. And now we're making our json-rpc exactly like that. There's a moral in there somewhere. -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH 1/2] sockets: add qemu_socketpair()
Signed-off-by: Corentin Chary --- osdep.c | 83 + qemu_socket.h |1 + 2 files changed, 84 insertions(+), 0 deletions(-) diff --git a/osdep.c b/osdep.c index 327583b..93bfbe0 100644 --- a/osdep.c +++ b/osdep.c @@ -147,6 +147,89 @@ int qemu_socket(int domain, int type, int protocol) return ret; } +#ifdef _WIN32 +int qemu_socketpair(int domain, int type, int protocol, int socks[2]) +{ +union { + struct sockaddr_in inaddr; + struct sockaddr addr; +} a; +int listener; +socklen_t addrlen = sizeof(a.inaddr); +int reuse = 1; + +if (domain == AF_UNIX) { +domain = AF_INET; +} + +if (socks == 0) { +return EINVAL; +} + +listener = qemu_socket(domain, type, protocol); +if (listener < 0) { +return listener; +} + +memset(&a, 0, sizeof(a)); +a.inaddr.sin_family = AF_INET; +a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); +a.inaddr.sin_port = 0; + +socks[0] = socks[1] = -1; + +if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, + (char*) &reuse, (socklen_t) sizeof(reuse)) == -1) { +goto error; +} +if (bind(listener, &a.addr, sizeof(a.inaddr)) < 0) { +goto error; +} + +memset(&a, 0, sizeof(a)); +if (getsockname(listener, &a.addr, &addrlen) < 0) { +goto error; +} + +a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); +a.inaddr.sin_family = AF_INET; + +if (listen(listener, 1) < 0) { +goto error; +} + +socks[0] = qemu_socket(AF_INET, SOCK_STREAM, 0); +if (socks[0] < 0) { +goto error; +} +if (connect(socks[0], &a.addr, sizeof(a.inaddr)) < 0) { +goto error; +} + +socks[1] = qemu_accept(listener, NULL, NULL); +if (socks[1] < 0) { +goto error; +} + +closesocket(listener); +return 0; + +error: +if (listener != -1) +closesocket(listener); +if (socks[0] != -1) +closesocket(socks[0]); +if (socks[1] != -1) +closesocket(socks[1]); +return -1; +} +#else +int qemu_socketpair(int domain, int type, int protocol, int socks[2]) +{ +return socketpair(domain, type, protocol, socks); +} +#endif + /* * Accept a connection and set FD_CLOEXEC */ diff --git a/qemu_socket.h b/qemu_socket.h index 180e4db..d7eb9a5 100644 --- a/qemu_socket.h +++ b/qemu_socket.h @@ -34,6 +34,7 @@ int inet_aton(const char *cp, struct in_addr *ia); /* misc helpers */ int qemu_socket(int domain, int type, int protocol); +int qemu_socketpair(int domain, int type, int protocol, int socks[2]); int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); void socket_set_nonblock(int fd); int send_all(int fd, const void *buf, int len1); -- 1.7.3.4
[Qemu-devel] [PATCH v2 2/3] Revert wrong fixes for -icount in the iothread case
This reverts commits 225d02cd and c9f7383c. While some parts of the latter could be saved, I preferred a smooth, complete revert. Signed-off-by: Paolo Bonzini --- qemu-timer.c | 66 +++-- 1 files changed, 36 insertions(+), 30 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index 88c7b28..62dd504 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -110,9 +110,12 @@ static int64_t cpu_get_clock(void) } } +#ifndef CONFIG_IOTHREAD static int64_t qemu_icount_delta(void) { -if (use_icount == 1) { +if (!use_icount) { +return 5000 * (int64_t) 100; +} else if (use_icount == 1) { /* When not using an adaptive execution frequency we tend to get badly out of sync with real time, so just delay for a reasonable amount of time. */ @@ -121,6 +124,7 @@ static int64_t qemu_icount_delta(void) return cpu_get_icount() - cpu_get_clock(); } } +#endif /* enable cpu_get_ticks() */ void cpu_enable_ticks(void) @@ -1074,39 +1078,41 @@ void quit_timers(void) int qemu_calculate_timeout(void) { +#ifndef CONFIG_IOTHREAD int timeout; -int64_t add; -int64_t delta; -/* When using icount, making forward progress with qemu_icount when the - guest CPU is idle is critical. We only use the static io-thread timeout - for non icount runs. */ -if (!use_icount || !vm_running) { -return 5000; -} - -/* Advance virtual time to the next event. */ -delta = qemu_icount_delta(); -if (delta > 0) { -/* If virtual time is ahead of real time then just - wait for IO. */ -timeout = (delta + 99) / 100; -} else { -/* Wait for either IO to occur or the next - timer event. */ -add = qemu_next_deadline(); -/* We advance the timer before checking for IO. - Limit the amount we advance so that early IO - activity won't get the guest too far ahead. */ -if (add > 1000) -add = 1000; -delta += add; -qemu_icount += qemu_icount_round (add); -timeout = delta / 100; -if (timeout < 0) -timeout = 0; +if (!vm_running) +timeout = 5000; +else { + /* XXX: use timeout computed from timers */ +int64_t add; +int64_t delta; +/* Advance virtual time to the next event. */ + delta = qemu_icount_delta(); +if (delta > 0) { +/* If virtual time is ahead of real time then just + wait for IO. */ +timeout = (delta + 99) / 100; +} else { +/* Wait for either IO to occur or the next + timer event. */ +add = qemu_next_deadline(); +/* We advance the timer before checking for IO. + Limit the amount we advance so that early IO + activity won't get the guest too far ahead. */ +if (add > 1000) +add = 1000; +delta += add; +qemu_icount += qemu_icount_round (add); +timeout = delta / 100; +if (timeout < 0) +timeout = 0; +} } return timeout; +#else /* CONFIG_IOTHREAD */ +return 1000; +#endif } -- 1.7.4
[Qemu-devel] [PATCH 13/13] vmstate: port mac_dbdma
Signed-off-by: Juan Quintela --- hw/mac_dbdma.c | 46 ++ 1 files changed, 22 insertions(+), 24 deletions(-) diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index c108aee..ed4458e 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -810,30 +810,28 @@ static CPUReadMemoryFunc * const dbdma_read[] = { dbdma_readl, }; -static void dbdma_save(QEMUFile *f, void *opaque) -{ -DBDMAState *s = opaque; -unsigned int i, j; - -for (i = 0; i < DBDMA_CHANNELS; i++) -for (j = 0; j < DBDMA_REGS; j++) -qemu_put_be32s(f, &s->channels[i].regs[j]); -} - -static int dbdma_load(QEMUFile *f, void *opaque, int version_id) -{ -DBDMAState *s = opaque; -unsigned int i, j; - -if (version_id != 2) -return -EINVAL; - -for (i = 0; i < DBDMA_CHANNELS; i++) -for (j = 0; j < DBDMA_REGS; j++) -qemu_get_be32s(f, &s->channels[i].regs[j]); +static const VMStateDescription vmstate_dbdma_channel = { +.name = "dbdma_channel", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS), +VMSTATE_END_OF_LIST() +} +}; -return 0; -} +static const VMStateDescription vmstate_dbdma = { +.name = "dbdma", +.version_id = 2, +.minimum_version_id = 2, +.minimum_version_id_old = 2, +.fields = (VMStateField[]) { +VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1, + vmstate_dbdma_channel, DBDMA_channel), +VMSTATE_END_OF_LIST() +} +}; static void dbdma_reset(void *opaque) { @@ -852,7 +850,7 @@ void* DBDMA_init (int *dbdma_mem_index) *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s, DEVICE_LITTLE_ENDIAN); -register_savevm(NULL, "dbdma", -1, 1, dbdma_save, dbdma_load, s); +vmstate_register(NULL, -1, &vmstate_dbdma, s); qemu_register_reset(dbdma_reset, s); dbdma_bh = qemu_bh_new(DBDMA_run_bh, s); -- 1.7.4
[Qemu-devel] [PATCH 2/2] vnc: don't mess up with iohandlers in the vnc thread
The threaded VNC servers messed up with QEMU fd handlers without any kind of locking, and that can cause some nasty race conditions. Using qemu_mutex_lock_iothread() won't work because vnc_dpy_cpy(), which will wait for the current job queue to finish, can be called with the iothread lock held. Instead, we now store the data in a temporary buffer, and use a socket pair to notify the main thread that new data is available. The data is not directly send through this socket because it would make the code more complex without any performance benefit. vnc_[un]lock_ouput() is still needed to access VncState members like abort, csock or jobs_buffer. Thanks to Jan Kiszka for helping me solve this issue. Signed-off-by: Corentin Chary --- ui/vnc-jobs-async.c | 50 -- ui/vnc-jobs-sync.c |4 ui/vnc-jobs.h |1 + ui/vnc.c| 16 ui/vnc.h|2 ++ 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c index f596247..543b5a9 100644 --- a/ui/vnc-jobs-async.c +++ b/ui/vnc-jobs-async.c @@ -28,6 +28,7 @@ #include "vnc.h" #include "vnc-jobs.h" +#include "qemu_socket.h" /* * Locking: @@ -155,6 +156,24 @@ void vnc_jobs_join(VncState *vs) qemu_cond_wait(&queue->cond, &queue->mutex); } vnc_unlock_queue(queue); +vnc_jobs_consume_buffer(vs); +} + +void vnc_jobs_consume_buffer(VncState *vs) +{ +bool flush; + +vnc_lock_output(vs); +if (vs->jobs_buffer.offset) { +vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset); +buffer_reset(&vs->jobs_buffer); +} +flush = vs->csock != -1 && vs->abort != true; +vnc_unlock_output(vs); + +if (flush) { + vnc_flush(vs); +} } /* @@ -197,7 +216,6 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) VncState vs; int n_rectangles; int saved_offset; -bool flush; vnc_lock_queue(queue); while (QTAILQ_EMPTY(&queue->jobs) && !queue->exit) { @@ -213,6 +231,7 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) vnc_lock_output(job->vs); if (job->vs->csock == -1 || job->vs->abort == true) { +vnc_unlock_output(job->vs); goto disconnected; } vnc_unlock_output(job->vs); @@ -233,10 +252,6 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) if (job->vs->csock == -1) { vnc_unlock_display(job->vs->vd); -/* output mutex must be locked before going to - * disconnected: - */ -vnc_lock_output(job->vs); goto disconnected; } @@ -254,24 +269,23 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) vs.output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF; -/* Switch back buffers */ vnc_lock_output(job->vs); -if (job->vs->csock == -1) { -goto disconnected; -} - -vnc_write(job->vs, vs.output.buffer, vs.output.offset); +if (job->vs->csock != -1) { +int notify = !job->vs->jobs_buffer.offset; -disconnected: -/* Copy persistent encoding data */ -vnc_async_encoding_end(job->vs, &vs); -flush = (job->vs->csock != -1 && job->vs->abort != true); -vnc_unlock_output(job->vs); +buffer_reserve(&job->vs->jobs_buffer, vs.output.offset); +buffer_append(&job->vs->jobs_buffer, vs.output.buffer, + vs.output.offset); +/* Copy persistent encoding data */ +vnc_async_encoding_end(job->vs, &vs); -if (flush) { -vnc_flush(job->vs); +if (notify) { +send(job->vs->jobs_socks[1], (char []){1}, 1, 0); +} } +vnc_unlock_output(job->vs); +disconnected: vnc_lock_queue(queue); QTAILQ_REMOVE(&queue->jobs, job, next); vnc_unlock_queue(queue); diff --git a/ui/vnc-jobs-sync.c b/ui/vnc-jobs-sync.c index 49b77af..3a4d7df 100644 --- a/ui/vnc-jobs-sync.c +++ b/ui/vnc-jobs-sync.c @@ -36,6 +36,10 @@ void vnc_jobs_join(VncState *vs) { } +void vnc_jobs_consume_buffer(VncState *vs) +{ +} + VncJob *vnc_job_new(VncState *vs) { vs->job.vs = vs; diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h index b8dab81..7c529b7 100644 --- a/ui/vnc-jobs.h +++ b/ui/vnc-jobs.h @@ -37,6 +37,7 @@ void vnc_job_push(VncJob *job); bool vnc_has_job(VncState *vs); void vnc_jobs_clear(VncState *vs); void vnc_jobs_join(VncState *vs); +void vnc_jobs_consume_buffer(VncState *vs); #ifdef CONFIG_VNC_THREAD diff --git a/ui/vnc.c b/ui/vnc.c index 610f884..48a81a2 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1011,6 +1011,10 @@ static void vnc_disconnect_finish(VncState *vs) #ifdef CONFIG_VNC_THREAD qemu_mutex_destroy(&vs->output_mutex); +qemu_set_fd_handler2(vs->jobs_socks[0], NULL, NULL, NULL, vs); +close(vs->jobs_socks[0]); +close(vs->jobs_socks[1]); +buffer_free(&vs->jobs_buffer); #endi
Re: [Qemu-devel] virtio block device and sysfs
On Tue, Sep 14, 2010 at 09:43:22AM +0200, Marc Haber wrote: > On Mon, Sep 13, 2010 at 09:34:24AM -0500, Ryan Harper wrote: > > It'll only be available to guests launched with newer qemu (0.13) as > > virtio-blk serial support is a new feature. > > Thanks for the information, I'll wait for the next release (or the > time to locally build 0.13-rc for testing, whatever happens first). I now have qemu-kvm 0.14, and the serial "number" is imported to the guest just fine, and there is also already a udev rule present in Debian which will make the disk show up in /dev/disk/by-id/virtio-foo. Thank you very much for helping, I really appreciate that. Greetings Marc -- - Marc Haber | "I don't trust Computers. They | Mailadresse im Header Mannheim, Germany | lose things."Winona Ryder | Fon: *49 621 72739834 Nordisch by Nature | How to make an American Quilt | Fax: *49 3221 2323190
[Qemu-devel] [PATCH 11/13] vmstate: port piix4
Signed-off-by: Juan Quintela --- hw/piix4.c | 25 +++-- 1 files changed, 11 insertions(+), 14 deletions(-) diff --git a/hw/piix4.c b/hw/piix4.c index 40cd91a..71f1f84 100644 --- a/hw/piix4.c +++ b/hw/piix4.c @@ -72,19 +72,16 @@ static void piix4_reset(void *opaque) pci_conf[0xae] = 0x00; } -static void piix_save(QEMUFile* f, void *opaque) -{ -PIIX4State *d = opaque; -pci_device_save(&d->dev, f); -} - -static int piix_load(QEMUFile* f, void *opaque, int version_id) -{ -PIIX4State *d = opaque; -if (version_id != 2) -return -EINVAL; -return pci_device_load(&d->dev, f); -} +static const VMStateDescription vmstate_piix4 = { +.name = "PIIX4", +.version_id = 2, +.minimum_version_id = 2, +.minimum_version_id_old = 2, +.fields = (VMStateField[]) { +VMSTATE_PCI_DEVICE(dev, PIIX4State), +VMSTATE_END_OF_LIST() +} +}; static int piix4_initfn(PCIDevice *dev) { @@ -92,7 +89,6 @@ static int piix4_initfn(PCIDevice *dev) uint8_t *pci_conf; isa_bus_new(&d->dev.qdev); -register_savevm(&d->dev.qdev, "PIIX4", 0, 2, piix_save, piix_load, d); pci_conf = d->dev.config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); @@ -117,6 +113,7 @@ static PCIDeviceInfo piix4_info[] = { .qdev.name= "PIIX4", .qdev.desc= "ISA bridge", .qdev.size= sizeof(PIIX4State), +.qdev.vmsd= &vmstate_piix4, .qdev.no_user = 1, .no_hotplug = 1, .init = piix4_initfn, -- 1.7.4
[Qemu-devel] Re: RFC: emulation of system flash
On 2011-03-10 12:48, Gleb Natapov wrote: > On Thu, Mar 10, 2011 at 12:27:55PM +0100, Jan Kiszka wrote: >> On 2011-03-10 10:47, Gleb Natapov wrote: >>> On Wed, Mar 09, 2011 at 08:51:23PM -0800, Jordan Justen wrote: Hi all, I have documented a simple flash-like device which I think could be useful for qemu/kvm in some cases. (Particularly for allowing persistent UEFI non-volatile variables.) http://wiki.qemu.org/Features/System_Flash Let me know if you have any suggestions or concerns. >>> >>> Two things. First You suggest to replace -bios with -flash. This will >>> make firmware upgrade painful process that will have to be performed >>> from inside the guest since the same flash image will contain both >>> firmware and whatever data was stored on a flash which presumably you >>> want to reuse after upgrading a firmware. My suggestion is to extend >>> -bios option like this: >>> >>> -bios bios.bin,flash=flash.bin,flash_base=addr >>> >>> flash.bin will be mapped at address flash_base, or, if flash_base is not >>> present, just below bios.bin. >> >> ...or define -flash in a way that allows mapping the bios image as an >> overlay to the otherwise guest-managed flash image. >> > It is not much different from what I proposed. The result will be the > same. Even option syntax will probably be the same :) -bios is PC-centric, the new command should be generic. > >>> >>> Second. I asked how flash is programmed because interfaces like CFI >>> where you write into flash memory address range to issue commands cannot >>> be emulated efficiently in KVM. KVM supports either regular memory slots >>> or IO memory, but in your proposal the same memory behaves as IO on >>> write and regular memory on read. Better idea would be to present >>> non-volatile flash as ISA virtio device. Should be simple to implement. >> >> Why not enhancing KVM memory slots to support direct read access while >> writes are trapped and forwarded to a user space device model? > Yes we can make memory slot that will be treated as memory on read and > IO on write, but first relying on that will prevent using flash interface > on older kernels and second it is not enough to implement the proposal. > When magic value is written into an address, the address become IO for > reading too, but KVM slot granularity is page, not byte, so KVM will > have to remove the slot to make it IO, but KVM can't execute code from > IO region (yet), so we will not be able to run firmware from flash and > simultaneously write into the flash. Yeah, right. I remember that this was also hairy over TCG if you tried to optimize flash emulation so that writing doesn't take orders of magnitude longer than on real HW. BTW, the programming granularity is not bytes but chips with common CFI. But that's still tricky if you want to run code from the same chip while updating parts of it. The easiest workaround would be handling the overlay regions as ROM all the time. Not accurate but realizable without kernel changes. > >> Virtio >> means that you have to patch the guest (which might be something else >> than flexible Linux...). >> > This intended to be used by firmware only and we control that. I'm thinking beyond this use case, beyond firmware flashes, beyond x86. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH v2 1/3] really fix -icount in the iothread case
The correct fix for -icount is to consider the biggest difference between iothread and non-iothread modes. In the traditional model, CPUs run _before_ the iothread calls select (or WaitForMultipleObjects for Win32). In the iothread model, CPUs run while the iothread isn't holding the mutex, i.e. _during_ those same calls. So, the iothread should always block as long as possible to let the CPUs run smoothly---the timeout might as well be infinite---and either the OS or the CPU thread itself will let the iothread know when something happens. At this point, the iothread wakes up and interrupts the CPU. This is exactly the approach that this patch takes: when cpu_exec_all returns in -icount mode, and it is because a vm_clock deadline has been met, it wakes up the iothread to process the timers. This fixes icount better than any other patch that was posted. Signed-off-by: Paolo Bonzini --- cpus.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/cpus.c b/cpus.c index 0f33945..a953bac 100644 --- a/cpus.c +++ b/cpus.c @@ -861,6 +861,9 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) while (1) { cpu_exec_all(); +if (use_icount && qemu_next_deadline() <= 0) { +qemu_notify_event(); +} qemu_tcg_wait_io_event(); } -- 1.7.4
[Qemu-devel] Re: [PATCH 2/2] vnc: don't mess up with iohandlers in the vnc thread
On 03/10/2011 01:59 PM, Corentin Chary wrote: Instead, we now store the data in a temporary buffer, and use a socket pair to notify the main thread that new data is available. You can use a bottom half for this instead of a special socket. Signaling a bottom half is async-signal- and thread-safe. Paolo
[Qemu-devel] Re: RFC: emulation of system flash
On Thu, Mar 10, 2011 at 01:06:14PM +0100, Jan Kiszka wrote: > On 2011-03-10 12:48, Gleb Natapov wrote: > > On Thu, Mar 10, 2011 at 12:27:55PM +0100, Jan Kiszka wrote: > >> On 2011-03-10 10:47, Gleb Natapov wrote: > >>> On Wed, Mar 09, 2011 at 08:51:23PM -0800, Jordan Justen wrote: > Hi all, > > I have documented a simple flash-like device which I think could be > useful for qemu/kvm in some cases. (Particularly for allowing > persistent UEFI non-volatile variables.) > > http://wiki.qemu.org/Features/System_Flash > > Let me know if you have any suggestions or concerns. > > >>> > >>> Two things. First You suggest to replace -bios with -flash. This will > >>> make firmware upgrade painful process that will have to be performed > >>> from inside the guest since the same flash image will contain both > >>> firmware and whatever data was stored on a flash which presumably you > >>> want to reuse after upgrading a firmware. My suggestion is to extend > >>> -bios option like this: > >>> > >>> -bios bios.bin,flash=flash.bin,flash_base=addr > >>> > >>> flash.bin will be mapped at address flash_base, or, if flash_base is not > >>> present, just below bios.bin. > >> > >> ...or define -flash in a way that allows mapping the bios image as an > >> overlay to the otherwise guest-managed flash image. > >> > > It is not much different from what I proposed. The result will be the > > same. Even option syntax will probably be the same :) > > -bios is PC-centric, the new command should be generic. > Well, I tried to reuse the option we already have instead of introducing another one. -bios can be extended beyond PC and represent general firmware specification. But I like the option you proposed in other email too, so I am not going to defend this one. > > > >>> > >>> Second. I asked how flash is programmed because interfaces like CFI > >>> where you write into flash memory address range to issue commands cannot > >>> be emulated efficiently in KVM. KVM supports either regular memory slots > >>> or IO memory, but in your proposal the same memory behaves as IO on > >>> write and regular memory on read. Better idea would be to present > >>> non-volatile flash as ISA virtio device. Should be simple to implement. > >> > >> Why not enhancing KVM memory slots to support direct read access while > >> writes are trapped and forwarded to a user space device model? > > Yes we can make memory slot that will be treated as memory on read and > > IO on write, but first relying on that will prevent using flash interface > > on older kernels and second it is not enough to implement the proposal. > > When magic value is written into an address, the address become IO for > > reading too, but KVM slot granularity is page, not byte, so KVM will > > have to remove the slot to make it IO, but KVM can't execute code from > > IO region (yet), so we will not be able to run firmware from flash and > > simultaneously write into the flash. > > Yeah, right. I remember that this was also hairy over TCG if you tried > to optimize flash emulation so that writing doesn't take orders of > magnitude longer than on real HW. > > BTW, the programming granularity is not bytes but chips with common CFI. > But that's still tricky if you want to run code from the same chip while > updating parts of it. The easiest workaround would be handling the > overlay regions as ROM all the time. Not accurate but realizable without > kernel changes. > So flash will be always IO and overlay will be always ROM. This will work, except BIOS upgrade from inside the guest will not be possible, but since we do not support this today too it doesn't bother me to much. > > > >> Virtio > >> means that you have to patch the guest (which might be something else > >> than flexible Linux...). > >> > > This intended to be used by firmware only and we control that. > > I'm thinking beyond this use case, beyond firmware flashes, beyond x86. > OK, but since both interfaces (virtio and one proposed in the wiki) are PV I fail to see the difference between them for any use case. If we implement CFI then it will be another story. -- Gleb.
[Qemu-devel] [PATCH 32/32] vmstate: stellaris use unused for placeholder entries
Signed-off-by: Juan Quintela --- hw/stellaris.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/hw/stellaris.c b/hw/stellaris.c index 6e31d89..74815ad 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -291,8 +291,7 @@ static const VMStateDescription vmstate_stellaris_gptm = { VMSTATE_UINT32(control, gptm_state), VMSTATE_UINT32(state, gptm_state), VMSTATE_UINT32(mask, gptm_state), -VMSTATE_UINT32(mode[0], gptm_state), -VMSTATE_UINT32(mode[0], gptm_state), +VMSTATE_UNUSED(8), VMSTATE_UINT32_ARRAY(load, gptm_state, 2), VMSTATE_UINT32_ARRAY(match, gptm_state, 2), VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2), -- 1.7.4
[Qemu-devel] [PATCH 05/13] vmstate: port max111x
Signed-off-by: Juan Quintela --- hw/max111x.c | 49 + 1 files changed, 17 insertions(+), 32 deletions(-) diff --git a/hw/max111x.c b/hw/max111x.c index 3adc3e4..70cd1af 100644 --- a/hw/max111x.c +++ b/hw/max111x.c @@ -94,36 +94,22 @@ static uint32_t max111x_transfer(SSISlave *dev, uint32_t value) return max111x_read(s); } -static void max111x_save(QEMUFile *f, void *opaque) -{ -MAX111xState *s = (MAX111xState *) opaque; -int i; - -qemu_put_8s(f, &s->tb1); -qemu_put_8s(f, &s->rb2); -qemu_put_8s(f, &s->rb3); -qemu_put_be32(f, s->inputs); -qemu_put_be32(f, s->com); -for (i = 0; i < s->inputs; i ++) -qemu_put_byte(f, s->input[i]); -} - -static int max111x_load(QEMUFile *f, void *opaque, int version_id) -{ -MAX111xState *s = (MAX111xState *) opaque; -int i; - -qemu_get_8s(f, &s->tb1); -qemu_get_8s(f, &s->rb2); -qemu_get_8s(f, &s->rb3); -if (s->inputs != qemu_get_be32(f)) -return -EINVAL; -s->com = qemu_get_be32(f); -for (i = 0; i < s->inputs; i ++) -s->input[i] = qemu_get_byte(f); - -return 0; -} +static const VMStateDescription vmstate_max111x = { +.name = "max111x", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT8(tb1, MAX111xState), +VMSTATE_UINT8(rb2, MAX111xState), +VMSTATE_UINT8(rb3, MAX111xState), +VMSTATE_INT32_EQUAL(inputs, MAX111xState), +VMSTATE_INT32(com, MAX111xState), +VMSTATE_ARRAY_INT32_UNSAFE(input, MAX111xState, inputs, + vmstate_info_uint8, uint8_t), +VMSTATE_END_OF_LIST() +} +}; static int max111x_init(SSISlave *dev, int inputs) { @@ -143,8 +129,7 @@ static int max111x_init(SSISlave *dev, int inputs) s->input[7] = 0x80; s->com = 0; -register_savevm(&dev->qdev, "max111x", -1, 0, -max111x_save, max111x_load, s); +vmstate_register(&dev->qdev, -1, &vmstate_max111x, s); return 0; } -- 1.7.4
Re: [Qemu-devel] [PATCH 14/22] qapi: add query-version QMP command
On 03/09/2011 04:47 PM, Anthony Liguori wrote: [ { 'type': 'MyType', fields: [['a', 'str'], ['b', 'int'], ['c', 'AnotherType']] } { 'event': 'MY_EVENT', 'arguments': [ ... ] } { 'command': 'my-command', 'arguments': [ ... ], 'return': ... } ] which leaves us room for additional metainformation. The concern is more about non-qemu consumers of the schema. Yeah, I dislike it too and I've been leaning towards changing it. My preference would be: { 'type': 'MyType', 'fields': { 'a': 'str', 'b': 'int', 'c': 'AnotherType' } } { 'event': 'MY_EVENT', 'arguments': {...} } { 'command': 'my-command', 'arguments': {...}, 'returns': 'int' } I do prefer the dictionary syntax for arguments over a list because a list implies order. Plus I think the syntax is just awkward and a whole lot easier to get wrong (too many/few elements in list). Yeah. We can rationalize it by saying that most dynamic consumers of the schema will not care about argument order, and that if they do, they can implement a custom parser. I don't think I want to make this sort of change just yet. Also note that the schema that will be exposed over the wire is not directly related to the schema we use for code generation. Right, we have to nail down the format for the former, though. -- error compiling committee.c: too many arguments to function
[Qemu-devel] Re: [PATCH 2/2] vnc: don't mess up with iohandlers in the vnc thread
On 03/10/2011 07:06 AM, Paolo Bonzini wrote: On 03/10/2011 01:59 PM, Corentin Chary wrote: Instead, we now store the data in a temporary buffer, and use a socket pair to notify the main thread that new data is available. You can use a bottom half for this instead of a special socket. Signaling a bottom half is async-signal- and thread-safe. Bottom halves are thread safe? I don't think so. They probably should be but they aren't today. Regards, Anthony Liguori Paolo
[Qemu-devel] Re: [PATCH 2/2] vnc: don't mess up with iohandlers in the vnc thread
On 10.03.2011 13:59, Corentin Chary wrote: The threaded VNC servers messed up with QEMU fd handlers without any kind of locking, and that can cause some nasty race conditions. Using qemu_mutex_lock_iothread() won't work because vnc_dpy_cpy(), which will wait for the current job queue to finish, can be called with the iothread lock held. Instead, we now store the data in a temporary buffer, and use a socket pair to notify the main thread that new data is available. The data is not directly send through this socket because it would make the code more complex without any performance benefit. vnc_[un]lock_ouput() is still needed to access VncState members like abort, csock or jobs_buffer. is this compatible with qemu-kvm? thanks, peter Thanks to Jan Kiszka for helping me solve this issue. Signed-off-by: Corentin Chary --- ui/vnc-jobs-async.c | 50 -- ui/vnc-jobs-sync.c |4 ui/vnc-jobs.h |1 + ui/vnc.c| 16 ui/vnc.h|2 ++ 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c index f596247..543b5a9 100644 --- a/ui/vnc-jobs-async.c +++ b/ui/vnc-jobs-async.c @@ -28,6 +28,7 @@ #include "vnc.h" #include "vnc-jobs.h" +#include "qemu_socket.h" /* * Locking: @@ -155,6 +156,24 @@ void vnc_jobs_join(VncState *vs) qemu_cond_wait(&queue->cond,&queue->mutex); } vnc_unlock_queue(queue); +vnc_jobs_consume_buffer(vs); +} + +void vnc_jobs_consume_buffer(VncState *vs) +{ +bool flush; + +vnc_lock_output(vs); +if (vs->jobs_buffer.offset) { +vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset); +buffer_reset(&vs->jobs_buffer); +} +flush = vs->csock != -1&& vs->abort != true; +vnc_unlock_output(vs); + +if (flush) { + vnc_flush(vs); +} } /* @@ -197,7 +216,6 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) VncState vs; int n_rectangles; int saved_offset; -bool flush; vnc_lock_queue(queue); while (QTAILQ_EMPTY(&queue->jobs)&& !queue->exit) { @@ -213,6 +231,7 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) vnc_lock_output(job->vs); if (job->vs->csock == -1 || job->vs->abort == true) { +vnc_unlock_output(job->vs); goto disconnected; } vnc_unlock_output(job->vs); @@ -233,10 +252,6 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) if (job->vs->csock == -1) { vnc_unlock_display(job->vs->vd); -/* output mutex must be locked before going to - * disconnected: - */ -vnc_lock_output(job->vs); goto disconnected; } @@ -254,24 +269,23 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) vs.output.buffer[saved_offset] = (n_rectangles>> 8)& 0xFF; vs.output.buffer[saved_offset + 1] = n_rectangles& 0xFF; -/* Switch back buffers */ vnc_lock_output(job->vs); -if (job->vs->csock == -1) { -goto disconnected; -} - -vnc_write(job->vs, vs.output.buffer, vs.output.offset); +if (job->vs->csock != -1) { +int notify = !job->vs->jobs_buffer.offset; -disconnected: -/* Copy persistent encoding data */ -vnc_async_encoding_end(job->vs,&vs); -flush = (job->vs->csock != -1&& job->vs->abort != true); -vnc_unlock_output(job->vs); +buffer_reserve(&job->vs->jobs_buffer, vs.output.offset); +buffer_append(&job->vs->jobs_buffer, vs.output.buffer, + vs.output.offset); +/* Copy persistent encoding data */ +vnc_async_encoding_end(job->vs,&vs); -if (flush) { -vnc_flush(job->vs); +if (notify) { +send(job->vs->jobs_socks[1], (char []){1}, 1, 0); +} } +vnc_unlock_output(job->vs); +disconnected: vnc_lock_queue(queue); QTAILQ_REMOVE(&queue->jobs, job, next); vnc_unlock_queue(queue); diff --git a/ui/vnc-jobs-sync.c b/ui/vnc-jobs-sync.c index 49b77af..3a4d7df 100644 --- a/ui/vnc-jobs-sync.c +++ b/ui/vnc-jobs-sync.c @@ -36,6 +36,10 @@ void vnc_jobs_join(VncState *vs) { } +void vnc_jobs_consume_buffer(VncState *vs) +{ +} + VncJob *vnc_job_new(VncState *vs) { vs->job.vs = vs; diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h index b8dab81..7c529b7 100644 --- a/ui/vnc-jobs.h +++ b/ui/vnc-jobs.h @@ -37,6 +37,7 @@ void vnc_job_push(VncJob *job); bool vnc_has_job(VncState *vs); void vnc_jobs_clear(VncState *vs); void vnc_jobs_join(VncState *vs); +void vnc_jobs_consume_buffer(VncState *vs); #ifdef CONFIG_VNC_THREAD diff --git a/ui/vnc.c b/ui/vnc.c index 610f884..48a81a2 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1011,6 +1011,10 @@ static void vnc_disconnect_finish(VncState *vs) #ifdef CONFIG_VNC_THREAD qemu_mutex_destroy(&vs->output_mutex); +qemu_set_fd_handler2(vs->jobs_socks[0],
[Qemu-devel] Re: RFC: emulation of system flash
On 2011-03-10 13:17, Gleb Natapov wrote: > On Thu, Mar 10, 2011 at 01:06:14PM +0100, Jan Kiszka wrote: >> On 2011-03-10 12:48, Gleb Natapov wrote: >>> On Thu, Mar 10, 2011 at 12:27:55PM +0100, Jan Kiszka wrote: On 2011-03-10 10:47, Gleb Natapov wrote: > On Wed, Mar 09, 2011 at 08:51:23PM -0800, Jordan Justen wrote: >> Hi all, >> >> I have documented a simple flash-like device which I think could be >> useful for qemu/kvm in some cases. (Particularly for allowing >> persistent UEFI non-volatile variables.) >> >> http://wiki.qemu.org/Features/System_Flash >> >> Let me know if you have any suggestions or concerns. >> > > Two things. First You suggest to replace -bios with -flash. This will > make firmware upgrade painful process that will have to be performed > from inside the guest since the same flash image will contain both > firmware and whatever data was stored on a flash which presumably you > want to reuse after upgrading a firmware. My suggestion is to extend > -bios option like this: > > -bios bios.bin,flash=flash.bin,flash_base=addr > > flash.bin will be mapped at address flash_base, or, if flash_base is not > present, just below bios.bin. ...or define -flash in a way that allows mapping the bios image as an overlay to the otherwise guest-managed flash image. >>> It is not much different from what I proposed. The result will be the >>> same. Even option syntax will probably be the same :) >> >> -bios is PC-centric, the new command should be generic. >> > Well, I tried to reuse the option we already have instead of introducing > another one. -bios can be extended beyond PC and represent general > firmware specification. But I like the option you proposed in other > email too, so I am not going to defend this one. > > >>> > > Second. I asked how flash is programmed because interfaces like CFI > where you write into flash memory address range to issue commands cannot > be emulated efficiently in KVM. KVM supports either regular memory slots > or IO memory, but in your proposal the same memory behaves as IO on > write and regular memory on read. Better idea would be to present > non-volatile flash as ISA virtio device. Should be simple to implement. Why not enhancing KVM memory slots to support direct read access while writes are trapped and forwarded to a user space device model? >>> Yes we can make memory slot that will be treated as memory on read and >>> IO on write, but first relying on that will prevent using flash interface >>> on older kernels and second it is not enough to implement the proposal. >>> When magic value is written into an address, the address become IO for >>> reading too, but KVM slot granularity is page, not byte, so KVM will >>> have to remove the slot to make it IO, but KVM can't execute code from >>> IO region (yet), so we will not be able to run firmware from flash and >>> simultaneously write into the flash. >> >> Yeah, right. I remember that this was also hairy over TCG if you tried >> to optimize flash emulation so that writing doesn't take orders of >> magnitude longer than on real HW. >> >> BTW, the programming granularity is not bytes but chips with common CFI. >> But that's still tricky if you want to run code from the same chip while >> updating parts of it. The easiest workaround would be handling the >> overlay regions as ROM all the time. Not accurate but realizable without >> kernel changes. >> > So flash will be always IO and overlay will be always ROM. This will Yes, and once we have KVM support for read-RAM/write-IO slots, flash will be able to switch between ROM and IO mode just like it already does under TCG. > work, except BIOS upgrade from inside the guest will not be possible, > but since we do not support this today too it doesn't bother me to much. > >>> Virtio means that you have to patch the guest (which might be something else than flexible Linux...). >>> This intended to be used by firmware only and we control that. >> >> I'm thinking beyond this use case, beyond firmware flashes, beyond x86. >> > OK, but since both interfaces (virtio and one proposed in the wiki) are PV > I fail to see the difference between them for any use case. If we > implement CFI then it will be another story. I'm proposing CFI (which already exists) with BIOS exception to avoid PV as far as possible. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 14/22] qapi: add query-version QMP command
On 03/10/2011 06:41 AM, Avi Kivity wrote: My preference would be: { 'type': 'MyType', 'fields': { 'a': 'str', 'b': 'int', 'c': 'AnotherType' } } { 'event': 'MY_EVENT', 'arguments': {...} } { 'command': 'my-command', 'arguments': {...}, 'returns': 'int' } I do prefer the dictionary syntax for arguments over a list because a list implies order. Plus I think the syntax is just awkward and a whole lot easier to get wrong (too many/few elements in list). Yeah. We can rationalize it by saying that most dynamic consumers of the schema will not care about argument order, and that if they do, they can implement a custom parser. I don't think I want to make this sort of change just yet. Also note that the schema that will be exposed over the wire is not directly related to the schema we use for code generation. Right, we have to nail down the format for the former, though. There's also enum syntax which I guess would be: { 'enum': 'MyEnum', values: [ 'value1', 'value2', 'value3' ] } The other thing that I'm delaying until post 0.15 is errors. I'd like to define errors as part of the schema. Something like: { 'error': 'FileNotFound', 'arguments': { 'filename': 'str' } } Regards, Anthony Liguori
[Qemu-devel] Re: [PATCH 2/2] vnc: don't mess up with iohandlers in the vnc thread
On 03/10/2011 02:45 PM, Anthony Liguori wrote: On 03/10/2011 07:06 AM, Paolo Bonzini wrote: On 03/10/2011 01:59 PM, Corentin Chary wrote: Instead, we now store the data in a temporary buffer, and use a socket pair to notify the main thread that new data is available. You can use a bottom half for this instead of a special socket. Signaling a bottom half is async-signal- and thread-safe. Bottom halves are thread safe? I don't think so. They probably should be but they aren't today. Creating a new bottom half is not thread-safe, but scheduling one is. Assuming that you never use qemu_bh_schedule_idle, qemu_bh_schedule boils down to: if (bh->scheduled) return; bh->scheduled = 1; /* stop the currently executing CPU to execute the BH ASAP */ qemu_notify_event(); You may have a spurious wakeup if two threads race on the same bottom half (including the signaling thread racing with the IO thread), but overall you can safely treat them as thread-safe. Paolo
[Qemu-devel] Re: [PATCH 2/2] vnc: don't mess up with iohandlers in the vnc thread
On Thu, Mar 10, 2011 at 1:45 PM, Anthony Liguori wrote: > On 03/10/2011 07:06 AM, Paolo Bonzini wrote: >> >> On 03/10/2011 01:59 PM, Corentin Chary wrote: >>> >>> Instead, we now store the data in a temporary buffer, and use a socket >>> pair to notify the main thread that new data is available. >> >> You can use a bottom half for this instead of a special socket. Signaling >> a bottom half is async-signal- and thread-safe. > > Bottom halves are thread safe? > > I don't think so. The bottom halves API is not thread safe, but calling qemu_bh_schedule_idle() in another thread *seems* to be safe (here, it would be protected from qemu_bh_delete() by vnc_lock_output()). -- Corentin Chary http://xf.iksaif.net
[Qemu-devel] [PATCH 11/32] vmstate: port pxa2xx_keypad
Signed-off-by: Juan Quintela --- hw/pxa2xx_keypad.c | 53 --- 1 files changed, 17 insertions(+), 36 deletions(-) diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c index d77dbf1..10ef154 100644 --- a/hw/pxa2xx_keypad.c +++ b/hw/pxa2xx_keypad.c @@ -289,40 +289,22 @@ static CPUWriteMemoryFunc * const pxa2xx_keypad_writefn[] = { pxa2xx_keypad_write }; -static void pxa2xx_keypad_save(QEMUFile *f, void *opaque) -{ -PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque; - -qemu_put_be32s(f, &s->kpc); -qemu_put_be32s(f, &s->kpdk); -qemu_put_be32s(f, &s->kprec); -qemu_put_be32s(f, &s->kpmk); -qemu_put_be32s(f, &s->kpas); -qemu_put_be32s(f, &s->kpasmkp[0]); -qemu_put_be32s(f, &s->kpasmkp[1]); -qemu_put_be32s(f, &s->kpasmkp[2]); -qemu_put_be32s(f, &s->kpasmkp[3]); -qemu_put_be32s(f, &s->kpkdi); - -} - -static int pxa2xx_keypad_load(QEMUFile *f, void *opaque, int version_id) -{ -PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque; - -qemu_get_be32s(f, &s->kpc); -qemu_get_be32s(f, &s->kpdk); -qemu_get_be32s(f, &s->kprec); -qemu_get_be32s(f, &s->kpmk); -qemu_get_be32s(f, &s->kpas); -qemu_get_be32s(f, &s->kpasmkp[0]); -qemu_get_be32s(f, &s->kpasmkp[1]); -qemu_get_be32s(f, &s->kpasmkp[2]); -qemu_get_be32s(f, &s->kpasmkp[3]); -qemu_get_be32s(f, &s->kpkdi); - -return 0; -} +static const VMStateDescription vmstate_pxa2xx_keypad = { +.name = "pxa2xx_keypad", +.version_id = 0, +.minimum_version_id = 0, +.minimum_version_id_old = 0, +.fields = (VMStateField[]) { +VMSTATE_UINT32(kpc, PXA2xxKeyPadState), +VMSTATE_UINT32(kpdk, PXA2xxKeyPadState), +VMSTATE_UINT32(kprec, PXA2xxKeyPadState), +VMSTATE_UINT32(kpmk, PXA2xxKeyPadState), +VMSTATE_UINT32(kpas, PXA2xxKeyPadState), +VMSTATE_UINT32_ARRAY(kpasmkp, PXA2xxKeyPadState, 4), +VMSTATE_UINT32(kpkdi, PXA2xxKeyPadState), +VMSTATE_END_OF_LIST() +} +}; PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base, qemu_irq irq) @@ -337,8 +319,7 @@ PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base, pxa2xx_keypad_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(base, 0x0010, iomemtype); -register_savevm(NULL, "pxa2xx_keypad", 0, 0, -pxa2xx_keypad_save, pxa2xx_keypad_load, s); +vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s); return s; } -- 1.7.4
[Qemu-devel] [PATCH 1/3] build: Create tools-obj-y variable
All our tools have to have exactly all this objects, just share them. Signed-off-by: Juan Quintela --- Makefile | 10 +++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index eca4c76..9e090cb 100644 --- a/Makefile +++ b/Makefile @@ -150,14 +150,18 @@ version.o: $(SRC_PATH)/version.rc config-host.mak version-obj-$(CONFIG_WIN32) += version.o ## +tools-obj-y=qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) +tools-obj-y+=$(block-obj-y) $(qobject-obj-y) $(version-obj-y) +tools-obj-y+=qemu-timer-common.o + qemu-img.o: qemu-img-cmds.h qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS) -qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) -qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) -qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $@") -- 1.7.4
Re: [Qemu-devel] [PATCH 0/9] VMState infrastructure
On 03/10/2011 05:33 AM, Juan Quintela wrote: Hi This is the infrastructure that I pushed on my previous series. Anthony don't like 58 patches series (why? O:-) And then split the series in three. Yeah, my intention was that you not send all series at once though :-) At any rate this series looks good. Regards, Anthony Liguori This are the infrastructure patches needed for the other two series. Anthony, please apply. Later, Juan. Juan Quintela (9): vmstate: add VMSTATE_UINT32_EQUAL vmstate: Fix varrays with uint8 indexes vmstate: add UINT32 VARRAYS vmstate: add VMSTATE_STRUCT_VARRAY_INT32 vmstate: add VMSTATE_INT64_ARRAY vmstate: add VMSTATE_STRUCT_VARRAY_UINT32 vmstate: Add a way to send a partial array vmstate: be able to store/save a pci device from a pointer vmstate: move timers to use test instead of version hw/hw.h | 78 ++ savevm.c | 25 2 files changed, 98 insertions(+), 5 deletions(-)
[Qemu-devel] [PATCH v2 0/3] build: make sharing of objects explicit
Hi Another week, another version. v2: - rename common-obj-y to softmmu-obj-y, so we can use common-obj-y for objects shared between tools and softmmu. v1: - all tools shared the same list of object files, create a variable instead or repeating them (tools-obj-y). - tools and softmmu targets share lots of objects, just make that explicit with shared-obj-y. Please review, Juan. Juan Quintela (3): build: Create tools-obj-y variable build: Rename common-obj-y to softmmu-obj-y build: Create common-obj-y for objects shared between tools and softmmu Makefile| 12 +++-- Makefile.objs | 120 -- Makefile.target |2 +- 3 files changed, 70 insertions(+), 64 deletions(-) -- 1.7.4
[Qemu-devel] Re: [PATCH 2/2] vnc: don't mess up with iohandlers in the vnc thread
On 03/10/2011 02:54 PM, Corentin Chary wrote: > > You can use a bottom half for this instead of a special socket. Signaling > > a bottom half is async-signal- and thread-safe. > > Bottom halves are thread safe? > > I don't think so. The bottom halves API is not thread safe, but calling qemu_bh_schedule_idle() Not _idle please. in another thread *seems* to be safe (here, it would be protected from qemu_bh_delete() by vnc_lock_output()). If it weren't protected against qemu_bh_delete, you would have already the same race between writing to the socket and closing it in another thread. Paolo
[Qemu-devel] [PATCH 3/3] build: Create common-obj-y for objects shared between tools and softmmu
This way we don't have to repeat them in two places. Signed-off-by: Juan Quintela --- Makefile |4 +--- Makefile.objs | 14 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 7811d74..42d2cab 100644 --- a/Makefile +++ b/Makefile @@ -150,9 +150,7 @@ version.o: $(SRC_PATH)/version.rc config-host.mak version-obj-$(CONFIG_WIN32) += version.o ## -tools-obj-y=qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) -tools-obj-y+=$(block-obj-y) $(qobject-obj-y) $(version-obj-y) -tools-obj-y+=qemu-timer-common.o +tools-obj-y = qemu-tool.o $(common-obj-y) $(trace-obj-y) $(version-obj-y) qemu-img.o: qemu-img-cmds.h qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS) diff --git a/Makefile.objs b/Makefile.objs index b525e81..7e54ae3 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -54,17 +54,21 @@ fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) ## +# common-obj-y has the object that are shared by qemu softmmu and tools + +common-obj-y = qemu-error.o $(block-obj-y) $(qobject-obj-y) $(oslib-obj-y) +common-obj-y += qemu-timer-common.o + +## # libqemu_common.a: Target independent part of system emulation. The # long term path is to suppress *all* target specific code in case of # system emulation, i.e. a single QEMU executable should support all # CPUs and machines. -softmmu-obj-y = $(block-obj-y) blockdev.o +softmmu-obj-y = $(common-obj-y) blockdev.o softmmu-obj-y += $(net-obj-y) -softmmu-obj-y += $(qobject-obj-y) softmmu-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX)) -softmmu-obj-y += readline.o console.o cursor.o async.o qemu-error.o -softmmu-obj-y += $(oslib-obj-y) +softmmu-obj-y += readline.o console.o cursor.o async.o softmmu-obj-$(CONFIG_WIN32) += os-win32.o softmmu-obj-$(CONFIG_POSIX) += os-posix.o @@ -145,7 +149,7 @@ softmmu-obj-y += iov.o acl.o softmmu-obj-$(CONFIG_THREAD) += qemu-thread.o softmmu-obj-$(CONFIG_POSIX) += compatfd.o softmmu-obj-y += notify.o event_notifier.o -softmmu-obj-y += qemu-timer.o qemu-timer-common.o +softmmu-obj-y += qemu-timer.o slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o -- 1.7.4
[Qemu-devel] [PATCH 2/3] build: Rename common-obj-y to softmmu-obj-y
It really represent object files shared between all softmmu targets. We will use common-obj-y for objects shared between softmmu and tools on next commit Signed-off-by: Juan Quintela --- Makefile|4 +- Makefile.objs | 116 +++--- Makefile.target |2 +- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Makefile b/Makefile index 9e090cb..7811d74 100644 --- a/Makefile +++ b/Makefile @@ -87,8 +87,8 @@ ifneq ($(wildcard config-host.mak),) include $(SRC_PATH)/Makefile.objs endif -$(common-obj-y): $(GENERATED_HEADERS) -$(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis +$(softmmu-obj-y): $(GENERATED_HEADERS) +$(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(softmmu-obj-y) subdir-libdis $(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(trace-obj-y) subdir-libdis-user subdir-libuser diff --git a/Makefile.objs b/Makefile.objs index 9e98a66..b525e81 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -59,54 +59,54 @@ fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) # system emulation, i.e. a single QEMU executable should support all # CPUs and machines. -common-obj-y = $(block-obj-y) blockdev.o -common-obj-y += $(net-obj-y) -common-obj-y += $(qobject-obj-y) -common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX)) -common-obj-y += readline.o console.o cursor.o async.o qemu-error.o -common-obj-y += $(oslib-obj-y) -common-obj-$(CONFIG_WIN32) += os-win32.o -common-obj-$(CONFIG_POSIX) += os-posix.o - -common-obj-y += tcg-runtime.o host-utils.o -common-obj-y += irq.o ioport.o input.o -common-obj-$(CONFIG_PTIMER) += ptimer.o -common-obj-$(CONFIG_MAX7310) += max7310.o -common-obj-$(CONFIG_WM8750) += wm8750.o -common-obj-$(CONFIG_TWL92230) += twl92230.o -common-obj-$(CONFIG_TSC2005) += tsc2005.o -common-obj-$(CONFIG_LM832X) += lm832x.o -common-obj-$(CONFIG_TMP105) += tmp105.o -common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o -common-obj-$(CONFIG_SSD0303) += ssd0303.o -common-obj-$(CONFIG_SSD0323) += ssd0323.o -common-obj-$(CONFIG_ADS7846) += ads7846.o -common-obj-$(CONFIG_MAX111X) += max111x.o -common-obj-$(CONFIG_DS1338) += ds1338.o -common-obj-y += i2c.o smbus.o smbus_eeprom.o -common-obj-y += eeprom93xx.o -common-obj-y += scsi-disk.o cdrom.o -common-obj-y += scsi-generic.o scsi-bus.o -common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o -common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o -common-obj-$(CONFIG_SSI) += ssi.o -common-obj-$(CONFIG_SSI_SD) += ssi-sd.o -common-obj-$(CONFIG_SD) += sd.o -common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o -common-obj-y += bt-hci-csr.o -common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o -common-obj-y += qemu-char.o savevm.o #aio.o -common-obj-y += msmouse.o ps2.o -common-obj-y += qdev.o qdev-properties.o -common-obj-y += block-migration.o -common-obj-y += pflib.o -common-obj-y += bitmap.o bitops.o - -common-obj-$(CONFIG_BRLAPI) += baum.o -common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o -common-obj-$(CONFIG_WIN32) += version.o - -common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o +softmmu-obj-y = $(block-obj-y) blockdev.o +softmmu-obj-y += $(net-obj-y) +softmmu-obj-y += $(qobject-obj-y) +softmmu-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX)) +softmmu-obj-y += readline.o console.o cursor.o async.o qemu-error.o +softmmu-obj-y += $(oslib-obj-y) +softmmu-obj-$(CONFIG_WIN32) += os-win32.o +softmmu-obj-$(CONFIG_POSIX) += os-posix.o + +softmmu-obj-y += tcg-runtime.o host-utils.o +softmmu-obj-y += irq.o ioport.o input.o +softmmu-obj-$(CONFIG_PTIMER) += ptimer.o +softmmu-obj-$(CONFIG_MAX7310) += max7310.o +softmmu-obj-$(CONFIG_WM8750) += wm8750.o +softmmu-obj-$(CONFIG_TWL92230) += twl92230.o +softmmu-obj-$(CONFIG_TSC2005) += tsc2005.o +softmmu-obj-$(CONFIG_LM832X) += lm832x.o +softmmu-obj-$(CONFIG_TMP105) += tmp105.o +softmmu-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o +softmmu-obj-$(CONFIG_SSD0303) += ssd0303.o +softmmu-obj-$(CONFIG_SSD0323) += ssd0323.o +softmmu-obj-$(CONFIG_ADS7846) += ads7846.o +softmmu-obj-$(CONFIG_MAX111X) += max111x.o +softmmu-obj-$(CONFIG_DS1338) += ds1338.o +softmmu-obj-y += i2c.o smbus.o smbus_eeprom.o +softmmu-obj-y += eeprom93xx.o +softmmu-obj-y += scsi-disk.o cdrom.o +softmmu-obj-y += scsi-generic.o scsi-bus.o +softmmu-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o +softmmu-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o +softmmu-obj-$(CONFIG_SSI) += ssi.o +softmmu-obj-$(CONFIG_SSI_SD) += ssi-sd.o +softmmu-obj-$(CONFIG_SD) += sd.o +softmmu-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o +softmmu-obj-y += bt-hci-csr.o +softmmu-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o +softmmu-obj-y += qemu-char.o savevm.o #aio.o +
Re: [Qemu-devel] [PATCH 19/22] qapi: add QMP put-event command
On 03/10/2011 06:39 AM, Avi Kivity wrote: What I mean is that the client should specify the handle, like it does for everything else it gives a name (netdevs, blockdevs, SCM_RIGHT fds, etc). { execute: listen-event, arguments: { event: blah, id: blah1 } } { execute: unlisten-event arguments: { id: blah1 } } Yeah, I understand, it just doesn't fit the model quite as well of signal accessors. Normally, in a signal/slot event model, you'd have some notion of an object model and/or hierarchy. For instance, with dbus, you'd do something like: bus = dbus.SystemBus() hal = # magic to get a hal object device = hal.FindDeviceByCapability('media.storage') device.connect_to_signal('media-changed', fn) We don't have objects and I don't mean to introduce them, but I like the idea of treating signals as objects and returning them via an accessor function. So the idea is that the handle is a marshalled form of the signal object. { 'BLOCK_IO_ERROR': { 'device': 'str', 'action': 'str', 'operation': 'str' } } [ 'get-block-io-error-event': {}, 'BLOCK_IO_ERROR' } The way we marshal a 'BLOCK_IO_ERROR' type is by generating a unique handle and returning that. I don't follow at all. Where's the handle here? Why don't we return the BLOCK_IO_ERROR as an object, on the wire? How we marshal an object depends on the RPC layer. We marshal events on the wire as an integer handle. That is only a concept within the wire protocol. We could just as easily return an object but without diving into JSON class hinting, it'd be pretty meaningless because we'd just return "{ 'handle': 32}" instead of "32". While this looks like an int on the wire, at both the server and libqmp level, it looks like a BlockIoErrorEvent object. So in QEMU: BlockIoErrorEvent *qmp_get_block_io_error_event(Error **errp) { } And in libqmp: BlockIoErrorEvent *libqmp_get_block_io_error_event(QmpSession *sess, Error **errp) { } What would the wire exchange look like? > { 'execute': 'get-block-io-error-event' } < { 'return' : 32 } ... < { 'event': 'BLOCK_IO_ERROR', 'data': { 'action': 'stop', 'device': 'ide0-hd0', 'operation': 'read' }, 'tag': 32 } ... > { 'execute': 'put-event', 'arguments': { 'tag': 32 } } Ignoring default events, you'll never see an event until you execute a signal accessor function. When you execute this function, you will start receiving the events and those events will carry a tag containing the handle returned by the signal accessor. A "signal accessor" is a command to start listening to a signal? Yes, it basically enables the signal for the session. So why not have the signal accessor provide the tag? Like execute: blah provides a tag? How would this map to a C API? You'd either have to completely drop the notion of signal objects and use a separate mechanism to register callbacks against a tag (and lose type safety) or do some major munging to have the C API take a radically different signature than the wire protocol. Within libqmp, any time you execute a signal accessor, a new signal object is created of the appropriate type. When that object is destroyed, you send a put-event to stop receiving the signal. When you connect to a signal object (via libqmp), you don't execute the signal accessor because the object is already receiving the signal. Default events (which exist to preserve compatibility) are a set of events that are automatically connected to after qmp_capabilities is executed. Because these connections are implicit, they arrive without a handle in the event object. At this point, libqmp just ignores default events. In the future, I'd like to add a command that can be executed before qmp_capabilities that will avoid connecting to default events. I'm really confused. Part of that is because the conversation mixes libqmp, server API, and wire protocol. I'd like to understand the wire protocol first, everything else follows from that. No, it's the opposite for me. We design a good C API and then figure out how to make it work well as a wire protocol. The whole point of this effort is to build an API that we can consume within QEMU such that we can start breaking large chunks of code out of the main executable. Regards, Anthony Liguori
[Qemu-devel] [PATCH] get rid of private bitmap functions in block/sheepdog.c, use generic ones
qemu now has generic bitmap functions, so don't redefine them in sheepdog.c, use common header instead. A small cleanup. Here's only one function which is actually used in sheepdog and gets replaced with a generic one (simplified): - static inline int test_bit(int nr, const volatile unsigned long *addr) + static inline int test_bit(int nr, const unsigned long *addr) { - return ((1UL << (nr % BITS_PER_LONG)) & ((unsigned long*)addr)[nr / BITS_PER_LONG])) != 0; + return 1UL & (addr[nr / BITS_PER_LONG] >> (nr & (BITS_PER_LONG-1))); } The body is equivalent, but the argument is not: there's "volatile" in there. Why it is used for - I'm not sure. Signed-off-by: Michael Tokarev diff --git a/block/sheepdog.c b/block/sheepdog.c index a54e0de..98946d7 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -13,6 +13,7 @@ #include "qemu-error.h" #include "qemu_socket.h" #include "block_int.h" +#include "bitops.h" #define SD_PROTO_VER 0x01 @@ -1829,20 +1830,6 @@ static int sd_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) return 0; } -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define BITS_PER_BYTE8 -#define BITS_TO_LONGS(nr)DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) -#define DECLARE_BITMAP(name,bits) \ -unsigned long name[BITS_TO_LONGS(bits)] - -#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long)) - -static inline int test_bit(unsigned int nr, const unsigned long *addr) -{ -return ((1UL << (nr % BITS_PER_LONG)) & -(((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; -} - static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) { BDRVSheepdogState *s = bs->opaque;