[Qemu-devel] memory access trace from qemu
Hi All - I would like to generate a trace of all memory accesses (i.e. read or write, physical address, and data content/payload). The end goal is to use this trace to drive a separate memory system simulator. Ideally, the trace would also provide core-id and a timestamp (but I am not as optimistic that qemu will give me these). I have noted that several previous threads address this topic, so perhaps the question becomes can I get in contact with those who have successfully done this before? I'd like to do as little as possible here :) to get what I want, and I'm hoping that either this has been rolled into the new qemu release or that a previously existing patch does most of what I want (i.e. which patch?). I would be happy to hack the qemu source code if there is only one or two places where I need to do invasive surgery. Thank you, Pete Stevenson
[Qemu-devel] [PATCH] qemu-img: Exit with code 0 if there is no error
Signed-off-by: Fam Zheng f...@redhat.com --- qemu-img.c | 68 +++--- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 8455994..756ccb1 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -58,7 +58,7 @@ static void format_print(void *opaque, const char *name) } /* Please keep in synch with qemu-img.texi */ -static void help(void) +static void help(bool error) { const char *help_msg = qemu-img version QEMU_VERSION , Copyright (c) 2004-2008 Fabrice Bellard\n @@ -129,7 +129,7 @@ static void help(void) printf(%s\nSupported formats:, help_msg); bdrv_iterate_format(format_print, NULL); printf(\n); -exit(1); +exit(error ? 1 : 0); } static int GCC_FMT_ATTR(2, 3) qprintf(bool quiet, const char *fmt, ...) @@ -352,7 +352,7 @@ static int img_create(int argc, char **argv) switch(c) { case '?': case 'h': -help(); +help(false); break; case 'F': base_fmt = optarg; @@ -398,7 +398,7 @@ static int img_create(int argc, char **argv) } if (optind = argc) { -help(); +help(true); } optind++; @@ -421,7 +421,7 @@ static int img_create(int argc, char **argv) img_size = (uint64_t)sval; } if (optind != argc) { -help(); +help(true); } bdrv_img_create(filename, fmt, base_filename, base_fmt, @@ -577,7 +577,7 @@ static int img_check(int argc, char **argv) switch(c) { case '?': case 'h': -help(); +help(false); break; case 'f': fmt = optarg; @@ -590,7 +590,7 @@ static int img_check(int argc, char **argv) } else if (!strcmp(optarg, all)) { fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS; } else { -help(); +help(true); } break; case OPTION_OUTPUT: @@ -602,7 +602,7 @@ static int img_check(int argc, char **argv) } } if (optind != argc - 1) { -help(); +help(true); } filename = argv[optind++]; @@ -699,7 +699,7 @@ static int img_commit(int argc, char **argv) switch(c) { case '?': case 'h': -help(); +help(false); break; case 'f': fmt = optarg; @@ -713,7 +713,7 @@ static int img_commit(int argc, char **argv) } } if (optind != argc - 1) { -help(); +help(true); } filename = argv[optind++]; @@ -932,7 +932,7 @@ static int img_compare(int argc, char **argv) switch (c) { case '?': case 'h': -help(); +help(false); break; case 'f': fmt1 = optarg; @@ -959,7 +959,7 @@ static int img_compare(int argc, char **argv) if (optind != argc - 2) { -help(); +help(true); } filename1 = argv[optind++]; filename2 = argv[optind++]; @@ -1176,7 +1176,7 @@ static int img_convert(int argc, char **argv) switch(c) { case '?': case 'h': -help(); +help(false); break; case 'f': fmt = optarg; @@ -1275,7 +1275,7 @@ static int img_convert(int argc, char **argv) } if (bs_n 1) { -help(); +help(true); } @@ -1868,7 +1868,7 @@ static int img_info(int argc, char **argv) switch(c) { case '?': case 'h': -help(); +help(false); break; case 'f': fmt = optarg; @@ -1882,7 +1882,7 @@ static int img_info(int argc, char **argv) } } if (optind != argc - 1) { -help(); +help(true); } filename = argv[optind++]; @@ -2036,7 +2036,7 @@ static int img_map(int argc, char **argv) switch (c) { case '?': case 'h': -help(); +help(false); break; case 'f': fmt = optarg; @@ -2047,7 +2047,7 @@ static int img_map(int argc, char **argv) } } if (optind = argc) { -help(); +help(true); } filename = argv[optind++]; @@ -2134,11 +2134,11 @@ static int img_snapshot(int argc, char **argv) switch(c) { case '?': case 'h': -help(); +help(false); return 0; case 'l': if (action) { -help(); +help(true); return 0; } action = SNAPSHOT_LIST; @@ -2146,7 +2146,7 @@ static int img_snapshot(int argc, char **argv) break; case 'a': if (action) { -help(); +help(true); return 0; } action =
[Qemu-devel] [PATCH] configure: Exit with code 0 with --help
There are two paths to show help and exit, one is with -h or --help, one is with invalid options. Only exit 1 with the latter case. Signed-off-by: Fam Zheng f...@redhat.com --- configure | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 69b9f56..b195efe 100755 --- a/configure +++ b/configure @@ -1087,7 +1087,10 @@ for opt do ;; --enable-quorum) quorum=yes ;; - *) echo ERROR: unknown option $opt; show_help=yes + *) + echo ERROR: unknown option $opt + show_help=yes + exit_code=1 ;; esac done @@ -1353,7 +1356,7 @@ Advanced options (experts only): NOTE: The object files are built at the place where configure is launched EOF -exit 1 +exit $exit_code fi # Now we have handled --enable-tcg-interpreter and know we're not just -- 1.9.2
Re: [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
On Fri, 18 Apr 2014 00:03:57 +1000 Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Thu, Apr 17, 2014 at 7:40 PM, Igor Mammedov imamm...@redhat.com wrote: On Thu, 17 Apr 2014 09:46:28 +1000 Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Fri, Apr 4, 2014 at 11:36 PM, Igor Mammedov imamm...@redhat.com wrote: Adds get_hotplug_handler() method to machine, and makes bus-less device to use it during hotplug as a means to discover hotplug handler controller. Returned controller is used to permorm a hotplug action. Signed-off-by: Igor Mammedov imamm...@redhat.com --- hw/core/qdev.c | 13 + include/hw/boards.h | 8 2 files changed, 21 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 60f9df1..50bb8f5 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -34,6 +34,7 @@ #include qapi/qmp/qjson.h #include monitor/monitor.h #include hw/hotplug.h +#include hw/boards.h int qdev_hotplug = 0; static bool qdev_hot_added = false; @@ -761,6 +762,18 @@ static void device_set_realized(Object *obj, bool value, Error **err) local_err == NULL) { hotplug_handler_plug(dev-parent_bus-hotplug_handler, dev, local_err); +} else if (local_err == NULL + object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) { This doesn't look right - you are relying on global state to implement hotplug. Later in the series you then need to do RTTI at the machine level to properly determine if hotplug is really appropriate then do some machine specific attachment. This idea of we dont need a bus just hotplug to the machine itself doesnt seem generic at all. If you It's rather allow to define at board level what should be hotplug-handler than using hardcoded in bus implementation one. If different buses behave different on hotplug then they should be different busses. The issue here is to discover which hotplug handler should be used for a bus-less device. Which MachineClass-get_hotplug_handler(machine, dev); does. QEMU so far is using bus to solve it, but it by no means is generic (i.e. applicable only bus-devices). Proposed bus-less hotplug is a simplified solution that is result of https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg04184.html discussion. need to define hotplug socket-side functionality, then that seems to me to be a bus level problem - and you should use a bus - probably SYSBUS or an extension thereof. Then your hotplug work can be Socket object + attached bus is rather workaround due to the lack of bus-less hotplug than a generic solution. generalized to sysbus and a range of devices rather than us having independent competing embedded vs PC hotplug implementations. SYSBUS are definitely is no go for hotplug, there were numerous attempts to make it hotpluggable during past years, which were immediately rejected. Reasoning in gist was Sysbus is legacy which shouldn't be used for anything new. Lets divide and conquer this - I agree Sysbus as a bus (TYPE_SYSTEM_BUS) sucks as we are trying to get rid of busses in favor of linkages etc.. So long term, SYSTEM_BUS should go away (along with TYPE_BUS itself). But TYPE_SYS_BUS_DEVICE should live on. Its a highly useful abstraction which allows you to define devices with any number of memory mapped regions. And this device level API doesn't define any real busisms so it should be possible to convert SYS_BUS_DEVICE to this bussless regime you are proposing anyway. Infact I do wonder exactly how hard it would be to patch one of your handlers to just call into the sysbus API and grab the memory regions and attach as you already do for DIMMs. Then you work works for all of sysbus and we can continue doing our embedded thing which some decent code sharing. It shouldn't be too hard to do globally if we initialize RAM address space in common QEMUMachine and provide default handler in there, that intercepts TYPE_SYS_BUS_DEVICE and does mapping of regions prepared by device. Regards, Peter That's one of the reasons why x86 APIC is not Sysbus device anymore and is attached to ICC bus. How do you implement hotplugging to multiple completely independent DIMM slots? (i.e. two slots at completely different places in the bus heir-achy). I probably do not understand what is a problem here. Why plugging bus-less DIMM, one would need to care about buses? Regarding DIMM, I think it is a bus. I'm not sure if it actually needs its own class yet (TBH I haven't gone line-line on this series looking for DIMMisms). It is ultimately a memory mapped bus if anything I think it should be: v7 of this series was using DIMMBus + DIMMDevice, but afaerber was pushing towards making DIMM bus-less device as a more generic solution so that it could be
Re: [Qemu-devel] [PATCH] configure: Exit with code 0 with --help
18.04.2014 10:25, Fam Zheng wrote: There are two paths to show help and exit, one is with -h or --help, one is with invalid options. Only exit 1 with the latter case. I'd rather put `exit 1' right in invalid option case, instead of jumping to help. Because help output is huge, and it is often difficult to see the error message. At max, at the error case, the script can output something like, `for a list of valid options, run $0 --help'. Here and for qemu-img case. Do you not agree? Thanks, /mjt
[Qemu-devel] [PATCH v3] doc: grammify allows to
English language grammar does not allow usage of the word allows directly followed by an infinitive, declaring constructs like something allows to do somestuff un-grammatical. Often it is possible to just insert one between allows and to to make the construct grammatical, but usually it is better to re-phrase the statement. This patch tries to fix 4 examples of allows to usage in qemu doc, but does not address comments in the code with similar constructs. It also adds missing the in the same line. Signed-off-by: Michael Tokarev m...@tls.msk.ru --- qemu-doc.texi |2 +- qemu-options.hx |7 --- 2 files changed, 5 insertions(+), 4 deletions(-) v2: catch one more occurence of the same construct in qemu-options.hx, in vnc encodings section. This statement may need rewriting which I don't provide in this patch, which just fixes the grammar. v3: one more case in qemu-options.hx diff --git a/qemu-doc.texi b/qemu-doc.texi index e6e20eb..88ec9bb 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -823,7 +823,7 @@ In this case, the block device must be exported using qemu-nbd: qemu-nbd --socket=/tmp/my_socket my_disk.qcow2 @end example -The use of qemu-nbd allows to share a disk between several guests: +The use of qemu-nbd allows sharing of a disk between several guests: @example qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2 @end example diff --git a/qemu-options.hx b/qemu-options.hx index 2d33815..6457034 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -444,7 +444,8 @@ This option defines the type of the media: disk or cdrom. @item cyls=@var{c},heads=@var{h},secs=@var{s}[,trans=@var{t}] These options have the same definition as they have in @option{-hdachs}. @item snapshot=@var{snapshot} -@var{snapshot} is on or off and allows to enable snapshot for given drive (see @option{-snapshot}). +@var{snapshot} is on or off and controls snapshot mode for the given drive +(see @option{-snapshot}). @item cache=@var{cache} @var{cache} is none, writeback, unsafe, directsync or writethrough and controls how the host cache is used to access block data. @item aio=@var{aio} @@ -1242,7 +1243,7 @@ Disable adaptive encodings. Adaptive encodings are enabled by default. An adaptive encoding will try to detect frequently updated screen regions, and send updates in these regions using a lossy encoding (like JPEG). This can be really helpful to save bandwidth when playing videos. Disabling -adaptive encodings allows to restore the original static behavior of encodings +adaptive encodings restores the original static behavior of encodings like Tight. @item share=[allow-exclusive|force-shared|ignore] @@ -2805,7 +2806,7 @@ UTC or local time, respectively. @code{localtime} is required for correct date i MS-DOS or Windows. To start at a specific point in time, provide @var{date} in the format @code{2006-06-17T16:01:21} or @code{2006-06-17}. The default base is UTC. -By default the RTC is driven by the host system time. This allows to use the +By default the RTC is driven by the host system time. This allows using of the RTC as accurate reference clock inside the guest, specifically if the host time is smoothly following an accurate external reference clock, e.g. via NTP. If you want to isolate the guest time from the host, you can set @option{clock} -- 1.7.10.4
[Qemu-devel] [PULL] Trivial patches for 2014-04-18
This is the same pull request as has been sent initially for 2.0 and which we didn't apply. Except that this time, I fixed one more allows to case which I overlooked in qemu-options.hx. I'm not re-sending whole series again, as at has been sent previously, will only re-send the changed patch as a reply to this message. Please consider pulling. The following changes since commit 2d03b49c3f225994c4b0b46146437d8c887d6774: Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140417-1' into staging (2014-04-17 21:37:26 +0100) are available in the git repository at: git://git.corpit.ru/qemu.git tags/trivial-patches-2014-04-18 for you to fetch changes up to b36dc67b95dedcece8757ec23bf42625a7ccda34: Fix grammar in comment (2014-04-18 10:33:36 +0400) trivial patches for 2014-04-18 Amos Kong (1): qga: trivial fix for unclear documentation of guest-set-time Chen Gang (1): vl: Report accelerator not supported for target more nicely Hani Benhabiles (1): net: Report error when device / hub combo is not found. Michael Tokarev (1): doc: grammify allows to Paolo Bonzini (1): scripts: add sample model file for Coverity Scan Peter Maydell (4): configure: Fix indentation of help for --enable/disable-debug-info hw/ide/ahci.c: Avoid shift left into sign bit int128.h: Avoid undefined behaviours involving signed arithmetic xbzrle.c: Avoid undefined behaviour with signed arithmetic Stefan Weil (2): configure: Remove redundant message for -Werror Fix grammar in comment configure|5 +- hw/i2c/smbus_eeprom.c|2 +- hw/ide/ahci.c|4 +- include/qemu/int128.h|4 +- net/net.c|4 +- qemu-doc.texi|2 +- qemu-options.hx |7 +- qga/commands-posix.c |2 +- qga/qapi-schema.json | 14 ++-- scripts/coverity-model.c | 183 ++ vl.c |2 +- xbzrle.c |8 +- 12 files changed, 212 insertions(+), 25 deletions(-) create mode 100644 scripts/coverity-model.c
Re: [Qemu-devel] [PATCH v2 1/4] vl.c: generalise qemu_get_machine_opts()
On Fri, Apr 18, 2014 at 2:53 PM, Paolo Bonzini pbonz...@redhat.com wrote: Il 18/04/2014 00:25, Peter Crosthwaite ha scritto: This nofail (i.e. does not return NULL) mechanism driving qemu_get_machine_opts() does not need to be specific to machine opts - its applicable to other types of opts. Generalise and re-implement qemu_get_machine_opts() as a caller of the generalisation. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- vl.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/vl.c b/vl.c index 9975e5a..bc12d0f 100644 --- a/vl.c +++ b/vl.c @@ -510,17 +510,12 @@ static QemuOptsList qemu_name_opts = { }, }; -/** - * Get machine options - * - * Returns: machine options (never null). - */ -QemuOpts *qemu_get_machine_opts(void) +static QemuOpts *qemu_get_opts_nofail(const char *type) { QemuOptsList *list; QemuOpts *opts; -list = qemu_find_opts(machine); +list = qemu_find_opts(type); assert(list); opts = qemu_opts_find(list, NULL); if (!opts) { @@ -529,6 +524,17 @@ QemuOpts *qemu_get_machine_opts(void) return opts; } +/** + * Get machine options + * + * Returns: machine options (never null). + */ + +QemuOpts *qemu_get_machine_opts(void) +{ +return qemu_get_opts_nofail(machine); +} + const char *qemu_get_vm_name(void) { return qemu_name; This is already planned for 2.1 as qemu_find_opts_singleton, which either Igor or Hu will send. I see. Anything else in that work that you see conflicting with other components of this series? AFAICT its just a trivial change to P2 to back onto the qemu_find_opts_singleton work and the rest stands as-is. Regards, Peter Paolo
Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
Hi, sorry, your patch was too late for QEMU 2.0. It remained unnoticed for two reasons: * Patches for some special version should show this in the subject line: [PATCH for 2.0] instead of [PATCH] * CC'ing the maintainers helps a lot, as you see now :-) More comments below. Am 18.04.2014 04:11, schrieb Sangho Park: Hi, maintainers. Could you check this patch? http://www.mail-archive.com/qemu-devel@nongnu.org/msg227161.html Thanks ps) We've checked the http://wiki.qemu.org/Contribute/SubmitAPatch. Yet, if we made any violation or mistake, let us know. We will appreciate your favor. -Original Message- From: Stanislav Vorobiov [mailto:s.vorob...@samsung.com] Sent: Thursday, April 17, 2014 6:08 PM To: qemu-devel@nongnu.org Cc: syeon.hw...@samsung.com; sangho1206.p...@samsung.com Subject: Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows Hi, everyone Any comments on this one ? This patch fixes pretty serious performance issues on windows, it would be great to have this in 2.0.0 On 04/15/2014 12:41 PM, Stanislav Vorobiov wrote: From: Sangho Park sangho1206.p...@samsung.com g_poll has a problem on windows when using timeouts 10ms, in glib/gpoll.c: /* If not, and we have a significant timeout, poll again with * timeout then. Note that this will return indication for only * one event, or only for messages. We ignore timeouts less than * ten milliseconds as they are mostly pointless on Windows, the * MsgWaitForMultipleObjectsEx() call will timeout right away * anyway. */ if (retval == 0 (timeout == INFINITE || timeout = 10)) retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); so whenever g_poll is called with timeout 10ms it does a quick poll instead of wait, this causes significant performance degradation of qemu, thus we should use WaitForMultipleObjectsEx directly Can you quantify this performance degradation and specify your test scenario? Did you find the source of those small timeouts? Which timeout values are used there? Would it be sufficient to round any timeout 0 and 10 to 10 for Windows hosts? Maybe this could be done in qemu_timeout_ns_to_ms. If this does not work, we still can use g_poll for timeout = 10 and call a new Windows specific polling function for timeout 10. Signed-off-by: Stanislav Vorobiov s.vorob...@samsung.com --- qemu-timer.c | 91 ++ 1 file changed, 91 insertions(+) diff --git a/qemu-timer.c b/qemu-timer.c index e15ce47..9fb92cb 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -315,6 +315,97 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout) ts.tv_nsec = timeout % 10LL; return ppoll((struct pollfd *)fds, nfds, ts, NULL); } +#elif defined(_WIN32) +guint i; +HANDLE handles[MAXIMUM_WAIT_OBJECTS]; +gint nhandles = 0; +int num_completed = 0; +gint timeout_ms = qemu_timeout_ns_to_ms(timeout); + +for (i = 0; i nfds; i++) { +gint j; + +if (fds[i].fd = 0) { +continue; +} + +/* don't add same handle several times + */ +for (j = 0; j nhandles; j++) { +if (handles[j] == (HANDLE)fds[i].fd) { +break; +} +} + +if (j == nhandles) { +if (nhandles == MAXIMUM_WAIT_OBJECTS) { +fprintf(stderr, Too many handles to wait for!\n); +break; +} else { +handles[nhandles++] = (HANDLE)fds[i].fd; +} +} +} + +for (i = 0; i nfds; ++i) { +fds[i].revents = 0; +} + +if (timeout_ms == -1) { +timeout_ms = INFINITE; +} + +if (nhandles == 0) { +if (timeout_ms == INFINITE) { +return -1; +} else { +SleepEx(timeout_ms, TRUE); +return 0; +} +} + +while (1) { +DWORD res; +gint j; + +res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, +timeout_ms, TRUE); + +if (res == WAIT_FAILED) { +for (i = 0; i nfds; ++i) { +fds[i].revents = 0; +} + +return -1; +} else if ((res == WAIT_TIMEOUT) || (res == WAIT_IO_COMPLETION) || + ((int)res WAIT_OBJECT_0) || + (res = (WAIT_OBJECT_0 + nhandles))) { +break; +} + +for (i = 0; i nfds; ++i) { +if (handles[res - WAIT_OBJECT_0] == (HANDLE)fds[i].fd) { +fds[i].revents = fds[i].events; +} +} + +++num_completed; + +if (nhandles = 1) { +break; +} + +/* poll the rest of the handles + */ +for (j = res - WAIT_OBJECT_0 + 1; j nhandles; j++) { +handles[j - 1] =
[Qemu-devel] [PATCH v2] configure: Improve help behavior
Old: There are two paths to show help and exit 1, one is with -h or --help, one is with invalid options. New: Show help and exit 0 for --help. On invalid option, don't show the long help and bury the early ERROR: line, just give a message pointing to --help. Signed-off-by: Fam Zheng f...@redhat.com --- configure | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 69b9f56..b1401c6 100755 --- a/configure +++ b/configure @@ -1087,7 +1087,10 @@ for opt do ;; --enable-quorum) quorum=yes ;; - *) echo ERROR: unknown option $opt; show_help=yes + *) + echo ERROR: unknown option $opt + echo Try '$0 --help' for more information + exit 1 ;; esac done @@ -1353,7 +1356,7 @@ Advanced options (experts only): NOTE: The object files are built at the place where configure is launched EOF -exit 1 +exit 0 fi # Now we have handled --enable-tcg-interpreter and know we're not just -- 1.9.2
Re: [Qemu-devel] [Qemu-trivial] [PATCH v4 0/2] convert -m to QemuOpts
On Thu, 20 Mar 2014 20:21:14 +0400 Michael Tokarev m...@tls.msk.ru wrote: 06.03.2014 13:39, Igor Mammedov wrote: Igor Mammedov (1): vl: convert -m to QemuOpts This patch (2/2) was mime-damaged, I had to edit it manually in order for it to apply. Please take a look at http://git.corpit.ru/?p=qemu.git;a=shortlog;h=refs/heads/trivial-patches-next to verify it's okay. Applied to -trivial. seeing your today's PULL trivial req, it looks like this patch was lost from your queue, could you reapply it please? Thanks, /mjt
Re: [Qemu-devel] [Qemu-trivial] [PATCH v4 0/2] convert -m to QemuOpts
18.04.2014 11:18, Igor Mammedov wrote: On Thu, 20 Mar 2014 20:21:14 +0400 Michael Tokarev m...@tls.msk.ru wrote: 06.03.2014 13:39, Igor Mammedov wrote: Igor Mammedov (1): vl: convert -m to QemuOpts This patch (2/2) was mime-damaged, I had to edit it manually in order for it to apply. Please take a look at http://git.corpit.ru/?p=qemu.git;a=shortlog;h=refs/heads/trivial-patches-next to verify it's okay. Applied to -trivial. seeing your today's PULL trivial req, it looks like this patch was lost from your queue, could you reapply it please? It isn't lost, it is waiting in a -next branch. I just re-sent a previous pullreq which were targetted 2.0 but hasn't been applied for 2.0. Other stuff (about 20 other patches) is waiting. Thank you for the reminder. Having in mind my previous sloppery with this stuff it is good to be reminded again, to not repeat past mistakes! /mjt
Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
Hi, Please see below On 04/18/2014 10:46 AM, Stefan Weil wrote: Hi, sorry, your patch was too late for QEMU 2.0. It remained unnoticed for two reasons: * Patches for some special version should show this in the subject line: [PATCH for 2.0] instead of [PATCH] * CC'ing the maintainers helps a lot, as you see now :-) More comments below. Am 18.04.2014 04:11, schrieb Sangho Park: Hi, maintainers. Could you check this patch? http://www.mail-archive.com/qemu-devel@nongnu.org/msg227161.html Thanks ps) We've checked the http://wiki.qemu.org/Contribute/SubmitAPatch. Yet, if we made any violation or mistake, let us know. We will appreciate your favor. -Original Message- From: Stanislav Vorobiov [mailto:s.vorob...@samsung.com] Sent: Thursday, April 17, 2014 6:08 PM To: qemu-devel@nongnu.org Cc: syeon.hw...@samsung.com; sangho1206.p...@samsung.com Subject: Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows Hi, everyone Any comments on this one ? This patch fixes pretty serious performance issues on windows, it would be great to have this in 2.0.0 On 04/15/2014 12:41 PM, Stanislav Vorobiov wrote: From: Sangho Park sangho1206.p...@samsung.com g_poll has a problem on windows when using timeouts 10ms, in glib/gpoll.c: /* If not, and we have a significant timeout, poll again with * timeout then. Note that this will return indication for only * one event, or only for messages. We ignore timeouts less than * ten milliseconds as they are mostly pointless on Windows, the * MsgWaitForMultipleObjectsEx() call will timeout right away * anyway. */ if (retval == 0 (timeout == INFINITE || timeout = 10)) retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); so whenever g_poll is called with timeout 10ms it does a quick poll instead of wait, this causes significant performance degradation of qemu, thus we should use WaitForMultipleObjectsEx directly Can you quantify this performance degradation and specify your test scenario? Did you find the source of those small timeouts? Which timeout values are used there? We don't have a separate test scenario, we've noticed that performance degradation on tizen emulator after merging with QEMU 1.7. It turned out that it was caused by this patch series: e93379b039030c68d85693a4bee2b76f814108d2 aio / timers: Rename qemu_timer_* functions ... 91c68f143d6e707c5783b162292dce38ae358c19 aio / timers: remove dummy_io_handler_flush from tests/test-aio.c The important part is main-loop.c:main_loop_wait which was: ret = os_host_main_loop_wait(timeout); and became: if (timeout == UINT32_MAX) { timeout_ns = -1; } else { timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS); } timeout_ns = qemu_soonest_timeout(timeout_ns, timerlistgroup_deadline_ns( main_loop_tlg)); ret = os_host_main_loop_wait(timeout_ns); os_host_main_loop_wait then does: g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w-num, poll_timeout_ns); So, the change made main_loop_wait take timer timeouts into account, thus, qemu_poll_ns started to get called with values 10ms and this caused problems on windows since those waits simply turned into polls due to g_poll logic. This is in fact g_poll's problem, timeout values passed to g_poll mean at least, i.e. g_poll MUST wait AT LEAST this time, it's allowed to wait more, but it's not allowed to wait less. IMHO this should be reported to glib as a bug, but it'll be nice to fix this in QEMU as well since it'll take too much time to get this into glib (if possible at all). Do we need to make some separate test to demonstrate this performance degradation ? Would it be sufficient to round any timeout 0 and 10 to 10 for Windows hosts? Maybe this could be done in qemu_timeout_ns_to_ms. We tried that, it gets almost as good as with this patch, but this makes timeouts like, say, 2ms wait for 10ms, so with this patch it's still better. If this does not work, we still can use g_poll for timeout = 10 and call a new Windows specific polling function for timeout 10. Does it have a point to separate things, if we've implemented this for timeouts 10ms why not use it for timeouts = 10ms ? The code in this patch is in fact g_poll's implementation without that timeout = 10 hack and it handles timeouts = 10ms as well as g_poll does. Signed-off-by: Stanislav Vorobiov s.vorob...@samsung.com --- qemu-timer.c | 91 ++ 1 file changed, 91 insertions(+) diff --git a/qemu-timer.c b/qemu-timer.c index e15ce47..9fb92cb 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -315,6 +315,97 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout) ts.tv_nsec = timeout % 10LL; return ppoll((struct pollfd *)fds, nfds, ts, NULL); }
Re: [Qemu-devel] [Spice-devel] Automatic spice port selection
- Mail original - Il 26/03/2014 17:15, Fabio Fantoni ha scritto: Time ago I have read somewhere that there is an option to automatically spice port in qemu as for vnc. I started to write a libxl patch to add this feature like the vnc one: https://github.com/Fantu/Xen/commit/63c54f354a34e7eb27b1c69016789a372a75843c Testing this patch lead to a missing to= parameter and I didn't found nothing else. Is there someone that can tell me that if it is possible to let qemu automatically assign a spice port like for vnc? libvirt does automatic port assignemnt for SPICE, but I think it does it 'manually' (with no support from SPICE). I don't think spice-server/qemu has magic to automatically allocate the spice port to be used. Christophe
Re: [Qemu-devel] [PATCH] configure: Add new target ppc64el-linux-user
On 17 April 2014 22:24, Doug Kwan dougk...@google.com wrote: This patch adds a new target for running ppc64 little-endian binaries in user mode. Only change to configure is included in this patch. Patch for loading and executing LE binaries will be submitted later. Please put the configure patch as the final patch in your series for handling LE PPC binaries -- we don't want to allow users to turn on a new target until it is actually implemented. (It's also hard to tell this is the correct configure change without seeing it in the context of the necessary linux-user adjustments.) thanks -- PMM
Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
Am 18.04.2014 09:34, schrieb Stanislav Vorobiov: Hi, Please see below On 04/18/2014 10:46 AM, Stefan Weil wrote: Hi, [...] Would it be sufficient to round any timeout 0 and 10 to 10 for Windows hosts? Maybe this could be done in qemu_timeout_ns_to_ms. We tried that, it gets almost as good as with this patch, but this makes timeouts like, say, 2ms wait for 10ms, so with this patch it's still better. If this does not work, we still can use g_poll for timeout = 10 and call a new Windows specific polling function for timeout 10. Does it have a point to separate things, if we've implemented this for timeouts 10ms why not use it for timeouts = 10ms ? The code in this patch is in fact g_poll's implementation without that timeout = 10 hack and it handles timeouts = 10ms as well as g_poll does. Did you send a bug report to the maintainers of glib? I think it would be good to do so. We can override the buggy implementation of g_poll for Windows by redirecting any call of g_poll to a new g_poll_fixed function. In file include/glib-compat.h: #if defined(_WIN32) /* g_poll does not handle timeout 10 ms correctly, so use wrapper. */ #define g_poll(fds, nfds, timeout) g_poll_fixed((fds, nfds, timeout) gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); #endif Then move your code into a new function g_poll_fixed() in file util/oslib-win32.c (and add there some comments, too). There is also some g_poll code in include/qemu-common.h. This should also be moved to include/glib-compat.h and must be excluded for _WIN32 when you add g_poll_fixed. Stefan
Re: [Qemu-devel] [Spice-devel] Automatic spice port selection
2014-04-18 9:42 GMT+02:00 Christophe Fergeau cferg...@redhat.com: - Mail original - Il 26/03/2014 17:15, Fabio Fantoni ha scritto: Time ago I have read somewhere that there is an option to automatically spice port in qemu as for vnc. I started to write a libxl patch to add this feature like the vnc one: https://github.com/Fantu/Xen/commit/63c54f354a34e7eb27b1c69016789a372a75843c Testing this patch lead to a missing to= parameter and I didn't found nothing else. Is there someone that can tell me that if it is possible to let qemu automatically assign a spice port like for vnc? libvirt does automatic port assignemnt for SPICE, but I think it does it 'manually' (with no support from SPICE). I don't think spice-server/qemu has magic to automatically allocate the spice port to be used. Christophe Thanks for reply. Can someone add spice automatic port selection on qemu similar to vnc ones please?
Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
On 18 Apr 2014, at 03:11, Sangho Park wrote: g_poll has a problem on windows when using timeouts 10ms, in glib/gpoll.c: /* If not, and we have a significant timeout, poll again with * timeout then. Note that this will return indication for only * one event, or only for messages. We ignore timeouts less than * ten milliseconds as they are mostly pointless on Windows, the * MsgWaitForMultipleObjectsEx() call will timeout right away * anyway. */ if (retval == 0 (timeout == INFINITE || timeout = 10)) retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); so whenever g_poll is called with timeout 10ms it does a quick poll instead of wait, this causes significant performance degradation of qemu, thus we should use WaitForMultipleObjectsEx directly As the author of the original changes, I don't know enough about Windows to know whether this change is sensible, but will happily admit my Windows coding was done completely blind (as I said at the time) and required more third party testing, so it would be unsurprising if there were issues. On the general issue, the problem you will face if g_poll waits LESS than the amount of time is that you'll get a busy wait for a while. For instance, if a timeout is scheduled 9ms ahead, and g_poll (or replacement) waits 0ms, then the system will continuously call g_poll, check whether a timer has expired, call g_poll, check whether a timer has expired and so on. During this period, no actual work will get done. Therefore, if the underlying poll has lower resolution than 1 ns (and does not wait for, at a minimum) the value specified, then it should round up. On Windows (or more accurately in the absence of ppoll), qemu uses gpoll and converts the timeout using qemu_timeout_ns_to_ms. What this does is returns 0 for a non-blocking timeout of 0, but otherwise rounds UP to the nearest millisecond. Code pasted below: int qemu_timeout_ns_to_ms(int64_t ns) { int64_t ms; if (ns 0) { return -1; } if (!ns) { return 0; } /* Always round up, because it's better to wait too long than to wait too * little and effectively busy-wait */ ms = (ns + SCALE_MS - 1) / SCALE_MS; /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */ if (ms (int64_t) INT32_MAX) { ms = INT32_MAX; } return (int) ms; } I suspect the easiest fix (certainly for debug purposes) would be to make all polls for non-zero time at least 10ms long. IE after the assignment of 'ms', do something like #ifdef BROKEN_POLL if (ms 10) { ms = 10; #endif } If you're actually saying g_poll has 10 millisecond resolution, or rounds down, then the appropriate course of action would be to change the rounding line to ms = (ns + 10*SCALE_MS - 1) / (10*SCALE_MS); where g_poll is broken like this. As I say, I have no Windows box to test this on, but I hope that's helpful. -- Alex Bligh
Re: [Qemu-devel] Change of TEXT_OFFSET for multi_v7_defconfig
On Thu, Apr 17, 2014 at 09:53:23PM -0500, Rob Herring wrote: On Thu, Apr 17, 2014 at 4:35 PM, Russell King - ARM Linux li...@arm.linux.org.uk wrote: No. You simply can't eliminate any of the above - each one has been negotiated through quite an amount of discussion with relevant parties and/or due to technical requirements and they just can't be magic'd away. Plus the ARM64 image format is different from our zImage format. It would make far *more* sense to align our Image format with our zImage format so existing boot loaders which look for the zImage magic numbers can boot plain Image files too. Moreover, since we could *never* align zImage with the ARM64 format, why on earth would we want to start using the ARM64 format for the Image format? I'm not talking about zImage. I'm talking about Image files only. The arm64 Image header could be added to ARM Image files and that would not hurt or change a thing for existing users. The cost is 64 bytes. No it isn't. The cost is 64-bytes *and* user confusion with two completely different headers for no reason what so ever. Why use the ARM64 version and then have it *block* existing boot loaders which look for the zImage magic from being able to boot an Image. It's a much saner idea to use the ARM32 zImage header than to use the ARM64 version - or nothing at all. -- FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly improving, and getting towards what was expected from it.
Re: [Qemu-devel] memory access trace from qemu
Hello, Pete. You can insert tracing code into the functions from the “include\exec\softmmu_template.h” file: like helper_le_ld_name, helper_le_st_name and so on. These functions are used for CPU emulation. However, you may also need to trace DMA accesses, that are executed through other functions and files. Pavel Dovgaluk From: qemu-devel-bounces+pavel.dovgaluk=ispras...@nongnu.org [mailto:qemu-devel-bounces+pavel.dovgaluk=ispras...@nongnu.org] On Behalf Of Pete Stevenson Sent: Friday, April 18, 2014 3:31 AM To: qemu-devel@nongnu.org Subject: [Qemu-devel] memory access trace from qemu Hi All - I would like to generate a trace of all memory accesses (i.e. read or write, physical address, and data content/payload). The end goal is to use this trace to drive a separate memory system simulator. Ideally, the trace would also provide core-id and a timestamp (but I am not as optimistic that qemu will give me these). I have noted that several previous threads address this topic, so perhaps the question becomes can I get in contact with those who have successfully done this before? I'd like to do as little as possible here :) to get what I want, and I'm hoping that either this has been rolled into the new qemu release or that a previously existing patch does most of what I want (i.e. which patch?). I would be happy to hack the qemu source code if there is only one or two places where I need to do invasive surgery. Thank you, Pete Stevenson
Re: [Qemu-devel] memory access trace from qemu
On Fri, Apr 18, 2014 at 12:48 PM, Pavel Dovgaluk pavel.dovga...@ispras.ru wrote: You can insert tracing code into the functions from the “include\exec\softmmu_template.h” file: like helper_le_ld_name, helper_le_st_name and so on. It's not enough, you also need to disable memory access fast path so that these functions are called every time. See e.g. this: http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg03226.html -- Thanks. -- Max
[Qemu-devel] [RFC] about don't support hotplug usb-ehci controller
Hi, Gerd. IMHO, the usb-ehci controller as a common PCI device, likes NIC. If we don't use the multifunction capability of EHCI, we should support to hot plug / unplug Usb-ehci controller. And I think the Bug 879096 is just a bug. Am I right? Thanks. The patch: http://lists.gnu.org/archive/html/qemu-devel/2012-11/msg03244.html Best regards, -Gonglei
Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
Hi, Please see below On 04/18/2014 12:29 PM, Alex Bligh wrote: On 18 Apr 2014, at 03:11, Sangho Park wrote: g_poll has a problem on windows when using timeouts 10ms, in glib/gpoll.c: /* If not, and we have a significant timeout, poll again with * timeout then. Note that this will return indication for only * one event, or only for messages. We ignore timeouts less than * ten milliseconds as they are mostly pointless on Windows, the * MsgWaitForMultipleObjectsEx() call will timeout right away * anyway. */ if (retval == 0 (timeout == INFINITE || timeout = 10)) retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); so whenever g_poll is called with timeout 10ms it does a quick poll instead of wait, this causes significant performance degradation of qemu, thus we should use WaitForMultipleObjectsEx directly As the author of the original changes, I don't know enough about Windows to know whether this change is sensible, but will happily admit my Windows coding was done completely blind (as I said at the time) and required more third party testing, so it would be unsurprising if there were issues. On the general issue, the problem you will face if g_poll waits LESS than the amount of time is that you'll get a busy wait for a while. For instance, if a timeout is scheduled 9ms ahead, and g_poll (or replacement) waits 0ms, then the system will continuously call g_poll, check whether a timer has expired, call g_poll, check whether a timer has expired and so on. During this period, no actual work will get done. Yes, this is exactly what we've experienced, CPU was hogged and overall performance of guest dropped. Therefore, if the underlying poll has lower resolution than 1 ns (and does not wait for, at a minimum) the value specified, then it should round up. On Windows (or more accurately in the absence of ppoll), qemu uses gpoll and converts the timeout using qemu_timeout_ns_to_ms. What this does is returns 0 for a non-blocking timeout of 0, but otherwise rounds UP to the nearest millisecond. Code pasted below: int qemu_timeout_ns_to_ms(int64_t ns) { int64_t ms; if (ns 0) { return -1; } if (!ns) { return 0; } /* Always round up, because it's better to wait too long than to wait too * little and effectively busy-wait */ ms = (ns + SCALE_MS - 1) / SCALE_MS; /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */ if (ms (int64_t) INT32_MAX) { ms = INT32_MAX; } return (int) ms; } I suspect the easiest fix (certainly for debug purposes) would be to make all polls for non-zero time at least 10ms long. IE after the assignment of 'ms', do something like #ifdef BROKEN_POLL if (ms 10) { ms = 10; #endif } If you're actually saying g_poll has 10 millisecond resolution, or rounds down, then the appropriate course of action would be to change the rounding line to ms = (ns + 10*SCALE_MS - 1) / (10*SCALE_MS); where g_poll is broken like this. As I say, I have no Windows box to test this on, but I hope that's helpful. Yes, it's possible to work around like this, but if we look at this: if (ms 10) { ms = 10; } the question arises: where did 10 come from ? It looks like a magic number and in fact it is, it was taken from glib's gpoll.c. But what if tomorrow glib changes and use, say, 15 in gpoll.c, then we'll observe the same CPU hogging in qemu again.
Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
Hi, see below On 04/18/2014 12:03 PM, Stefan Weil wrote: Am 18.04.2014 09:34, schrieb Stanislav Vorobiov: Hi, Please see below On 04/18/2014 10:46 AM, Stefan Weil wrote: Hi, [...] Would it be sufficient to round any timeout 0 and 10 to 10 for Windows hosts? Maybe this could be done in qemu_timeout_ns_to_ms. We tried that, it gets almost as good as with this patch, but this makes timeouts like, say, 2ms wait for 10ms, so with this patch it's still better. If this does not work, we still can use g_poll for timeout = 10 and call a new Windows specific polling function for timeout 10. Does it have a point to separate things, if we've implemented this for timeouts 10ms why not use it for timeouts = 10ms ? The code in this patch is in fact g_poll's implementation without that timeout = 10 hack and it handles timeouts = 10ms as well as g_poll does. Did you send a bug report to the maintainers of glib? I think it would be good to do so. I've filed a bug report here - https://bugzilla.gnome.org/show_bug.cgi?id=728486 We can override the buggy implementation of g_poll for Windows by redirecting any call of g_poll to a new g_poll_fixed function. In file include/glib-compat.h: #if defined(_WIN32) /* g_poll does not handle timeout 10 ms correctly, so use wrapper. */ #define g_poll(fds, nfds, timeout) g_poll_fixed((fds, nfds, timeout) gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); #endif Then move your code into a new function g_poll_fixed() in file util/oslib-win32.c (and add there some comments, too). There is also some g_poll code in include/qemu-common.h. This should also be moved to include/glib-compat.h and must be excluded for _WIN32 when you add g_poll_fixed. Stefan
Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
On 18 Apr 2014, at 10:26, Stanislav Vorobiov wrote: Yes, it's possible to work around like this, but if we look at this: if (ms 10) { ms = 10; } the question arises: where did 10 come from ? It looks like a magic number and in fact it is, it was taken from glib's gpoll.c. But what if tomorrow glib changes and use, say, 15 in gpoll.c, then we'll observe the same CPU hogging in qemu again. Well obviously the real fix is either to fix the bug in glib, or to do what I did when I introduced ppoll, which was to conclude that the glib implementation of gpoll was inadequate and that it should be replaced locally if possible with something with microsecond, if not nanosecond, resolution (obviously nanosecond resolution itself never occurs in practice). Perhaps that's what you are trying to do and I have misunderstood. -- Alex Bligh
[Qemu-devel] [PATCH v2] glib: fix g_poll early timeout on windows
From: Sangho Park sangho1206.p...@samsung.com g_poll has a problem on windows when using timeouts 10ms, in glib/gpoll.c: /* If not, and we have a significant timeout, poll again with * timeout then. Note that this will return indication for only * one event, or only for messages. We ignore timeouts less than * ten milliseconds as they are mostly pointless on Windows, the * MsgWaitForMultipleObjectsEx() call will timeout right away * anyway. */ if (retval == 0 (timeout == INFINITE || timeout = 10)) retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); so whenever g_poll is called with timeout 10ms it does a quick poll instead of wait, this causes significant performance degradation of qemu, thus we should use WaitForMultipleObjectsEx directly Signed-off-by: Stanislav Vorobiov s.vorob...@samsung.com --- include/glib-compat.h | 19 + include/qemu-common.h | 12 -- util/oslib-win32.c| 112 + 3 files changed, 131 insertions(+), 12 deletions(-) diff --git a/include/glib-compat.h b/include/glib-compat.h index 8aa77af..2d4258e 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -24,4 +24,23 @@ static inline guint g_timeout_add_seconds(guint interval, GSourceFunc function, } #endif +#ifdef _WIN32 +/* + * g_poll has a problem on windows when using + * timeouts 10ms, so use wrapper. + */ +#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, qemu_timeout_ns_to_ms(timeout)) +gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout_ms); +#elif !GLIB_CHECK_VERSION(2, 20, 0) +/* + * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly + * on older systems. + */ +static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) +{ +GMainContext *ctx = g_main_context_default(); +return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); +} +#endif + #endif diff --git a/include/qemu-common.h b/include/qemu-common.h index a998e8d..3f3fd60 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -124,18 +124,6 @@ int qemu_main(int argc, char **argv, char **envp); void qemu_get_timedate(struct tm *tm, int offset); int qemu_timedate_diff(struct tm *tm); -#if !GLIB_CHECK_VERSION(2, 20, 0) -/* - * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly - * on older systems. - */ -static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) -{ -GMainContext *ctx = g_main_context_default(); -return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); -} -#endif - /** * is_help_option: * @s: string to test diff --git a/util/oslib-win32.c b/util/oslib-win32.c index 93f7d35..006259e 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -238,3 +238,115 @@ char *qemu_get_exec_dir(void) { return g_strdup(exec_dir); } + +/* + * g_poll has a problem on windows when using + * timeouts 10ms, in glib/gpoll.c: + * + * // If not, and we have a significant timeout, poll again with + * // timeout then. Note that this will return indication for only + * // one event, or only for messages. We ignore timeouts less than + * // ten milliseconds as they are mostly pointless on Windows, the + * // MsgWaitForMultipleObjectsEx() call will timeout right away + * // anyway. + * + * if (retval == 0 (timeout == INFINITE || timeout = 10)) + * retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); + * + * So whenever g_poll is called with timeout 10ms it does + * a quick poll instead of wait, this causes significant performance + * degradation of qemu, thus we should use WaitForMultipleObjectsEx + * directly + */ +gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout_ms) +{ +guint i; +HANDLE handles[MAXIMUM_WAIT_OBJECTS]; +gint nhandles = 0; +int num_completed = 0; + +for (i = 0; i nfds; i++) { +gint j; + +if (fds[i].fd = 0) { +continue; +} + +/* don't add same handle several times + */ +for (j = 0; j nhandles; j++) { +if (handles[j] == (HANDLE)fds[i].fd) { +break; +} +} + +if (j == nhandles) { +if (nhandles == MAXIMUM_WAIT_OBJECTS) { +fprintf(stderr, Too many handles to wait for!\n); +break; +} else { +handles[nhandles++] = (HANDLE)fds[i].fd; +} +} +} + +for (i = 0; i nfds; ++i) { +fds[i].revents = 0; +} + +if (timeout_ms == -1) { +timeout_ms = INFINITE; +} + +if (nhandles == 0) { +if (timeout_ms == INFINITE) { +return -1; +} else { +SleepEx(timeout_ms, TRUE); +return 0; +} +} + +while (1) { +DWORD res; +gint j; + +res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, +timeout_ms, TRUE); + +if (res == WAIT_FAILED) { +
[Qemu-devel] [PATCH] po/Makefile: Fix source path for in-tree builds
Use an absolute value for SRC_PATH. This fixes a build problem: $ LANG=C make -C po update make: Entering directory `/qemu/po' GEN ../po/messages.po /bin/sh: 1: cannot create ../po/messages.po: Directory nonexistent make: *** [../po/messages.po] Error 2 make: Leaving directory `/qemu/po' Signed-off-by: Stefan Weil s...@weilnetz.de --- po/Makefile |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/Makefile b/po/Makefile index 705166e..576b172 100644 --- a/po/Makefile +++ b/po/Makefile @@ -2,7 +2,7 @@ # process and also within the source tree to update the translation files. # Set SRC_PATH for in-tree builds without configuration. -SRC_PATH=.. +SRC_PATH=$(shell cd .. pwd) -include ../config-host.mak include $(SRC_PATH)/rules.mak -- 1.7.10.4
[Qemu-devel] [PATCH] po: Update all *.po files
Most changes were caused by line changes in ui/gtk.c and updated automatically by running make -C po update. In addition, the header entry Language was fixed, see this reference: http://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html. Project-Id-Version now shows the current QEMU version. Some unused translations for _FILE were removed, too. Signed-off-by: Stefan Weil s...@weilnetz.de --- Paolo, there are some Italian translations missing, maybe you want to add them? Peter, perhaps updating these files should be added to the process which creates a new QEMU version. Regards Stefan po/de_DE.po| 31 ++- po/fr_FR.po| 28 ++-- po/hu.po | 31 ++- po/it.po | 31 ++- po/messages.po | 26 +- po/tr.po | 28 ++-- 6 files changed, 83 insertions(+), 92 deletions(-) diff --git a/po/de_DE.po b/po/de_DE.po index 8636f3b..379757c 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -4,61 +4,58 @@ # msgid msgstr -Project-Id-Version: QEMU 1.4.50\n +Project-Id-Version: QEMU 2.0.50\n Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n -POT-Creation-Date: 2013-11-16 15:25+0100\n +POT-Creation-Date: 2014-04-18 13:53+0200\n PO-Revision-Date: 2012-02-28 16:00+0100\n Last-Translator: Kevin Wolf kw...@redhat.com\n Language-Team: Deutsch d...@li.org\n -Language: \n +Language: de\n MIME-Version: 1.0\n Content-Type: text/plain; charset=UTF-8\n Content-Transfer-Encoding: 8bit\n Plural-Forms: nplurals=2; plural=(n!=1);\n -#: ui/gtk.c:217 +#: ui/gtk.c:222 msgid - Press Ctrl+Alt+G to release grab msgstr - Strg+Alt+G drücken, um Eingabegeräte freizugeben -#: ui/gtk.c:221 +#: ui/gtk.c:226 msgid [Paused] msgstr [Angehalten] -#: ui/gtk.c:1331 +#: ui/gtk.c:1360 msgid _Pause msgstr _Angehalten -#: ui/gtk.c:1337 +#: ui/gtk.c:1366 msgid _Reset msgstr _Reset -#: ui/gtk.c:1340 +#: ui/gtk.c:1369 msgid Power _Down msgstr _Herunterfahren -#: ui/gtk.c:1398 +#: ui/gtk.c:1427 msgid Zoom To _Fit msgstr Auf _Fenstergröße skalieren -#: ui/gtk.c:1404 +#: ui/gtk.c:1433 msgid Grab On _Hover msgstr Tastatur _automatisch einfangen -#: ui/gtk.c:1407 +#: ui/gtk.c:1436 msgid _Grab Input msgstr _Eingabegeräte einfangen -#: ui/gtk.c:1434 +#: ui/gtk.c:1463 msgid Show _Tabs msgstr _Tableiste anzeigen -#: ui/gtk.c:1448 +#: ui/gtk.c:1477 msgid _Machine msgstr _Maschine -#: ui/gtk.c:1453 +#: ui/gtk.c:1482 msgid _View msgstr _Ansicht - -#~ msgid _File -#~ msgstr _Datei diff --git a/po/fr_FR.po b/po/fr_FR.po index e27ccbc..9b55be8 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -4,59 +4,59 @@ # Aurelien Jarno aurel...@aurel32.net, 2013. msgid msgstr -Project-Id-Version: QEMU 1.4.50\n +Project-Id-Version: QEMU 2.0.50\n Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n -POT-Creation-Date: 2013-11-16 15:25+0100\n +POT-Creation-Date: 2014-04-18 13:53+0200\n PO-Revision-Date: 2013-03-31 19:39+0200\n Last-Translator: Aurelien Jarno aurel...@aurel32.net\n Language-Team: French f...@li.org\n -Language: \n +Language: fr\n MIME-Version: 1.0\n Content-Type: text/plain; charset=UTF-8\n Content-Transfer-Encoding: 8bit\n Plural-Forms: nplurals=2; plural=n != 1;\n X-Generator: Lokalize 1.4\n -#: ui/gtk.c:217 +#: ui/gtk.c:222 msgid - Press Ctrl+Alt+G to release grab msgstr - Appuyer sur Ctrl+Alt+G pour arrêter la capture -#: ui/gtk.c:221 +#: ui/gtk.c:226 msgid [Paused] msgstr [En pause] -#: ui/gtk.c:1331 +#: ui/gtk.c:1360 msgid _Pause msgstr _Pause -#: ui/gtk.c:1337 +#: ui/gtk.c:1366 msgid _Reset msgstr _Réinitialiser -#: ui/gtk.c:1340 +#: ui/gtk.c:1369 msgid Power _Down msgstr _Éteindre -#: ui/gtk.c:1398 +#: ui/gtk.c:1427 msgid Zoom To _Fit msgstr Zoomer pour _ajuster -#: ui/gtk.c:1404 +#: ui/gtk.c:1433 msgid Grab On _Hover msgstr Capturer en _survolant -#: ui/gtk.c:1407 +#: ui/gtk.c:1436 msgid _Grab Input msgstr _Capturer les entrées -#: ui/gtk.c:1434 +#: ui/gtk.c:1463 msgid Show _Tabs msgstr Montrer les _onglets -#: ui/gtk.c:1448 +#: ui/gtk.c:1477 msgid _Machine msgstr _Machine -#: ui/gtk.c:1453 +#: ui/gtk.c:1482 msgid _View msgstr _Vue diff --git a/po/hu.po b/po/hu.po index b298712..fbe2e1e 100644 --- a/po/hu.po +++ b/po/hu.po @@ -4,60 +4,57 @@ # msgid msgstr -Project-Id-Version: QEMU 1.4.50\n +Project-Id-Version: QEMU 2.0.50\n Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n -POT-Creation-Date: 2013-11-16 15:25+0100\n +POT-Creation-Date: 2014-04-18 13:53+0200\n PO-Revision-Date: 2013-05-06 20:42+0200\n Last-Translator: Ákos Kovács akoskov...@gmx.com\n Language-Team: Hungarian h...@li.org\n -Language: \n +Language: hu\n MIME-Version: 1.0\n Content-Type: text/plain; charset=UTF-8\n Content-Transfer-Encoding: 8bit\n -#: ui/gtk.c:217 +#: ui/gtk.c:222 msgid - Press Ctrl+Alt+G to release grab msgstr - Nyomj Ctrl+Alt+G-t a bemeneti eszközök elengedéséhez
[Qemu-devel] [PATCH] vmdk: Optimize cluster allocation
On mounted NFS filesystem, ftruncate is much much slower than doing a zero write. Changing this significantly speeds up cluster allocation. Comparing by converting a cirros image (296M) to VMDK on an NFS mount point, over 1Gbe LAN: $ time qemu-img convert cirros-0.3.1.img /mnt/a.raw -O vmdk Before: real0m26.464s user0m0.133s sys 0m0.527s After: real0m2.120s user0m0.080s sys 0m0.197s Signed-off-by: Fam Zheng f...@redhat.com --- block/vmdk.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index b69988d..b829265 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1036,6 +1036,7 @@ static int get_cluster_offset(BlockDriverState *bs, int min_index, i, j; uint32_t min_count, *l2_table; bool zeroed = false; +int ret; if (m_data) { m_data-valid = 0; @@ -1110,11 +,15 @@ static int get_cluster_offset(BlockDriverState *bs, /* Avoid the L2 tables update for the images that have snapshots. */ *cluster_offset = bdrv_getlength(extent-file); +assert(0 == (*cluster_offset (extent-cluster_sectors - 1))); if (!extent-compressed) { -bdrv_truncate( -extent-file, -*cluster_offset + (extent-cluster_sectors 9) -); +ret = bdrv_write_zeroes(extent-file, +*cluster_offset BDRV_SECTOR_BITS, +extent-cluster_sectors, +0); +if (ret) { +return VMDK_ERROR; +} } *cluster_offset = 9; -- 1.9.2
Re: [Qemu-devel] Regression (?) due to c4177479 ('spapr: make sure RMA is in first mode of first memory node')
On 04/18/2014 09:03 AM, Nishanth Aravamudan wrote: On 18.04.2014 [08:46:55 +1000], Benjamin Herrenschmidt wrote: On Fri, 2014-04-18 at 08:43 +1000, Alexey Kardashevskiy wrote: On 04/18/2014 06:25 AM, Nishanth Aravamudan wrote: Hi Alexey, Prior to the $SUBJECT commit, we could present memoryless node0s to guests. Now, we indicate that we don't have the requisite 128M for the RMA if node 0 has no memory. Note that a memoryless node0 is possible under PowerVM (but not predictably present) so I was hoping to use KVM to test relevant fixes for memoryless nodes. I think this change is a misinterpretation of the PAPR standard, though. Yes, the RMA must be in the first block of memory, but that isn't necessarily on node 0. The topology of a PAPR-compliant guest does not require a node 0 (and in fact, under PowerVM, Linux doesn't actually require node 0 either, but it would under KVM). Thoughts? I suppose it's fine to say that node 0 must be sufficiently populated under KVM -- there's not really a reason to not have memory on a given node (except maybe ballooning). I can keep the commit reverted locally for testing purposes. Just wanted to see if the semantic change was intentional. PAPR spec 2.7: C.6.6 Memory Node === This section defines the PAPR modifications to the OF /memory node. In PAPR, the memory allocated to an OS image may be divided into a number of allocation units called ???regions??? or ???Logical Memory Blocks (LMB). An OS image may be dynamically allocated additional regions or may be asked to release regions. Each LMB is either represented in the device tree by its own /memory node or by an entry in /ibm,dynamic-reconfiguration-memory nodes (see Section C.6.6.2??? ???ibm,dynamic-reconfiguration-memory?? on page 1089). The /memory node that refers to the storage starting at real address zero (???reg??? property starting at the value zero) always remains allocated to an OS image. The client program is initially loaded into this storage, called the RMA, that is represented by the first value of the ???reg??? property of this first /memory node. === The last sentence is why the change was made. It does not say first populated node. I am adding Ben as he had very strong opinion about this thing. You are confusing device-tree node with NUMA nodes. Yes, it must be the LMB at address 0, which is the /memory node, but that doesn't have to be NUMA node 0. Yeah, so I think the check that was added: -if (spapr-rma_size node0_size) { -fprintf(stderr, Error: Numa node 0 has to span the RMA (%#08HWADDR_PR -spapr-rma_size); -exit(1); -} incorrectly is checking against node0_size? It should be checking against the first LMB instead, right? Which would be what in the current QEMU? If I read the current QEMU code correctly, NUMA nodes and device tree nodes are the same thing for SPAPR now, see spapr_populate_memory() function. -- Alexey
Re: [Qemu-devel] qemu-ga: How to static compilation qemu-ga.exe for windows on fedora 18
Any ideas about the issue ? Regards. -Original Message- From: Gonglei (Arei) Sent: Wednesday, April 16, 2014 10:05 AM To: qemu-devel@nongnu.org Cc: mdr...@linux.vnet.ibm.com; Wangrui (K) Subject: qemu-ga: How to static compilation qemu-ga.exe for windows on fedora 18 Hi, I'm using qemu-ga.exe in windows server 2008 R2 64. I want to use it without libraries such as iconv.dll, libglib-2.0-0.dll, libintl-8.dll and libssp-0.dll So I use static compilation on fedora 18. build qemu-1.7.0: # for Windows using MinGW on linux (Fedora 18) ./configure --enable-guest-agent --cross-prefix=x86_64-w64-mingw32- --static make qemu-ga.exe Build success as expected. But qemu-ga.exe runs error when it steps to the first glib library function (such as g_malloc). Problem Event Name: BEX64 Application Name: qemu-ga.exe Application Version: 1.7.0.0 Application Timestamp: 534d10dd Fault Module Name: StackHash_1d2c Fault Module Version: 0.0.0.0 Fault Module Timestamp: Exception Offset: Exception Code: c005 Exception Data: 0008 OS Version: 6.1.7601.2.1.0.768.3 Locale ID: 2052 Is my compilation steps wrong? Thanks. BTW, It's OK if qemu-ga.exe run with DLLs. Best regards, -Gonglei
[Qemu-devel] [PATCH 1/4] Replace acpi_pcihp_get_bsel with generic object_property_get_int
acpi_pcihp_get_bsel implements functionality of object_property_get_int for specific property named ACPI_PCIHP_PROP_BSEL, but fails to decrement object's reference counter properly. Replacing it with generic object_property_get_int serves two purposes: reducing code duplication and fixing memory leak. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- hw/acpi/pcihp.c | 23 ++- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index f80c480..ff44aec 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -61,24 +61,11 @@ typedef struct AcpiPciHpFind { PCIBus *bus; } AcpiPciHpFind; -static int acpi_pcihp_get_bsel(PCIBus *bus) -{ -QObject *o = object_property_get_qobject(OBJECT(bus), - ACPI_PCIHP_PROP_BSEL, NULL); -int64_t bsel = -1; -if (o) { -bsel = qint_get_int(qobject_to_qint(o)); -} -if (bsel 0) { -return -1; -} -return bsel; -} - static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque) { AcpiPciHpFind *find = opaque; -if (find-bsel == acpi_pcihp_get_bsel(bus)) { +if (find-bsel == object_property_get_int(OBJECT(bus), + ACPI_PCIHP_PROP_BSEL, NULL)) { find-bus = bus; } } @@ -185,7 +172,8 @@ void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, { PCIDevice *pdev = PCI_DEVICE(dev); int slot = PCI_SLOT(pdev-devfn); -int bsel = acpi_pcihp_get_bsel(pdev-bus); +int bsel = object_property_get_int(OBJECT(pdev-bus), + ACPI_PCIHP_PROP_BSEL, NULL); if (bsel 0) { error_setg(errp, Unsupported bus. Bus doesn't have property ' ACPI_PCIHP_PROP_BSEL ' set); @@ -210,7 +198,8 @@ void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, { PCIDevice *pdev = PCI_DEVICE(dev); int slot = PCI_SLOT(pdev-devfn); -int bsel = acpi_pcihp_get_bsel(pdev-bus); +int bsel = object_property_get_int(OBJECT(pdev-bus), + ACPI_PCIHP_PROP_BSEL, NULL); if (bsel 0) { error_setg(errp, Unsupported bus. Bus doesn't have property ' ACPI_PCIHP_PROP_BSEL ' set); -- 1.7.10.4
[Qemu-devel] [PATCH 3/4] graphic_console_init: do not receive unneeded error descriptions
Error set by error_set is dynamically allocated and needs to be cleared properly later. graphic_console_init neither needs error descriptions nor frees them. Pass NULL instead of actual pointers to avoid unnecessary memory allocations. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- ui/console.c |7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ui/console.c b/ui/console.c index e057755..438b6bd 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1590,7 +1590,6 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, const GraphicHwOps *hw_ops, void *opaque) { -Error *local_err = NULL; int width = 640; int height = 480; QemuConsole *s; @@ -1602,10 +1601,8 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, s-hw_ops = hw_ops; s-hw = opaque; if (dev) { -object_property_set_link(OBJECT(s), OBJECT(dev), - device, local_err); -object_property_set_int(OBJECT(s), head, -head, local_err); +object_property_set_link(OBJECT(s), OBJECT(dev), device, NULL); +object_property_set_int(OBJECT(s), head, head, NULL); } s-surface = qemu_create_displaysurface(width, height); -- 1.7.10.4
[Qemu-devel] [PATCH 4/4] PortioList: fix PortioList uses so they do not leak memory
PortioList is an abstraction used for construction of MemoryRegionPortioList from MemoryRegionPortio. It is not needed later, so there is no need to allocate it dynamically. Also portio_list_destroy should be called to free memory allocated in portio_list_init. This change spans several target platforms. The following testcases cover all changed lines: qemu-system-ppc -M prep qemu-system-i386 -vga qxl qemu-system-i386 -M isapc -soundhw adlib -device ib700,id=watchdog0,bus=isa.0 Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- hw/audio/adlib.c|7 --- hw/display/qxl.c|9 + hw/display/vga.c| 16 +--- hw/dma/i82374.c |7 --- hw/isa/isa-bus.c|7 --- hw/ppc/prep.c |7 --- hw/watchdog/wdt_ib700.c |7 --- 7 files changed, 34 insertions(+), 26 deletions(-) Coding style in adlib.c slightly differs from QEMU coding style. Particularly there are spaces between function name and parenthesis. I decided to not mix coding styles, but as a result checkpatch.pl complains on this patch. diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 28eed81..e43d990 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -293,7 +293,7 @@ static MemoryRegionPortio adlib_portio_list[] = { static void adlib_realizefn (DeviceState *dev, Error **errp) { AdlibState *s = ADLIB(dev); -PortioList *port_list = g_new(PortioList, 1); +PortioList port_list; struct audsettings as; if (glob_adlib) { @@ -349,8 +349,9 @@ static void adlib_realizefn (DeviceState *dev, Error **errp) adlib_portio_list[0].offset = s-port; adlib_portio_list[1].offset = s-port + 8; -portio_list_init (port_list, OBJECT(s), adlib_portio_list, s, adlib); -portio_list_add (port_list, isa_address_space_io(s-parent_obj), 0); +portio_list_init (port_list, OBJECT(s), adlib_portio_list, s, adlib); +portio_list_add (port_list, isa_address_space_io(s-parent_obj), 0); +portio_list_destroy (port_list); } static Property adlib_properties[] = { diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 47bbf1f..7a361c7 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2055,7 +2055,7 @@ static int qxl_init_primary(PCIDevice *dev) { PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev); VGACommonState *vga = qxl-vga; -PortioList *qxl_vga_port_list = g_new(PortioList, 1); +PortioList qxl_vga_port_list; int rc; qxl-id = 0; @@ -2064,10 +2064,11 @@ static int qxl_init_primary(PCIDevice *dev) vga_common_init(vga, OBJECT(dev)); vga_init(vga, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), false); -portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list, +portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list, vga, vga); -portio_list_set_flush_coalesced(qxl_vga_port_list); -portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0); +portio_list_set_flush_coalesced(qxl_vga_port_list); +portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0); +portio_list_destroy(qxl_vga_port_list); vga-con = graphic_console_init(DEVICE(dev), 0, qxl_ops, qxl); qemu_spice_display_init_common(qxl-ssd); diff --git a/hw/display/vga.c b/hw/display/vga.c index 063319d..72feafd 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -2351,8 +2351,8 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, { MemoryRegion *vga_io_memory; const MemoryRegionPortio *vga_ports, *vbe_ports; -PortioList *vga_port_list = g_new(PortioList, 1); -PortioList *vbe_port_list = g_new(PortioList, 1); +PortioList vga_port_list; +PortioList vbe_port_list; qemu_register_reset(vga_reset, s); @@ -2367,13 +2367,15 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, 1); memory_region_set_coalescing(vga_io_memory); if (init_vga_ports) { -portio_list_init(vga_port_list, obj, vga_ports, s, vga); -portio_list_set_flush_coalesced(vga_port_list); -portio_list_add(vga_port_list, address_space_io, 0x3b0); +portio_list_init(vga_port_list, obj, vga_ports, s, vga); +portio_list_set_flush_coalesced(vga_port_list); +portio_list_add(vga_port_list, address_space_io, 0x3b0); +portio_list_destroy(vga_port_list); } if (vbe_ports) { -portio_list_init(vbe_port_list, obj, vbe_ports, s, vbe); -portio_list_add(vbe_port_list, address_space_io, 0x1ce); +portio_list_init(vbe_port_list, obj, vbe_ports, s, vbe); +portio_list_add(vbe_port_list, address_space_io, 0x1ce); +portio_list_destroy(vbe_port_list); } } diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c index dc7a767..f27ce25 100644 --- a/hw/dma/i82374.c +++ b/hw/dma/i82374.c @@ -137,11 +137,12 @@
[Qemu-devel] [PATCH 0/4] Fix memory leaks in QEMU
I tried running QEMU under Valgrind's Memcheck tool and managed to find some memory leaks. I only checked definitely lost reports. I ignored reports related to SDL/GTK because it is hard to tell if memory leak occurred in QEMU or in the library. All found errors followed one pattern: 1) Callee allocates some memory and returns pointer to the caller expecting it to free this memory later. 2) Caller knows nothing about the nature of the pointer returned and does not perform the required cleanup. In actual code callee often does not allocate memory directly but calls some function that calls some other function ... that calls some other function that dynamically allocates memory. Tracking pointers through this stacktrace is not an easy task without detailed knowledge of QEMU core. The things get even more complicated because QEMU has 4 different ways to allocate and deallocate memory mixed together: 1) malloc and free, 2) g_malloc and g_free, 3) tcg_malloc and tcg_pool_reset, 4) QObjects with reference counting. List of culprits. error_set: It allocates memory for error description. Then this error description is propagated to the caller and needs to be deallocated at some point with error_free. Usually it is done correctly. I fixed one missing deallocation in graphic_console_init. object_property_get_qobject: Returned QObject implements reference counting, caller must perform decref. Outside object model this function is only used in ACPI. I added missing decrefs, but I wonder if it can be replaced with safe function object_property_get_int. The only difference is in handling case when requested property is not set. PortioList: For some unknown reason people tend to allocate PortioList with g_new but not g_free it later. They probably think that portio_list_add saves pointer in some global variables, which it does not. Also portio_list_destroy was never called and memory allocated in portio_list_init was leaking. I'm not sure how PortioList was inteded to be used by its author. There is portio_list_del function that removes memory regions related to PortioList from memory hierarchy. It can be used for cleanup in the end of the work and it needs PortioList to perform the task. But it is never used, so for now I made all PortioList variables local (allocated on stack) and added calls to portio_list_destroy after portio_list_add. qemu_allocate_irqs: The most troublesome case. It will need its own patch series and I need some advices on how to deal with it. qemu_allocate_irqs allocates two arrays: one for actual IRQState structures and one for pointers to IRQState structures also known as qemu_irq. While the first array is used during emulation process, the second one is only needed to return pointers to the caller. Elements of the second array are eventually passed to sysbus_connect_irq or qdev_connect_gpio_out and get copied in the process (they are passed by value). After that the second array is not needed anymore and all pointers to it get lost. At that moment memory leak occurs if the array is not free'd. And it almost never does. qemu_allocate_irqs has poor interface. Not only it returns pointer to dynamically allocated memory and expects caller to free it, but it does so in a very counterintuitive manner. Caller still needs IRQs allocated by qemu_allocate_irqs yet it must free returned memory at the same time. Each emulated board needs interrupts so nearly every board calls qemu_allocate_irqs at least once. There are more than 90 occurrences in QEMU sources. Changing it will affect every target. Testing all of them will be very hard. But I believe it should be done nevertheless. Peculiar fact: out of 90+ calls to qemu_allocate_irqs 47 allocate 1 interrupt. 27 of them use the following weird code snippet: some_function(qemu_allocate_irqs(handler, opaque, 1)[0]); instead of using simpler qemu_allocate_irq. The proper solution would be to introduce qemu_init_irqs function which initializes already allocated array of qemu_irq, then rewrite every piece of code calling qemu_allocate_irqs with either qemu_init_irqs or qemu_allocate_irq, and then remove qemu_allocate_irqs completely. Pros: we get rid of qemu_allocate_irqs in one go. Cons: literally ever board gets affected. Another approach is to introduce new function qemu_init_irqs, mark qemu_allocate_irqs as deprecated and gradually rewrite code over period of time. But I do not think it is viable. QEMU core has complex API which is not well documented. As a result people learn it from examples. And all examples of interrupt allocation will be bad at that moment. As a result maintainers will need to keep very close watch to not allow new bad code to slip into upstream. Any thoughts on how to deal with qemu_allocate_irqs? Is there any archive of guest system images for testing
[Qemu-devel] [PATCH 2/4] acpi-build: properly decrement objects' reference counters
Object returned bu object_property_get_qobject needs it's reference counter to be decremented when it is not needed by caller anymore. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- hw/i386/acpi-build.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index c98df88..1ef8ca9 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -156,18 +156,21 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) } else { pm-s3_disabled = false; } +qobject_decref(o); o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL); if (o) { pm-s4_disabled = qint_get_int(qobject_to_qint(o)); } else { pm-s4_disabled = false; } +qobject_decref(o); o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL); if (o) { pm-s4_val = qint_get_int(qobject_to_qint(o)); } else { pm-s4_val = false; } +qobject_decref(o); /* Fill in mandatory properties */ pm-sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL); @@ -973,6 +976,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) } } +qobject_decref(bsel); build_free_array(bus_table); build_pci_bus_state_cleanup(child); g_free(child); @@ -1362,10 +1366,12 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) return false; } mcfg-mcfg_base = qint_get_int(qobject_to_qint(o)); +qobject_decref(o); o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL); assert(o); mcfg-mcfg_size = qint_get_int(qobject_to_qint(o)); +qobject_decref(o); return true; } -- 1.7.10.4
[Qemu-devel] AArch64: QEMU fails in swapcontext
Hello Peter All, I am trying to figure out a problem in qemu on aarch64 (with kvm enabled). I have found this problem in many different versions of qemu (v2.0.0-rc3/rc2/rc1/rc0, master 2d03b49), and I believe that either I am missing something common in all of these versions or its a genuine bug in qemu on aarch64. The problem is triggered by virtqueue_notify() function (in virtio_ring.c) from the guest kernel and fails in the qemu_coroutine_new() while trying to do the swapcontext(old_uc, uc) (see coroutine-ucontext.c:164). The sigsetjmp(old_env, 0) just before the swapcontext() call seems to work fine, as it returns 0, and then we invoke the swapcontext(). The host kernel reports: qemu-system-aar[596]: bad frame in sys_rt_sigreturn: pc=004462e0 sp=7f8020f000 and kills the qemu process due to segmentation fault. The pc=004462e0 is for the coroutine_trampoline() but we don't actually reach it, when this particular crash happens. Just to give you an idea of the code I am talking about: $~/qemu[master]$ git blame -L 159,166 coroutine-ucontext.c 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 159) makecontext(uc, (void (*)(void))coroutine_trampoline, 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 160) 2, arg.i[0], arg.i[1]); 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 161) 6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 162) /* swapcontext() in, siglongjmp() back out */ 6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 163) if (!sigsetjmp(old_env, 0)) { 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 164) swapcontext(old_uc, uc); 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 165) } 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 166) return co-base; My qemu configure/run commands are: ./configure --target-list=aarch64-softmmu \ --cross-prefix=aarch64-linux-gnu- \ --enable-fdt *--enable-kvm* --disable-werror \ --audio-drv-list= --static ./qemu-system-aarch64 \ *-enable-kvm* -nographic -kernel Image\ -drive if=none,file=disk_oe64.img,id=fs \ -device virtio-blk-device,drive=fs \ -m 1024 -M virt -cpu host \ -append earlyprintk console=ttyAMA0 mem=1024M rootwait root=/dev/vda rw init=/bin/sh Any ideas/comments on how to resolve this issue? Best Regards, Hamayun
Re: [Qemu-devel] [PATCH v3 0/4] Add max-ram-below-4g (was Add pci_hole_min_size machine option)
Am 25.03.2014 10:08, schrieb Michael S. Tsirkin: On Mon, Mar 24, 2014 at 07:55:32PM -0400, Don Slutz wrote: Changes v2 to v3: Stefano Stabellini: Acked-by #1 xen-all: Fix xen_hvm_init() to adjust pc memory Adjust for code readability #4 xen-all: Pass max_ram_below_4g to xen_hvm_init. Set max_ram_below_4g always and use it to calculate above_4g_mem_size, below_4g_mem_size. Changes v1 to v2: Michael S. Tsirkin: Rename option. Only add it to machine types that support it. Split into 4 parts. 1/4 -- xen-all: Fix xen_hvm_init() to adjust pc memory layout This looks to be a possible bug that has yet to be found. below_4g_mem_size and above_4g_mem_size are stored in PcGuestInfo (pc_guest_info_init) which are currently not correct. This and 4/4 change the same lines. 2/4 -- GlobalProperty: Display warning about unused -global My testing showed that setting a global property on an object that is not used is not reported at all. This is added to help when the new global is set but not used. The negative not_used was picked so that all static objects are assumed to be used even when they are not. 3/4 -- pc q35: Add new object pc-memory-layout The objects that it might make sense to add this property to all get created too late. So add a new object just to hold this property. Name it so that it is expected that only pc (and q35) machine types support it. 4/4 -- xen-all: Pass max_ram_below_4g to xen_hvm_init Seprate the xen only part of the change. Currectly based on patch 1/4 Don Slutz (4): xen-all: Fix xen_hvm_init() to adjust pc memory layout. GlobalProperty: Display warning about unused -global pc q35: Add new object pc-memory-layout. xen-all: Pass max_ram_below_4g to xen_hvm_init. hw/core/qdev-properties-system.c | 1 + hw/core/qdev-properties.c| 15 hw/i386/pc.c | 42 hw/i386/pc_piix.c| 52 +++- hw/i386/pc_q35.c | 50 ++ include/hw/i386/pc.h | 2 ++ include/hw/qdev-core.h | 1 + include/hw/qdev-properties.h | 1 + include/hw/xen/xen.h | 3 ++- vl.c | 2 ++ xen-all.c| 46 +++ xen-stub.c | 3 ++- 12 files changed, 165 insertions(+), 53 deletions(-) Andreas, could you review pls, esp patch 2? Michael, I don't see a dependency of the later patches on 2/4, so I'd like to split that one out of this series and reiterate. I'll have some minor comments on the rest. Don, in general please do not end subjects with a dot. CC'ing Eduardo and Igor who looked into 4G issues previously. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v3 1/4] xen-all: Fix xen_hvm_init() to adjust pc memory layout.
Am 25.03.2014 00:55, schrieb Don Slutz: This is just below_4g_mem_size and above_4g_mem_size which is used later in QEMU. Signed-off-by: Don Slutz dsl...@verizon.com Acked-by: Stefano Stabellini stefano.stabell...@eu.citrix.com Please remember to place your Signed-off-by last. In theory you would place another Signed-off-by last, but in practice we usually drop the first one if there are no other Sobs. Think of someone taking your patch, making changes and applying it to some downstream; then Stefano did not ack the modified patch signed off by someone else, but rather you are asserting that Stefano acked the patch in the form you are sending it. --- hw/i386/pc_piix.c| 31 --- hw/i386/pc_q35.c | 29 +++-- include/hw/xen/xen.h | 3 ++- xen-all.c| 24 ++-- xen-stub.c | 3 ++- 5 files changed, 49 insertions(+), 41 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 7930a26..bd52f6e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -96,21 +96,6 @@ static void pc_init1(QEMUMachineInitArgs *args, FWCfgState *fw_cfg = NULL; PcGuestInfo *guest_info; -if (xen_enabled() xen_hvm_init(ram_memory) != 0) { -fprintf(stderr, xen hardware virtual machine initialisation failed\n); -exit(1); -} - -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), icc-bridge, - OBJECT(icc_bridge), NULL); - -pc_cpus_init(args-cpu_model, icc_bridge); - -if (kvm_enabled() kvmclock_enabled) { -kvmclock_create(); -} - /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory). * If it doesn't, we need to split it in chunks below and above 4G. * In any case, try to make sure that guest addresses aligned at @@ -127,6 +112,22 @@ static void pc_init1(QEMUMachineInitArgs *args, below_4g_mem_size = args-ram_size; } +if (xen_enabled() xen_hvm_init(below_4g_mem_size, above_4g_mem_size, + ram_memory) != 0) { +fprintf(stderr, xen hardware virtual machine initialisation failed\n); +exit(1); +} + +icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); +object_property_add_child(qdev_get_machine(), icc-bridge, + OBJECT(icc_bridge), NULL); + +pc_cpus_init(args-cpu_model, icc_bridge); + +if (kvm_enabled() kvmclock_enabled) { +kvmclock_create(); +} + if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); memory_region_init(pci_memory, NULL, pci, UINT64_MAX); Movement looks okay to me, CC'ing Igor. Did you test KVM or only Xen? It would be nice to follow up replacing fprintf() with error_report() though in a separate patch. diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c844dc2..6e34fe1 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -83,20 +83,6 @@ static void pc_q35_init(QEMUMachineInitArgs *args) DeviceState *icc_bridge; PcGuestInfo *guest_info; -if (xen_enabled() xen_hvm_init(ram_memory) != 0) { -fprintf(stderr, xen hardware virtual machine initialisation failed\n); -exit(1); -} - -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), icc-bridge, - OBJECT(icc_bridge), NULL); - -pc_cpus_init(args-cpu_model, icc_bridge); -pc_acpi_init(q35-acpi-dsdt.aml); - -kvmclock_create(); - /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping * also known as MMCFG). @@ -115,6 +101,21 @@ static void pc_q35_init(QEMUMachineInitArgs *args) below_4g_mem_size = args-ram_size; } +if (xen_enabled() xen_hvm_init(below_4g_mem_size, above_4g_mem_size, + ram_memory) != 0) { +fprintf(stderr, xen hardware virtual machine initialisation failed\n); +exit(1); +} + +icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); +object_property_add_child(qdev_get_machine(), icc-bridge, + OBJECT(icc_bridge), NULL); + +pc_cpus_init(args-cpu_model, icc_bridge); +pc_acpi_init(q35-acpi-dsdt.aml); + +kvmclock_create(); + /* pci enabled */ if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); [snip] Dito here. Xen parts look sane to me. Reviewed-by: Andreas Färber afaer...@suse.de Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH] qemu-img: Exit with code 0 if there is no error
On 04/18/2014 12:23 AM, Fam Zheng wrote: Signed-off-by: Fam Zheng f...@redhat.com --- qemu-img.c | 68 +++--- 1 file changed, 34 insertions(+), 34 deletions(-) /* Please keep in synch with qemu-img.texi */ -static void help(void) +static void help(bool error) This doesn't intuitively tell me whether 'true' is success (0 status) or failure (non-zero status). { const char *help_msg = qemu-img version QEMU_VERSION , Copyright (c) 2004-2008 Fabrice Bellard\n @@ -129,7 +129,7 @@ static void help(void) printf(%s\nSupported formats:, help_msg); bdrv_iterate_format(format_print, NULL); printf(\n); -exit(1); +exit(error ? 1 : 0); Oh - true for failure. I'd MUCH rather see: static void help(int status) ... exit(status) and all callers use: help(EXIT_SUCCESS) or help(EXIT_FAILURE) as appropriate. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] AArch64: QEMU fails in swapcontext
On 04/18/2014 07:00 AM, Mian M. Hamayun wrote: Hello Peter All, I am trying to figure out a problem in qemu on aarch64 (with kvm enabled). I have found this problem in many different versions of qemu (v2.0.0-rc3/rc2/rc1/rc0, master 2d03b49), and I believe that either I am missing something common in all of these versions or its a genuine bug in qemu on aarch64. The problem is triggered by virtqueue_notify() function (in virtio_ring.c) from the guest kernel and fails in the qemu_coroutine_new() while trying to do the swapcontext(old_uc, uc) (see coroutine-ucontext.c:164). The sigsetjmp(old_env, 0) just before the swapcontext() call seems to work fine, as it returns 0, and then we invoke the swapcontext(). The host kernel reports: qemu-system-aar[596]: bad frame in sys_rt_sigreturn: pc=004462e0 sp=7f8020f000 and kills the qemu process due to segmentation fault. The pc=004462e0 is for the coroutine_trampoline() but we don't actually reach it, when this particular crash happens. Just to give you an idea of the code I am talking about: $~/qemu[master]$ git blame -L 159,166 coroutine-ucontext.c 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 159) makecontext(uc, (void (*)(void))coroutine_trampoline, 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 160) 2, arg.i[0], arg.i[1]); 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 161) 6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 162) /* swapcontext() in, siglongjmp() back out */ 6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 163) if (!sigsetjmp(old_env, 0)) { 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 164) swapcontext(old_uc, uc); 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 165) } 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 166) return co-base; My qemu configure/run commands are: ./configure --target-list=aarch64-softmmu \ --cross-prefix=aarch64-linux-gnu- \ --enable-fdt *--enable-kvm* --disable-werror \ --audio-drv-list= --static ./qemu-system-aarch64 \ *-enable-kvm* -nographic -kernel Image\ -drive if=none,file=disk_oe64.img,id=fs \ -device virtio-blk-device,drive=fs \ -m 1024 -M virt -cpu host \ -append earlyprintk console=ttyAMA0 mem=1024M rootwait root=/dev/vda rw init=/bin/sh Any ideas/comments on how to resolve this issue? Note that a patch has just gone into glibc to rewrite setcontext et al for aarch64. I'd try using git glibc before looking too much deeper. r~
[Qemu-devel] [PATCH 00/37] target-ppc: Decimal Floating Point
This patch series adds emulation of the PowerPC Decimal Floating Point (DFP) instructions. The complete set of DFP instructions defined by the Power ISA is introduced. The foundation of the emulation code is libdecnumber, a software library that models DFP numbers and operations in a manner similar to how softfloat models IEEE Binary Floating Point. A subset of the libdecnumber source (from GCC) is dropped into the QEMU source tree and modified slightly; only libdecnumber files containing code that is required to implement the PowerPC DFP instructions are copied. The DFP instructions are implemented via helpers. A typical helper does the following: - The contents of the source registers (PPC FPRs) are converted to libdecnumber's internal representation, the decNumber type. Inputs are either 64 bit (Long) or 128 bit (Extended or Quad) densely packed decimal (DPD), depending on the specific instruction being emulated. - A libdecnumber operation is invoked, producing a decNumber result as well as status flags. - A chain of post-processors is executed to convert status flags and/or input and output data to PPC status (usually FPSCR bits). - The decNumber result is converted back to DPD format and written into the target FPR(s). Tom Musta (37): libdecnumber: Introduce libdecnumber Code libdecnumber: Eliminate #include *Symbols.h libdecnumber: Prepare libdecnumber for QEMU include structure libdecnumber: Modify dconfig.h to Integrate with QEMU libdecnumber: Change gstdint.h to stdint.h libdecnumber: Eliminate redundant declarations libdecnumber: Eliminate Unused Variable in decSetSubnormal target-ppc: Enable Building of libdecnumber libdecnumber: Introduce decNumberFrom[U]Int64 libdecnumber: Introduce decNumberIntegralToInt64 libdecnumber: Fix decNumberSetBCD target-ppc: Define FPR Pointer Type for Helpers target-ppc: Introduce Generator Macros for DFP Arithmetic Forms target-ppc: Introduce Decoder Macros for DFP target-ppc: Introduce DFP Helper Utilities target-ppc: Introduce DFP Post Processor Utilities target-ppc: Introduce DFP Add target-ppc: Introduce DFP Subtract target-ppc: Introduce DFP Multiply target-ppc: Introduce DFP Divide target-ppc: Introduce DFP Compares target-ppc: Introduce DFP Test Data Class target-ppc: Introduce DFP Test Data Group target-ppc: Introduce DFP Test Exponent target-ppc: Introduce DFP Test Significance target-ppc: Introduce DFP Quantize target-ppc: Introduce DFP Reround target-ppc: Introduce DFP Round to Integer target-ppc: Introduce DFP Convert to Long/Extended target-ppc: Introduce Round to DFP Short/Long target-ppc: Introduce DFP Convert to Fixed target-ppc: Introduce DFP Convert to Fixed target-ppc: Introduce DFP Decode DPD to BCD target-ppc: Introduce DFP Encode BCD to DPD target-ppc: Introduce DFP Extract Biased Exponent target-ppc: Introduce DFP Insert Biased Exponent target-ppc: Introduce DFP Shift Significand Makefile.target|6 + default-configs/ppc-linux-user.mak |1 + default-configs/ppc-softmmu.mak|1 + default-configs/ppc64-linux-user.mak |1 + default-configs/ppc64-softmmu.mak |1 + include/libdecnumber/dconfig.h | 40 + include/libdecnumber/decContext.h | 257 + include/libdecnumber/decDPD.h | 1215 include/libdecnumber/decNumber.h | 202 + include/libdecnumber/decNumberLocal.h | 665 +++ include/libdecnumber/dpd/decimal128.h | 100 + include/libdecnumber/dpd/decimal128Local.h | 47 + include/libdecnumber/dpd/decimal32.h | 98 + include/libdecnumber/dpd/decimal64.h | 100 + libdecnumber/decContext.c | 434 ++ libdecnumber/decNumber.c | 8200 libdecnumber/dpd/decimal128.c | 564 ++ libdecnumber/dpd/decimal128Local.h | 42 + libdecnumber/dpd/decimal32.c | 489 ++ libdecnumber/dpd/decimal64.c | 850 +++ target-ppc/Makefile.objs |1 + target-ppc/dfp_helper.c| 1327 + target-ppc/helper.h| 54 + target-ppc/translate.c | 386 ++ 24 files changed, 15081 insertions(+), 0 deletions(-) create mode 100644 include/libdecnumber/dconfig.h create mode 100644 include/libdecnumber/decContext.h create mode 100644 include/libdecnumber/decDPD.h create mode 100644 include/libdecnumber/decNumber.h create mode 100644 include/libdecnumber/decNumberLocal.h create mode 100644 include/libdecnumber/dpd/decimal128.h create mode 100644 include/libdecnumber/dpd/decimal128Local.h create mode 100644 include/libdecnumber/dpd/decimal32.h create mode 100644 include/libdecnumber/dpd/decimal64.h create mode 100644 libdecnumber/decContext.c create mode 100644 libdecnumber/decNumber.c create mode
[Qemu-devel] [PATCH 04/37] libdecnumber: Modify dconfig.h to Integrate with QEMU
Modify the dconfig.h header file so that libdecnumber code integrates QEMU configuration. Specifically: - the WORDS_BIGENDIAN preprocessor macro is used in libdecnumber code to determines endianness. It is derived from the existing QEMU macro HOST_WORDS_BIGENDIAN which is defined in config-host.h. - the DECPUN macro determines the number of decimal digits (aka declets) per unit (byte). This is 3 for PowerPC DFP. Signed-off-by: Tom Musta tommu...@gmail.com --- include/libdecnumber/dconfig.h | 24 ++-- 1 files changed, 6 insertions(+), 18 deletions(-) diff --git a/include/libdecnumber/dconfig.h b/include/libdecnumber/dconfig.h index ffbad25..2f0455a 100644 --- a/include/libdecnumber/dconfig.h +++ b/include/libdecnumber/dconfig.h @@ -27,26 +27,14 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifdef IN_LIBGCC2 +#include config-host.h -#include tconfig.h -#include coretypes.h -#include tm.h - -#ifndef LIBGCC2_WORDS_BIG_ENDIAN -#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN -#endif - -#ifndef LIBGCC2_FLOAT_WORDS_BIG_ENDIAN -#define LIBGCC2_FLOAT_WORDS_BIG_ENDIAN LIBGCC2_WORDS_BIG_ENDIAN -#endif - -#if LIBGCC2_FLOAT_WORDS_BIG_ENDIAN +#if defined(HOST_WORDS_BIGENDIAN) #define WORDS_BIGENDIAN 1 -#endif - #else +#define WORDS_BIGENDIAN 0 +#endif -#include config.h - +#ifndef DECDPUN +#define DECDPUN 3 #endif -- 1.7.1
[Qemu-devel] [PATCH 02/37] libdecnumber: Eliminate #include *Symbols.h
The various *Symbols.h files were not copied from the original GCC libdecnumber library; they are not necessary for use in QEMU. Remove all instances of #include *Symbols.h Signed-off-by: Tom Musta tommu...@gmail.com --- include/libdecnumber/decContext.h |1 - include/libdecnumber/decDPD.h |1 - include/libdecnumber/decNumber.h |1 - include/libdecnumber/decNumberLocal.h |2 -- include/libdecnumber/dpd/decimal128.h |1 - include/libdecnumber/dpd/decimal32.h |1 - include/libdecnumber/dpd/decimal64.h |1 - 7 files changed, 0 insertions(+), 8 deletions(-) diff --git a/include/libdecnumber/decContext.h b/include/libdecnumber/decContext.h index f80d03c..1a3f15e 100644 --- a/include/libdecnumber/decContext.h +++ b/include/libdecnumber/decContext.h @@ -237,7 +237,6 @@ /* decContext routines */ - #include decContextSymbols.h extern decContext * decContextClearStatus(decContext *, uint32_t); extern decContext * decContextDefault(decContext *, int32_t); diff --git a/include/libdecnumber/decDPD.h b/include/libdecnumber/decDPD.h index a4710d6..5967fb4 100644 --- a/include/libdecnumber/decDPD.h +++ b/include/libdecnumber/decDPD.h @@ -35,7 +35,6 @@ /* */ /* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */ -#include decDPDSymbols.h /* This include file defines several DPD and BCD conversion tables:*/ /* */ diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h index 0a9fdce..aa99a5b 100644 --- a/include/libdecnumber/decNumber.h +++ b/include/libdecnumber/decNumber.h @@ -111,7 +111,6 @@ /* decNumber public functions and macros */ /* */ - #include decNumberSymbols.h /* Conversions */ decNumber * decNumberFromInt32(decNumber *, int32_t); diff --git a/include/libdecnumber/decNumberLocal.h b/include/libdecnumber/decNumberLocal.h index f1568f7..f2a919b 100644 --- a/include/libdecnumber/decNumberLocal.h +++ b/include/libdecnumber/decNumberLocal.h @@ -100,7 +100,6 @@ extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */ extern const uInt DECPOWERS[10]; /* powers of ten table*/ /* The following are included from decDPD.h*/ -#include decDPDSymbols.h extern const uShort DPD2BIN[1024]; /* DPD - 0-999 */ extern const uShort BIN2DPD[1000]; /* 0-999 - DPD */ extern const uInt DPD2BINK[1024]; /* DPD - 0-999000*/ @@ -326,7 +325,6 @@ #define DFISSNAN(df) ((DFWORD(df, 0)0x7e00)==0x7e00) /* Shared lookup tables*/ -#include decCommonSymbols.h extern const uInt DECCOMBMSD[64]; /* Combination field - MSD */ extern const uInt DECCOMBFROM[48]; /* exp+msd - Combination */ diff --git a/include/libdecnumber/dpd/decimal128.h b/include/libdecnumber/dpd/decimal128.h index f8f5b5a..251b964 100644 --- a/include/libdecnumber/dpd/decimal128.h +++ b/include/libdecnumber/dpd/decimal128.h @@ -82,7 +82,6 @@ /* Routines*/ /* */ - #include decimal128Symbols.h /* String conversions */ decimal128 * decimal128FromString(decimal128 *, const char *, decContext *); diff --git a/include/libdecnumber/dpd/decimal32.h b/include/libdecnumber/dpd/decimal32.h index 0d53046..5f06cd4 100644 --- a/include/libdecnumber/dpd/decimal32.h +++ b/include/libdecnumber/dpd/decimal32.h @@ -80,7 +80,6 @@ /* Routines*/ /* */ - #include decimal32Symbols.h /* String conversions */ decimal32 * decimal32FromString(decimal32 *, const char *, decContext *); diff --git a/include/libdecnumber/dpd/decimal64.h b/include/libdecnumber/dpd/decimal64.h index 549b626..c391e25 100644 --- a/include/libdecnumber/dpd/decimal64.h +++ b/include/libdecnumber/dpd/decimal64.h @@ -82,7 +82,6 @@ /* Routines*/ /* */ - #include decimal64Symbols.h /* String conversions */ decimal64 * decimal64FromString(decimal64 *, const char *, decContext *); -- 1.7.1
[Qemu-devel] [PATCH 03/37] libdecnumber: Prepare libdecnumber for QEMU include structure
Consistent with other libraries in QEMU, the libdecnumber header files were placed in include/libdecnumber, separate from the C code. This is different from the original libdecnumber source, where they were co-located. Change the libdecnumber source code so that it reflects this split. Specifically, modify directives of the form: #include xxx.h to look like: #include libdecnumber/xxx.h Signed-off-by: Tom Musta tommu...@gmail.com --- include/libdecnumber/decNumber.h |2 +- include/libdecnumber/decNumberLocal.h |2 +- include/libdecnumber/dpd/decimal128.h |2 +- include/libdecnumber/dpd/decimal32.h |2 +- include/libdecnumber/dpd/decimal64.h |2 +- libdecnumber/decContext.c |6 +++--- libdecnumber/decNumber.c |6 +++--- libdecnumber/dpd/decimal128.c |8 libdecnumber/dpd/decimal32.c |8 libdecnumber/dpd/decimal64.c | 12 ++-- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h index aa99a5b..fb324bd 100644 --- a/include/libdecnumber/decNumber.h +++ b/include/libdecnumber/decNumber.h @@ -39,7 +39,7 @@ #define DECAUTHOR Mike Cowlishaw /* Who to blame */ #if !defined(DECCONTEXT) -#include decContext.h +#include libdecnumber/decContext.h #endif /* Bit settings for decNumber.bits */ diff --git a/include/libdecnumber/decNumberLocal.h b/include/libdecnumber/decNumberLocal.h index f2a919b..f5f508f 100644 --- a/include/libdecnumber/decNumberLocal.h +++ b/include/libdecnumber/decNumberLocal.h @@ -44,7 +44,7 @@ #include stdlib.h/* for abs */ #include string.h/* for memset, strcpy */ - #include dconfig.h /* for WORDS_BIGENDIAN */ + #include libdecnumber/dconfig.h /* Conditional code flag -- set this to match hardware platform */ /* 1=little-endian, 0=big-endian */ diff --git a/include/libdecnumber/dpd/decimal128.h b/include/libdecnumber/dpd/decimal128.h index 251b964..7d9ee24 100644 --- a/include/libdecnumber/dpd/decimal128.h +++ b/include/libdecnumber/dpd/decimal128.h @@ -60,7 +60,7 @@ #define DECNUMDIGITS DECIMAL128_Pmax /* size if not already defined*/ #endif #ifndef DECNUMBER -#include decNumber.h /* context and number library */ +#include libdecnumber/decNumber.h #endif /* Decimal 128-bit type, accessible by bytes */ diff --git a/include/libdecnumber/dpd/decimal32.h b/include/libdecnumber/dpd/decimal32.h index 5f06cd4..de313e0 100644 --- a/include/libdecnumber/dpd/decimal32.h +++ b/include/libdecnumber/dpd/decimal32.h @@ -60,7 +60,7 @@ #define DECNUMDIGITS DECIMAL32_Pmax /* size if not already defined*/ #endif #ifndef DECNUMBER -#include decNumber.h /* context and number library */ +#include libdecnumber/decNumber.h #endif /* Decimal 32-bit type, accessible by bytes */ diff --git a/include/libdecnumber/dpd/decimal64.h b/include/libdecnumber/dpd/decimal64.h index c391e25..2f6c049 100644 --- a/include/libdecnumber/dpd/decimal64.h +++ b/include/libdecnumber/dpd/decimal64.h @@ -62,7 +62,7 @@ #define DECNUMDIGITS DECIMAL64_Pmax /* size if not already defined*/ #endif #ifndef DECNUMBER -#include decNumber.h /* context and number library */ +#include libdecnumber/decNumber.h #endif /* Decimal 64-bit type, accessible by bytes*/ diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c index d2e3bed..737cca9 100644 --- a/libdecnumber/decContext.c +++ b/libdecnumber/decContext.c @@ -37,9 +37,9 @@ #include string.h /* for strcmp */ #include stdio.h /* for printf if DECCHECK */ -#include dconfig.h /* for GCC definitions */ -#include decContext.h /* context and base types */ -#include decNumberLocal.h /* decNumber local types, etc. */ +#include libdecnumber/dconfig.h +#include libdecnumber/decContext.h +#include libdecnumber/decNumberLocal.h #if DECCHECK /* compile-time endian tester [assumes sizeof(Int)1] */ diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c index f9a624a..1bfc081 100644 --- a/libdecnumber/decNumber.c +++ b/libdecnumber/decNumber.c @@ -170,9 +170,9 @@ #include stdio.h/* for printf [if needed] */ #include string.h /* for strcpy */ #include ctype.h/* for lower */ -#include dconfig.h /* for GCC definitions */ -#include decNumber.h/* base number library */ -#include decNumberLocal.h /* decNumber local types, etc. */ +#include libdecnumber/dconfig.h +#include libdecnumber/decNumber.h +#include libdecnumber/decNumberLocal.h /* Constants */ /* Public lookup table used by
[Qemu-devel] [PATCH 08/37] target-ppc: Enable Building of libdecnumber
Enable compilation of the newly added libdecnumber library code. Object file targets are added to Makefile.target using a newly introduced flag CONFIG_LIBDECNUMBER. The flag is added to the PowerPC targets (ppc[64]-linux-user, ppc[64]-softmmu). Signed-off-by: Tom Musta tommu...@gmail.com --- Makefile.target |6 ++ default-configs/ppc-linux-user.mak |1 + default-configs/ppc-softmmu.mak |1 + default-configs/ppc64-linux-user.mak |1 + default-configs/ppc64-softmmu.mak|1 + 5 files changed, 10 insertions(+), 0 deletions(-) diff --git a/Makefile.target b/Makefile.target index ba12340..ccb7b9c 100644 --- a/Makefile.target +++ b/Makefile.target @@ -82,6 +82,12 @@ obj-y += disas.o obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o +obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decContext.o +obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decNumber.o +obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal32.o +obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal64.o +obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal128.o + # # Linux user emulator target diff --git a/default-configs/ppc-linux-user.mak b/default-configs/ppc-linux-user.mak index 6273df2..260ba41 100644 --- a/default-configs/ppc-linux-user.mak +++ b/default-configs/ppc-linux-user.mak @@ -1 +1,2 @@ # Default configuration for ppc-linux-user +CONFIG_LIBDECNUMBER=y diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index 07c51ce..33f8d84 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -49,3 +49,4 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM)) CONFIG_MC146818RTC=y CONFIG_ETSEC=y CONFIG_ISA_TESTDEV=y +CONFIG_LIBDECNUMBER=y diff --git a/default-configs/ppc64-linux-user.mak b/default-configs/ppc64-linux-user.mak index 422d3fb..e731ce0 100644 --- a/default-configs/ppc64-linux-user.mak +++ b/default-configs/ppc64-linux-user.mak @@ -1 +1,2 @@ # Default configuration for ppc64-linux-user +CONFIG_LIBDECNUMBER=y diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index e2beac6..37a15b7 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -58,3 +58,4 @@ CONFIG_I82374=y CONFIG_I8257=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y +CONFIG_LIBDECNUMBER=y -- 1.7.1
[Qemu-devel] [PATCH 07/37] libdecnumber: Eliminate Unused Variable in decSetSubnormal
Eliminate an unused variable in the decSetSubnormal routine. The variable dnexp is declared and eventually set but never used, and thus may trigger an unused-but-set-variable warning. Signed-off-by: Tom Musta tommu...@gmail.com --- libdecnumber/decNumber.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c index 1bfc081..f6b6eb1 100644 --- a/libdecnumber/decNumber.c +++ b/libdecnumber/decNumber.c @@ -7403,7 +7403,6 @@ static void decSetMaxValue(decNumber *dn, decContext *set) { /* -- */ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue, uInt *status) { - Int dnexp; /* saves original exponent */ decContext workset;/* work */ Int etiny, adjust; /* .. */ @@ -7448,7 +7447,6 @@ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue, /* adjust0, so need to rescale the result so exponent becomes Etiny */ /* [this code is similar to that in rescale] */ - dnexp=dn-exponent; /* save exponent */ workset=*set;/* clone rounding, etc. */ workset.digits=dn-digits-adjust;/* set requested length */ workset.emin-=adjust;/* and adjust emin to match */ -- 1.7.1
[Qemu-devel] [PATCH 06/37] libdecnumber: Eliminate redundant declarations
Eliminate redundant declarations of symbols DPD2BIN and BIN2DPD in various .c source files. These symbols are already declared in decDPD.h and thus will trigger 'redundant redeclaration of ?XXX?' warnings, which, of course, may fail QEMU compilation. Signed-off-by: Tom Musta tommu...@gmail.com --- libdecnumber/dpd/decimal128.c |2 -- libdecnumber/dpd/decimal32.c |2 -- libdecnumber/dpd/decimal64.c |2 -- 3 files changed, 0 insertions(+), 6 deletions(-) diff --git a/libdecnumber/dpd/decimal128.c b/libdecnumber/dpd/decimal128.c index 8f8e983..7551b7c 100644 --- a/libdecnumber/dpd/decimal128.c +++ b/libdecnumber/dpd/decimal128.c @@ -50,8 +50,6 @@ /* Utility routines and tables [in decimal64.c] */ extern const uInt COMBEXP[32], COMBMSD[32]; -extern const uShort DPD2BIN[1024]; -extern const uShort BIN2DPD[1000]; /* [not used] */ extern const uByte BIN2CHAR[4001]; extern void decDigitsFromDPD(decNumber *, const uInt *, Int); diff --git a/libdecnumber/dpd/decimal32.c b/libdecnumber/dpd/decimal32.c index f8d30e6..095ab75 100644 --- a/libdecnumber/dpd/decimal32.c +++ b/libdecnumber/dpd/decimal32.c @@ -50,8 +50,6 @@ /* Utility tables and routines [in decimal64.c] */ extern const uInt COMBEXP[32], COMBMSD[32]; -extern const uShort DPD2BIN[1024]; -extern const uShort BIN2DPD[1000]; extern const uByte BIN2CHAR[4001]; extern void decDigitsToDPD(const decNumber *, uInt *, Int); diff --git a/libdecnumber/dpd/decimal64.c b/libdecnumber/dpd/decimal64.c index 3bd2776..8256084 100644 --- a/libdecnumber/dpd/decimal64.c +++ b/libdecnumber/dpd/decimal64.c @@ -50,8 +50,6 @@ /* Utility routines and tables [in decimal64.c]; externs for C++ */ extern const uInt COMBEXP[32], COMBMSD[32]; -extern const uShort DPD2BIN[1024]; -extern const uShort BIN2DPD[1000]; extern const uByte BIN2CHAR[4001]; extern void decDigitsFromDPD(decNumber *, const uInt *, Int); -- 1.7.1
[Qemu-devel] [PATCH 13/37] target-ppc: Introduce Generator Macros for DFP Arithmetic Forms
Add general support for generators of PowerPC Decimal Floating Point helpers. Some utilities are annotated with GCC attribute unused in order to preserve build bisection. These annotations will be removed in later patches. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/translate.c | 177 1 files changed, 177 insertions(+), 0 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index e3fcb03..abbab1f 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -467,6 +467,12 @@ EXTRACT_HELPER(AA, 1, 1); /* Link */ EXTRACT_HELPER(LK, 0, 1); +/* DFP Z22-form */ +EXTRACT_HELPER(DCM, 10, 6) + +/* DFP Z23-form */ +EXTRACT_HELPER(RMC, 9, 2) + /* Create a mask between start and end bits */ static inline target_ulong MASK(uint32_t start, uint32_t end) { @@ -503,6 +509,7 @@ EXTRACT_HELPER_SPLIT(xC, 3, 1, 6, 5); EXTRACT_HELPER(DM, 8, 2); EXTRACT_HELPER(UIM, 16, 2); EXTRACT_HELPER(SHW, 8, 2); +EXTRACT_HELPER(SP, 19, 2); /*/ /* PowerPC instructions table*/ @@ -8180,6 +8187,176 @@ static void gen_xxsldwi(DisasContext *ctx) tcg_temp_free_i64(xtl); } +/*** Decimal Floating Point ***/ + +static inline TCGv_ptr gen_fprp_ptr(int reg) +{ +TCGv_ptr r = tcg_temp_new_ptr(); +tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg])); +return r; +} + +#if defined(TARGET_PPC64) +__attribute__ ((unused)) +static void gen_set_cr6_from_fpscr(DisasContext *ctx) +{ +TCGv_i32 tmp = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(tmp, cpu_fpscr); +tcg_gen_shri_i32(cpu_crf[1], tmp, 28); +tcg_temp_free_i32(tmp); +} +#else +__attribute__ ((unused)) +static void gen_set_cr6_from_fpscr(DisasContext *ctx) +{ +tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28); +} +#endif + +#define GEN_DFP_T_A_B_Rc(name) \ +static void gen_##name(DisasContext *ctx)\ +{\ +TCGv_ptr rd, ra, rb; \ +if (unlikely(!ctx-fpu_enabled)) { \ +gen_exception(ctx, POWERPC_EXCP_FPU);\ +return; \ +}\ +gen_update_nip(ctx, ctx-nip - 4); \ +rd = gen_fprp_ptr(rD(ctx-opcode)); \ +ra = gen_fprp_ptr(rA(ctx-opcode)); \ +rb = gen_fprp_ptr(rB(ctx-opcode)); \ +gen_helper_##name(cpu_env, rd, ra, rb); \ +if (unlikely(Rc(ctx-opcode) != 0)) {\ +gen_set_cr6_from_fpscr(ctx); \ +}\ +tcg_temp_free_ptr(rd); \ +tcg_temp_free_ptr(ra); \ +tcg_temp_free_ptr(rb); \ +} + +#define GEN_DFP_BF_A_B(name) \ +static void gen_##name(DisasContext *ctx) \ +{ \ +TCGv_ptr ra, rb; \ +if (unlikely(!ctx-fpu_enabled)) {\ +gen_exception(ctx, POWERPC_EXCP_FPU); \ +return; \ +} \ +gen_update_nip(ctx, ctx-nip - 4);\ +ra = gen_fprp_ptr(rA(ctx-opcode)); \ +rb = gen_fprp_ptr(rB(ctx-opcode)); \ +gen_helper_##name(cpu_crf[crfD(ctx-opcode)], \ + cpu_env, ra, rb); \ +tcg_temp_free_ptr(ra);\ +tcg_temp_free_ptr(rb);\ +} + +#define GEN_DFP_BF_A_DCM(name)\ +static void gen_##name(DisasContext *ctx) \ +{ \ +TCGv_ptr ra; \ +TCGv_i32 dcm; \ +if (unlikely(!ctx-fpu_enabled)) {\ +gen_exception(ctx, POWERPC_EXCP_FPU); \ +return; \ +} \ +gen_update_nip(ctx, ctx-nip - 4);\ +ra = gen_fprp_ptr(rA(ctx-opcode)); \ +dcm = tcg_const_i32(DCM(ctx-opcode));\ +gen_helper_##name(cpu_crf[crfD(ctx-opcode)], \ + cpu_env, ra, dcm); \ +tcg_temp_free_ptr(ra);\ +tcg_temp_free_i32(dcm); \ +} + +#define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2)\ +static void gen_##name(DisasContext *ctx) \ +{ \ +TCGv_ptr rt, rb; \ +TCGv_i32 u32_1, u32_2;\ +if (unlikely(!ctx-fpu_enabled)) {\ +gen_exception(ctx, POWERPC_EXCP_FPU); \ +return;
[Qemu-devel] [PATCH 10/37] libdecnumber: Introduce decNumberIntegralToInt64
Introduce a new conversion function to the libdecnumber library. This function converts a decNumber to a signed 64-bit integer. In order to support 64-bit integers (which may have up to 19 decimal digits), the existing powers of 10 array is expanded from 10 to 19 entries. Signed-off-by: Tom Musta tommu...@gmail.com --- include/libdecnumber/decNumber.h |1 + include/libdecnumber/decNumberLocal.h |2 +- libdecnumber/decContext.c |6 +++- libdecnumber/decNumber.c | 46 - 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h index f4bf994..9fa4e6a 100644 --- a/include/libdecnumber/decNumber.h +++ b/include/libdecnumber/decNumber.h @@ -122,6 +122,7 @@ char * decNumberToEngString(const decNumber *, char *); uint32_tdecNumberToUInt32(const decNumber *, decContext *); int32_t decNumberToInt32(const decNumber *, decContext *); + int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set); uint8_t * decNumberGetBCD(const decNumber *, uint8_t *); decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t); diff --git a/include/libdecnumber/decNumberLocal.h b/include/libdecnumber/decNumberLocal.h index f5f508f..cd4eb79 100644 --- a/include/libdecnumber/decNumberLocal.h +++ b/include/libdecnumber/decNumberLocal.h @@ -98,7 +98,7 @@ /* Shared lookup tables*/ extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */ - extern const uInt DECPOWERS[10]; /* powers of ten table*/ + extern const uLong DECPOWERS[19];/* powers of ten table*/ /* The following are included from decDPD.h*/ extern const uShort DPD2BIN[1024]; /* DPD - 0-999 */ extern const uShort BIN2DPD[1000]; /* 0-999 - DPD */ diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c index 737cca9..88e5dd0 100644 --- a/libdecnumber/decContext.c +++ b/libdecnumber/decContext.c @@ -56,8 +56,10 @@ const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */ /* -- */ /* Powers of ten (powers[n]==10**n, 0=n=9) */ /* -- */ -const uInt DECPOWERS[10]={1, 10, 100, 1000, 1, 10, 100, - 1000, 1, 10}; +const uLong DECPOWERS[19] = {1, 10, 100, 1000, 1, 10, 100, + 1000, 1, 10, 100, 1000, + 1, 10, 100, 1000, + 1, 10, 100, }; /* -- */ /* decContextClearStatus -- clear bits in current status */ diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c index 01ef30a..825fde0 100644 --- a/libdecnumber/decNumber.c +++ b/libdecnumber/decNumber.c @@ -471,6 +471,50 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin) return dn; } /* decNumberFromUInt64 */ +/* -- */ +/* to-int64 -- conversion to int64*/ +/**/ +/* dn is the decNumber to convert. dn is assumed to have been */ +/*rounded to a floating point integer value. */ +/* set is the context for reporting errors */ +/* returns the converted decNumber, or 0 if Invalid is set */ +/**/ +/* Invalid is set if the decNumber is a NaN, Infinite or is out of*/ +/* range for a signed 64 bit integer. */ +/* -- */ + +int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set) +{ +if (decNumberIsSpecial(dn) || (dn-exponent 0) || + (dn-digits + dn-exponent 19)) { +goto Invalid; +} else { +int64_t d;/* work */ +const Unit *up; /* .. */ +uint64_t hi = 0; +up = dn-lsu; /* - lsu */ + +for (d = 1; d = dn-digits; up++, d += DECDPUN) { +uint64_t prev = hi; +hi += *up * powers[d-1]; +if ((hi prev) || (hi INT64_MAX)) { +goto Invalid; +} +} + +uint64_t prev = hi; +hi *= (uint64_t)powers[dn-exponent]; +if ((hi prev) || (hi INT64_MAX)) { +goto Invalid; +} +return (decNumberIsNegative(dn)) ? -((int64_t)hi) : (int64_t)hi; +} + +Invalid: +decContextSetStatus(set, DEC_Invalid_operation); +return 0; +} /*
[Qemu-devel] [PATCH 12/37] target-ppc: Define FPR Pointer Type for Helpers
Define a floating pointer register pointer type in the PowerPC helper header. The type will be used to pass FPR register operands to Decimal Floating Point (DFP) helpers. A pointer is used because the quad word forms of PowerPC DFP instructions operate on adjacent pairs of floating point registers and thus can be thought of as arrays of length 2. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/helper.h |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 99f10de..1bebc8e 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -614,4 +614,8 @@ DEF_HELPER_3(store_601_batl, void, env, i32, tl) DEF_HELPER_3(store_601_batu, void, env, i32, tl) #endif +#define dh_alias_fprp ptr +#define dh_ctype_fprp uint64_t * +#define dh_is_signed_fprp dh_is_signed_ptr + #include exec/def-helper.h -- 1.7.1
[Qemu-devel] [PATCH 09/37] libdecnumber: Introduce decNumberFrom[U]Int64
Introduce two conversion functions to the libdecnumber library. These conversions transform 64 bit integers to the internal decNumber representation. Both a signed and unsigned version is added. Signed-off-by: Tom Musta tommu...@gmail.com --- include/libdecnumber/decNumber.h |2 ++ libdecnumber/decNumber.c | 36 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h index fb324bd..f4bf994 100644 --- a/include/libdecnumber/decNumber.h +++ b/include/libdecnumber/decNumber.h @@ -115,6 +115,8 @@ /* Conversions */ decNumber * decNumberFromInt32(decNumber *, int32_t); decNumber * decNumberFromUInt32(decNumber *, uint32_t); + decNumber *decNumberFromInt64(decNumber *, int64_t); + decNumber *decNumberFromUInt64(decNumber *, uint64_t); decNumber * decNumberFromString(decNumber *, const char *, decContext *); char * decNumberToString(const decNumber *, char *); char * decNumberToEngString(const decNumber *, char *); diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c index f6b6eb1..01ef30a 100644 --- a/libdecnumber/decNumber.c +++ b/libdecnumber/decNumber.c @@ -436,6 +436,42 @@ uInt decNumberToUInt32(const decNumber *dn, decContext *set) { return 0; } /* decNumberToUInt32 */ +decNumber *decNumberFromInt64(decNumber *dn, int64_t in) +{ +uint64_t unsig; +if (in = 0) { +unsig = in; +} else { /* negative (possibly BADINT) */ +if (in == INT64_MIN) { +unsig = 1ull 63; /* special case */ +} else { +unsig = -in; /* invert */ +} +} +/* in is now positive */ +decNumberFromUInt64(dn, unsig); +if (in 0) { +dn-bits = DECNEG;/* sign needed */ +} +return dn; +} /* decNumberFromInt64 */ + +decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin) +{ +Unit *up; /* work pointer */ +decNumberZero(dn);/* clean */ +if (uin == 0) { +return dn;/* [or decGetDigits bad call] */ +} +for (up = dn-lsu; uin 0; up++) { +*up = (Unit)(uin % (DECDPUNMAX + 1)); +uin = uin / (DECDPUNMAX + 1); +} +dn-digits = decGetDigits(dn-lsu, up-dn-lsu); +return dn; +} /* decNumberFromUInt64 */ + + /* -- */ /* to-scientific-string -- conversion to numeric string */ /* to-engineering-string -- conversion to numeric string */ -- 1.7.1
[Qemu-devel] [PATCH 11/37] libdecnumber: Fix decNumberSetBCD
Fix a simple bug in the decNumberSetBCD() function. This function encodes a decNumber with n BCD digits. The original code erroneously computed the number of declets from the dn argument, which is the output decNumber value, and hence may contain garbage. Instead, the input n value is used. Signed-off-by: Tom Musta tommu...@gmail.com --- libdecnumber/decNumber.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c index 825fde0..c4269a4 100644 --- a/libdecnumber/decNumber.c +++ b/libdecnumber/decNumber.c @@ -3547,7 +3547,7 @@ uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) { /* and bcd[0] zero. */ /* -- */ decNumber * decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) { - Unit *up=dn-lsu+D2U(dn-digits)-1; /* - msu [target pointer] */ + Unit *up = dn-lsu + D2U(n) - 1; /* - msu [target pointer] */ const uByte *ub=bcd; /* - source msd */ #if DECDPUN==1 /* trivial simple copy */ -- 1.7.1
[Qemu-devel] [PATCH 17/37] target-ppc: Introduce DFP Add
Add emulation of the PowerPC Decimal Floating Point Add instructions dadd[q][.] Various GCC unused annotations are removed since it is now safe to remove them. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 129 +-- target-ppc/helper.h |2 + target-ppc/translate.c |7 ++- 3 files changed, 132 insertions(+), 6 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 0c11696..100b0d7 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -77,7 +77,6 @@ static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr) decContextSetRounding(context, rnd); } -__attribute__ ((unused)) static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a, uint64_t *b, CPUPPCState *env) { @@ -102,7 +101,6 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a, } } -__attribute__ ((unused)) static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a, uint64_t *b, CPUPPCState *env) { @@ -150,7 +148,6 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a, #define FP_VE (1ull FPSCR_VE) #define FP_FI (1ull FPSCR_FI) -__attribute__ ((unused)) static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag, uint64_t enabled) { @@ -162,7 +159,103 @@ static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag, typedef void (*PPC_DFP_PostProc)(struct PPC_DFP *); -__attribute__ ((unused)) +static void dfp_set_FPRF_from_FRT_with_context(struct PPC_DFP *dfp, +decContext *context) +{ +uint64_t fprf = 0; + +/* construct FPRF */ +switch (decNumberClass(dfp-t, context)) { +case DEC_CLASS_SNAN: +fprf = 0x01; +break; +case DEC_CLASS_QNAN: +fprf = 0x11; +break; +case DEC_CLASS_NEG_INF: +fprf = 0x09; +break; +case DEC_CLASS_NEG_NORMAL: +fprf = 0x08; +break; +case DEC_CLASS_NEG_SUBNORMAL: +fprf = 0x18; +break; +case DEC_CLASS_NEG_ZERO: +fprf = 0x12; +break; +case DEC_CLASS_POS_ZERO: +fprf = 0x02; +break; +case DEC_CLASS_POS_SUBNORMAL: +fprf = 0x14; +break; +case DEC_CLASS_POS_NORMAL: +fprf = 0x04; +break; +case DEC_CLASS_POS_INF: +fprf = 0x05; +break; +default: +assert(0); /* should never get here */ +} +dfp-env-fpscr = ~(0x1F 12); +dfp-env-fpscr |= (fprf 12); +} + +static void dfp_set_FPRF_from_FRT(struct PPC_DFP *dfp) +{ +dfp_set_FPRF_from_FRT_with_context(dfp, dfp-context); +} + +static void dfp_check_for_OX(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Overflow) { +dfp_set_FPSCR_flag(dfp, FP_OX, FP_OE); +} +} + +static void dfp_check_for_UX(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Underflow) { +dfp_set_FPSCR_flag(dfp, FP_UX, FP_UE); +} +} + +static void dfp_check_for_XX(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Inexact) { +dfp_set_FPSCR_flag(dfp, FP_XX | FP_FI, FP_XE); +} +} + +static void dfp_check_for_VXSNAN(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Invalid_operation) { +if (decNumberIsSNaN(dfp-a) || decNumberIsSNaN(dfp-b)) { +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FP_VE); +} +} +} + +static void dfp_check_for_VXISI(struct PPC_DFP *dfp, int testForSameSign) +{ +if (dfp-context.status DEC_Invalid_operation) { +if (decNumberIsInfinite(dfp-a) decNumberIsInfinite(dfp-b)) { +int same = decNumberClass(dfp-a, dfp-context) == + decNumberClass(dfp-b, dfp-context); +if ((same testForSameSign) || (!same !testForSameSign)) { +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXISI, FP_VE); +} +} +} +} + +static void dfp_check_for_VXISI_add(struct PPC_DFP *dfp) +{ +dfp_check_for_VXISI(dfp, 0); +} + static void dfp_run_post_processors(struct PPC_DFP *dfp, PPC_DFP_PostProc post_processors[], const size_t n) { @@ -172,3 +265,31 @@ static void dfp_run_post_processors(struct PPC_DFP *dfp, post_processors[i](dfp); } } + +#define DFP_HELPER_TAB(op, dnop, postprocs, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ +{ \ +struct PPC_DFP dfp; \ +dfp_prepare_decimal##size(dfp, a, b, env); \ +dnop(dfp.t, dfp.a, dfp.b, dfp.context); \ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, dfp.context); \ +dfp_run_post_processors(dfp, postprocs, ARRAY_SIZE(postprocs)); \ +
[Qemu-devel] [PATCH 14/37] target-ppc: Introduce Decoder Macros for DFP
Add decoder macros for the various Decimal Floating Point instruction forms. Illegal instruction masks are used to not only guard against reserved instruction field use, but also to catch illegal quad word forms that use odd-numbered floating point registers. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/translate.c | 109 1 files changed, 109 insertions(+), 0 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index abbab1f..12aee63 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -11176,6 +11176,115 @@ GEN_XXSEL_ROW(0x1F) GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01), +#undef GEN_DFP_T_A_B_Rc +#undef GEN_DFP_BF_A_B +#undef GEN_DFP_BF_A_DCM +#undef GEN_DFP_T_B_U32_U32_Rc +#undef GEN_DFP_T_A_B_I32_Rc +#undef GEN_DFP_T_B_Rc +#undef GEN_DFP_T_FPR_I32_Rc + +#define _GEN_DFP_LONG(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_LONGx2(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_LONGx4(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_QUAD(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_QUADx2(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_QUADx4(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP) + +#define GEN_DFP_T_A_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x) + +#define GEN_DFP_Tp_Ap_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00210800) + +#define GEN_DFP_Tp_A_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00200800) + +#define GEN_DFP_T_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x001F) + +#define GEN_DFP_Tp_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x003F0800) + +#define GEN_DFP_Tp_B_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x003F) + +#define GEN_DFP_T_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x001F0800) + +#define GEN_DFP_BF_A_B(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x0001) + +#define GEN_DFP_BF_Ap_Bp(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00610801) + +#define GEN_DFP_BF_A_Bp(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00600801) + +#define GEN_DFP_BF_A_DCM(name, op1, op2) \ +_GEN_DFP_LONGx2(name, op1, op2, 0x0061) + +#define GEN_DFP_BF_Ap_DCM(name, op1, op2) \ +_GEN_DFP_QUADx2(name, op1, op2, 0x00610001) + +#define GEN_DFP_T_A_B_RMC_Rc(name, op1, op2) \ +_GEN_DFP_LONGx4(name, op1, op2, 0x) + +#define GEN_DFP_Tp_Ap_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x02010800) + +#define GEN_DFP_Tp_A_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x02000800) + +#define GEN_DFP_TE_T_B_RMC_Rc(name, op1, op2) \ +_GEN_DFP_LONGx4(name, op1, op2, 0x) + +#define GEN_DFP_TE_Tp_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x00200800) + +#define GEN_DFP_R_T_B_RMC_Rc(name, op1, op2) \ +_GEN_DFP_LONGx4(name, op1, op2, 0x001E) + +#define GEN_DFP_R_Tp_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x003E0800) + +#define GEN_DFP_SP_T_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x0007) + +#define GEN_DFP_SP_Tp_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00270800) + +#define GEN_DFP_S_T_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x000F) + +#define GEN_DFP_S_Tp_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x002F0800) + +#define GEN_DFP_T_A_SH_Rc(name, op1, op2) \ +_GEN_DFP_LONGx2(name, op1, op2, 0x) + +#define GEN_DFP_Tp_Ap_SH_Rc(name, op1, op2) \ +_GEN_DFP_QUADx2(name, op1, op2, 0x0021) + #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH 29/37] target-ppc: Introduce DFP Convert to Long/Extended
Add emulation of the PowerPC Convert to DFP Long (dctdp[.]) and Convert to DFP Extended (dctqpq[.]) instructions. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 35 +++ target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 41 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 5c60492..a719797 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -286,6 +286,15 @@ static void dfp_check_for_VXSNAN(struct PPC_DFP *dfp) } } +static void dfp_check_for_VXSNAN_and_convert_to_QNaN(struct PPC_DFP *dfp) +{ +if (decNumberIsSNaN(dfp-t)) { +dfp-t.bits = ~DECSNAN; +dfp-t.bits |= DECNAN; +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FP_VE); +} +} + static void dfp_check_for_VXISI(struct PPC_DFP *dfp, int testForSameSign) { if (dfp-context.status DEC_Invalid_operation) { @@ -845,3 +854,29 @@ PPC_DFP_PostProc RINTN_PPs[] = { DFP_HELPER_RINT(drintn, RINTN_PPs, 64) DFP_HELPER_RINT(drintnq, RINTN_PPs, 128) + +void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b) +{ +struct PPC_DFP dfp; +uint32_t b_short = *b; +dfp_prepare_decimal64(dfp, 0, 0, env); +decimal32ToNumber((decimal32 *)b_short, dfp.t); +decimal64FromNumber((decimal64 *)t, dfp.t, dfp.context); +dfp_set_FPRF_from_FRT(dfp); +} + +PPC_DFP_PostProc CTQPQ_PPs[] = { +dfp_check_for_VXSNAN_and_convert_to_QNaN, +dfp_set_FPRF_from_FRT, +}; + +void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b) +{ +struct PPC_DFP dfp; +dfp_prepare_decimal128(dfp, 0, 0, env); +decimal64ToNumber((decimal64 *)b, dfp.t); +dfp_run_post_processors(dfp, CTQPQ_PPs, ARRAY_SIZE(CTQPQ_PPs)); +decimal128FromNumber((decimal128 *)dfp.t64, dfp.t, dfp.context); +t[0] = dfp.t64[HI_IDX]; +t[1] = dfp.t64[LO_IDX]; +} diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 2ef18c2..a99ca1c 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -648,4 +648,6 @@ DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32) +DEF_HELPER_3(dctdp, void, env, fprp, fprp) +DEF_HELPER_3(dctqpq, void, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 65b1503..da70c8d 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8386,6 +8386,8 @@ GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC) GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC) GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC) GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC) +GEN_DFP_T_B_Rc(dctdp) +GEN_DFP_T_B_Rc(dctqpq) /*** SPE extension ***/ /* Register moves */ @@ -11343,6 +11345,8 @@ GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03), GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03), GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07), GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07), +GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08), +GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH 24/37] target-ppc: Introduce DFP Test Exponent
Add emulation of the PowerPC Decimal Floating Point Test Exponent instructions dtstex[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 32 target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 38 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index ad24d05..fa62164 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -512,3 +512,35 @@ uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)\ DFP_HELPER_TSTDG(dtstdg, 64) DFP_HELPER_TSTDG(dtstdgq, 128) + +#define DFP_HELPER_TSTEX(op, size) \ +uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \ +{\ +struct PPC_DFP dfp; \ +int expa, expb, a_is_special, b_is_special; \ + \ +dfp_prepare_decimal##size(dfp, a, b, env); \ + \ +expa = dfp.a.exponent; \ +expb = dfp.b.exponent; \ +a_is_special = decNumberIsSpecial(dfp.a); \ +b_is_special = decNumberIsSpecial(dfp.b); \ + \ +if (a_is_special || b_is_special) { \ +int atype = a_is_special ? (decNumberIsNaN(dfp.a) ? 4 : 2) : 1; \ +int btype = b_is_special ? (decNumberIsNaN(dfp.b) ? 4 : 2) : 1; \ +dfp.crbf = (atype ^ btype) ? 0x1 : 0x2; \ +} else if (expa expb) {\ +dfp.crbf = 0x8; \ +} else if (expa expb) {\ +dfp.crbf = 0x4; \ +} else { \ +dfp.crbf = 0x2; \ +}\ + \ +dfp_run_post_processors(dfp, DTST_PPs, ARRAY_SIZE(DTST_PPs)); \ +return dfp.crbf; \ +} + +DFP_HELPER_TSTEX(dtstex, 64) +DFP_HELPER_TSTEX(dtstexq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 8c0c5d5..af9d9c9 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -634,4 +634,6 @@ DEF_HELPER_3(dtstdc, i32, env, fprp, i32) DEF_HELPER_3(dtstdcq, i32, env, fprp, i32) DEF_HELPER_3(dtstdg, i32, env, fprp, i32) DEF_HELPER_3(dtstdgq, i32, env, fprp, i32) +DEF_HELPER_3(dtstex, i32, env, fprp, fprp) +DEF_HELPER_3(dtstexq, i32, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 8df0ebc..510c2a7 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8372,6 +8372,8 @@ GEN_DFP_BF_A_DCM(dtstdc) GEN_DFP_BF_A_DCM(dtstdcq) GEN_DFP_BF_A_DCM(dtstdg) GEN_DFP_BF_A_DCM(dtstdgq) +GEN_DFP_BF_A_B(dtstex) +GEN_DFP_BF_A_B(dtstexq) /*** SPE extension ***/ /* Register moves */ @@ -11315,6 +11317,8 @@ GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06), GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06), GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07), GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07), +GEN_DFP_BF_A_B(dtstex, 0x02, 0x05), +GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH 19/37] target-ppc: Introduce DFP Multiply
Add emulation of the PowerPC Decimal Floating Point Multiply instructions dmul[q][.] Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 22 ++ target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 28 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 7fd7724..3a4e041 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -261,6 +261,16 @@ static void dfp_check_for_VXISI_subtract(struct PPC_DFP *dfp) dfp_check_for_VXISI(dfp, 1); } +static void dfp_check_for_VXIMZ(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Invalid_operation) { +if ((decNumberIsInfinite(dfp-a) decNumberIsZero(dfp-b)) || +(decNumberIsInfinite(dfp-b) decNumberIsZero(dfp-a))) { +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXIMZ, FP_VE); +} +} +} + static void dfp_run_post_processors(struct PPC_DFP *dfp, PPC_DFP_PostProc post_processors[], const size_t n) @@ -311,3 +321,15 @@ PPC_DFP_PostProc SUB_PPs[] = { DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64) DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128) + +PPC_DFP_PostProc MUL_PPs[] = { +dfp_set_FPRF_from_FRT, +dfp_check_for_OX, +dfp_check_for_UX, +dfp_check_for_XX, +dfp_check_for_VXSNAN, +dfp_check_for_VXIMZ, +}; + +DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64) +DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 7ae8d03..17c75ab 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -622,4 +622,6 @@ DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp) DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp) DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp) DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp) +DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp) +DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 80dc53c..a36ead4 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8360,6 +8360,8 @@ GEN_DFP_T_A_B_Rc(dadd) GEN_DFP_T_A_B_Rc(daddq) GEN_DFP_T_A_B_Rc(dsub) GEN_DFP_T_A_B_Rc(dsubq) +GEN_DFP_T_A_B_Rc(dmul) +GEN_DFP_T_A_B_Rc(dmulq) /*** SPE extension ***/ /* Register moves */ @@ -11291,6 +11293,8 @@ GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00), GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00), GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10), GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10), +GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01), +GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH 26/37] target-ppc: Introduce DFP Quantize
Add emulation of the PowerPC Decimal Floating Point Quantize instructions dquai[q][.] and dqua[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 131 +++ target-ppc/helper.h |4 ++ target-ppc/translate.c |8 +++ 3 files changed, 143 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index eb6e041..ff00cd4 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -77,6 +77,47 @@ static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr) decContextSetRounding(context, rnd); } +static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc, + struct PPC_DFP *dfp) +{ +enum rounding rnd; +if (r == 0) { +switch (rmc 3) { +case 0: +rnd = DEC_ROUND_HALF_EVEN; +break; +case 1: +rnd = DEC_ROUND_DOWN; +break; +case 2: +rnd = DEC_ROUND_HALF_UP; +break; +case 3: /* use FPSCR rounding mode */ +return; +default: +assert(0); /* cannot get here */ +} +} else { /* r == 1 */ +switch (rmc 3) { +case 0: +rnd = DEC_ROUND_CEILING; +break; +case 1: +rnd = DEC_ROUND_FLOOR; +break; +case 2: +rnd = DEC_ROUND_UP; +break; +case 3: +rnd = DEC_ROUND_HALF_DOWN; +break; +default: +assert(0); /* cannot get here */ +} +} +decContextSetRounding(dfp-context, rnd); +} + static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a, uint64_t *b, CPUPPCState *env) { @@ -301,6 +342,15 @@ static void dfp_check_for_VXVC(struct PPC_DFP *dfp) } } +static void dfp_check_for_VXCVI(struct PPC_DFP *dfp) +{ +if ((dfp-context.status DEC_Invalid_operation) +(!decNumberIsSNaN(dfp-a)) +(!decNumberIsSNaN(dfp-b))) { +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE); +} +} + static void dfp_set_CRBF_from_T(struct PPC_DFP *dfp) { if (decNumberIsNaN(dfp-t)) { @@ -330,6 +380,12 @@ static void dfp_run_post_processors(struct PPC_DFP *dfp, } } +static inline void dfp_makeQNaN(decNumber *dn) +{ +dn-bits = ~DECSPECIAL; +dn-bits |= DECNAN; +} + #define DFP_HELPER_TAB(op, dnop, postprocs, size) \ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ { \ @@ -579,3 +635,78 @@ uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \ DFP_HELPER_TSTSF(dtstsf, 64) DFP_HELPER_TSTSF(dtstsfq, 128) + +PPC_DFP_PostProc QUA_PPs[] = { +dfp_set_FPRF_from_FRT, +dfp_check_for_XX, +dfp_check_for_VXSNAN, +dfp_check_for_VXCVI, +}; + +static void dfp_quantize(uint8_t rmc, struct PPC_DFP *dfp) +{ +dfp_set_round_mode_from_immediate(0, rmc, dfp); +decNumberQuantize(dfp-t, dfp-b, dfp-a, dfp-context); +if (decNumberIsSNaN(dfp-a)) { +dfp-t = dfp-a; +dfp_makeQNaN(dfp-t); +} else if (decNumberIsSNaN(dfp-b)) { +dfp-t = dfp-b; +dfp_makeQNaN(dfp-t); +} else if (decNumberIsQNaN(dfp-a)) { +dfp-t = dfp-a; +} else if (decNumberIsQNaN(dfp-b)) { +dfp-t = dfp-b; +} +} + +#define DFP_HELPER_QUAI(op, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,\ + uint32_t te, uint32_t rmc) \ +{ \ +struct PPC_DFP dfp; \ +\ +dfp_prepare_decimal##size(dfp, 0, b, env); \ +\ +decNumberFromUInt32(dfp.a, 1); \ +dfp.a.exponent = (int32_t)((int8_t)(te 3) 3); \ +\ +dfp_quantize(rmc, dfp);\ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, \ + dfp.context);\ +dfp_run_post_processors(dfp, QUA_PPs, ARRAY_SIZE(QUA_PPs));\ +\ +if (size == 64) { \ +t[0] = dfp.t64[0]; \ +} else if (size == 128) { \ +t[0] = dfp.t64[HI_IDX];
[Qemu-devel] [PATCH 27/37] target-ppc: Introduce DFP Reround
Add emulation of the PowerPC Decimal Floating Point Reround instructions drrnd[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 97 +++ target-ppc/helper.h |2 + target-ppc/translate.c |4 ++ 3 files changed, 103 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index ff00cd4..d2031b8 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -386,6 +386,23 @@ static inline void dfp_makeQNaN(decNumber *dn) dn-bits |= DECNAN; } +static inline int dfp_get_digit(decNumber *dn, int n) +{ +assert(DECDPUN == 3); +int unit = n / DECDPUN; +int dig = n % DECDPUN; +switch (dig) { +case 0: +return dn-lsu[unit] % 10; +case 1: +return (dn-lsu[unit] / 10) % 10; +case 2: +return dn-lsu[unit] / 100; +default: +assert(0); +} +} + #define DFP_HELPER_TAB(op, dnop, postprocs, size) \ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ { \ @@ -710,3 +727,83 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,\ DFP_HELPER_QUA(dqua, 64) DFP_HELPER_QUA(dquaq, 128) + +static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax, + struct PPC_DFP *dfp) +{ +int msd_orig, msd_rslt; + +if (unlikely((ref_sig == 0) || (dfp-b.digits = ref_sig))) { +dfp-t = dfp-b; +if (decNumberIsSNaN(dfp-b)) { +dfp_makeQNaN(dfp-t); +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FPSCR_VE); +} +return; +} + +/* Reround is equivalent to quantizing b with 1**E(n) where */ +/* n = exp(b) + numDigits(b) - reference_significance. */ + +decNumberFromUInt32(dfp-a, 1); +dfp-a.exponent = dfp-b.exponent + dfp-b.digits - ref_sig; + +if (unlikely(dfp-a.exponent xmax)) { +dfp-t.digits = 0; +dfp-t.bits = ~DECNEG; +dfp_makeQNaN(dfp-t); +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE); +return; +} + +dfp_quantize(rmc, dfp); + +msd_orig = dfp_get_digit(dfp-b, dfp-b.digits-1); +msd_rslt = dfp_get_digit(dfp-t, dfp-t.digits-1); + +/* If the quantization resulted in rounding up to the next magnitude, */ +/* then we need to shift the significand and adjust the exponent. */ + +if (unlikely((msd_orig == 9) (msd_rslt == 1))) { + +decNumber negone; + +decNumberFromInt32(negone, -1); +decNumberShift(dfp-t, dfp-t, negone, dfp-context); +dfp-t.exponent++; + +if (unlikely(dfp-t.exponent xmax)) { +dfp_makeQNaN(dfp-t); +dfp-t.digits = 0; +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE); +/* Inhibit XX in this case */ +decContextClearStatus(dfp-context, DEC_Inexact); +} +} +} + +#define DFP_HELPER_RRND(op, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,\ + uint64_t *b, uint32_t rmc) \ +{ \ +struct PPC_DFP dfp; \ +int32_t ref_sig = *a 0x3F;\ +int32_t xmax = ((size) == 64) ? 369 : 6111; \ +\ +dfp_prepare_decimal##size(dfp, 0, b, env); \ +\ +_dfp_reround(rmc, ref_sig, xmax, dfp); \ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, \ + dfp.context);\ +dfp_run_post_processors(dfp, QUA_PPs, ARRAY_SIZE(QUA_PPs));\ +\ +if (size == 64) { \ +t[0] = dfp.t64[0]; \ +} else if (size == 128) { \ +t[0] = dfp.t64[HI_IDX]; \ +t[1] = dfp.t64[LO_IDX]; \ +} \ +} + +DFP_HELPER_RRND(drrnd, 64) +DFP_HELPER_RRND(drrndq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 81b29e5..b63affb 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -642,4 +642,6 @@ DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
[Qemu-devel] [PATCH 33/37] target-ppc: Introduce DFP Decode DPD to BCD
Add emulation of the Power PC Decimal Floating Point Decode Densely Packed Decimal to Binary Coded Decimal instructions ddedpd[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 66 +++ target-ppc/helper.h |2 + target-ppc/translate.c |4 +++ 3 files changed, 72 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index bf30bd8..174db20 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -993,3 +993,69 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ DFP_HELPER_CTFIX(dctfix, 64) DFP_HELPER_CTFIX(dctfixq, 128) + +static inline void dfp_set_bcd_digit_64(uint64_t *t, uint8_t digit, +unsigned n) +{ +*t |= ((uint64_t)(digit 0xF) (n 2)); +} + +static inline void dfp_set_bcd_digit_128(uint64_t *t, uint8_t digit, + unsigned n) +{ +t[(n 0x10) ? HI_IDX : LO_IDX] |= +((uint64_t)(digit 0xF) ((n 15) 2)); +} + +static inline void dfp_set_sign_64(uint64_t *t, uint8_t sgn) +{ +*t = 4; +*t |= (sgn 0xF); +} + +static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn) +{ +t[HI_IDX] = 4; +t[HI_IDX] |= (t[LO_IDX] 60); +t[LO_IDX] = 4; +t[LO_IDX] |= (sgn 0xF); +} + +#define DFP_HELPER_DEDPD(op, size)\ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \ +{ \ +struct PPC_DFP dfp; \ +uint8_t digits[34]; \ +int i, N; \ + \ +dfp_prepare_decimal##size(dfp, 0, b, env); \ + \ +decNumberGetBCD(dfp.b, digits); \ +dfp.t64[0] = dfp.t64[1] = 0; \ +N = dfp.b.digits; \ + \ +for (i = 0; (i N) (i (size)/4); i++) { \ +dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i); \ +} \ + \ +if (sp 2) { \ +uint8_t sgn; \ + \ +if (decNumberIsNegative(dfp.b)) {\ +sgn = 0xD;\ +} else { \ +sgn = ((sp 1) ? 0xF : 0xC); \ +} \ +dfp_set_sign_##size(dfp.t64, sgn);\ +} \ + \ +if (size == 64) { \ +t[0] = dfp.t64[0];\ +} else if (size == 128) { \ +t[0] = dfp.t64[HI_IDX]; \ +t[1] = dfp.t64[LO_IDX]; \ +} \ +} + +DFP_HELPER_DEDPD(ddedpd, 64) +DFP_HELPER_DEDPD(ddedpdq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 30ba9d9..0d5acf5 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -656,4 +656,6 @@ DEF_HELPER_3(dcffix, void, env, fprp, fprp) DEF_HELPER_3(dcffixq, void, env, fprp, fprp) DEF_HELPER_3(dctfix, void, env, fprp, fprp) DEF_HELPER_3(dctfixq, void, env, fprp, fprp) +DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32) +DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 3f2f649..395a048 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8394,6 +8394,8 @@ GEN_DFP_T_B_Rc(dcffix) GEN_DFP_T_B_Rc(dcffixq) GEN_DFP_T_B_Rc(dctfix) GEN_DFP_T_B_Rc(dctfixq) +GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP) +GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP) /*** SPE extension ***/ /* Register moves */ @@ -11359,6
[Qemu-devel] [PATCH 34/37] target-ppc: Introduce DFP Encode BCD to DPD
Add emulation of the PowerPC Decimal Floating Point Encode Binary Coded Decimal to Densely Packed Decimal instructions denbcd[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 72 +++ target-ppc/helper.h |2 + target-ppc/translate.c |4 ++ 3 files changed, 78 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 174db20..79729c9 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -1059,3 +1059,75 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \ DFP_HELPER_DEDPD(ddedpd, 64) DFP_HELPER_DEDPD(ddedpdq, 128) + +static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n) +{ +return *t ((n 2) 63) 15; +} + +static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n) +{ +return t[(n 0x10) ? HI_IDX : LO_IDX] ((n 2) 63) 15; +} + +#define DFP_HELPER_ENBCD(op, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \ +{\ +struct PPC_DFP dfp; \ +uint8_t digits[32]; \ +int n = 0, offset = 0, sgn = 0, nonzero = 0; \ + \ +dfp_prepare_decimal##size(dfp, 0, b, env); \ + \ +decNumberZero(dfp.t); \ + \ +if (s) { \ +uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++); \ +switch (sgnNibble) { \ +case 0xD:\ +case 0xB:\ +sgn = 1; \ +break; \ +case 0xC:\ +case 0xF:\ +case 0xA:\ +case 0xE:\ +sgn = 0; \ +break; \ +default: \ +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);\ +return; \ +}\ +}\ + \ +while (offset (size)/4) { \ +n++; \ +digits[(size)/4-n] = dfp_get_bcd_digit_##size(dfp.b64, offset++);\ +if (digits[(size)/4-n] 10) { \ +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);\ +return; \ +} else { \ +nonzero |= (digits[(size)/4-n] 0); \ +}\ +}\ + \ +if (nonzero) { \ +decNumberSetBCD(dfp.t, digits+((size)/4)-n, n); \ +}\ + \ +if (s sgn) { \ +dfp.t.bits |= DECNEG;\ +}\ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, \ + dfp.context); \ +dfp_set_FPRF_from_FRT(dfp);
[Qemu-devel] [PATCH 32/37] target-ppc: Introduce DFP Convert to Fixed
Add emulation of the PowerPC Decimal Floating Point Convert to Fixed instructions dctfix[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 36 target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 42 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index ea9ef15..bf30bd8 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -957,3 +957,39 @@ PPC_DFP_PostProc CFFIX_PPs[] = { DFP_HELPER_CFFIX(dcffix, 64) DFP_HELPER_CFFIX(dcffixq, 128) + +#define DFP_HELPER_CTFIX(op, size)\ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ +{ \ +struct PPC_DFP dfp; \ +dfp_prepare_decimal##size(dfp, 0, b, env); \ + \ +if (unlikely(decNumberIsSpecial(dfp.b))) { \ +uint64_t invalid_flags = FP_VX | FP_VXCVI;\ +if (decNumberIsInfinite(dfp.b)) {\ +dfp.t64[0] = decNumberIsNegative(dfp.b) ? INT64_MIN : INT64_MAX; \ +} else { /* NaN */\ +dfp.t64[0] = INT64_MIN; \ +if (decNumberIsSNaN(dfp.b)) {\ +invalid_flags |= FP_VXSNAN; \ +} \ +} \ +dfp_set_FPSCR_flag(dfp, invalid_flags, FP_VE); \ +} else if (unlikely(decNumberIsZero(dfp.b))) { \ +dfp.t64[0] = 0; \ +} else { \ +decNumberToIntegralExact(dfp.b, dfp.b, dfp.context); \ +dfp.t64[0] = decNumberIntegralToInt64(dfp.b, dfp.context); \ +if (decContextTestStatus(dfp.context, DEC_Invalid_operation)) { \ +dfp.t64[0] = decNumberIsNegative(dfp.b) ? INT64_MIN : INT64_MAX; \ +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE);\ +} else { \ +dfp_check_for_XX(dfp); \ +} \ +} \ + \ +*t = dfp.t64[0]; \ +} + +DFP_HELPER_CTFIX(dctfix, 64) +DFP_HELPER_CTFIX(dctfixq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 0f64fb8..30ba9d9 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -654,4 +654,6 @@ DEF_HELPER_3(drsp, void, env, fprp, fprp) DEF_HELPER_3(drdpq, void, env, fprp, fprp) DEF_HELPER_3(dcffix, void, env, fprp, fprp) DEF_HELPER_3(dcffixq, void, env, fprp, fprp) +DEF_HELPER_3(dctfix, void, env, fprp, fprp) +DEF_HELPER_3(dctfixq, void, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 76682f6..3f2f649 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8392,6 +8392,8 @@ GEN_DFP_T_B_Rc(drsp) GEN_DFP_T_B_Rc(drdpq) GEN_DFP_T_B_Rc(dcffix) GEN_DFP_T_B_Rc(dcffixq) +GEN_DFP_T_B_Rc(dctfix) +GEN_DFP_T_B_Rc(dctfixq) /*** SPE extension ***/ /* Register moves */ @@ -11355,6 +11357,8 @@ GEN_DFP_T_B_Rc(drsp, 0x02, 0x18), GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18), GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19), GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19), +GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09), +GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH 37/37] target-ppc: Introduce DFP Shift Significand
Add emulation of the PowerPC Decimal Floating Point Shift Significand Left Immediate (dscli[q][.]) and DFP Shift Significant Right Immediate (dscri[q][.]) instructions. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 95 +++ target-ppc/helper.h |4 ++ target-ppc/translate.c | 10 + 3 files changed, 109 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 98ced28..3ff6777 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -1230,3 +1230,98 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ DFP_HELPER_IEX(diex, 64) DFP_HELPER_IEX(diexq, 128) + +static void dfp_clear_lmd_from_g5msb(uint64_t *t) +{ + +/* The most significant 5 bits of the PowerPC DFP format combine bits */ +/* from the left-most decimal digit (LMD) and the biased exponent. */ +/* This routine clears the LMD bits while preserving the exponent */ +/* bits. See Figure 80: Encoding of bits 0:4 of the G field for */ +/* Finite Numbers in the Power ISA for additional details. */ + +uint64_t g5msb = (*t 58) 0x1F; + +if ((g5msb 3) 3) { /* LMD in [0-7] ? */ + *t = ~(7ULL 58); +} else { + switch (g5msb 7) { + case 0: + case 1: + g5msb = 0; + break; + case 2: + case 3: + g5msb = 0x8; + break; + case 4: + case 5: + g5msb = 0x10; + break; + case 6: + g5msb = 0x1E; + break; + case 7: + g5msb = 0x1F; + break; + } + +*t = ~(0x1fULL 58); +*t |= (g5msb 58); +} +} + +#define DFP_HELPER_SHIFT(op, size, shift_left) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,\ + uint32_t sh) \ +{ \ +struct PPC_DFP dfp; \ +unsigned max_digits = ((size) == 64) ? 16 : 34; \ +\ +dfp_prepare_decimal##size(dfp, a, 0, env); \ +\ +if (sh = max_digits) { \ +\ +decNumber shd; \ +unsigned special = dfp.a.bits DECSPECIAL; \ +\ +if (shift_left) { \ +decNumberFromUInt32(shd, sh); \ +} else {\ +decNumberFromInt32(shd, -((int32_t)sh)); \ +} \ +\ +dfp.a.bits = ~DECSPECIAL; \ +decNumberShift(dfp.t, dfp.a, shd, dfp.context); \ +\ +dfp.t.bits |= special; \ +if (special (dfp.t.digits = max_digits)) { \ +dfp.t.digits = max_digits - 1; \ +} \ +\ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, \ + dfp.context);\ +} else {\ +if ((size) == 64) { \ +dfp.t64[0] = dfp.a64[0] 0xFFFCULL;\ +dfp_clear_lmd_from_g5msb(dfp.t64); \ +} else {\ +dfp.t64[HI_IDX] = dfp.a64[HI_IDX] \ + 0xC000ULL;\ +dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX); \ +dfp.t64[LO_IDX] = 0;\ +} \ +} \ +\ +if ((size) == 64) { \ +t[0] = dfp.t64[0]; \ +} else {\ +t[0] = dfp.t64[HI_IDX];
[Qemu-devel] [PATCH 36/37] target-ppc: Introduce DFP Insert Biased Exponent
Add emulation of the PowerPC Decimal Floating Point Insert Biased Exponent instructions diex[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 68 +++ target-ppc/helper.h |2 + target-ppc/translate.c |4 +++ 3 files changed, 74 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 327380e..98ced28 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -1162,3 +1162,71 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ DFP_HELPER_XEX(dxex, 64) DFP_HELPER_XEX(dxexq, 128) + +static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw) +{ +*t = 0x8003ULL; +*t |= (raw (63-13)); +} + +static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw) +{ +t[HI_IDX] = 0x80003fffULL; +t[HI_IDX] |= (raw (63-17)); +} + +#define DFP_HELPER_IEX(op, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ +{ \ +struct PPC_DFP dfp; \ +uint64_t raw_qnan, raw_snan, raw_inf, max_exp;\ +int bias; \ +int64_t exp = *((int64_t *)a);\ + \ +dfp_prepare_decimal##size(dfp, 0, b, env); \ + \ +if ((size) == 64) { \ +max_exp = 767;\ +raw_qnan = 0x1F00;\ +raw_snan = 0x1F80;\ +raw_inf = 0x1E00; \ +bias = 398; \ +} else if ((size) == 128) { \ +max_exp = 12287; \ +raw_qnan = 0x1f000; \ +raw_snan = 0x1f800; \ +raw_inf = 0x1e000;\ +bias = 6176; \ +} else { \ +assert(0);\ +} \ + \ +if (unlikely((exp 0) || (exp max_exp))) { \ +dfp.t64[0] = dfp.b64[0]; \ +dfp.t64[1] = dfp.b64[1]; \ +if (exp == -1) { \ +dfp_set_raw_exp_##size(dfp.t64, raw_inf); \ +} else if (exp == -3) { \ +dfp_set_raw_exp_##size(dfp.t64, raw_snan);\ +} else { \ +dfp_set_raw_exp_##size(dfp.t64, raw_qnan);\ +} \ +} else { \ +dfp.t = dfp.b;\ +if (unlikely(decNumberIsSpecial(dfp.t))) { \ +dfp.t.bits = ~DECSPECIAL;\ +} \ +dfp.t.exponent = exp - bias; \ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, \ + dfp.context); \ +} \ +if (size == 64) { \ +t[0] = dfp.t64[0];\ +} else if (size == 128) { \ +t[0] = dfp.t64[HI_IDX]; \ +t[1] = dfp.t64[LO_IDX]; \ +} \ +} + +DFP_HELPER_IEX(diex, 64) +DFP_HELPER_IEX(diexq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 77da769..03c86ce 100644 ---
[Qemu-devel] [PATCH 20/37] target-ppc: Introduce DFP Divide
Add emulation of the PowerPC Decimal Floating Point Divide instructions ddiv[q][.] Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 36 target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 42 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 3a4e041..a9b2bbb 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -229,6 +229,13 @@ static void dfp_check_for_XX(struct PPC_DFP *dfp) } } +static void dfp_check_for_ZX(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Division_by_zero) { +dfp_set_FPSCR_flag(dfp, FP_ZX, FP_ZE); +} +} + static void dfp_check_for_VXSNAN(struct PPC_DFP *dfp) { if (dfp-context.status DEC_Invalid_operation) { @@ -271,6 +278,21 @@ static void dfp_check_for_VXIMZ(struct PPC_DFP *dfp) } } +static void dfp_check_for_VXZDZ(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Division_undefined) { +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXZDZ, FP_VE); +} +} + +static void dfp_check_for_VXIDI(struct PPC_DFP *dfp) +{ +if (dfp-context.status DEC_Invalid_operation) { +if (decNumberIsInfinite(dfp-a) decNumberIsInfinite(dfp-b)) { +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXIDI, FP_VE); +} +} +} static void dfp_run_post_processors(struct PPC_DFP *dfp, PPC_DFP_PostProc post_processors[], const size_t n) @@ -333,3 +355,17 @@ PPC_DFP_PostProc MUL_PPs[] = { DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64) DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128) + +PPC_DFP_PostProc DIV_PPs[] = { +dfp_set_FPRF_from_FRT, +dfp_check_for_OX, +dfp_check_for_UX, +dfp_check_for_ZX, +dfp_check_for_XX, +dfp_check_for_VXSNAN, +dfp_check_for_VXZDZ, +dfp_check_for_VXIDI, +}; + +DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64) +DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 17c75ab..93342ea 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -624,4 +624,6 @@ DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp) DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp) DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp) DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp) +DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp) +DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index a36ead4..1c2c49f 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8362,6 +8362,8 @@ GEN_DFP_T_A_B_Rc(dsub) GEN_DFP_T_A_B_Rc(dsubq) GEN_DFP_T_A_B_Rc(dmul) GEN_DFP_T_A_B_Rc(dmulq) +GEN_DFP_T_A_B_Rc(ddiv) +GEN_DFP_T_A_B_Rc(ddivq) /*** SPE extension ***/ /* Register moves */ @@ -11295,6 +11297,8 @@ GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10), GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10), GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01), GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01), +GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11), +GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH 05/37] libdecnumber: Change gstdint.h to stdint.h
Replace the inclusion of gstdint.h with the standard stdint.h header file. Signed-off-by: Tom Musta tommu...@gmail.com --- include/libdecnumber/decContext.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/include/libdecnumber/decContext.h b/include/libdecnumber/decContext.h index 1a3f15e..c3e46f4 100644 --- a/include/libdecnumber/decContext.h +++ b/include/libdecnumber/decContext.h @@ -56,7 +56,7 @@ #define DECCFULLNAME Decimal Context Descriptor /* Verbose name */ #define DECCAUTHOR Mike Cowlishaw /* Who to blame */ - #include gstdint.h/* C99 standard integers */ + #include stdint.h #include stdio.h /* for printf, etc.*/ #include signal.h /* for traps */ -- 1.7.1
Re: [Qemu-devel] [RFC v2 3/6] vfio: add vfio-platform support
On Wed, 2014-04-09 at 16:33 +0100, Eric Auger wrote: From: Kim Phillips kim.phill...@linaro.org Functions for which PCI and platform device support share are moved into common.c. The common vfio_{get,put}_group() get an additional argument, a pointer to a vfio_reset_handler(), for which to pass on to qemu_register_reset, but only if it exists (the platform device code currently passes a NULL as its reset_handler). For the platform device code, we basically use SysBusDevice instead of PCIDevice. Since realize() returns void, unlike PCIDevice's initfn, error codes are moved into the error message text with %m. Currently only MMIO access is supported at this time. The perceived path for future QEMU development is: - add support for interrupts - verify and test platform dev unmap path - test existing PCI path for any regressions - add support for creating platform devices on the qemu command line - currently device address specification is hardcoded for test development on Calxeda Midway's fff51000.ethernet device - reset is not supported and registration of reset functions is bypassed for platform devices. - there is no standard means of resetting a platform device, unsure if it suffices to be handled at device--VFIO binding time Signed-off-by: Kim Phillips kim.phill...@linaro.org [1] http://www.spinics.net/lists/kvm-arm/msg08195.html --- hw/vfio/Makefile.objs | 2 + hw/vfio/common.c | 486 ++ hw/vfio/pci.c | 480 ++--- hw/vfio/platform.c| 381 +++ hw/vfio/vfio-common.h | 55 ++ 5 files changed, 937 insertions(+), 467 deletions(-) create mode 100644 hw/vfio/common.c create mode 100644 hw/vfio/platform.c create mode 100644 hw/vfio/vfio-common.h diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index 31c7dab..c5c76fe 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -1,3 +1,5 @@ ifeq ($(CONFIG_LINUX), y) +obj-$(CONFIG_SOFTMMU) += common.o obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_SOFTMMU) += platform.o endif diff --git a/hw/vfio/common.c b/hw/vfio/common.c new file mode 100644 index 000..9d1f723 --- /dev/null +++ b/hw/vfio/common.c @@ -0,0 +1,486 @@ +/* + * vfio based device assignment support + * + * Copyright Red Hat, Inc. 2012 + * + * Authors: + * Alex Williamson alex.william...@redhat.com + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Based on qemu-kvm device-assignment: + * Adapted for KVM by Qumranet. + * Copyright (c) 2007, Neocleus, Alex Novik (a...@neocleus.com) + * Copyright (c) 2007, Neocleus, Guy Zana (g...@neocleus.com) + * Copyright (C) 2008, Qumranet, Amit Shah (amit.s...@qumranet.com) + * Copyright (C) 2008, Red Hat, Amit Shah (amit.s...@redhat.com) + * Copyright (C) 2008, IBM, Muli Ben-Yehuda (m...@il.ibm.com) + */ + +#include dirent.h +#include linux/vfio.h +#include sys/ioctl.h +#include sys/mman.h +#include sys/stat.h +#include sys/types.h +#include unistd.h + +#include config.h +#include exec/address-spaces.h +#include exec/memory.h +#include hw/pci/msi.h +#include hw/pci/msix.h +#include hw/pci/pci.h I expect these pci includes aren't really needed +#include qemu-common.h +#include qemu/error-report.h +#include qemu/event_notifier.h +#include qemu/queue.h +#include qemu/range.h +#include sysemu/kvm.h +#include sysemu/sysemu.h + +#include vfio-common.h + +#define DEBUG_VFIO +#ifdef DEBUG_VFIO +#define DPRINTF(fmt, ...) \ +do { fprintf(stderr, vfio: fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ +do { } while (0) +#endif DEBUG_VFIO should probably be in vfio-common.h + +static QLIST_HEAD(, VFIOContainer) +container_list = QLIST_HEAD_INITIALIZER(container_list); + +QLIST_HEAD(, VFIOGroup) +group_list = QLIST_HEAD_INITIALIZER(group_list); + + +struct VFIODevice; I don't see where this is needed. + +#ifdef CONFIG_KVM +/* + * We have a single VFIO pseudo device per KVM VM. Once created it lives + * for the life of the VM. Closing the file descriptor only drops our + * reference to it and the device's reference to kvm. Therefore once + * initialized, this file descriptor is only released on QEMU exit and + * we'll re-use it should another vfio device be attached before then. + */ +static int vfio_kvm_device_fd = -1; +#endif + +/* + * DMA - Mapping and unmapping for the type1 IOMMU interface used on x86 + */ +static int vfio_dma_unmap(VFIOContainer *container, + hwaddr iova, ram_addr_t size) +{ +struct vfio_iommu_type1_dma_unmap unmap = { +.argsz = sizeof(unmap), +.flags = 0, +.iova = iova, +.size = size, +}; + +if (ioctl(container-fd,
Re: [Qemu-devel] [PATCH 0/4] Fix memory leaks in QEMU
On 18 April 2014 14:41, Kirill Batuzov batuz...@ispras.ru wrote: qemu_allocate_irqs: The most troublesome case. It will need its own patch series and I need some advices on how to deal with it. I would suggest that we should deal with this by converting from qemu_irq to a QOM property or link based interface for GPIO/IRQ lines. There's not much point in overhauling the IRQ APIs twice. Note that generally these leaks are not really leaks, because we set up the board and wire IRQs together once, and they remain that way for the lifetime of QEMU and are freed automatically when QEMU exits. thanks -- PMM
[Qemu-devel] [PATCH 15/37] target-ppc: Introduce DFP Helper Utilities
Add a new file (dfp_helper.c) to the PowerPC implementation for Decimal Floating Point (DFP) emulation. This first version of the file declares a structure that will be used by DFP helpers. It also implements utilities that will initialize such a structure for either a long (64 bit) DFP instruction or an extended (128 bit, aka quad) instruction. Some utility functions are annotated with the unused attribute in order to preserve build bisection. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/Makefile.objs |1 + target-ppc/dfp_helper.c | 132 ++ 2 files changed, 133 insertions(+), 0 deletions(-) create mode 100644 target-ppc/dfp_helper.c diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs index 3cb23e0..a7ae392 100644 --- a/target-ppc/Makefile.objs +++ b/target-ppc/Makefile.objs @@ -6,6 +6,7 @@ obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o endif obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o +obj-y += dfp_helper.o obj-y += excp_helper.o obj-y += fpu_helper.o obj-y += int_helper.o diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c new file mode 100644 index 000..18cf0cd --- /dev/null +++ b/target-ppc/dfp_helper.c @@ -0,0 +1,132 @@ +/* + * PowerPC Decimal Floating Point (DPF) emulation helpers for QEMU. + * + * Copyright (c) 2014 IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include cpu.h +#include helper.h + +#define DECNUMDIGITS 34 +#include libdecnumber/decContext.h +#include libdecnumber/decNumber.h +#include libdecnumber/dpd/decimal32.h +#include libdecnumber/dpd/decimal64.h +#include libdecnumber/dpd/decimal128.h + +#if defined(HOST_WORDS_BIGENDIAN) +#define HI_IDX 0 +#define LO_IDX 1 +#else +#define HI_IDX 1 +#define LO_IDX 0 +#endif + +struct PPC_DFP { +CPUPPCState *env; +uint64_t t64[2], a64[2], b64[2]; +decNumber t, a, b; +decContext context; +uint8_t crbf; +}; + +static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr) +{ +enum rounding rnd; + +switch ((fpscr 32) 0x7) { +case 0: +rnd = DEC_ROUND_HALF_EVEN; +break; +case 1: +rnd = DEC_ROUND_DOWN; +break; +case 2: + rnd = DEC_ROUND_CEILING; + break; +case 3: + rnd = DEC_ROUND_FLOOR; + break; +case 4: + rnd = DEC_ROUND_HALF_UP; + break; +case 5: + rnd = DEC_ROUND_HALF_DOWN; + break; +case 6: + rnd = DEC_ROUND_UP; + break; +case 7: + rnd = DEC_ROUND_05UP; + break; +} + +decContextSetRounding(context, rnd); +} + +__attribute__ ((unused)) +static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a, +uint64_t *b, CPUPPCState *env) +{ +decContextDefault(dfp-context, DEC_INIT_DECIMAL64); +dfp_prepare_rounding_mode(dfp-context, env-fpscr); +dfp-env = env; + +if (a) { +dfp-a64[0] = *a; +decimal64ToNumber((decimal64 *)dfp-a64, dfp-a); +} else { +dfp-a64[0] = 0; +decNumberZero(dfp-a); +} + +if (b) { +dfp-b64[0] = *b; +decimal64ToNumber((decimal64 *)dfp-b64, dfp-b); +} else { +dfp-b64[0] = 0; +decNumberZero(dfp-b); +} +} + +__attribute__ ((unused)) +static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a, +uint64_t *b, CPUPPCState *env) +{ +decContextDefault(dfp-context, DEC_INIT_DECIMAL128); +dfp_prepare_rounding_mode(dfp-context, env-fpscr); +dfp-env = env; + +if (a) { +dfp-a64[0] = a[HI_IDX]; +dfp-a64[1] = a[LO_IDX]; +decimal128ToNumber((decimal128 *)dfp-a64, dfp-a); +} else { +dfp-a64[0] = dfp-a64[1] = 0; +decNumberZero(dfp-a); +} + +if (b) { +dfp-b64[0] = b[HI_IDX]; +dfp-b64[1] = b[LO_IDX]; +decimal128ToNumber((decimal128 *)dfp-b64, dfp-b); +} else { +dfp-b64[0] = dfp-b64[1] = 0; +decNumberZero(dfp-b); +} +} + + -- 1.7.1
Re: [Qemu-devel] [PATCH v3 2/4] GlobalProperty: Display warning about unused -global
Hi Don, Am 25.03.2014 00:55, schrieb Don Slutz: This can help a user understand why -global was ignored. For example: with -vga cirrus; -global vga.vgamem_mb=16 is just ignored when -global cirrus-vga.vgamem_mb=16 is not. This is currently clear when the wrong property is provided: out/x86_64-softmmu/qemu-system-x86_64 -global cirrus-vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) qemu-system-x86_64: Property '.vram_size_mb' not found Aborted (core dumped) vs out/x86_64-softmmu/qemu-system-x86_64 -global vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) VNC server running on `::1:5900' ^Cqemu: terminating on signal 2 Signed-off-by: Don Slutz dsl...@verizon.com Improving this is greatly appreciated, thanks. Now, I can see two ways things can go wrong: a) Mistyping or later refactoring devices, or b) user typos or thinkos. And four ways to set globals: -global, config file (I hope?), legacy command line options (vl.c) and machine .compat_props. If a property does not exist on the instance of an existing type, object_property_parse() will raise an Error and we will abort in device_post_init(). What we are silently missing is if a type is misspelled; for that we can probably add an Error **errp to the two qdev_prop_register_global*() functions - assuming QOM types are already registered at that point. qom-test would help us catch any such mistake by instantiating each machine. I note that your proposed check is not failing, but still, with hot-add of e.g. PCI devices we might well get a global property default for a type that is not instantiated immediately but possibly used later on. --- hw/core/qdev-properties-system.c | 1 + hw/core/qdev-properties.c| 15 +++ include/hw/qdev-core.h | 1 + include/hw/qdev-properties.h | 1 + vl.c | 2 ++ 5 files changed, 20 insertions(+) FWIW I'd prefer qdev: for consistency (and yes, it's ambiguous), since there are no GlobalProperty files or directory. diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index de83561..9c742ca 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -444,6 +444,7 @@ static int qdev_add_one_global(QemuOpts *opts, void *opaque) g-driver = qemu_opt_get(opts, driver); g-property = qemu_opt_get(opts, property); g-value= qemu_opt_get(opts, value); +g-not_used = true; qdev_prop_register_global(g); return 0; } IIUC your patch relies on not_used being false in the non-QemuOpts case to avoid noise when using -nodefaults or pc*-x.y. Still, the C99 struct initializations elsewhere get that field as well, hmm. An alternative would be a separate linked list for user-supplied globals. diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index c67acf5..437c008 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -951,6 +951,20 @@ void qdev_prop_register_global_list(GlobalProperty *props) } } +void qdev_prop_check_global(void) +{ +GlobalProperty *prop; + +QTAILQ_FOREACH(prop, global_props, next) { +if (!prop-not_used) { +continue; +} +fprintf(stderr, Warning: \-global %s.%s=%s\ not used\n, +prop-driver, prop-property, prop-value); + +} +} + void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename, Error **errp) { @@ -962,6 +976,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename, if (strcmp(typename, prop-driver) != 0) { continue; } +prop-not_used = false; object_property_parse(OBJECT(dev), prop-value, prop-property, err); if (err != NULL) { error_propagate(errp, err); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index dbe473c..131fb49 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -235,6 +235,7 @@ typedef struct GlobalProperty { const char *driver; const char *property; const char *value; +bool not_used; QTAILQ_ENTRY(GlobalProperty) next; } GlobalProperty; diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index c46e908..fbca313 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -180,6 +180,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); void qdev_prop_register_global(GlobalProperty *prop); void qdev_prop_register_global_list(GlobalProperty *props); +void qdev_prop_check_global(void); void qdev_prop_set_globals(DeviceState *dev, Error **errp); void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
Re: [Qemu-devel] [PATCH] qemu-img: Exit with code 0 if there is no error
18.04.2014 18:29, Eric Blake wrote: On 04/18/2014 12:23 AM, Fam Zheng wrote: Signed-off-by: Fam Zheng f...@redhat.com --- qemu-img.c | 68 +++--- 1 file changed, 34 insertions(+), 34 deletions(-) /* Please keep in synch with qemu-img.texi */ -static void help(void) +static void help(bool error) This doesn't intuitively tell me whether 'true' is success (0 status) or failure (non-zero status). { const char *help_msg = qemu-img version QEMU_VERSION , Copyright (c) 2004-2008 Fabrice Bellard\n @@ -129,7 +129,7 @@ static void help(void) printf(%s\nSupported formats:, help_msg); bdrv_iterate_format(format_print, NULL); printf(\n); -exit(1); +exit(error ? 1 : 0); Oh - true for failure. I'd MUCH rather see: As I already pointed out in a comment for similar patch for ./configure, maybe it is better to _not_ print help output in case of error, because this way, the most important error message scrolls up the screen replaced by the help text. Instead, it might be better to say something like, run ./qemu-img --help for list of available options and exit non-zero in case of some option error instead of printing whole help text. This way, there's no need to pass anything to the help() function. Thanks, /mjt
[Qemu-devel] [PATCH 16/37] target-ppc: Introduce DFP Post Processor Utilities
Add post-processing utilities to the PowerPC Decimal Floating Point (DFP) helper code. Post-processors are small routines that execute after a preliminary DFP result is computed. They are used, among other things, to compute status bits. This change defines a function type for post processors as well as a generic routine to run a list (array) of post-processors. Actual post-processor implementations will be added as needed by specific DFP helpers in subsequent changes. Some routines are annotated with the GCC unused attribute in order to preserve build bisection. The annotation will be removed in subsequent patches. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 42 ++ 1 files changed, 42 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 18cf0cd..0c11696 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -129,4 +129,46 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a, } } +#define FP_FX (1ull FPSCR_FX) +#define FP_FEX (1ull FPSCR_FEX) +#define FP_OX (1ull FPSCR_OX) +#define FP_OE (1ull FPSCR_OE) +#define FP_UX (1ull FPSCR_UX) +#define FP_UE (1ull FPSCR_UE) +#define FP_XX (1ull FPSCR_XX) +#define FP_XE (1ull FPSCR_XE) +#define FP_ZX (1ull FPSCR_ZX) +#define FP_ZE (1ull FPSCR_ZE) +#define FP_VX (1ull FPSCR_VX) +#define FP_VXSNAN (1ull FPSCR_VXSNAN) +#define FP_VXISI(1ull FPSCR_VXISI) +#define FP_VXIMZ(1ull FPSCR_VXIMZ) +#define FP_VXZDZ(1ull FPSCR_VXZDZ) +#define FP_VXIDI(1ull FPSCR_VXIDI) +#define FP_VXVC (1ull FPSCR_VXVC) +#define FP_VXCVI(1ull FPSCR_VXCVI) +#define FP_VE (1ull FPSCR_VE) +#define FP_FI (1ull FPSCR_FI) +__attribute__ ((unused)) +static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag, +uint64_t enabled) +{ +dfp-env-fpscr |= (flag | FP_FX); +if (dfp-env-fpscr enabled) { +dfp-env-fpscr |= FP_FEX; +} +} + +typedef void (*PPC_DFP_PostProc)(struct PPC_DFP *); + +__attribute__ ((unused)) +static void dfp_run_post_processors(struct PPC_DFP *dfp, +PPC_DFP_PostProc post_processors[], const size_t n) +{ +int i; + +for (i = 0; i n; i++) { +post_processors[i](dfp); +} +} -- 1.7.1
[Qemu-devel] [PATCH 35/37] target-ppc: Introduce DFP Extract Biased Exponent
Add emulation of the PowerPC Decimal Floating Point Extract Biased Exponent instructions dxex[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 31 +++ target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 37 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 79729c9..327380e 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -1131,3 +1131,34 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \ DFP_HELPER_ENBCD(denbcd, 64) DFP_HELPER_ENBCD(denbcdq, 128) + +#define DFP_HELPER_XEX(op, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ +{ \ +struct PPC_DFP dfp;\ + \ +dfp_prepare_decimal##size(dfp, 0, b, env);\ + \ +if (unlikely(decNumberIsSpecial(dfp.b))) {\ +if (decNumberIsInfinite(dfp.b)) { \ +*t = -1; \ +} else if (decNumberIsSNaN(dfp.b)) { \ +*t = -3; \ +} else if (decNumberIsQNaN(dfp.b)) { \ +*t = -2; \ +} else { \ +assert(0); \ +} \ +} else { \ +if ((size) == 64) {\ +*t = dfp.b.exponent + 398; \ +} else if ((size) == 128) {\ +*t = dfp.b.exponent + 6176;\ +} else { \ +assert(0); \ +} \ +} \ +} + +DFP_HELPER_XEX(dxex, 64) +DFP_HELPER_XEX(dxexq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 98c8276..77da769 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -660,4 +660,6 @@ DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32) DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32) DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32) DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32) +DEF_HELPER_3(dxex, void, env, fprp, fprp) +DEF_HELPER_3(dxexq, void, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 6a2b51c..a975505 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8398,6 +8398,8 @@ GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP) GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP) GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP) GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP) +GEN_DFP_T_B_Rc(dxex) +GEN_DFP_T_B_Rc(dxexq) /*** SPE extension ***/ /* Register moves */ @@ -11367,6 +11369,8 @@ GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a), GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a), GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a), GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a), +GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b), +GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
Re: [Qemu-devel] [Xen-devel] [PATCH v3 2/4] GlobalProperty: Display warning about unused -global
2014-04-18 17:21 GMT+02:00 Andreas Färber afaer...@suse.de: Hi Don, Am 25.03.2014 00:55, schrieb Don Slutz: This can help a user understand why -global was ignored. For example: with -vga cirrus; -global vga.vgamem_mb=16 is just ignored when -global cirrus-vga.vgamem_mb=16 is not. This is currently clear when the wrong property is provided: out/x86_64-softmmu/qemu-system-x86_64 -global cirrus-vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) qemu-system-x86_64: Property '.vram_size_mb' not found Aborted (core dumped) vs out/x86_64-softmmu/qemu-system-x86_64 -global vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) VNC server running on `::1:5900' ^Cqemu: terminating on signal 2 I added the cirrus video memory setting in libxl time ago (using -global vga.vram_size_mb), testing it with qemu 1.3 and also on qemu 1.6 when I changed from -vga to -device if I remember good. Has been changed in recent versions or something was not right even though it seemed right to me? Thanks for any reply and sorry for my bad english. Signed-off-by: Don Slutz dsl...@verizon.com Improving this is greatly appreciated, thanks. Now, I can see two ways things can go wrong: a) Mistyping or later refactoring devices, or b) user typos or thinkos. And four ways to set globals: -global, config file (I hope?), legacy command line options (vl.c) and machine .compat_props. If a property does not exist on the instance of an existing type, object_property_parse() will raise an Error and we will abort in device_post_init(). What we are silently missing is if a type is misspelled; for that we can probably add an Error **errp to the two qdev_prop_register_global*() functions - assuming QOM types are already registered at that point. qom-test would help us catch any such mistake by instantiating each machine. I note that your proposed check is not failing, but still, with hot-add of e.g. PCI devices we might well get a global property default for a type that is not instantiated immediately but possibly used later on. --- hw/core/qdev-properties-system.c | 1 + hw/core/qdev-properties.c| 15 +++ include/hw/qdev-core.h | 1 + include/hw/qdev-properties.h | 1 + vl.c | 2 ++ 5 files changed, 20 insertions(+) FWIW I'd prefer qdev: for consistency (and yes, it's ambiguous), since there are no GlobalProperty files or directory. diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index de83561..9c742ca 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -444,6 +444,7 @@ static int qdev_add_one_global(QemuOpts *opts, void *opaque) g-driver = qemu_opt_get(opts, driver); g-property = qemu_opt_get(opts, property); g-value= qemu_opt_get(opts, value); +g-not_used = true; qdev_prop_register_global(g); return 0; } IIUC your patch relies on not_used being false in the non-QemuOpts case to avoid noise when using -nodefaults or pc*-x.y. Still, the C99 struct initializations elsewhere get that field as well, hmm. An alternative would be a separate linked list for user-supplied globals. diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index c67acf5..437c008 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -951,6 +951,20 @@ void qdev_prop_register_global_list(GlobalProperty *props) } } +void qdev_prop_check_global(void) +{ +GlobalProperty *prop; + +QTAILQ_FOREACH(prop, global_props, next) { +if (!prop-not_used) { +continue; +} +fprintf(stderr, Warning: \-global %s.%s=%s\ not used\n, +prop-driver, prop-property, prop-value); + +} +} + void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename, Error **errp) { @@ -962,6 +976,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename, if (strcmp(typename, prop-driver) != 0) { continue; } +prop-not_used = false; object_property_parse(OBJECT(dev), prop-value, prop-property, err); if (err != NULL) { error_propagate(errp, err); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index dbe473c..131fb49 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -235,6 +235,7 @@ typedef struct GlobalProperty { const char *driver; const char *property; const char *value; +bool not_used; QTAILQ_ENTRY(GlobalProperty) next; } GlobalProperty; diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index c46e908..fbca313
[Qemu-devel] [PATCH 23/37] target-ppc: Introduce DFP Test Data Group
Add emulation of the PowerPC Decimal Floating Point Test Data Group instructions dtstdg[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 55 +++ target-ppc/helper.h |2 + target-ppc/translate.c |4 +++ 3 files changed, 61 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 625df93..ad24d05 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -457,3 +457,58 @@ uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)\ DFP_HELPER_TSTDC(dtstdc, 64) DFP_HELPER_TSTDC(dtstdcq, 128) + +#define DFP_HELPER_TSTDG(op, size) \ +uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)\ +{\ +struct PPC_DFP dfp; \ +int minexp, maxexp, nzero_digits, nzero_idx, is_negative, is_zero, \ +is_extreme_exp, is_subnormal, is_normal, leftmost_is_nonzero,\ +match; \ + \ +dfp_prepare_decimal##size(dfp, a, 0, env); \ + \ +if ((size) == 64) { \ +minexp = -398; \ +maxexp = 369;\ +nzero_digits = 16; \ +nzero_idx = 5; \ +} else if ((size) == 128) { \ +minexp = -6176; \ +maxexp = 6111; \ +nzero_digits = 34; \ +nzero_idx = 11; \ +}\ + \ +is_negative = decNumberIsNegative(dfp.a); \ +is_zero = decNumberIsZero(dfp.a); \ +is_extreme_exp = (dfp.a.exponent == maxexp) || \ + (dfp.a.exponent == minexp); \ +is_subnormal = decNumberIsSubnormal(dfp.a, dfp.context); \ +is_normal = decNumberIsNormal(dfp.a, dfp.context); \ +leftmost_is_nonzero = (dfp.a.digits == nzero_digits) \ + (dfp.a.lsu[nzero_idx] != 0); \ +match = 0; \ + \ +match |= (dcm 0x20) is_zero !is_extreme_exp; \ +match |= (dcm 0x10) is_zero is_extreme_exp; \ +match |= (dcm 0x08) \ + (is_subnormal || (is_normal is_extreme_exp));\ +match |= (dcm 0x04) is_normal !is_extreme_exp \ + !leftmost_is_nonzero; \ +match |= (dcm 0x02) is_normal !is_extreme_exp \ + leftmost_is_nonzero;\ +match |= (dcm 0x01) decNumberIsSpecial(dfp.a); \ + \ +if (is_negative) { \ +dfp.crbf = match ? 0xA : 0x8;\ +} else { \ +dfp.crbf = match ? 0x2 : 0x0;\ +}\ + \ +dfp_run_post_processors(dfp, DTST_PPs, ARRAY_SIZE(DTST_PPs)); \ +return dfp.crbf; \ +} + +DFP_HELPER_TSTDG(dtstdg, 64) +DFP_HELPER_TSTDG(dtstdgq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 95d5a36..8c0c5d5 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -632,4 +632,6 @@ DEF_HELPER_3(dcmpu, i32, env, fprp, fprp) DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp) DEF_HELPER_3(dtstdc, i32, env, fprp, i32) DEF_HELPER_3(dtstdcq, i32, env, fprp, i32) +DEF_HELPER_3(dtstdg, i32, env, fprp, i32) +DEF_HELPER_3(dtstdgq, i32, env, fprp, i32) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index
[Qemu-devel] [PATCH 25/37] target-ppc: Introduce DFP Test Significance
Add emulation of the PowerPC Decimal Floating Point Test Significance instructions dtstsf[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 35 +++ target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 41 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index fa62164..eb6e041 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -544,3 +544,38 @@ uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \ DFP_HELPER_TSTEX(dtstex, 64) DFP_HELPER_TSTEX(dtstexq, 128) + +#define DFP_HELPER_TSTSF(op, size) \ +uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \ +{\ +struct PPC_DFP dfp; \ +unsigned k; \ + \ +dfp_prepare_decimal##size(dfp, 0, b, env); \ + \ +k = *a 0x3F; \ + \ +if (unlikely(decNumberIsSpecial(dfp.b))) { \ +dfp.crbf = 1;\ +} else if (k == 0) { \ +dfp.crbf = 4;\ +} else if (unlikely(decNumberIsZero(dfp.b))) { \ +/* Zero has no sig digits */ \ +dfp.crbf = 4;\ +} else { \ +unsigned nsd = dfp.b.digits; \ +if (k nsd) { \ +dfp.crbf = 8;\ +} else if (k nsd) {\ +dfp.crbf = 4;\ +} else { \ +dfp.crbf = 2;\ +}\ +}\ + \ +dfp_run_post_processors(dfp, DTST_PPs, ARRAY_SIZE(DTST_PPs)); \ +return dfp.crbf; \ +} + +DFP_HELPER_TSTSF(dtstsf, 64) +DFP_HELPER_TSTSF(dtstsfq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index af9d9c9..182e871 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -636,4 +636,6 @@ DEF_HELPER_3(dtstdg, i32, env, fprp, i32) DEF_HELPER_3(dtstdgq, i32, env, fprp, i32) DEF_HELPER_3(dtstex, i32, env, fprp, fprp) DEF_HELPER_3(dtstexq, i32, env, fprp, fprp) +DEF_HELPER_3(dtstsf, i32, env, fprp, fprp) +DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 510c2a7..d059802 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8374,6 +8374,8 @@ GEN_DFP_BF_A_DCM(dtstdg) GEN_DFP_BF_A_DCM(dtstdgq) GEN_DFP_BF_A_B(dtstex) GEN_DFP_BF_A_B(dtstexq) +GEN_DFP_BF_A_B(dtstsf) +GEN_DFP_BF_A_B(dtstsfq) /*** SPE extension ***/ /* Register moves */ @@ -11319,6 +11321,8 @@ GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07), GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07), GEN_DFP_BF_A_B(dtstex, 0x02, 0x05), GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05), +GEN_DFP_BF_A_B(dtstsf, 0x02, 0x15), +GEN_DFP_BF_A_Bp(dtstsfq, 0x02, 0x15), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
Re: [Qemu-devel] [PATCH v3 3/4] pc q35: Add new object pc-memory-layout.
Am 25.03.2014 00:55, schrieb Don Slutz: This new object has the property max-ram-below-4g. If you add enough PCI devices then all mmio for them will not fit below 4G which may not be the layout the user wanted. This allows you to increase the below 4G address space that PCI devices can use (aka decrease ram below 4G) and therefore in more cases not have any mmio that is above 4G. For example adding -global pc-memory-layout.max-ram-below-4g=2G to the command line will limit the amount of ram that is below 4G to 2G. Signed-off-by: Don Slutz dsl...@verizon.com --- hw/i386/pc.c | 42 ++ hw/i386/pc_piix.c| 23 +-- hw/i386/pc_q35.c | 23 +-- include/hw/i386/pc.h | 2 ++ 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 14f0d91..45339f3 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1429,3 +1429,45 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) gsi_state-ioapic_irq[i] = qdev_get_gpio_in(dev, i); } } + +/* pc-memory-layout stuff */ + +typedef struct PcMemoryLayoutState PcMemoryLayoutState; PCMemoryLayoutState? + +/** + * @PcMemoryLayoutState: Please drop @. + */ +struct PcMemoryLayoutState { +/* private */ +Object parent_obj; +/* public */ + +uint64_t max_ram_below_4g; +}; + +static Property pc_memory_layout_props[] = { +DEFINE_PROP_SIZE(max-ram-below-4g, PcMemoryLayoutState, + max_ram_below_4g, 0), +DEFINE_PROP_END_OF_LIST(), +}; + +static void pc_memory_layout_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); + +dc-props = pc_memory_layout_props; +} + +static const TypeInfo pc_memory_layout_info = { +.name = TYPE_PC_MEMORY_LAYOUT, +.parent = TYPE_DEVICE, +.instance_size = sizeof(PcMemoryLayoutState), +.class_init = pc_memory_layout_class_init, +}; + +static void pc_memory_layout_register_types(void) +{ +type_register_static(pc_memory_layout_info); +} + +type_init(pc_memory_layout_register_types) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index bd52f6e..81d730d 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -95,6 +95,23 @@ static void pc_init1(QEMUMachineInitArgs *args, DeviceState *icc_bridge; FWCfgState *fw_cfg = NULL; PcGuestInfo *guest_info; +Object *pc_memory_layout; +uint64_t max_ram_below_4g; +ram_addr_t lowmem = 0xe000; + +pc_memory_layout = object_new(TYPE_PC_MEMORY_LAYOUT); +max_ram_below_4g = object_property_get_int(pc_memory_layout, + max-ram-below-4g, + NULL); +if (max_ram_below_4g) { Isn't this always zero due to the default value? +if (max_ram_below_4g (1ULL 32)) { +fprintf(stderr, +%s: max_ram_below_4g=%lld too big adjusted to %lld\n, +__func__, (long long)max_ram_below_4g, 1ULL 32); Is this forgotten debug output? For a user, __func__ is not helpful and error_report() would be preferable. Also please just use PRIx64 for max_ram_below_4g rather than casting. +max_ram_below_4g = 1ULL 32; +} +lowmem = max_ram_below_4g; +} /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory). * If it doesn't, we need to split it in chunks below and above 4G. @@ -103,8 +120,10 @@ static void pc_init1(QEMUMachineInitArgs *args, * For old machine types, use whatever split we used historically to avoid * breaking migration. */ -if (args-ram_size = 0xe000) { -ram_addr_t lowmem = gigabyte_align ? 0xc000 : 0xe000; +if (args-ram_size = lowmem) { +if (!max_ram_below_4g gigabyte_align) { +lowmem = 0xc000; +} above_4g_mem_size = args-ram_size - lowmem; below_4g_mem_size = lowmem; } else { We don't have central, recursive realization of devices yet. That means your device is instantiated but never realized, and while you're not exposing any global state it allows to tweak the property value throughout device lifetime. Also you're forgetting to add this device to the composition tree via object_property_add_child(). Neither ACPI code nor future QOM code can discover it that way. diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 6e34fe1..529f53d 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -82,6 +82,23 @@ static void pc_q35_init(QEMUMachineInitArgs *args) PCIDevice *ahci; DeviceState *icc_bridge; PcGuestInfo *guest_info; +Object *pc_memory_layout; +uint64_t max_ram_below_4g; +ram_addr_t lowmem = 0xb000; + +pc_memory_layout = object_new(TYPE_PC_MEMORY_LAYOUT); +
Re: [Qemu-devel] [PATCH v2] glib: fix g_poll early timeout on windows
Please see my remarks below. Am 18.04.2014 13:51, schrieb Stanislav Vorobiov: From: Sangho Park sangho1206.p...@samsung.com g_poll has a problem on windows when using timeouts 10ms, in glib/gpoll.c: /* If not, and we have a significant timeout, poll again with * timeout then. Note that this will return indication for only * one event, or only for messages. We ignore timeouts less than * ten milliseconds as they are mostly pointless on Windows, the * MsgWaitForMultipleObjectsEx() call will timeout right away * anyway. */ if (retval == 0 (timeout == INFINITE || timeout = 10)) retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); so whenever g_poll is called with timeout 10ms it does a quick poll instead of wait, this causes significant performance degradation of qemu, thus we should use WaitForMultipleObjectsEx directly Signed-off-by: Stanislav Vorobiov s.vorob...@samsung.com --- include/glib-compat.h | 19 + include/qemu-common.h | 12 -- util/oslib-win32.c| 112 + 3 files changed, 131 insertions(+), 12 deletions(-) diff --git a/include/glib-compat.h b/include/glib-compat.h index 8aa77af..2d4258e 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -24,4 +24,23 @@ static inline guint g_timeout_add_seconds(guint interval, GSourceFunc function, } #endif +#ifdef _WIN32 +/* + * g_poll has a problem on windows when using + * timeouts 10ms, so use wrapper. + */ +#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, qemu_timeout_ns_to_ms(timeout)) qemu_timeout_ns_to_ms is not needed here (g_poll is called with timeout given in ms, and so is g_poll_fixed). +gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout_ms); +#elif !GLIB_CHECK_VERSION(2, 20, 0) +/* + * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly + * on older systems. + */ +static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) +{ +GMainContext *ctx = g_main_context_default(); +return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); +} +#endif + #endif diff --git a/include/qemu-common.h b/include/qemu-common.h index a998e8d..3f3fd60 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -124,18 +124,6 @@ int qemu_main(int argc, char **argv, char **envp); void qemu_get_timedate(struct tm *tm, int offset); int qemu_timedate_diff(struct tm *tm); -#if !GLIB_CHECK_VERSION(2, 20, 0) -/* - * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly - * on older systems. - */ -static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) -{ -GMainContext *ctx = g_main_context_default(); -return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); -} -#endif - /** * is_help_option: * @s: string to test diff --git a/util/oslib-win32.c b/util/oslib-win32.c index 93f7d35..006259e 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -238,3 +238,115 @@ char *qemu_get_exec_dir(void) { return g_strdup(exec_dir); } + +/* + * g_poll has a problem on windows when using Windows + * timeouts 10ms, in glib/gpoll.c: + * + * // If not, and we have a significant timeout, poll again with + * // timeout then. Note that this will return indication for only + * // one event, or only for messages. We ignore timeouts less than + * // ten milliseconds as they are mostly pointless on Windows, the + * // MsgWaitForMultipleObjectsEx() call will timeout right away + * // anyway. + * + * if (retval == 0 (timeout == INFINITE || timeout = 10)) + * retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); + * + * So whenever g_poll is called with timeout 10ms it does + * a quick poll instead of wait, this causes significant performance + * degradation of qemu, thus we should use WaitForMultipleObjectsEx QEMU + * directly + */ +gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout_ms) +{ +guint i; +HANDLE handles[MAXIMUM_WAIT_OBJECTS]; +gint nhandles = 0; +int num_completed = 0; + +for (i = 0; i nfds; i++) { +gint j; + +if (fds[i].fd = 0) { +continue; +} + +/* don't add same handle several times + */ +for (j = 0; j nhandles; j++) { +if (handles[j] == (HANDLE)fds[i].fd) { +break; +} +} + +if (j == nhandles) { +if (nhandles == MAXIMUM_WAIT_OBJECTS) { +fprintf(stderr, Too many handles to wait for!\n); +break; +} else { +handles[nhandles++] = (HANDLE)fds[i].fd; +} +} +} + +for (i = 0; i nfds; ++i) { +fds[i].revents = 0; +} + +if (timeout_ms == -1) { +timeout_ms = INFINITE; +} + +if (nhandles == 0) { +
[Qemu-devel] [PATCH 28/37] target-ppc: Introduce DFP Round to Integer
Add emulation of the PowerPC Decimal Floating Point (DFP) Round to FP Integer With Inexact (drintx[q][.]) and DFP Round to FP Integer Without Inexact (drintn[q][.]) instructions. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 38 ++ target-ppc/helper.h |4 target-ppc/translate.c |8 3 files changed, 50 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index d2031b8..5c60492 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -807,3 +807,41 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,\ DFP_HELPER_RRND(drrnd, 64) DFP_HELPER_RRND(drrndq, 128) + +#define DFP_HELPER_RINT(op, postprocs, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \ + uint32_t r, uint32_t rmc) \ +{ \ +struct PPC_DFP dfp; \ + \ +dfp_prepare_decimal##size(dfp, 0, b, env); \ + \ +dfp_set_round_mode_from_immediate(r, rmc, dfp); \ +decNumberToIntegralExact(dfp.t, dfp.b, dfp.context); \ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, dfp.context); \ +dfp_run_post_processors(dfp, postprocs, ARRAY_SIZE(postprocs)); \ + \ +if (size == 64) { \ +t[0] = dfp.t64[0]; \ +} else if (size == 128) { \ +t[0] = dfp.t64[HI_IDX]; \ +t[1] = dfp.t64[LO_IDX]; \ +} \ +} + +PPC_DFP_PostProc RINTX_PPs[] = { +dfp_set_FPRF_from_FRT, +dfp_check_for_XX, +dfp_check_for_VXSNAN, +}; + +DFP_HELPER_RINT(drintx, RINTX_PPs, 64) +DFP_HELPER_RINT(drintxq, RINTX_PPs, 128) + +PPC_DFP_PostProc RINTN_PPs[] = { +dfp_set_FPRF_from_FRT, +dfp_check_for_VXSNAN, +}; + +DFP_HELPER_RINT(drintn, RINTN_PPs, 64) +DFP_HELPER_RINT(drintnq, RINTN_PPs, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index b63affb..2ef18c2 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -644,4 +644,8 @@ DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32) DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32) DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32) DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32) +DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32) +DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32) +DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32) +DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 3738012..65b1503 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8382,6 +8382,10 @@ GEN_DFP_T_A_B_I32_Rc(dqua, RMC) GEN_DFP_T_A_B_I32_Rc(dquaq, RMC) GEN_DFP_T_A_B_I32_Rc(drrnd, RMC) GEN_DFP_T_A_B_I32_Rc(drrndq, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC) /*** SPE extension ***/ /* Register moves */ @@ -11335,6 +11339,10 @@ GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00), GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00), GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01), GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01), +GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03), +GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03), +GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07), +GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
Re: [Qemu-devel] [Xen-devel] [PATCH v3 2/4] GlobalProperty: Display warning about unused -global
Am 18.04.2014 17:36, schrieb Fabio Fantoni: 2014-04-18 17:21 GMT+02:00 Andreas Färber afaer...@suse.de mailto:afaer...@suse.de: Hi Don, Am 25.03.2014 00 tel:25.03.2014%2000:55, schrieb Don Slutz: This can help a user understand why -global was ignored. For example: with -vga cirrus; -global vga.vgamem_mb=16 is just ignored when -global cirrus-vga.vgamem_mb=16 is not. This is currently clear when the wrong property is provided: out/x86_64-softmmu/qemu-system-x86_64 -global cirrus-vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) qemu-system-x86_64: Property '.vram_size_mb' not found Aborted (core dumped) vs out/x86_64-softmmu/qemu-system-x86_64 -global vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) VNC server running on `::1:5900' ^Cqemu: terminating on signal 2 I added the cirrus video memory setting in libxl time ago (using -global vga.vram_size_mb), testing it with qemu 1.3 and also on qemu 1.6 when I changed from -vga to -device if I remember good. Has been changed in recent versions or something was not right even though it seemed right to me? There are multiple graphics cards to choose from. When using -vga std or -device vga, then -global vga.foo=bar gets used; if -vga cirrus or -device cirrus-vga then it needs to be -global cirrus-vga.foo=bar and any -global vga.foo=bar gets ignored - unless you manage to add it as secondary (PCI) graphics card. Regards, Andreas P.S. Please remember to use text format mails. -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH 22/37] target-ppc: Introduce DFP Test Data Class
Add emulation of the PowerPC Decimal Floating Point Test Data Class instructions dtstdc[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 32 target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 38 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 87163dd..625df93 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -425,3 +425,35 @@ PPC_DFP_PostProc CMPO_PPs[] = { DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64) DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128) + +PPC_DFP_PostProc DTST_PPs[] = { +dfp_set_FPCC_from_CRBF, +}; + +#define DFP_HELPER_TSTDC(op, size) \ +uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)\ +{\ +struct PPC_DFP dfp; \ +int match = 0; \ + \ +dfp_prepare_decimal##size(dfp, a, 0, env); \ + \ +match |= (dcm 0x20) decNumberIsZero(dfp.a);\ +match |= (dcm 0x10) decNumberIsSubnormal(dfp.a, dfp.context); \ +match |= (dcm 0x08) decNumberIsNormal(dfp.a, dfp.context);\ +match |= (dcm 0x04) decNumberIsInfinite(dfp.a);\ +match |= (dcm 0x02) decNumberIsQNaN(dfp.a);\ +match |= (dcm 0x01) decNumberIsSNaN(dfp.a);\ + \ +if (decNumberIsNegative(dfp.a)) { \ +dfp.crbf = match ? 0xA : 0x8;\ +} else { \ +dfp.crbf = match ? 0x2 : 0x0;\ +}\ + \ +dfp_run_post_processors(dfp, DTST_PPs, ARRAY_SIZE(DTST_PPs)); \ +return dfp.crbf; \ +} + +DFP_HELPER_TSTDC(dtstdc, 64) +DFP_HELPER_TSTDC(dtstdcq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 68ac7a0..95d5a36 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -630,4 +630,6 @@ DEF_HELPER_3(dcmpo, i32, env, fprp, fprp) DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp) DEF_HELPER_3(dcmpu, i32, env, fprp, fprp) DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp) +DEF_HELPER_3(dtstdc, i32, env, fprp, i32) +DEF_HELPER_3(dtstdcq, i32, env, fprp, i32) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index ccc5a83..b4bc126 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8368,6 +8368,8 @@ GEN_DFP_BF_A_B(dcmpu) GEN_DFP_BF_A_B(dcmpuq) GEN_DFP_BF_A_B(dcmpo) GEN_DFP_BF_A_B(dcmpoq) +GEN_DFP_BF_A_DCM(dtstdc) +GEN_DFP_BF_A_DCM(dtstdcq) /*** SPE extension ***/ /* Register moves */ @@ -11307,6 +11309,8 @@ GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14), GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14), GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04), GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04), +GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06), +GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH 21/37] target-ppc: Introduce DFP Compares
Add emulation of the PowerPC Decimal Floating Point Compare instructions dcmpu[q] and dcmpo[q]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 56 +++ target-ppc/helper.h |4 +++ target-ppc/translate.c |8 ++ 3 files changed, 68 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index a9b2bbb..87163dd 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -294,6 +294,32 @@ static void dfp_check_for_VXIDI(struct PPC_DFP *dfp) } } +static void dfp_check_for_VXVC(struct PPC_DFP *dfp) +{ +if (decNumberIsNaN(dfp-a) || decNumberIsNaN(dfp-b)) { +dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXVC, FP_VE); +} +} + +static void dfp_set_CRBF_from_T(struct PPC_DFP *dfp) +{ +if (decNumberIsNaN(dfp-t)) { +dfp-crbf = 1; +} else if (decNumberIsZero(dfp-t)) { +dfp-crbf = 2; +} else if (decNumberIsNegative(dfp-t)) { +dfp-crbf = 8; +} else { +dfp-crbf = 4; +} +} + +static void dfp_set_FPCC_from_CRBF(struct PPC_DFP *dfp) +{ +dfp-env-fpscr = ~(0xF 12); +dfp-env-fpscr |= (dfp-crbf 12); +} + static void dfp_run_post_processors(struct PPC_DFP *dfp, PPC_DFP_PostProc post_processors[], const size_t n) { @@ -369,3 +395,33 @@ PPC_DFP_PostProc DIV_PPs[] = { DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64) DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128) + +#define DFP_HELPER_BF_AB(op, dnop, postprocs, size) \ +uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \ +{ \ +struct PPC_DFP dfp; \ +dfp_prepare_decimal##size(dfp, a, b, env); \ +dnop(dfp.t, dfp.a, dfp.b, dfp.context); \ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, dfp.context); \ +dfp_run_post_processors(dfp, postprocs, ARRAY_SIZE(postprocs)); \ +return dfp.crbf; \ +} + +PPC_DFP_PostProc CMPU_PPs[] = { +dfp_set_CRBF_from_T, +dfp_set_FPCC_from_CRBF, +dfp_check_for_VXSNAN, +}; + +DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64) +DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128) + +PPC_DFP_PostProc CMPO_PPs[] = { +dfp_set_CRBF_from_T, +dfp_set_FPCC_from_CRBF, +dfp_check_for_VXSNAN, +dfp_check_for_VXVC, +}; + +DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64) +DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 93342ea..68ac7a0 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -626,4 +626,8 @@ DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp) DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp) DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp) DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp) +DEF_HELPER_3(dcmpo, i32, env, fprp, fprp) +DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp) +DEF_HELPER_3(dcmpu, i32, env, fprp, fprp) +DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 1c2c49f..ccc5a83 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8364,6 +8364,10 @@ GEN_DFP_T_A_B_Rc(dmul) GEN_DFP_T_A_B_Rc(dmulq) GEN_DFP_T_A_B_Rc(ddiv) GEN_DFP_T_A_B_Rc(ddivq) +GEN_DFP_BF_A_B(dcmpu) +GEN_DFP_BF_A_B(dcmpuq) +GEN_DFP_BF_A_B(dcmpo) +GEN_DFP_BF_A_B(dcmpoq) /*** SPE extension ***/ /* Register moves */ @@ -11299,6 +11303,10 @@ GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01), GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01), GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11), GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11), +GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14), +GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14), +GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04), +GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
Re: [Qemu-devel] [PATCH v3 4/4] xen-all: Pass max_ram_below_4g to xen_hvm_init.
Am 25.03.2014 00:55, schrieb Don Slutz: This is the xen part of pc q35: Add new object pc-memory-layout. Signed-off-by: Don Slutz dsl...@verizon.com --- v3: Adjust for code readability. Set max_ram_below_4g always and use it to calculate above_4g_mem_size, below_4g_mem_size. hw/i386/pc_piix.c| 4 ++-- hw/i386/pc_q35.c | 4 ++-- include/hw/xen/xen.h | 4 ++-- xen-all.c| 40 +--- xen-stub.c | 4 ++-- 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 81d730d..8a93548 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -131,8 +131,8 @@ static void pc_init1(QEMUMachineInitArgs *args, below_4g_mem_size = args-ram_size; } -if (xen_enabled() xen_hvm_init(below_4g_mem_size, above_4g_mem_size, - ram_memory) != 0) { +if (xen_enabled() xen_hvm_init(max_ram_below_4g, below_4g_mem_size, + above_4g_mem_size, ram_memory) != 0) { fprintf(stderr, xen hardware virtual machine initialisation failed\n); exit(1); } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 529f53d..09e98e6 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -120,8 +120,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args) below_4g_mem_size = args-ram_size; } -if (xen_enabled() xen_hvm_init(below_4g_mem_size, above_4g_mem_size, - ram_memory) != 0) { +if (xen_enabled() xen_hvm_init(max_ram_below_4g, below_4g_mem_size, + above_4g_mem_size, ram_memory) != 0) { fprintf(stderr, xen hardware virtual machine initialisation failed\n); exit(1); } diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 0f3942e..eca39a5 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -40,8 +40,8 @@ int xen_init(QEMUMachine *machine); void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); #if defined(NEED_CPU_H) !defined(CONFIG_USER_ONLY) -int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, - MemoryRegion **ram_memory); +int xen_hvm_init(ram_addr_t max_ram_below_4g, ram_addr_t *below_4g_mem_size, + ram_addr_t *above_4g_mem_size, MemoryRegion **ram_memory); void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, struct MemoryRegion *mr); void xen_modified_memory(ram_addr_t start, ram_addr_t length); diff --git a/xen-all.c b/xen-all.c index c64300c..3f6f890 100644 --- a/xen-all.c +++ b/xen-all.c @@ -155,31 +155,32 @@ qemu_irq *xen_interrupt_controller_init(void) /* Memory Ops */ -static void xen_ram_init(ram_addr_t *below_4g_mem_size, +static void xen_ram_init(ram_addr_t ram_size, ram_addr_t max_ram_below_4g, + ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, - ram_addr_t ram_size, MemoryRegion **ram_memory_p) + MemoryRegion **ram_memory_p) { MemoryRegion *sysmem = get_system_memory(); ram_addr_t block_len; -block_len = ram_size; -if (ram_size = HVM_BELOW_4G_RAM_END) { -/* Xen does not allocate the memory continuously, and keep a hole at - * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH - */ -block_len += HVM_BELOW_4G_MMIO_LENGTH; -} -memory_region_init_ram(ram_memory, NULL, xen.ram, block_len); -*ram_memory_p = ram_memory; -vmstate_register_ram_global(ram_memory); - -if (ram_size = HVM_BELOW_4G_RAM_END) { -*above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; -*below_4g_mem_size = HVM_BELOW_4G_RAM_END; +max_ram_below_4g = max_ram_below_4g ? max_ram_below_4g : HVM_BELOW_4G_RAM_END; Isn't max_ram_below_4g still always zero at this point? Are you guys still using your own Xen machine types? Then you could set a compat_props entry for all (not just legacy) machines to override the actual pc-memory-layout max-ram-below-4g property value to avoid the ?: here. Especially since I'm not seeing this modified value being written back to the device. Considering that machines are objects now, might it be easier to set this property on the machine object itself rather than having an unused stub object hanging in limbo? Would create a dependency on Marcel's series though (which like this series I now need to start reviewing). +if (ram_size = max_ram_below_4g) { +*above_4g_mem_size = ram_size - max_ram_below_4g; +*below_4g_mem_size = max_ram_below_4g; } else { *above_4g_mem_size = 0; *below_4g_mem_size = ram_size; } +if (!*above_4g_mem_size) { +block_len = ram_size; +} else { +/* Xen
[Qemu-devel] [PATCH 30/37] target-ppc: Introduce Round to DFP Short/Long
Add emulation of the PowerPC Round to DFP Short (drsp[.]) and Round to DFP Long (drdpq[.]) instructions. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 52 +++ target-ppc/helper.h |2 + target-ppc/translate.c |4 +++ 3 files changed, 58 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index a719797..25afaba 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -249,6 +249,20 @@ static void dfp_set_FPRF_from_FRT(struct PPC_DFP *dfp) dfp_set_FPRF_from_FRT_with_context(dfp, dfp-context); } +static void dfp_set_FPRF_from_FRT_short(struct PPC_DFP *dfp) +{ +decContext shortContext; +decContextDefault(shortContext, DEC_INIT_DECIMAL32); +dfp_set_FPRF_from_FRT_with_context(dfp, shortContext); +} + +static void dfp_set_FPRF_from_FRT_long(struct PPC_DFP *dfp) +{ +decContext longContext; +decContextDefault(longContext, DEC_INIT_DECIMAL64); +dfp_set_FPRF_from_FRT_with_context(dfp, longContext); +} + static void dfp_check_for_OX(struct PPC_DFP *dfp) { if (dfp-context.status DEC_Overflow) { @@ -880,3 +894,41 @@ void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b) t[0] = dfp.t64[HI_IDX]; t[1] = dfp.t64[LO_IDX]; } + +PPC_DFP_PostProc RSP_PPs[] = { +dfp_set_FPRF_from_FRT_short, +dfp_check_for_OX, +dfp_check_for_UX, +dfp_check_for_XX, +}; + +void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b) +{ +struct PPC_DFP dfp; +uint32_t t_short = 0; +dfp_prepare_decimal64(dfp, 0, b, env); +decimal32FromNumber((decimal32 *)t_short, dfp.b, dfp.context); +decimal32ToNumber((decimal32 *)t_short, dfp.t); +dfp_run_post_processors(dfp, RSP_PPs, ARRAY_SIZE(RSP_PPs)); +*t = t_short; +} + +PPC_DFP_PostProc RDPQ_PPs[] = { +dfp_check_for_VXSNAN_and_convert_to_QNaN, +dfp_set_FPRF_from_FRT_long, +dfp_check_for_OX, +dfp_check_for_UX, +dfp_check_for_XX, +}; + +void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b) +{ +struct PPC_DFP dfp; +dfp_prepare_decimal128(dfp, 0, b, env); +decimal64FromNumber((decimal64 *)dfp.t64, dfp.b, dfp.context); +decimal64ToNumber((decimal64 *)dfp.t64, dfp.t); +dfp_run_post_processors(dfp, RDPQ_PPs, ARRAY_SIZE(RDPQ_PPs)); +decimal64FromNumber((decimal64 *)dfp.t64, dfp.t, dfp.context); +t[0] = dfp.t64[0]; +t[1] = 0; +} diff --git a/target-ppc/helper.h b/target-ppc/helper.h index a99ca1c..d9ef8f6 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -650,4 +650,6 @@ DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32) DEF_HELPER_3(dctdp, void, env, fprp, fprp) DEF_HELPER_3(dctqpq, void, env, fprp, fprp) +DEF_HELPER_3(drsp, void, env, fprp, fprp) +DEF_HELPER_3(drdpq, void, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index da70c8d..391f55d 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8388,6 +8388,8 @@ GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC) GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC) GEN_DFP_T_B_Rc(dctdp) GEN_DFP_T_B_Rc(dctqpq) +GEN_DFP_T_B_Rc(drsp) +GEN_DFP_T_B_Rc(drdpq) /*** SPE extension ***/ /* Register moves */ @@ -11347,6 +11349,8 @@ GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07), GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07), GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08), GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08), +GEN_DFP_T_B_Rc(drsp, 0x02, 0x18), +GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
[Qemu-devel] [PATCH v3] glib: fix g_poll early timeout on windows
From: Sangho Park sangho1206.p...@samsung.com g_poll has a problem on Windows when using timeouts 10ms, in glib/gpoll.c: /* If not, and we have a significant timeout, poll again with * timeout then. Note that this will return indication for only * one event, or only for messages. We ignore timeouts less than * ten milliseconds as they are mostly pointless on Windows, the * MsgWaitForMultipleObjectsEx() call will timeout right away * anyway. */ if (retval == 0 (timeout == INFINITE || timeout = 10)) retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); so whenever g_poll is called with timeout 10ms it does a quick poll instead of wait, this causes significant performance degradation of QEMU, thus we should use WaitForMultipleObjectsEx directly Signed-off-by: Stanislav Vorobiov s.vorob...@samsung.com --- include/glib-compat.h | 19 + include/qemu-common.h | 12 -- util/oslib-win32.c| 112 + 3 files changed, 131 insertions(+), 12 deletions(-) diff --git a/include/glib-compat.h b/include/glib-compat.h index 8aa77af..1280fb2 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -24,4 +24,23 @@ static inline guint g_timeout_add_seconds(guint interval, GSourceFunc function, } #endif +#ifdef _WIN32 +/* + * g_poll has a problem on Windows when using + * timeouts 10ms, so use wrapper. + */ +#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, timeout) +gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); +#elif !GLIB_CHECK_VERSION(2, 20, 0) +/* + * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly + * on older systems. + */ +static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) +{ +GMainContext *ctx = g_main_context_default(); +return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); +} +#endif + #endif diff --git a/include/qemu-common.h b/include/qemu-common.h index a998e8d..3f3fd60 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -124,18 +124,6 @@ int qemu_main(int argc, char **argv, char **envp); void qemu_get_timedate(struct tm *tm, int offset); int qemu_timedate_diff(struct tm *tm); -#if !GLIB_CHECK_VERSION(2, 20, 0) -/* - * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly - * on older systems. - */ -static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) -{ -GMainContext *ctx = g_main_context_default(); -return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); -} -#endif - /** * is_help_option: * @s: string to test diff --git a/util/oslib-win32.c b/util/oslib-win32.c index 93f7d35..fa1f451 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -238,3 +238,115 @@ char *qemu_get_exec_dir(void) { return g_strdup(exec_dir); } + +/* + * g_poll has a problem on Windows when using + * timeouts 10ms, in glib/gpoll.c: + * + * // If not, and we have a significant timeout, poll again with + * // timeout then. Note that this will return indication for only + * // one event, or only for messages. We ignore timeouts less than + * // ten milliseconds as they are mostly pointless on Windows, the + * // MsgWaitForMultipleObjectsEx() call will timeout right away + * // anyway. + * + * if (retval == 0 (timeout == INFINITE || timeout = 10)) + * retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); + * + * So whenever g_poll is called with timeout 10ms it does + * a quick poll instead of wait, this causes significant performance + * degradation of QEMU, thus we should use WaitForMultipleObjectsEx + * directly + */ +gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout) +{ +guint i; +HANDLE handles[MAXIMUM_WAIT_OBJECTS]; +gint nhandles = 0; +int num_completed = 0; + +for (i = 0; i nfds; i++) { +gint j; + +if (fds[i].fd = 0) { +continue; +} + +/* don't add same handle several times + */ +for (j = 0; j nhandles; j++) { +if (handles[j] == (HANDLE)fds[i].fd) { +break; +} +} + +if (j == nhandles) { +if (nhandles == MAXIMUM_WAIT_OBJECTS) { +fprintf(stderr, Too many handles to wait for!\n); +break; +} else { +handles[nhandles++] = (HANDLE)fds[i].fd; +} +} +} + +for (i = 0; i nfds; ++i) { +fds[i].revents = 0; +} + +if (timeout == -1) { +timeout = INFINITE; +} + +if (nhandles == 0) { +if (timeout == INFINITE) { +return -1; +} else { +SleepEx(timeout, TRUE); +return 0; +} +} + +while (1) { +DWORD res; +gint j; + +res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, +timeout, TRUE); + +if (res == WAIT_FAILED) { +for (i = 0; i nfds; ++i) { +
Re: [Qemu-devel] [PATCH 1/4] Replace acpi_pcihp_get_bsel with generic object_property_get_int
Am 18.04.2014 15:41, schrieb Kirill Batuzov: acpi_pcihp_get_bsel implements functionality of object_property_get_int for specific property named ACPI_PCIHP_PROP_BSEL, but fails to decrement object's reference counter properly. Replacing it with generic object_property_get_int serves two purposes: reducing code duplication and fixing memory leak. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- hw/acpi/pcihp.c | 23 ++- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index f80c480..ff44aec 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -61,24 +61,11 @@ typedef struct AcpiPciHpFind { PCIBus *bus; } AcpiPciHpFind; -static int acpi_pcihp_get_bsel(PCIBus *bus) -{ -QObject *o = object_property_get_qobject(OBJECT(bus), - ACPI_PCIHP_PROP_BSEL, NULL); -int64_t bsel = -1; -if (o) { -bsel = qint_get_int(qobject_to_qint(o)); -} -if (bsel 0) { -return -1; -} -return bsel; -} - static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque) { AcpiPciHpFind *find = opaque; -if (find-bsel == acpi_pcihp_get_bsel(bus)) { +if (find-bsel == object_property_get_int(OBJECT(bus), + ACPI_PCIHP_PROP_BSEL, NULL)) { find-bus = bus; } } I note that the wrapper function was changing negative values up to be -1, which is getting dropped here. Not sure if it matters. @@ -185,7 +172,8 @@ void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, { PCIDevice *pdev = PCI_DEVICE(dev); int slot = PCI_SLOT(pdev-devfn); -int bsel = acpi_pcihp_get_bsel(pdev-bus); +int bsel = object_property_get_int(OBJECT(pdev-bus), + ACPI_PCIHP_PROP_BSEL, NULL); if (bsel 0) { error_setg(errp, Unsupported bus. Bus doesn't have property ' ACPI_PCIHP_PROP_BSEL ' set); @@ -210,7 +198,8 @@ void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, { PCIDevice *pdev = PCI_DEVICE(dev); int slot = PCI_SLOT(pdev-devfn); -int bsel = acpi_pcihp_get_bsel(pdev-bus); +int bsel = object_property_get_int(OBJECT(pdev-bus), + ACPI_PCIHP_PROP_BSEL, NULL); if (bsel 0) { error_setg(errp, Unsupported bus. Bus doesn't have property ' ACPI_PCIHP_PROP_BSEL ' set); These ones seem to just check for 0, so look okay from reading the patch. CC'ing mst. The alternative would be to leave the wrapper around and just replace the ..._get_qobject() with the ..._get_int() inside. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH 31/37] target-ppc: Introduce DFP Convert to Fixed
Add emulation of the PowerPC Decimal Floating Point Convert to Fixed instructions dctfix[q][.]. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 25 + target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 31 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 25afaba..ea9ef15 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -932,3 +932,28 @@ void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b) t[0] = dfp.t64[0]; t[1] = 0; } + +#define DFP_HELPER_CFFIX(op, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ +{ \ +struct PPC_DFP dfp; \ +dfp_prepare_decimal##size(dfp, 0, b, env); \ +decNumberFromInt64(dfp.t, (int64_t)(*b)); \ +decimal##size##FromNumber((decimal##size *)dfp.t64, dfp.t, dfp.context); \ +dfp_run_post_processors(dfp, CFFIX_PPs, ARRAY_SIZE(CFFIX_PPs)); \ + \ +if (size == 64) { \ +t[0] = dfp.t64[0]; \ +} else if (size == 128) { \ +t[0] = dfp.t64[HI_IDX]; \ +t[1] = dfp.t64[LO_IDX]; \ +} \ +} + +PPC_DFP_PostProc CFFIX_PPs[] = { +dfp_set_FPRF_from_FRT, +dfp_check_for_XX, +}; + +DFP_HELPER_CFFIX(dcffix, 64) +DFP_HELPER_CFFIX(dcffixq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index d9ef8f6..0f64fb8 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -652,4 +652,6 @@ DEF_HELPER_3(dctdp, void, env, fprp, fprp) DEF_HELPER_3(dctqpq, void, env, fprp, fprp) DEF_HELPER_3(drsp, void, env, fprp, fprp) DEF_HELPER_3(drdpq, void, env, fprp, fprp) +DEF_HELPER_3(dcffix, void, env, fprp, fprp) +DEF_HELPER_3(dcffixq, void, env, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 391f55d..76682f6 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8390,6 +8390,8 @@ GEN_DFP_T_B_Rc(dctdp) GEN_DFP_T_B_Rc(dctqpq) GEN_DFP_T_B_Rc(drsp) GEN_DFP_T_B_Rc(drdpq) +GEN_DFP_T_B_Rc(dcffix) +GEN_DFP_T_B_Rc(dcffixq) /*** SPE extension ***/ /* Register moves */ @@ -11351,6 +11353,8 @@ GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08), GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08), GEN_DFP_T_B_Rc(drsp, 0x02, 0x18), GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18), +GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19), +GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
Re: [Qemu-devel] [PATCH 3/4] graphic_console_init: do not receive unneeded error descriptions
Am 18.04.2014 15:41, schrieb Kirill Batuzov: Error set by error_set is dynamically allocated and needs to be cleared properly later. graphic_console_init neither needs error descriptions nor frees them. Pass NULL instead of actual pointers to avoid unnecessary memory allocations. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- ui/console.c |7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ui/console.c b/ui/console.c index e057755..438b6bd 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1590,7 +1590,6 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, const GraphicHwOps *hw_ops, void *opaque) { -Error *local_err = NULL; int width = 640; int height = 480; QemuConsole *s; @@ -1602,10 +1601,8 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, s-hw_ops = hw_ops; s-hw = opaque; if (dev) { -object_property_set_link(OBJECT(s), OBJECT(dev), - device, local_err); -object_property_set_int(OBJECT(s), head, -head, local_err); +object_property_set_link(OBJECT(s), OBJECT(dev), device, NULL); +object_property_set_int(OBJECT(s), head, head, NULL); I guess it would be better to use error_abort rather than failing silently. CC'ing Gerd. Regards, Andreas } s-surface = qemu_create_displaysurface(width, height); -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH 18/37] target-ppc: Introduce DFP Subtract
Add emulation of the PowerPC Decimal Floating Point Subtract instructions dsub[q][.] Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/dfp_helper.c | 18 ++ target-ppc/helper.h |2 ++ target-ppc/translate.c |5 - 3 files changed, 24 insertions(+), 1 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 100b0d7..7fd7724 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -256,6 +256,12 @@ static void dfp_check_for_VXISI_add(struct PPC_DFP *dfp) dfp_check_for_VXISI(dfp, 0); } +static void dfp_check_for_VXISI_subtract(struct PPC_DFP *dfp) +{ +dfp_check_for_VXISI(dfp, 1); +} + + static void dfp_run_post_processors(struct PPC_DFP *dfp, PPC_DFP_PostProc post_processors[], const size_t n) { @@ -293,3 +299,15 @@ PPC_DFP_PostProc ADD_PPs[] = { DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64) DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128) + +PPC_DFP_PostProc SUB_PPs[] = { +dfp_set_FPRF_from_FRT, +dfp_check_for_OX, +dfp_check_for_UX, +dfp_check_for_XX, +dfp_check_for_VXSNAN, +dfp_check_for_VXISI_subtract, +}; + +DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64) +DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 337c005..7ae8d03 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -620,4 +620,6 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl) DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp) DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp) +DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp) +DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp) #include exec/def-helper.h diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 4550667..80dc53c 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8358,7 +8358,8 @@ static void gen_##name(DisasContext *ctx) \ GEN_DFP_T_A_B_Rc(dadd) GEN_DFP_T_A_B_Rc(daddq) - +GEN_DFP_T_A_B_Rc(dsub) +GEN_DFP_T_A_B_Rc(dsubq) /*** SPE extension ***/ /* Register moves */ @@ -11288,6 +11289,8 @@ _GEN_DFP_QUADx2(name, op1, op2, 0x0021) GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00), GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00), +GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10), +GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1
Re: [Qemu-devel] [PATCH 4/4] PortioList: fix PortioList uses so they do not leak memory
Am 18.04.2014 15:41, schrieb Kirill Batuzov: PortioList is an abstraction used for construction of MemoryRegionPortioList from MemoryRegionPortio. It is not needed later, so there is no need to allocate it dynamically. Also portio_list_destroy should be called to free memory allocated in portio_list_init. This change spans several target platforms. The following testcases cover all changed lines: qemu-system-ppc -M prep qemu-system-i386 -vga qxl qemu-system-i386 -M isapc -soundhw adlib -device ib700,id=watchdog0,bus=isa.0 Signed-off-by: Kirill Batuzov batuz...@ispras.ru Your changes look correct, but I'm not sure about our future plans with this API. CC'ing some people to help review this. Regards, Andreas --- hw/audio/adlib.c|7 --- hw/display/qxl.c|9 + hw/display/vga.c| 16 +--- hw/dma/i82374.c |7 --- hw/isa/isa-bus.c|7 --- hw/ppc/prep.c |7 --- hw/watchdog/wdt_ib700.c |7 --- 7 files changed, 34 insertions(+), 26 deletions(-) Coding style in adlib.c slightly differs from QEMU coding style. Particularly there are spaces between function name and parenthesis. I decided to not mix coding styles, but as a result checkpatch.pl complains on this patch. diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 28eed81..e43d990 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -293,7 +293,7 @@ static MemoryRegionPortio adlib_portio_list[] = { static void adlib_realizefn (DeviceState *dev, Error **errp) { AdlibState *s = ADLIB(dev); -PortioList *port_list = g_new(PortioList, 1); +PortioList port_list; struct audsettings as; if (glob_adlib) { @@ -349,8 +349,9 @@ static void adlib_realizefn (DeviceState *dev, Error **errp) adlib_portio_list[0].offset = s-port; adlib_portio_list[1].offset = s-port + 8; -portio_list_init (port_list, OBJECT(s), adlib_portio_list, s, adlib); -portio_list_add (port_list, isa_address_space_io(s-parent_obj), 0); +portio_list_init (port_list, OBJECT(s), adlib_portio_list, s, adlib); +portio_list_add (port_list, isa_address_space_io(s-parent_obj), 0); +portio_list_destroy (port_list); } static Property adlib_properties[] = { diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 47bbf1f..7a361c7 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2055,7 +2055,7 @@ static int qxl_init_primary(PCIDevice *dev) { PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev); VGACommonState *vga = qxl-vga; -PortioList *qxl_vga_port_list = g_new(PortioList, 1); +PortioList qxl_vga_port_list; int rc; qxl-id = 0; @@ -2064,10 +2064,11 @@ static int qxl_init_primary(PCIDevice *dev) vga_common_init(vga, OBJECT(dev)); vga_init(vga, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), false); -portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list, +portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list, vga, vga); -portio_list_set_flush_coalesced(qxl_vga_port_list); -portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0); +portio_list_set_flush_coalesced(qxl_vga_port_list); +portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0); +portio_list_destroy(qxl_vga_port_list); vga-con = graphic_console_init(DEVICE(dev), 0, qxl_ops, qxl); qemu_spice_display_init_common(qxl-ssd); diff --git a/hw/display/vga.c b/hw/display/vga.c index 063319d..72feafd 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -2351,8 +2351,8 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, { MemoryRegion *vga_io_memory; const MemoryRegionPortio *vga_ports, *vbe_ports; -PortioList *vga_port_list = g_new(PortioList, 1); -PortioList *vbe_port_list = g_new(PortioList, 1); +PortioList vga_port_list; +PortioList vbe_port_list; qemu_register_reset(vga_reset, s); @@ -2367,13 +2367,15 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, 1); memory_region_set_coalescing(vga_io_memory); if (init_vga_ports) { -portio_list_init(vga_port_list, obj, vga_ports, s, vga); -portio_list_set_flush_coalesced(vga_port_list); -portio_list_add(vga_port_list, address_space_io, 0x3b0); +portio_list_init(vga_port_list, obj, vga_ports, s, vga); +portio_list_set_flush_coalesced(vga_port_list); +portio_list_add(vga_port_list, address_space_io, 0x3b0); +portio_list_destroy(vga_port_list); } if (vbe_ports) { -portio_list_init(vbe_port_list, obj, vbe_ports, s, vbe); -portio_list_add(vbe_port_list, address_space_io, 0x1ce); +
Re: [Qemu-devel] [Xen-devel] [PATCH v3 2/4] GlobalProperty: Display warning about unused -global
Il 18/04/2014 17:59, Andreas Färber ha scritto: Am 18.04.2014 17:36, schrieb Fabio Fantoni: 2014-04-18 17:21 GMT+02:00 Andreas Färber afaer...@suse.de mailto:afaer...@suse.de: Hi Don, Am 25.03.2014 00 tel:25.03.2014%2000:55, schrieb Don Slutz: This can help a user understand why -global was ignored. For example: with -vga cirrus; -global vga.vgamem_mb=16 is just ignored when -global cirrus-vga.vgamem_mb=16 is not. This is currently clear when the wrong property is provided: out/x86_64-softmmu/qemu-system-x86_64 -global cirrus-vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) qemu-system-x86_64: Property '.vram_size_mb' not found Aborted (core dumped) vs out/x86_64-softmmu/qemu-system-x86_64 -global vga.vram_size_mb=16 -monitor pty -vga cirrus char device redirected to /dev/pts/20 (label compat_monitor0) VNC server running on `::1:5900' ^Cqemu: terminating on signal 2 I added the cirrus video memory setting in libxl time ago (using -global vga.vram_size_mb), testing it with qemu 1.3 and also on qemu 1.6 when I changed from -vga to -device if I remember good. Has been changed in recent versions or something was not right even though it seemed right to me? There are multiple graphics cards to choose from. When using -vga std or -device vga, then -global vga.foo=bar gets used; if -vga cirrus or -device cirrus-vga then it needs to be -global cirrus-vga.foo=bar and any -global vga.foo=bar gets ignored - unless you manage to add it as secondary (PCI) graphics card. Thanks for your reply. Can you tell me if also -device cirrus-vga,vram_size_mb=N is correct and working? Thanks for any reply. Regards, Andreas P.S. Please remember to use text format mails.
Re: [Qemu-devel] [PATCH 0/4] Fix memory leaks in QEMU
Note that generally these leaks are not really leaks, because we set up the board and wire IRQs together once, and they remain that way for the lifetime of QEMU and are freed automatically when QEMU exits. Unfortunately they are really leaks. As I said qemu_allocate_irqs allocates two chunks of memory, not one. This is what happening. qemu_allocate_irqs calls qemu_extend_irqs which starts allocating memory: (old is NULL and n_old is 0 here) s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n); p = old ? g_renew(struct IRQState, s[0], n + n_old) : g_new(struct IRQState, n); We'll call the first chunk S, and the second P. I have capitalized letters to avoid confusion with variable names. Chunk P indeed will be wired, but chunk S will be leaked. What happens next: for (i = 0; i n + n_old; i++) { if (i = n_old) { p-handler = handler; p-opaque = opaque; p-n = i; } s[i] = p; p++; } Now chunk S has pointers to chunk P stored in it. After that s (a pointer to chunk S) is returned to the caller. return s; Let's have a look at the caller. Suppose it was omap2420_mpu_init. Here is the code: s-wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0]; qemu_allocate_irqs returned pointer to chunk S. It got immediately dereferenced. Result of this dereference - a pointer to P - is written to s-wakeup. But all pointers to chunk S are lost. We have a memory leak. And something like this happens every time qemu_allocate_irqs is called. -- Kirill
Re: [Qemu-devel] [PATCH 1/4] Replace acpi_pcihp_get_bsel with generic object_property_get_int
Andreas Färber писал 2014-04-18 20:30: Am 18.04.2014 15:41, schrieb Kirill Batuzov: acpi_pcihp_get_bsel implements functionality of object_property_get_int for specific property named ACPI_PCIHP_PROP_BSEL, but fails to decrement object's reference counter properly. Replacing it with generic object_property_get_int serves two purposes: reducing code duplication and fixing memory leak. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- hw/acpi/pcihp.c | 23 ++- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index f80c480..ff44aec 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -61,24 +61,11 @@ typedef struct AcpiPciHpFind { PCIBus *bus; } AcpiPciHpFind; -static int acpi_pcihp_get_bsel(PCIBus *bus) -{ -QObject *o = object_property_get_qobject(OBJECT(bus), - ACPI_PCIHP_PROP_BSEL, NULL); -int64_t bsel = -1; -if (o) { -bsel = qint_get_int(qobject_to_qint(o)); -} -if (bsel 0) { -return -1; -} -return bsel; -} - static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque) { AcpiPciHpFind *find = opaque; -if (find-bsel == acpi_pcihp_get_bsel(bus)) { +if (find-bsel == object_property_get_int(OBJECT(bus), + ACPI_PCIHP_PROP_BSEL, NULL)) { find-bus = bus; } } I note that the wrapper function was changing negative values up to be -1, which is getting dropped here. Not sure if it matters. ACPI_PCIHP_PROP_BSEL is unsigned 32 bit integer, so it can not be negative. object_property_get_int returns int64_t, so even overflow can not cause negative values to appear. @@ -185,7 +172,8 @@ void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, { PCIDevice *pdev = PCI_DEVICE(dev); int slot = PCI_SLOT(pdev-devfn); -int bsel = acpi_pcihp_get_bsel(pdev-bus); +int bsel = object_property_get_int(OBJECT(pdev-bus), + ACPI_PCIHP_PROP_BSEL, NULL); if (bsel 0) { error_setg(errp, Unsupported bus. Bus doesn't have property ' ACPI_PCIHP_PROP_BSEL ' set); @@ -210,7 +198,8 @@ void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, { PCIDevice *pdev = PCI_DEVICE(dev); int slot = PCI_SLOT(pdev-devfn); -int bsel = acpi_pcihp_get_bsel(pdev-bus); +int bsel = object_property_get_int(OBJECT(pdev-bus), + ACPI_PCIHP_PROP_BSEL, NULL); if (bsel 0) { error_setg(errp, Unsupported bus. Bus doesn't have property ' ACPI_PCIHP_PROP_BSEL ' set); These ones seem to just check for 0, so look okay from reading the patch. CC'ing mst. The alternative would be to leave the wrapper around and just replace the ..._get_qobject() with the ..._get_int() inside. Regards, Andreas
[Qemu-devel] [Bug 1308542] Re: hang in qemu_gluster_init
glfs_init cannot be called before since it checks for cmds_args-volfile_server which is allocated only in glfs_set_volfile_server. We should either modify glfs_fini or define a new function to do the cleanup based on if init is done or not. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1308542 Title: hang in qemu_gluster_init Status in QEMU: New Bug description: In qemu_gluster_init, if the call to either glfs_set_volfile_server or glfs_set_logging fails into the out case, glfs_fini is called without having first calling glfs_init. This causes glfs_lock to spin forever on this bit: while (!fs-init) pthread_cond_wait (fs-cond, fs-mutex); And here's the bottom part of the backtrace when hung: #0 pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:183 #1 0x7feceebf58c3 in glfs_lock (fs=0x7fecf15660b0) at glfs-internal.h:156 #2 glfs_active_subvol (fs=0x7fecf15660b0) at glfs-resolve.c:799 #3 0x7feceebeb5b4 in glfs_fini (fs=0x7fecf15660b0) at glfs.c:652 #4 0x7fecf0043c73 in qemu_gluster_init (gconf=value optimized out, filename=value optimized out) at /usr/src/debug/qemu-kvm-0.12.1.2/block/gluster.c:229 I believe this can be fixed by simply moving the call to glfs_init after the call to glfs_new but before the calls to glfs_set_volfile_server or glfs_set_logging. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1308542/+subscriptions
Re: [Qemu-devel] [PATCH 0/4] Fix memory leaks in QEMU
On 18 April 2014 18:08, Kirill Batuzov batuz...@ispras.ru wrote: And something like this happens every time qemu_allocate_irqs is called. Which generally only happens in the board init stage, ie once. So why care? Leaks are interesting if they happen in code that could be called multiple times (eg for hotplugged devices). A handful of bytes which we only allocate once is irrelevant: it gets freed on QEMU exit anyway. As I say, we will at some point want to overhaul the qemu_irq APIs to more QOM like behaviour, which gets us a bunch of nice things like properly named inputs and outputs and maybe ability to wire things up via config file or command line; and as a side effect we should end up with the corresponding allocations being tracked. But until we get to that, there really isn't a practical problem with the current approach for board level IRQ wiring. If we're leaking IRQ related memory in hotpluggable device init/deinit that might be worth fixing. thanks -- PMM
Re: [Qemu-devel] qemu + rbd block driver with cache=writeback, is live migration safe ?
Thanks Kevin for for the full explain! cache.writeback=on,cache.direct=off,cache.no-flush=off I didn't known about the cache options split,thanks. rbd does, to my knowledge, not use the kernel page cache, so we're safe from that part. It does however honour the cache.direct flag when it decides whether to use its own cache. rbd doesn't implement bdrv_invalidate_cache() in order to clear that cache when migration completes. Maybe some ceph devs could comment about this ? No, such a QMP command doesn't exist, though it would be possible to implement (for toggling cache.direct, that is; cache.writeback is guest visible and can therefore only be toggled by the guest) yes, that's what I have in mind, toggling cache.direct=on before migration, then disable it after the migration. - Mail original - De: Kevin Wolf kw...@redhat.com À: Alexandre DERUMIER aderum...@odiso.com Cc: qemu-devel qemu-devel@nongnu.org, ceph-us...@lists.ceph.com Envoyé: Mardi 15 Avril 2014 11:36:22 Objet: Re: [Qemu-devel] qemu + rbd block driver with cache=writeback, is live migration safe ? Am 12.04.2014 um 17:01 hat Alexandre DERUMIER geschrieben: Hello, I known that qemu live migration with disk with cache=writeback are not safe with storage like nfs,iscsi... Is it also true with rbd ? First of all, in order to avoid misunderstandings, let's be clear that there are three dimensions for the cache configuration of qemu block devices. In current versions, they are separately configurable and cache=writeback really expands to: cache.writeback=on,cache.direct=off,cache.no-flush=off The problematic part of this for live migration is generally not cache.writeback being enabled, but cache.direct being disabled. The reason for that is that the destination host will open the image file immediately, because it needs things like the image size to correctly initialise the emulated disk devices. Now during the migration the source keeps working on the image, so if qemu read some metadata on the destination host, that metadata may be stale by the time that the migration actually completes. In order to solve this problem, qemu calls bdrv_invalidate_cache(), which throws away everything that is cached in qemu so that it is reread from the image. However, this is ineffective if there are other caches having stale data, such as the kernel page cache. cache.direct bypasses the kernel page cache, so this is why it's important in many cases. rbd does, to my knowledge, not use the kernel page cache, so we're safe from that part. It does however honour the cache.direct flag when it decides whether to use its own cache. rbd doesn't implement bdrv_invalidate_cache() in order to clear that cache when migration completes. So the answer to your original question is that it's probably _not_ safe to use live migration with rbd and cache.direct=off. If yes, it is possible to disable manually writeback online with qmp ? No, such a QMP command doesn't exist, though it would be possible to implement (for toggling cache.direct, that is; cache.writeback is guest visible and can therefore only be toggled by the guest). Kevin
Re: [Qemu-devel] [PATCH 09/37] libdecnumber: Introduce decNumberFrom[U]Int64
On 04/18/2014 07:50 AM, Tom Musta wrote: +uint64_t unsig; +if (in = 0) { +unsig = in; +} else { /* negative (possibly BADINT) */ +if (in == INT64_MIN) { +unsig = 1ull 63; /* special case */ +} else { +unsig = -in; /* invert */ +} +} I know the other code you imported does this but... ug. How about just uint64_t unsig = in; if (in 0) { unsig = -unsig; } which neatly handles the INT_MIN thing in a defined way. r~
Re: [Qemu-devel] AArch64: QEMU fails in swapcontext
On 18/04/2014 16:44, Richard Henderson wrote: On 04/18/2014 07:00 AM, Mian M. Hamayun wrote: Hello Peter All, I am trying to figure out a problem in qemu on aarch64 (with kvm enabled). I have found this problem in many different versions of qemu (v2.0.0-rc3/rc2/rc1/rc0, master 2d03b49), and I believe that either I am missing something common in all of these versions or its a genuine bug in qemu on aarch64. The problem is triggered by virtqueue_notify() function (in virtio_ring.c) from the guest kernel and fails in the qemu_coroutine_new() while trying to do the swapcontext(old_uc, uc) (see coroutine-ucontext.c:164). The sigsetjmp(old_env, 0) just before the swapcontext() call seems to work fine, as it returns 0, and then we invoke the swapcontext(). The host kernel reports: qemu-system-aar[596]: bad frame in sys_rt_sigreturn: pc=004462e0 sp=7f8020f000 and kills the qemu process due to segmentation fault. The pc=004462e0 is for the coroutine_trampoline() but we don't actually reach it, when this particular crash happens. Just to give you an idea of the code I am talking about: $~/qemu[master]$ git blame -L 159,166 coroutine-ucontext.c 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 159) makecontext(uc, (void (*)(void))coroutine_trampoline, 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 160) 2, arg.i[0], arg.i[1]); 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 161) 6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 162) /* swapcontext() in, siglongjmp() back out */ 6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 163) if (!sigsetjmp(old_env, 0)) { 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 164) swapcontext(old_uc, uc); 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 165) } 00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 166) return co-base; My qemu configure/run commands are: ./configure --target-list=aarch64-softmmu \ --cross-prefix=aarch64-linux-gnu- \ --enable-fdt *--enable-kvm* --disable-werror \ --audio-drv-list= --static ./qemu-system-aarch64 \ *-enable-kvm* -nographic -kernel Image\ -drive if=none,file=disk_oe64.img,id=fs \ -device virtio-blk-device,drive=fs \ -m 1024 -M virt -cpu host \ -append earlyprintk console=ttyAMA0 mem=1024M rootwait root=/dev/vda rw init=/bin/sh Any ideas/comments on how to resolve this issue? Note that a patch has just gone into glibc to rewrite setcontext et al for aarch64. I'd try using git glibc before looking too much deeper. r~ It seems right to me as well, as the setcontext related bug (for aarch64) has recently been posted/fixed in glibc: https://sourceware.org/bugzilla/show_bug.cgi?id=16629 I have also tested the example posted at: https://sourceware.org/bugzilla/attachment.cgi?id=7435 and I get the following output on x86_64: start f2 start f1 finish f2 finish f1 {ss_sp: (nil), ss_flags: 2, ss_size: 0} {ss_sp: (nil), ss_flags: 2, ss_size: 0} and this one on AArch64: start f2 start f1 finish f2 finish f1 {ss_sp: (nil), ss_flags: 2, ss_size: 0} *{ss_sp: 0x7ff7e723f0, ss_flags: 0, ss_size: 8192}* I will first look into updating my glibc for AArch64 before coming back to qemu. Thanks for your support, Hamayun
Re: [Qemu-devel] [PATCH 17/37] target-ppc: Introduce DFP Add
On 04/18/2014 07:50 AM, Tom Musta wrote: +PPC_DFP_PostProc ADD_PPs[] = { static const. r~