[Qemu-devel] [PATCH v11 07/10] file-posix: support BDRV_REQ_ALLOCATE
Current write_zeroes implementation is good enough to satisfy this flag too Signed-off-by: Anton Nefedov --- block/file-posix.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/block/file-posix.c b/block/file-posix.c index a65e464cbc..c3fbf53853 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -607,6 +607,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, } else { s->discard_zeroes = true; s->has_fallocate = true; +bs->supported_zero_flags = BDRV_REQ_ALLOCATE; } } else { if (!(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { @@ -650,10 +651,11 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, #ifdef CONFIG_XFS if (platform_test_xfs_fd(s->fd)) { s->is_xfs = true; +bs->supported_zero_flags = BDRV_REQ_ALLOCATE; } #endif -bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; +bs->supported_zero_flags |= BDRV_REQ_MAY_UNMAP; ret = 0; fail: if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { @@ -1552,6 +1554,10 @@ static int handle_aiocb_write_zeroes(void *opaque) s->has_fallocate = false; #endif +if (!s->has_fallocate) { +aiocb->bs->supported_zero_flags &= ~BDRV_REQ_ALLOCATE; +} + return -ENOTSUP; } -- 2.17.1
[Qemu-devel] [PATCH v11 00/10] qcow2: cluster space preallocation
new in v11: - patch 4, 9: fixed commentary format - patch 4: removed one hunk with a dead check - patch 5: added commentary to BDRV_REQ_ALLOCATE definition - new auxiliary patch 6 for the following patch-7 change: - patch 7: reset BDRV_REQ_ALLOCATE from supported flag if CONFIG_FALLOCATE is false - patch 9: add commentary about missing qcow2_pre_write_overlap_check(). Omit redundant changes in the test 060. v10: http://lists.nongnu.org/archive/html/qemu-devel/2018-12/msg00121.html - patches 1-3,6,7: rebase after REQ_WRITE_UNCHANGED - patch 3: drop supported_zero_flags. My bad, no write_zeroes in quorum. - patch 4: almost trivial rebase. RB-tags not stripped. Choose another constant for BDRV_REQ_ALLOCATE - patch 5: rebase. Instead of marking REQ_ALLOCATE serialising, accompany it with REQ_SERIALISING. - patch 7: add symmetric copy-on-read change - patch 8: trivial rebase. RB-tags not stripped. This pull request is to start to improve a few performance points of qcow2 format: 1. non cluster-aligned write requests (to unallocated clusters) explicitly pad data with zeroes if there is no backing data. Resulting increase in ops number and potential cluster fragmentation (on the host file) is already solved by: ee22a9d qcow2: Merge the writing of the COW regions with the guest data However, in case of zero COW regions, that can be avoided at all but the whole clusters are preallocated and zeroed in a single efficient write_zeroes() operation 2. moreover, efficient write_zeroes() operation can be used to preallocate space megabytes (*configurable number) ahead which gives noticeable improvement on some storage types (e.g. distributed storage) where the space allocation operation might be expensive) (Not included in this patchset since v6). 3. this will also allow to enable simultaneous writes to the same unallocated cluster after the space has been allocated & zeroed but before the first data is written and the cluster is linked to L2. (Not included in this patchset). Efficient write_zeroes usually implies that the blocks are not actually written to but only reserved and marked as zeroed by the storage. In this patchset, file-posix driver is marked as supporting this operation if it supports (/configured to support) fallocate() operation. Existing bdrv_write_zeroes() falls back to writing zero buffers if write_zeroes is not supported by the driver. A new flag (BDRV_REQ_ALLOCATE) is introduced to avoid that but return ENOTSUP. Such allocate requests are also implemented to possibly overlap with the other requests. No wait is performed but an error returned in such case as well. So the operation should be considered advisory and a fallback scenario still handled by the caller (in this case, qcow2 driver). simple perf test: qemu-img create -f qcow2 test.img 4G && \ qemu-img bench -c $((1024*1024)) -f qcow2 -n -s 4k -t none -w test.img test results (seconds): +---+---+--+---+--+--+ | file|before| after| gain | +---+---+--+---+--+--+ |ssd| 61.153 | 36.313 | 41% | |hdd| 112.676 | 122.056 | -8% | +---+--+--+--+ Anton Nefedov (10): mirror: inherit supported write/zero flags blkverify: set supported write/zero flags quorum: set supported write flags block: introduce BDRV_REQ_ALLOCATE flag block: treat BDRV_REQ_ALLOCATE as serialising file-posix: reset fallocate-related flags without CONFIG_FALLOCATE* file-posix: support BDRV_REQ_ALLOCATE block: support BDRV_REQ_ALLOCATE in passthrough drivers qcow2: skip writing zero buffers to empty COW areas iotest 134: test cluster-misaligned encrypted write qapi/block-core.json | 4 +- block/qcow2.h | 6 +++ include/block/block.h | 13 +- include/block/block_int.h | 3 +- block/blkdebug.c | 2 +- block/blkverify.c | 10 - block/copy-on-read.c | 4 +- block/file-posix.c | 16 +-- block/io.c | 45 +++ block/mirror.c | 8 +++- block/qcow2-cluster.c | 2 +- block/qcow2.c | 89 +- block/quorum.c | 19 +++- block/raw-format.c | 2 +- block/trace-events | 1 + tests/qemu-iotests/060 | 7 ++- tests/qemu-iotests/060.out | 5 ++- tests/qemu-iotests/134 | 9 tests/qemu-iotests/134.out | 10 + 19 files changed, 227 insertions(+), 28 deletions(-) -- 2.17.1
[Qemu-devel] [PATCH v11 03/10] quorum: set supported write flags
Signed-off-by: Anton Nefedov Reviewed-by: Alberto Garcia Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/quorum.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/block/quorum.c b/block/quorum.c index 16b3c8067c..d21a6a3b8e 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -857,6 +857,19 @@ static QemuOptsList quorum_runtime_opts = { }, }; +static void quorum_set_supported_flags(BlockDriverState *bs) +{ +BDRVQuorumState *s = bs->opaque; +int i; + +bs->supported_write_flags = BDRV_REQ_FUA; +for (i = 0; i < s->num_children; i++) { +bs->supported_write_flags &= s->children[i]->bs->supported_write_flags; +} + +bs->supported_write_flags |= BDRV_REQ_WRITE_UNCHANGED; +} + static int quorum_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -950,7 +963,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, } s->next_child_index = s->num_children; -bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED; +quorum_set_supported_flags(bs); g_free(opened); goto exit; @@ -1025,6 +1038,8 @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, s->children = g_renew(BdrvChild *, s->children, s->num_children + 1); s->children[s->num_children++] = child; +quorum_set_supported_flags(bs); + out: bdrv_drained_end(bs); } @@ -1063,6 +1078,8 @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child, bdrv_unref_child(bs, child); bdrv_drained_end(bs); + +quorum_set_supported_flags(bs); } static void quorum_refresh_filename(BlockDriverState *bs, QDict *options) -- 2.17.1
[Qemu-devel] [PATCH v11 01/10] mirror: inherit supported write/zero flags
Signed-off-by: Anton Nefedov Reviewed-by: Alberto Garcia Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/mirror.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index ab59ad77e8..be52c9be9c 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1529,8 +1529,12 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs, mirror_top_bs->implicit = true; } mirror_top_bs->total_sectors = bs->total_sectors; -mirror_top_bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED; -mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED; +mirror_top_bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED | +(BDRV_REQ_FUA & bs->supported_write_flags); +mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED | +((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) + & bs->supported_zero_flags); + bs_opaque = g_new0(MirrorBDSOpaque, 1); mirror_top_bs->opaque = bs_opaque; bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs)); -- 2.17.1
Re: [Qemu-devel] [PATCH qemu v3] ppc/spapr: Receive and store device tree blob from SLOF
On 18/12/2018 15:30, Alexey Kardashevskiy wrote: > > > On 18/12/2018 14:49, David Gibson wrote: >> On Tue, Dec 18, 2018 at 02:04:54PM +1100, Alexey Kardashevskiy wrote: >>> >>> >>> On 18/12/2018 13:09, David Gibson wrote: On Mon, Dec 17, 2018 at 05:21:33PM +1100, David Gibson wrote: > On Fri, Dec 14, 2018 at 12:55:20PM +1100, Alexey Kardashevskiy wrote: >> SLOF receives a device tree and updates it with various properties >> before switching to the guest kernel and QEMU is not aware of any changes >> made by SLOF. Since there is no real RTAS (QEMU implements it), it makes >> sense to pass the SLOF final device tree to QEMU to let it implement >> RTAS related tasks better, such as PCI host bus adapter hotplug. >> >> Specifially, now QEMU can find out the actual XICS phandle (for PHB >> hotplug) and the RTAS linux,rtas-entry/base properties (for firmware >> assisted NMI - FWNMI). >> >> This stores the initial DT blob in the sPAPR machine and replaces it >> in the KVMPPC_H_UPDATE_DT (new private hypercall) handler. >> >> This adds an @update_dt_enabled machine property to allow backward >> migration. >> >> SLOF already has a hypercall since >> https://github.com/aik/SLOF/commit/e6fc84652c9c0073f9183 >> >> This makes use of the new fdt_check_full() helper. In order to allow >> the configure script to pick the correct DTC version, this adjusts >> the DTC presense test. >> >> Signed-off-by: Alexey Kardashevskiy > > Applied, thanks. And now, unapplied. I don't know quite how, but somehow this patch is causing aarch64 tests to SEGV. >>> >>> >>> /home/aik/p/qemu/configure --target-list=aarch64-softmmu >>> --source-path=/home/aik/p/qemu/ --disable-git-update --with-git=false >>>--enable-trace-backend=log >>> >>> and >>> >>> make -C /home/aik/pbuild/qemu-localhost-aarch64-rel/ -j24 check >>> >>> did not produce segv. I am running this all on a power8 box + ubuntu >>> 1804, what is your config? >> >> Hm, curious. I'm using Fedora 29 on an x86 host. > > > Fedora 27 on x86_64 is all right too :-/ Let's upgrade... Upgraded, bad experience - usb ethernet module did not load, and now it does not remember the screen configuration - when the external monitor is detached - all windows jump to the laptop screen and never come back to the external one when reattached :( And the latest QEMU does not compile with gcc 8.2.1 from fc28: /home/aik/p/qemu-dwg/util/memfd.c:38:12: error: static declaration of ‘memfd_create’ follows non-static declaration static int memfd_create(const char *name, unsigned int flags) ^~~~ In file included from /usr/include/bits/mman-linux.h:117, from /usr/include/bits/mman.h:49, from /usr/include/sys/mman.h:41, from /home/aik/p/qemu-dwg/include/sysemu/os-posix.h:29, from /home/aik/p/qemu-dwg/include/qemu/osdep.h:119, from /home/aik/p/qemu-dwg/util/memfd.c:28: /usr/include/bits/mman-shared.h:46:5: note: previous declaration of ‘memfd_create’ was here int memfd_create (const char *__name, unsigned int __flags) __THROW; ^~~~ /home/aik/p/qemu-dwg/block/file-posix.c:1585:14: error: static declaration of ‘copy_file_range’ follows non-static declaration static off_t copy_file_range(int in_fd, off_t *in_off, int out_fd, ^~~ In file included from /home/aik/p/qemu-dwg/include/qemu/osdep.h:90, from /home/aik/p/qemu-dwg/block/file-posix.c:25: /usr/include/unistd.h:1107:9: note: previous declaration of ‘copy_file_range’ was here ssize_t copy_file_range (int __infd, __off64_t *__pinoff, ^~~ after fixing these, there is still no segv anyway. Hm :( -- Alexey
Re: [Qemu-devel] [PATCH] spapr: Add H-Call H_HOME_NODE_ASSOCIATIVITY
On 18/12/2018 05:29, David Gibson wrote: > On Mon, Dec 17, 2018 at 03:00:55PM +0100, Laurent Vivier wrote: >> H_HOME_NODE_ASSOCIATIVITY H-Call returns the associativity domain >> designation associated with the identifier input parameter. >> >> Remove the warning message from the kernel: >> VPHN is not supported. Disabling polling.. >> >> Signed-off-by: Laurent Vivier > > From the looks of PAPR, I suspect this call isn't of much use outside > PowerVM guests, though it probably wouldn't do any harm. This call is used by the kernel to get the node id of a CPU on hotplug and fixes a crash when we hotplug a CPU in a memory-less/CPU-less node where this information is missing (not initialized from the device-tree). > BenH, Paulus, any thoughts? > > One nit in implementation: if you implement this hcall, it's supposed > to be advertised by adding hcall-vphn to ibm,hypertas-functions. ok in v2. Thanks, Laurent >> --- >> Based-on: <20181213040126.6768-1-da...@gibson.dropbear.id.au> >> "[PULL 00/27] ppc-for-4.0 queue 20181213" >> >> hw/ppc/spapr_hcall.c | 39 +++ >> include/hw/ppc/spapr.h | 1 + >> 2 files changed, 40 insertions(+) >> >> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c >> index 78fecc8fe9..454ec594fd 100644 >> --- a/hw/ppc/spapr_hcall.c >> +++ b/hw/ppc/spapr_hcall.c >> @@ -1663,6 +1663,41 @@ static target_ulong >> h_client_architecture_support(PowerPCCPU *cpu, >> return H_SUCCESS; >> } >> >> +static target_ulong h_home_node_associativity(PowerPCCPU *cpu, >> + sPAPRMachineState *spapr, >> + target_ulong opcode, >> + target_ulong *args) >> +{ >> +target_ulong flags = args[0]; >> +target_ulong procno = args[1]; >> +PowerPCCPU *tcpu; >> +int idx; >> + >> +/* only support procno from H_REGISTER_VPA */ >> +if ((flags & 0x1) == 0) { >> +return H_PARAMETER; >> +} >> + >> +tcpu = spapr_find_cpu(procno); >> +if (tcpu == NULL) { >> +return H_P2; >> +} >> + >> +/* sequence is the same as in the "ibm,associativity" property */ >> + >> +idx = 0; >> +#define ASSOCIATIVITY(a, b) (((uint64_t)a << 32) | ((uint64_t)b & >> 0x)) >> +args[idx++] = ASSOCIATIVITY(0, 0); >> +args[idx++] = ASSOCIATIVITY(0, tcpu->node_id); >> +args[idx++] = ASSOCIATIVITY(procno, -1); >> +for ( ; idx < 6; idx++) { >> +args[idx] = -1; >> +} >> +#undef ASSOCIATIVITY >> + >> +return H_SUCCESS; >> +} >> + >> static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu, >>sPAPRMachineState *spapr, >>target_ulong opcode, >> @@ -1864,6 +1899,10 @@ static void hypercall_register_types(void) >> spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support); >> >> spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt); >> + >> +/* Virtual Processor Home Node */ >> +spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY, >> + h_home_node_associativity); >> } >> >> type_init(hypercall_register_types) >> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h >> index b1a2515107..eb13e2b614 100644 >> --- a/include/hw/ppc/spapr.h >> +++ b/include/hw/ppc/spapr.h >> @@ -447,6 +447,7 @@ struct sPAPRMachineState { >> #define H_GET_EM_PARMS 0x2B8 >> #define H_SET_MPP 0x2D0 >> #define H_GET_MPP 0x2D4 >> +#define H_HOME_NODE_ASSOCIATIVITY 0x2EC >> #define H_XIRR_X0x2FC >> #define H_RANDOM0x300 >> #define H_SET_MODE 0x31C >
[Qemu-devel] [Bug 1808928] [NEW] Bitmap Extra data is not supported
Public bug reported: i am using dirty bitmaps and drive-backup. It works as aspected. Lately, i encounter a disastrous error. There is not any information about that situation. I cannot reach/open/attach/info or anything with a qcow2 file. virsh version Compiled against library: libvirt 4.10.0 Using library: libvirt 4.10.0 Using API: QEMU 4.10.0 Running hypervisor: QEMU 2.12.0 "qemu-img: Could not open '/var/lib/libvirt/images/test.qcow2': Bitmap extra data is not supported" what is that mean? what should i do? i cannot remove bitmap. i cannot open image or query. ** Affects: qemu Importance: Undecided Status: New ** Tags: bitmaps block dirt qcow2 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1808928 Title: Bitmap Extra data is not supported Status in QEMU: New Bug description: i am using dirty bitmaps and drive-backup. It works as aspected. Lately, i encounter a disastrous error. There is not any information about that situation. I cannot reach/open/attach/info or anything with a qcow2 file. virsh version Compiled against library: libvirt 4.10.0 Using library: libvirt 4.10.0 Using API: QEMU 4.10.0 Running hypervisor: QEMU 2.12.0 "qemu-img: Could not open '/var/lib/libvirt/images/test.qcow2': Bitmap extra data is not supported" what is that mean? what should i do? i cannot remove bitmap. i cannot open image or query. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1808928/+subscriptions
Re: [Qemu-devel] [PATCH] qapi: fix flat union on uncovered branches conditionals
Marc-André Lureau writes: > Default branches variant should use the member conditional. > > This fixes compilation with --disable-replication. > > Fixes: 335d10cd8e2c3bb6067804b095aaf6371fc1983e > > Signed-off-by: Marc-André Lureau > --- > scripts/qapi/common.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py > index 8c2d97369e..d385a08270 100644 > --- a/scripts/qapi/common.py > +++ b/scripts/qapi/common.py > @@ -1460,7 +1460,7 @@ class QAPISchemaObjectTypeVariants(object): > cases = set([v.name for v in self.variants]) > for m in self.tag_member.type.members: > if m.name not in cases: > -v = QAPISchemaObjectTypeVariant(m.name, 'q_empty') > +v = QAPISchemaObjectTypeVariant(m.name, 'q_empty', > m.ifcond) > v.set_owner(self.tag_member.owner) > self.variants.append(v) > for v in self.variants: Long line, happy to wrap it when I apply. I append the diff of generated code. Reviewed-by: Markus Armbruster diff -rup qapi-gen-fb06411210/qapi-introspect.c qapi-gen-ce1a1aec47/qapi-introspect.c --- qapi-gen-fb06411210/qapi-introspect.c 2018-12-18 08:15:43.929724950 +0100 +++ qapi-gen-ce1a1aec47/qapi-introspect.c 2018-12-18 08:11:30.927263620 +0100 @@ -10068,11 +10068,13 @@ const QLitObject qmp_schema_qlit = QLIT_ { "type", QLIT_QSTR("0"), }, {} })), +#if defined(CONFIG_REPLICATION) QLIT_QDICT(((QLitDictEntry[]) { { "case", QLIT_QSTR("replication"), }, { "type", QLIT_QSTR("0"), }, {} })), +#endif /* defined(CONFIG_REPLICATION) */ QLIT_QDICT(((QLitDictEntry[]) { { "case", QLIT_QSTR("throttle"), }, { "type", QLIT_QSTR("0"), }, diff -rup qapi-gen-fb06411210/qapi-visit-block-core.c qapi-gen-ce1a1aec47/qapi-visit-block-core.c --- qapi-gen-fb06411210/qapi-visit-block-core.c 2018-12-18 08:15:43.833726292 +0100 +++ qapi-gen-ce1a1aec47/qapi-visit-block-core.c 2018-12-18 08:11:30.833264935 +0100 @@ -7175,8 +7175,10 @@ void visit_type_BlockdevCreateOptions_me break; case BLOCKDEV_DRIVER_RAW: break; +#if defined(CONFIG_REPLICATION) case BLOCKDEV_DRIVER_REPLICATION: break; +#endif /* defined(CONFIG_REPLICATION) */ case BLOCKDEV_DRIVER_THROTTLE: break; case BLOCKDEV_DRIVER_VMDK:
Re: [Qemu-devel] [PATCH v3 2/2] hw: vmmouse: Use link instead of pointer property
Philippe Mathieu-Daudé writes: > On 12/17/18 8:01 PM, Markus Armbruster wrote: >> Philippe Mathieu-Daudé writes: >> >>> Hi Li, >>> >>> On 11/29/18 5:52 AM, Li Qiang wrote: According to qdev-properties.h, properties of pointer type should be avoided. Turn "ps2_mouse" into a link. Reviewed-by: Markus Armbruster Reviewed-by: Darren Kenny Signed-off-by: Li Qiang --- >> [...] diff --git a/hw/i386/vmmouse.c b/hw/i386/vmmouse.c index 4412eaf604..f63aac6673 100644 --- a/hw/i386/vmmouse.c +++ b/hw/i386/vmmouse.c >> [...] @@ -283,8 +289,6 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data) dc->realize = vmmouse_realizefn; dc->reset = vmmouse_reset; dc->vmsd = _vmmouse; -dc->props = vmmouse_properties; -/* Reason: pointer property "ps2_mouse" */ dc->user_creatable = false; >>> >>> "user_creatable = false" must have an justification comment. >> >> Correct. Aside: more ->user_creatable = false without a comment have crept in since I last swept them out. >>> Can you keep 'Reason: link property "ps2_mouse"'? >> >> Is this a valid reason? >> >> A pointer property is one, because it can only be set by code. > > I prefer the original comment :) > > /* Reason: pointer property "ps2_mouse" */ A pointer property can't be set by -device because there's no sane way to pick a value. Not true for a link property: it's value is a QOM path. But I'm not sure such setting of link properties has been implemented. If it isn't, then /* Reason: link property "ps2_mouse */ is perfect. If it isn, then it's wrong, possibly along with with dc->user_creatable = false. >>> Eventually the maintainer taking this patch can fix this for you. >>> >>> With the comment: >>> Reviewed-by: Philippe Mathieu-Daudé >>> } >> [...] >>
[Qemu-devel] [PATCH 20/34] target/ppc: convert vsplt[bhw] to use vector operations
Signed-off-by: Richard Henderson --- target/ppc/helper.h | 3 -- target/ppc/int_helper.c | 24 --- target/ppc/translate/vmx-impl.inc.c | 45 + 3 files changed, 26 insertions(+), 46 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 2aa60e5d36..069daa9883 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -246,9 +246,6 @@ DEF_HELPER_3(vrld, void, avr, avr, avr) DEF_HELPER_3(vsl, void, avr, avr, avr) DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) -DEF_HELPER_3(vspltb, void, avr, avr, i32) -DEF_HELPER_3(vsplth, void, avr, avr, i32) -DEF_HELPER_3(vspltw, void, avr, avr, i32) DEF_HELPER_3(vextractub, void, avr, avr, i32) DEF_HELPER_3(vextractuh, void, avr, avr, i32) DEF_HELPER_3(vextractuw, void, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index e44c0d90ee..3bf0fdb6c5 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1918,30 +1918,6 @@ void helper_vslo(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #endif } -/* Experimental testing shows that hardware masks the immediate. */ -#define _SPLAT_MASKED(element) (splat & (ARRAY_SIZE(r->element) - 1)) -#if defined(HOST_WORDS_BIGENDIAN) -#define SPLAT_ELEMENT(element) _SPLAT_MASKED(element) -#else -#define SPLAT_ELEMENT(element) \ -(ARRAY_SIZE(r->element) - 1 - _SPLAT_MASKED(element)) -#endif -#define VSPLT(suffix, element) \ -void helper_vsplt##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \ -{ \ -uint32_t s = b->element[SPLAT_ELEMENT(element)];\ -int i; \ -\ -for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ -r->element[i] = s; \ -} \ -} -VSPLT(b, u8) -VSPLT(h, u16) -VSPLT(w, u32) -#undef VSPLT -#undef SPLAT_ELEMENT -#undef _SPLAT_MASKED #if defined(HOST_WORDS_BIGENDIAN) #define VINSERT(suffix, element)\ void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index be638cdb1a..529ae0e5f5 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -814,24 +814,31 @@ GEN_VXFORM_NOA(vprtybw, 1, 24); GEN_VXFORM_NOA(vprtybd, 1, 24); GEN_VXFORM_NOA(vprtybq, 1, 24); -#define GEN_VXFORM_UIMM(name, opc2, opc3) \ -static void glue(gen_, name)(DisasContext *ctx) \ -{ \ -TCGv_ptr rb, rd;\ -TCGv_i32 uimm; \ -if (unlikely(!ctx->altivec_enabled)) { \ -gen_exception(ctx, POWERPC_EXCP_VPU); \ -return; \ -} \ -uimm = tcg_const_i32(UIMM5(ctx->opcode)); \ -rb = gen_avr_ptr(rB(ctx->opcode)); \ -rd = gen_avr_ptr(rD(ctx->opcode)); \ -gen_helper_##name (rd, rb, uimm); \ -tcg_temp_free_i32(uimm);\ -tcg_temp_free_ptr(rb); \ -tcg_temp_free_ptr(rd); \ +static void gen_vsplt(DisasContext *ctx, int vece) +{ +int uimm, dofs, bofs; + +if (unlikely(!ctx->altivec_enabled)) { +gen_exception(ctx, POWERPC_EXCP_VPU); +return; } +uimm = UIMM5(ctx->opcode); +bofs = avr64_offset(rB(ctx->opcode), true); +dofs = avr64_offset(rD(ctx->opcode), true); + +/* Experimental testing shows that hardware masks the immediate. */ +bofs += (uimm << vece) & 15; +#ifndef HOST_WORDS_BIGENDIAN +bofs ^= 15; +#endif + +tcg_gen_gvec_dup_mem(vece, dofs, bofs, 16, 16); +} + +#define GEN_VXFORM_VSPLT(name, vece, opc2, opc3) \ +static void glue(gen_, name)(DisasContext *ctx) { gen_vsplt(ctx, vece); } + #define GEN_VXFORM_UIMM_ENV(name, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ { \ @@ -873,9 +880,9 @@ static void glue(gen_, name)(DisasContext *ctx)
[Qemu-devel] [PATCH 34/34] target/ppc: convert vmin* and vmax* to vector operations
Signed-off-by: Richard Henderson --- target/ppc/helper.h | 16 --- target/ppc/int_helper.c | 27 target/ppc/translate/vmx-impl.inc.c | 32 ++--- 3 files changed, 16 insertions(+), 59 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 3daf6bf863..18910d18a4 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -117,22 +117,6 @@ DEF_HELPER_3(vabsduw, void, avr, avr, avr) DEF_HELPER_3(vavgsb, void, avr, avr, avr) DEF_HELPER_3(vavgsh, void, avr, avr, avr) DEF_HELPER_3(vavgsw, void, avr, avr, avr) -DEF_HELPER_3(vminsb, void, avr, avr, avr) -DEF_HELPER_3(vminsh, void, avr, avr, avr) -DEF_HELPER_3(vminsw, void, avr, avr, avr) -DEF_HELPER_3(vminsd, void, avr, avr, avr) -DEF_HELPER_3(vmaxsb, void, avr, avr, avr) -DEF_HELPER_3(vmaxsh, void, avr, avr, avr) -DEF_HELPER_3(vmaxsw, void, avr, avr, avr) -DEF_HELPER_3(vmaxsd, void, avr, avr, avr) -DEF_HELPER_3(vminub, void, avr, avr, avr) -DEF_HELPER_3(vminuh, void, avr, avr, avr) -DEF_HELPER_3(vminuw, void, avr, avr, avr) -DEF_HELPER_3(vminud, void, avr, avr, avr) -DEF_HELPER_3(vmaxub, void, avr, avr, avr) -DEF_HELPER_3(vmaxuh, void, avr, avr, avr) -DEF_HELPER_3(vmaxuw, void, avr, avr, avr) -DEF_HELPER_3(vmaxud, void, avr, avr, avr) DEF_HELPER_4(vcmpequb, void, env, avr, avr, avr) DEF_HELPER_4(vcmpequh, void, env, avr, avr, avr) DEF_HELPER_4(vcmpequw, void, env, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 22671c71e5..b9793364fd 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -937,33 +937,6 @@ void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } } -#define VMINMAX_DO(name, compare, element) \ -void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ -{ \ -int i; \ -\ -for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ -if (a->element[i] compare b->element[i]) { \ -r->element[i] = b->element[i]; \ -} else {\ -r->element[i] = a->element[i]; \ -} \ -} \ -} -#define VMINMAX(suffix, element)\ -VMINMAX_DO(min##suffix, >, element) \ -VMINMAX_DO(max##suffix, <, element) -VMINMAX(sb, s8) -VMINMAX(sh, s16) -VMINMAX(sw, s32) -VMINMAX(sd, s64) -VMINMAX(ub, u8) -VMINMAX(uh, u16) -VMINMAX(uw, u32) -VMINMAX(ud, u64) -#undef VMINMAX_DO -#undef VMINMAX - void helper_vmladduhm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int i; diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index c6a53a9f63..399d18707f 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -412,22 +412,22 @@ GEN_VXFORM_V(vsububm, MO_8, tcg_gen_gvec_sub, 0, 16); GEN_VXFORM_V(vsubuhm, MO_16, tcg_gen_gvec_sub, 0, 17); GEN_VXFORM_V(vsubuwm, MO_32, tcg_gen_gvec_sub, 0, 18); GEN_VXFORM_V(vsubudm, MO_64, tcg_gen_gvec_sub, 0, 19); -GEN_VXFORM(vmaxub, 1, 0); -GEN_VXFORM(vmaxuh, 1, 1); -GEN_VXFORM(vmaxuw, 1, 2); -GEN_VXFORM(vmaxud, 1, 3); -GEN_VXFORM(vmaxsb, 1, 4); -GEN_VXFORM(vmaxsh, 1, 5); -GEN_VXFORM(vmaxsw, 1, 6); -GEN_VXFORM(vmaxsd, 1, 7); -GEN_VXFORM(vminub, 1, 8); -GEN_VXFORM(vminuh, 1, 9); -GEN_VXFORM(vminuw, 1, 10); -GEN_VXFORM(vminud, 1, 11); -GEN_VXFORM(vminsb, 1, 12); -GEN_VXFORM(vminsh, 1, 13); -GEN_VXFORM(vminsw, 1, 14); -GEN_VXFORM(vminsd, 1, 15); +GEN_VXFORM_V(vmaxub, MO_8, tcg_gen_gvec_umax, 1, 0); +GEN_VXFORM_V(vmaxuh, MO_16, tcg_gen_gvec_umax, 1, 1); +GEN_VXFORM_V(vmaxuw, MO_32, tcg_gen_gvec_umax, 1, 2); +GEN_VXFORM_V(vmaxud, MO_64, tcg_gen_gvec_umax, 1, 3); +GEN_VXFORM_V(vmaxsb, MO_8, tcg_gen_gvec_smax, 1, 4); +GEN_VXFORM_V(vmaxsh, MO_16, tcg_gen_gvec_smax, 1, 5); +GEN_VXFORM_V(vmaxsw, MO_32, tcg_gen_gvec_smax, 1, 6); +GEN_VXFORM_V(vmaxsd, MO_64, tcg_gen_gvec_smax, 1, 7); +GEN_VXFORM_V(vminub, MO_8, tcg_gen_gvec_umin, 1, 8); +GEN_VXFORM_V(vminuh, MO_16, tcg_gen_gvec_umin, 1, 9); +GEN_VXFORM_V(vminuw, MO_32, tcg_gen_gvec_umin, 1, 10); +GEN_VXFORM_V(vminud, MO_64, tcg_gen_gvec_umin, 1, 11); +GEN_VXFORM_V(vminsb, MO_8, tcg_gen_gvec_smin, 1, 12); +GEN_VXFORM_V(vminsh, MO_16, tcg_gen_gvec_smin, 1, 13); +GEN_VXFORM_V(vminsw, MO_32, tcg_gen_gvec_smin, 1, 14); +GEN_VXFORM_V(vminsd, MO_64, tcg_gen_gvec_smin, 1, 15); GEN_VXFORM(vavgub, 1, 16); GEN_VXFORM(vabsdub, 1, 16); GEN_VXFORM_DUAL(vavgub, PPC_ALTIVEC, PPC_NONE, \ -- 2.17.2
[Qemu-devel] [PATCH 24/34] target/ppc: convert xxspltw to vector operations
Signed-off-by: Richard Henderson --- target/ppc/translate/vsx-impl.inc.c | 36 + 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index d88d6bbd74..a040038ed4 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1318,38 +1318,24 @@ static void gen_xxsel(DisasContext * ctx) static void gen_xxspltw(DisasContext *ctx) { -TCGv_i64 b, b2; -TCGv_i64 vsr; - -vsr = tcg_temp_new_i64(); -if (UIM(ctx->opcode) & 2) { -get_cpu_vsrl(vsr, xB(ctx->opcode)); -} else { -get_cpu_vsrh(vsr, xB(ctx->opcode)); -} +int rt = xT(ctx->opcode); +int rb = xB(ctx->opcode); +int uim = UIM(ctx->opcode); +int tofs, bofs; if (unlikely(!ctx->vsx_enabled)) { gen_exception(ctx, POWERPC_EXCP_VSXU); return; } -b = tcg_temp_new_i64(); -b2 = tcg_temp_new_i64(); +tofs = vsr_full_offset(rt); +bofs = vsr_full_offset(rb); +bofs += uim << MO_32; +#ifndef HOST_WORDS_BIG_ENDIAN +bofs ^= 8 | 4; +#endif -if (UIM(ctx->opcode) & 1) { -tcg_gen_ext32u_i64(b, vsr); -} else { -tcg_gen_shri_i64(b, vsr, 32); -} - -tcg_gen_shli_i64(b2, b, 32); -tcg_gen_or_i64(vsr, b, b2); -set_cpu_vsrh(xT(ctx->opcode), vsr); -set_cpu_vsrl(xT(ctx->opcode), vsr); - -tcg_temp_free_i64(vsr); -tcg_temp_free_i64(b); -tcg_temp_free_i64(b2); +tcg_gen_gvec_dup_mem(MO_32, tofs, bofs, 16, 16); } #define pattern(x) (((x) & 0xff) * (~(uint64_t)0 / 0xff)) -- 2.17.2
[Qemu-devel] [PATCH 01/34] tcg: Add logical simplifications during gvec expand
We handle many of these during integer expansion, and the rest of them during integer optimization. Signed-off-by: Richard Henderson --- tcg/tcg-op-gvec.c | 35 ++- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c index 61c25f5784..ec231b78fb 100644 --- a/tcg/tcg-op-gvec.c +++ b/tcg/tcg-op-gvec.c @@ -1840,7 +1840,12 @@ void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs, .opc = INDEX_op_and_vec, .prefer_i64 = TCG_TARGET_REG_BITS == 64, }; -tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); + +if (aofs == bofs) { +tcg_gen_gvec_mov(vece, dofs, aofs, oprsz, maxsz); +} else { +tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); +} } void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs, @@ -1853,7 +1858,12 @@ void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs, .opc = INDEX_op_or_vec, .prefer_i64 = TCG_TARGET_REG_BITS == 64, }; -tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); + +if (aofs == bofs) { +tcg_gen_gvec_mov(vece, dofs, aofs, oprsz, maxsz); +} else { +tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); +} } void tcg_gen_gvec_xor(unsigned vece, uint32_t dofs, uint32_t aofs, @@ -1866,7 +1876,12 @@ void tcg_gen_gvec_xor(unsigned vece, uint32_t dofs, uint32_t aofs, .opc = INDEX_op_xor_vec, .prefer_i64 = TCG_TARGET_REG_BITS == 64, }; -tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); + +if (aofs == bofs) { +tcg_gen_gvec_dup8i(dofs, oprsz, maxsz, 0); +} else { +tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); +} } void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs, @@ -1879,7 +1894,12 @@ void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs, .opc = INDEX_op_andc_vec, .prefer_i64 = TCG_TARGET_REG_BITS == 64, }; -tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); + +if (aofs == bofs) { +tcg_gen_gvec_dup8i(dofs, oprsz, maxsz, 0); +} else { +tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); +} } void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs, @@ -1892,7 +1912,12 @@ void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs, .opc = INDEX_op_orc_vec, .prefer_i64 = TCG_TARGET_REG_BITS == 64, }; -tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); + +if (aofs == bofs) { +tcg_gen_gvec_dup8i(dofs, oprsz, maxsz, -1); +} else { +tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, ); +} } static const GVecGen2s gop_ands = { -- 2.17.2
Re: [Qemu-devel] [PULL 32/32] qapi: add conditions to REPLICATION type/commands on the schema
Marc-André Lureau writes: > Hi > > On Mon, Dec 17, 2018 at 8:01 PM Thomas Huth wrote: >> >> On 2018-12-13 19:43, Markus Armbruster wrote: >> > From: Marc-André Lureau >> > >> > Add #if defined(CONFIG_REPLICATION) in generated code, and adjust the >> > code accordingly. >> > >> > Made conditional: >> > >> > * xen-set-replication, query-xen-replication-status, >> > xen-colo-do-checkpoint >> > >> > Before the patch, we first register the commands unconditionally in >> > generated code (requires a stub), then conditionally unregister in >> > qmp_unregister_commands_hack(). >> > >> > Afterwards, we register only when CONFIG_REPLICATION. The command >> > fails exactly the same, with CommandNotFound. >> > >> > Improvement, because now query-qmp-schema is accurate, and we're one >> > step closer to killing qmp_unregister_commands_hack(). >> > >> > * enum BlockdevDriver value "replication" in command blockdev-add >> > >> > * BlockdevOptions variant @replication >> > >> > and related structures. >> > >> > Signed-off-by: Marc-André Lureau >> > Reviewed-by: Markus Armbruster >> > Message-Id: <20181213123724.4866-23-marcandre.lur...@redhat.com> >> > Signed-off-by: Markus Armbruster >> > --- >> > migration/colo.c | 16 >> > monitor.c| 5 - >> > qapi/block-core.json | 13 + >> > qapi/migration.json | 12 >> > 4 files changed, 21 insertions(+), 25 deletions(-) >> >> I think this might have broken compilation with --disable-replication: >> >> https://gitlab.com/huth/qemu/-/jobs/135648240 >> >> Any ideas how to fix it? > > We introduced a regression by dropping osdep.h include from headers. > > To me, it's best to include osdep.h in headers, since the ifdef exist > there. But I have been told we include it in .c instead. I'll upstream > the qapi/scripts to include it. This can't be the cause: qapi/qapi-visit-block-core.c includes osdep.h first, like all our .c files. > thanks for the report, sorry for the regression You've since posted a fix to add the missing ifdeffery. I'm testing it while I write :)
[Qemu-devel] [PATCH 29/34] target/ppc: Add helper_mfvscr
This is required before changing the representation of the register. Signed-off-by: Richard Henderson --- target/ppc/helper.h | 1 + target/ppc/arch_dump.c | 3 ++- target/ppc/int_helper.c | 5 + target/ppc/translate/vmx-impl.inc.c | 2 +- target/ppc/translate_init.inc.c | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index b3ffe28103..7dbb08b9dd 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -295,6 +295,7 @@ DEF_HELPER_5(vmsumshm, void, env, avr, avr, avr, avr) DEF_HELPER_5(vmsumshs, void, env, avr, avr, avr, avr) DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_2(mtvscr, TCG_CALL_NO_RWG, void, env, i32) +DEF_HELPER_FLAGS_1(mfvscr, TCG_CALL_NO_RWG, i32, env) DEF_HELPER_3(lvebx, void, env, avr, tl) DEF_HELPER_3(lvehx, void, env, avr, tl) DEF_HELPER_3(lvewx, void, env, avr, tl) diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c index c272d0d3d4..f753798789 100644 --- a/target/ppc/arch_dump.c +++ b/target/ppc/arch_dump.c @@ -17,6 +17,7 @@ #include "elf.h" #include "sysemu/dump.h" #include "sysemu/kvm.h" +#include "exec/helper-proto.h" #ifdef TARGET_PPC64 #define ELFCLASS ELFCLASS64 @@ -173,7 +174,7 @@ static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu) vmxregset->avr[i].u64[1] = cpu->env.vsr[32 + i].u64[1]; } } -vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr); +vmxregset->vscr.u32[3] = cpu_to_dump32(s, helper_mfvscr(>env)); } static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 0443f33cd2..75201bbba6 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -475,6 +475,11 @@ void helper_mtvscr(CPUPPCState *env, uint32_t vscr) set_flush_to_zero((vscr >> VSCR_NJ) & 1, >vec_status); } +uint32_t helper_mfvscr(CPUPPCState *env) +{ +return env->vscr; +} + void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int i; diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index ab6da3aa55..1c0c461241 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -187,7 +187,7 @@ static void gen_mfvscr(DisasContext *ctx) tcg_gen_movi_i64(avr, 0); set_avr64(rD(ctx->opcode), avr, true); t = tcg_temp_new_i32(); -tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr)); +gen_helper_mfvscr(t, cpu_env); tcg_gen_extu_i32_i64(avr, t); set_avr64(rD(ctx->opcode), avr, false); tcg_temp_free_i32(t); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 292b1df700..353285c6bd 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9527,7 +9527,7 @@ static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 16; } if (n == 32) { -stl_p(mem_buf, env->vscr); +stl_p(mem_buf, helper_mfvscr(env)); ppc_maybe_bswap_register(env, mem_buf, 4); return 4; } -- 2.17.2
[Qemu-devel] [PATCH 11/34] target/ppc: introduce get_fpr() and set_fpr() helpers for FP register access
From: Mark Cave-Ayland These helpers allow us to move FP register values to/from the specified TCGv_i64 argument in the VSR helpers to be introduced shortly. To prevent FP helpers accessing the cpu_fpr array directly, add extra TCG temporaries as required. Signed-off-by: Mark Cave-Ayland Message-Id: <20181217122405.18732-2-mark.cave-ayl...@ilande.co.uk> --- target/ppc/translate.c | 10 + target/ppc/translate/fp-impl.inc.c | 490 ++--- 2 files changed, 390 insertions(+), 110 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 2b37910248..1d4bf624a3 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6694,6 +6694,16 @@ static inline void gen_##name(DisasContext *ctx) \ GEN_TM_PRIV_NOOP(treclaim); GEN_TM_PRIV_NOOP(trechkpt); +static inline void get_fpr(TCGv_i64 dst, int regno) +{ +tcg_gen_mov_i64(dst, cpu_fpr[regno]); +} + +static inline void set_fpr(int regno, TCGv_i64 src) +{ +tcg_gen_mov_i64(cpu_fpr[regno], src); +} + #include "translate/fp-impl.inc.c" #include "translate/vmx-impl.inc.c" diff --git a/target/ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c index 08770ba9f5..04b8733055 100644 --- a/target/ppc/translate/fp-impl.inc.c +++ b/target/ppc/translate/fp-impl.inc.c @@ -34,24 +34,38 @@ static void gen_set_cr1_from_fpscr(DisasContext *ctx) #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type) \ static void gen_f##name(DisasContext *ctx)\ { \ +TCGv_i64 t0; \ +TCGv_i64 t1; \ +TCGv_i64 t2; \ +TCGv_i64 t3; \ if (unlikely(!ctx->fpu_enabled)) {\ gen_exception(ctx, POWERPC_EXCP_FPU); \ return; \ } \ +t0 = tcg_temp_new_i64(); \ +t1 = tcg_temp_new_i64(); \ +t2 = tcg_temp_new_i64(); \ +t3 = tcg_temp_new_i64(); \ gen_reset_fpstatus(); \ -gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, \ - cpu_fpr[rA(ctx->opcode)],\ - cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \ +get_fpr(t0, rA(ctx->opcode)); \ +get_fpr(t1, rC(ctx->opcode)); \ +get_fpr(t2, rB(ctx->opcode)); \ +gen_helper_f##op(t3, cpu_env, t0, t1, t2);\ if (isfloat) {\ -gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,\ -cpu_fpr[rD(ctx->opcode)]);\ +get_fpr(t0, rD(ctx->opcode)); \ +gen_helper_frsp(t3, cpu_env, t0); \ } \ +set_fpr(rD(ctx->opcode), t3); \ if (set_fprf) { \ -gen_compute_fprf_float64(cpu_fpr[rD(ctx->opcode)]); \ +gen_compute_fprf_float64(t3); \ } \ if (unlikely(Rc(ctx->opcode) != 0)) { \ gen_set_cr1_from_fpscr(ctx); \ } \ +tcg_temp_free_i64(t0);\ +tcg_temp_free_i64(t1);\ +tcg_temp_free_i64(t2);\ +tcg_temp_free_i64(t3);\ } #define GEN_FLOAT_ACB(name, op2, set_fprf, type) \ @@ -61,24 +75,34 @@ _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type); #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type) \ static void
[Qemu-devel] [PATCH 27/34] target/ppc: Use helper_mtvscr for reset and gdb
Not setting flush_to_zero from gdb_set_avr_reg was a bug. Signed-off-by: Richard Henderson --- target/ppc/translate_init.inc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index b83097141c..292b1df700 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -601,10 +601,9 @@ static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn) static inline void vscr_init(CPUPPCState *env, uint32_t val) { -env->vscr = val; /* Altivec always uses round-to-nearest */ set_float_rounding_mode(float_round_nearest_even, >vec_status); -set_flush_to_zero(vscr_nj, >vec_status); +helper_mtvscr(env, val); } #ifdef CONFIG_USER_ONLY @@ -9556,7 +9555,7 @@ static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) } if (n == 32) { ppc_maybe_bswap_register(env, mem_buf, 4); -env->vscr = ldl_p(mem_buf); +helper_mtvscr(env, ldl_p(mem_buf)); return 4; } if (n == 33) { -- 2.17.2
[Qemu-devel] [PATCH 14/34] target/ppc: switch FPR, VMX and VSX helpers to access data directly from cpu_env
From: Mark Cave-Ayland Instead of accessing the FPR, VMX and VSX registers through static arrays of TCGv_i64 globals, remove them and change the helpers to load/store data directly within cpu_env. Signed-off-by: Mark Cave-Ayland Reviewed-by: Richard Henderson Message-Id: <20181217122405.18732-6-mark.cave-ayl...@ilande.co.uk> --- target/ppc/translate.c | 59 - target/ppc/translate/vsx-impl.inc.c | 4 +- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index fa3e8dc114..5923c688cd 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -55,15 +55,9 @@ /* global register indexes */ static char cpu_reg_names[10*3 + 22*4 /* GPR */ + 10*4 + 22*5 /* SPE GPRh */ -+ 10*4 + 22*5 /* FPR */ -+ 2*(10*6 + 22*7) /* AVRh, AVRl */ -+ 10*5 + 22*6 /* VSR */ + 8*5 /* CRF */]; static TCGv cpu_gpr[32]; static TCGv cpu_gprh[32]; -static TCGv_i64 cpu_fpr[32]; -static TCGv_i64 cpu_avrh[32], cpu_avrl[32]; -static TCGv_i64 cpu_vsr[32]; static TCGv_i32 cpu_crf[8]; static TCGv cpu_nip; static TCGv cpu_msr; @@ -108,39 +102,6 @@ void ppc_translate_init(void) offsetof(CPUPPCState, gprh[i]), p); p += (i < 10) ? 4 : 5; cpu_reg_names_size -= (i < 10) ? 4 : 5; - -snprintf(p, cpu_reg_names_size, "fp%d", i); -cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env, -offsetof(CPUPPCState, fpr[i]), p); -p += (i < 10) ? 4 : 5; -cpu_reg_names_size -= (i < 10) ? 4 : 5; - -snprintf(p, cpu_reg_names_size, "avr%dH", i); -#ifdef HOST_WORDS_BIGENDIAN -cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env, - offsetof(CPUPPCState, avr[i].u64[0]), p); -#else -cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env, - offsetof(CPUPPCState, avr[i].u64[1]), p); -#endif -p += (i < 10) ? 6 : 7; -cpu_reg_names_size -= (i < 10) ? 6 : 7; - -snprintf(p, cpu_reg_names_size, "avr%dL", i); -#ifdef HOST_WORDS_BIGENDIAN -cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env, - offsetof(CPUPPCState, avr[i].u64[1]), p); -#else -cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env, - offsetof(CPUPPCState, avr[i].u64[0]), p); -#endif -p += (i < 10) ? 6 : 7; -cpu_reg_names_size -= (i < 10) ? 6 : 7; -snprintf(p, cpu_reg_names_size, "vsr%d", i); -cpu_vsr[i] = tcg_global_mem_new_i64(cpu_env, -offsetof(CPUPPCState, vsr[i]), p); -p += (i < 10) ? 5 : 6; -cpu_reg_names_size -= (i < 10) ? 5 : 6; } cpu_nip = tcg_global_mem_new(cpu_env, @@ -6696,22 +6657,34 @@ GEN_TM_PRIV_NOOP(trechkpt); static inline void get_fpr(TCGv_i64 dst, int regno) { -tcg_gen_mov_i64(dst, cpu_fpr[regno]); +tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, fpr[regno])); } static inline void set_fpr(int regno, TCGv_i64 src) { -tcg_gen_mov_i64(cpu_fpr[regno], src); +tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, fpr[regno])); } static inline void get_avr64(TCGv_i64 dst, int regno, bool high) { -tcg_gen_mov_i64(dst, (high ? cpu_avrh : cpu_avrl)[regno]); +#ifdef HOST_WORDS_BIGENDIAN +tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, + avr[regno].u64[(high ? 0 : 1)])); +#else +tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, + avr[regno].u64[(high ? 1 : 0)])); +#endif } static inline void set_avr64(int regno, TCGv_i64 src, bool high) { -tcg_gen_mov_i64((high ? cpu_avrh : cpu_avrl)[regno], src); +#ifdef HOST_WORDS_BIGENDIAN +tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, + avr[regno].u64[(high ? 0 : 1)])); +#else +tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, + avr[regno].u64[(high ? 1 : 0)])); +#endif } #include "translate/fp-impl.inc.c" diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index e9a05d66f7..20e1fd9324 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -2,12 +2,12 @@ static inline void get_vsr(TCGv_i64 dst, int n) { -tcg_gen_mov_i64(dst, cpu_vsr[n]); +tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[n])); } static inline void set_vsr(int n, TCGv_i64 src) { -tcg_gen_mov_i64(cpu_vsr[n], src); +tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[n])); } static inline void get_cpu_vsrh(TCGv_i64 dst, int n) -- 2.17.2
[Qemu-devel] [PATCH 19/34] target/ppc: convert vspltis[bhw] to use vector operations
Signed-off-by: Richard Henderson --- target/ppc/helper.h | 3 --- target/ppc/int_helper.c | 15 target/ppc/translate/vmx-impl.inc.c | 36 +++-- 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 553ff500c8..2aa60e5d36 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -246,9 +246,6 @@ DEF_HELPER_3(vrld, void, avr, avr, avr) DEF_HELPER_3(vsl, void, avr, avr, avr) DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) -DEF_HELPER_2(vspltisb, void, avr, i32) -DEF_HELPER_2(vspltish, void, avr, i32) -DEF_HELPER_2(vspltisw, void, avr, i32) DEF_HELPER_3(vspltb, void, avr, avr, i32) DEF_HELPER_3(vsplth, void, avr, avr, i32) DEF_HELPER_3(vspltw, void, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 4547453ef1..e44c0d90ee 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -2066,21 +2066,6 @@ VNEG(vnegw, s32) VNEG(vnegd, s64) #undef VNEG -#define VSPLTI(suffix, element, splat_type) \ -void helper_vspltis##suffix(ppc_avr_t *r, uint32_t splat) \ -{ \ -splat_type x = (int8_t)(splat << 3) >> 3; \ -int i; \ -\ -for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ -r->element[i] = x; \ -} \ -} -VSPLTI(b, s8, int8_t) -VSPLTI(h, s16, int16_t) -VSPLTI(w, s32, int32_t) -#undef VSPLTI - #define VSR(suffix, element, mask) \ void helper_vsr##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index e353d3f174..be638cdb1a 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -720,25 +720,21 @@ GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \ GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \ vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207) -#define GEN_VXFORM_SIMM(name, opc2, opc3) \ +#define GEN_VXFORM_DUPI(name, tcg_op, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ { \ -TCGv_ptr rd;\ -TCGv_i32 simm; \ +int simm; \ if (unlikely(!ctx->altivec_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_VPU); \ return; \ } \ -simm = tcg_const_i32(SIMM5(ctx->opcode)); \ -rd = gen_avr_ptr(rD(ctx->opcode)); \ -gen_helper_##name (rd, simm); \ -tcg_temp_free_i32(simm);\ -tcg_temp_free_ptr(rd); \ +simm = SIMM5(ctx->opcode); \ +tcg_op(avr64_offset(rD(ctx->opcode), true), 16, 16, simm); \ } -GEN_VXFORM_SIMM(vspltisb, 6, 12); -GEN_VXFORM_SIMM(vspltish, 6, 13); -GEN_VXFORM_SIMM(vspltisw, 6, 14); +GEN_VXFORM_DUPI(vspltisb, tcg_gen_gvec_dup8i, 6, 12); +GEN_VXFORM_DUPI(vspltish, tcg_gen_gvec_dup16i, 6, 13); +GEN_VXFORM_DUPI(vspltisw, tcg_gen_gvec_dup32i, 6, 14); #define GEN_VXFORM_NOA(name, opc2, opc3)\ static void glue(gen_, name)(DisasContext *ctx) \ @@ -818,22 +814,6 @@ GEN_VXFORM_NOA(vprtybw, 1, 24); GEN_VXFORM_NOA(vprtybd, 1, 24); GEN_VXFORM_NOA(vprtybq, 1, 24); -#define GEN_VXFORM_SIMM(name, opc2, opc3) \ -static void glue(gen_, name)(DisasContext *ctx) \ -{ \ -TCGv_ptr rd;\ -TCGv_i32 simm; \ -if (unlikely(!ctx->altivec_enabled)) { \ -gen_exception(ctx, POWERPC_EXCP_VPU); \ -return; \ -} \ -
[Qemu-devel] [PATCH 32/34] target/ppc: Split out VSCR_SAT to a vector field
Change the representation of VSCR_SAT such that it is easy to set from vector code. Signed-off-by: Richard Henderson --- target/ppc/cpu.h| 4 +++- target/ppc/int_helper.c | 11 --- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index a2fe6058b1..26d2e16720 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1063,10 +1063,12 @@ struct CPUPPCState { /* Special purpose registers */ target_ulong spr[1024]; ppc_spr_t spr_cb[1024]; -/* Vector status and control register */ +/* Vector status and control register, minus VSCR_SAT. */ uint32_t vscr; /* VSX registers (including FP and AVR) */ ppc_vsr_t vsr[64] QEMU_ALIGNED(16); +/* Non-zero if and only if VSCR_SAT should be set. */ +ppc_vsr_t vscr_sat; /* SPE registers */ uint64_t spe_acc; uint32_t spe_fscr; diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 38aa3e85a6..9dbcbcd87a 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -471,18 +471,23 @@ void helper_lvsr(ppc_avr_t *r, target_ulong sh) void helper_mtvscr(CPUPPCState *env, uint32_t vscr) { -env->vscr = vscr; +env->vscr = vscr & ~(1u << VSCR_SAT); +/* Which bit we set is completely arbitrary, but clear the rest. */ +env->vscr_sat.u64[0] = vscr & (1u << VSCR_SAT); +env->vscr_sat.u64[1] = 0; set_flush_to_zero((vscr >> VSCR_NJ) & 1, >vec_status); } uint32_t helper_mfvscr(CPUPPCState *env) { -return env->vscr; +uint32_t sat = (env->vscr_sat.u64[0] | env->vscr_sat.u64[1]) != 0; +return env->vscr | (sat << VSCR_SAT); } static inline void set_vscr_sat(CPUPPCState *env) { -env->vscr |= 1 << VSCR_SAT; +/* The choice of non-zero value is arbitrary. */ +env->vscr_sat.u32[0] = 1; } void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) -- 2.17.2
[Qemu-devel] [PATCH 07/34] tcg: Add opcodes for vector minmax arithmetic
Signed-off-by: Richard Henderson --- accel/tcg/tcg-runtime.h | 20 tcg/aarch64/tcg-target.h | 1 + tcg/i386/tcg-target.h| 1 + tcg/tcg-op-gvec.h| 10 ++ tcg/tcg-op.h | 4 + tcg/tcg-opc.h| 4 + tcg/tcg.h| 1 + accel/tcg/tcg-runtime-gvec.c | 224 +++ tcg/tcg-op-gvec.c| 108 + tcg/tcg-op-vec.c | 20 tcg/tcg.c| 5 + 11 files changed, 398 insertions(+) diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h index 835ddfebb2..dfe325625c 100644 --- a/accel/tcg/tcg-runtime.h +++ b/accel/tcg/tcg-runtime.h @@ -200,6 +200,26 @@ DEF_HELPER_FLAGS_4(gvec_ussub16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_ussub32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_ussub64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_smin8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_smin16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_smin32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_smin64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(gvec_smax8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_smax16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_smax32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_smax64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(gvec_umin8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_umin16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_umin32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_umin64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(gvec_umax8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_umax16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_umax32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_umax64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + DEF_HELPER_FLAGS_3(gvec_neg8, TCG_CALL_NO_RWG, void, ptr, ptr, i32) DEF_HELPER_FLAGS_3(gvec_neg16, TCG_CALL_NO_RWG, void, ptr, ptr, i32) DEF_HELPER_FLAGS_3(gvec_neg32, TCG_CALL_NO_RWG, void, ptr, ptr, i32) diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index 98556bcf22..545a6eec75 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -136,6 +136,7 @@ typedef enum { #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 #define TCG_TARGET_HAS_sat_vec 0 +#define TCG_TARGET_HAS_minmax_vec 0 #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_HAS_MEMORY_BSWAP 1 diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index f50234d97b..efbd5a6fc9 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -186,6 +186,7 @@ extern bool have_avx2; #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 #define TCG_TARGET_HAS_sat_vec 1 +#define TCG_TARGET_HAS_minmax_vec 0 #define TCG_TARGET_deposit_i32_valid(ofs, len) \ (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \ diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h index 2cb447112e..4734eef7de 100644 --- a/tcg/tcg-op-gvec.h +++ b/tcg/tcg-op-gvec.h @@ -234,6 +234,16 @@ void tcg_gen_gvec_usadd(unsigned vece, uint32_t dofs, uint32_t aofs, void tcg_gen_gvec_ussub(unsigned vece, uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t oprsz, uint32_t maxsz); +/* Min/max. */ +void tcg_gen_gvec_smin(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz); +void tcg_gen_gvec_umin(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz); +void tcg_gen_gvec_smax(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz); +void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz); + void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t oprsz, uint32_t maxsz); void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs, diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 90b3193bf3..042c45e807 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -970,6 +970,10 @@ void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a,
[Qemu-devel] [PATCH 30/34] target/ppc: Use mtvscr/mfvscr for vmstate
This is required before changing the representation of the register. Signed-off-by: Richard Henderson --- target/ppc/machine.c | 44 +--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 451cf376b4..3c27a89166 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -10,6 +10,7 @@ #include "migration/cpu.h" #include "qapi/error.h" #include "kvm_ppc.h" +#include "exec/helper-proto.h" static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) { @@ -17,7 +18,7 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) CPUPPCState *env = >env; unsigned int i, j; target_ulong sdr1; -uint32_t fpscr; +uint32_t fpscr, vscr; #if defined(TARGET_PPC64) int32_t slb_nr; #endif @@ -84,7 +85,8 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) if (!cpu->vhyp) { ppc_store_sdr1(env, sdr1); } -qemu_get_be32s(f, >vscr); +qemu_get_be32s(f, ); +helper_mtvscr(env, vscr); qemu_get_be64s(f, >spe_acc); qemu_get_be32s(f, >spe_fscr); qemu_get_betls(f, >msr_mask); @@ -429,6 +431,28 @@ static bool altivec_needed(void *opaque) return (cpu->env.insns_flags & PPC_ALTIVEC); } +static int get_vscr(QEMUFile *f, void *opaque, size_t size, +const VMStateField *field) +{ +PowerPCCPU *cpu = opaque; +helper_mtvscr(>env, qemu_get_be32(f)); +return 0; +} + +static int put_vscr(QEMUFile *f, void *opaque, size_t size, +const VMStateField *field, QJSON *vmdesc) +{ +PowerPCCPU *cpu = opaque; +qemu_put_be32(f, helper_mfvscr(>env)); +return 0; +} + +static const VMStateInfo vmstate_vscr = { +.name = "cpu/altivec/vscr", +.get = get_vscr, +.put = put_vscr, +}; + static const VMStateDescription vmstate_altivec = { .name = "cpu/altivec", .version_id = 1, @@ -436,7 +460,21 @@ static const VMStateDescription vmstate_altivec = { .needed = altivec_needed, .fields = (VMStateField[]) { VMSTATE_AVR_ARRAY(env.vsr, PowerPCCPU, 32), -VMSTATE_UINT32(env.vscr, PowerPCCPU), +/* + * Save the architecture value of the vscr, not the internally + * expanded version. Since this architecture value does not + * exist in memory to be stored, this requires a but of hoop + * jumping. We want OFFSET=0 so that we effectively pass CPU + * to the helper functions. + */ +{ +.name = "vscr", +.version_id = 0, +.size = sizeof(uint32_t), +.info = _vscr, +.flags = VMS_SINGLE, +.offset = 0 +}, VMSTATE_END_OF_LIST() }, }; -- 2.17.2
[Qemu-devel] [PATCH 18/34] target/ppc: convert vaddu[b, h, w, d] and vsubu[b, h, w, d] over to use vector operations
From: Mark Cave-Ayland Signed-off-by: Mark Cave-Ayland Reviewed-by: Richard Henderson Message-Id: <20181217122405.18732-10-mark.cave-ayl...@ilande.co.uk> --- target/ppc/helper.h | 8 target/ppc/int_helper.c | 7 --- target/ppc/translate/vmx-impl.inc.c | 16 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index c7de04e068..553ff500c8 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -108,14 +108,6 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64) #define dh_ctype_avr ppc_avr_t * #define dh_is_signed_avr dh_is_signed_ptr -DEF_HELPER_3(vaddubm, void, avr, avr, avr) -DEF_HELPER_3(vadduhm, void, avr, avr, avr) -DEF_HELPER_3(vadduwm, void, avr, avr, avr) -DEF_HELPER_3(vaddudm, void, avr, avr, avr) -DEF_HELPER_3(vsububm, void, avr, avr, avr) -DEF_HELPER_3(vsubuhm, void, avr, avr, avr) -DEF_HELPER_3(vsubuwm, void, avr, avr, avr) -DEF_HELPER_3(vsubudm, void, avr, avr, avr) DEF_HELPER_3(vavgub, void, avr, avr, avr) DEF_HELPER_3(vavguh, void, avr, avr, avr) DEF_HELPER_3(vavguw, void, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 9d715be25c..4547453ef1 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -531,13 +531,6 @@ void helper_vprtybq(ppc_avr_t *r, ppc_avr_t *b) r->element[i] = a->element[i] op b->element[i]; \ } \ } -#define VARITH(suffix, element) \ -VARITH_DO(add##suffix, +, element) \ -VARITH_DO(sub##suffix, -, element) -VARITH(ubm, u8) -VARITH(uhm, u16) -VARITH(uwm, u32) -VARITH(udm, u64) VARITH_DO(muluwm, *, u32) #undef VARITH_DO #undef VARITH diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index c13828a09d..e353d3f174 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -411,18 +411,18 @@ static void glue(gen_, name)(DisasContext *ctx) \ tcg_temp_free_ptr(rb); \ } -GEN_VXFORM(vaddubm, 0, 0); +GEN_VXFORM_V(vaddubm, MO_8, tcg_gen_gvec_add, 0, 0); GEN_VXFORM_DUAL_EXT(vaddubm, PPC_ALTIVEC, PPC_NONE, 0, \ vmul10cuq, PPC_NONE, PPC2_ISA300, 0xF800) -GEN_VXFORM(vadduhm, 0, 1); +GEN_VXFORM_V(vadduhm, MO_16, tcg_gen_gvec_add, 0, 1); GEN_VXFORM_DUAL(vadduhm, PPC_ALTIVEC, PPC_NONE, \ vmul10ecuq, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vadduwm, 0, 2); -GEN_VXFORM(vaddudm, 0, 3); -GEN_VXFORM(vsububm, 0, 16); -GEN_VXFORM(vsubuhm, 0, 17); -GEN_VXFORM(vsubuwm, 0, 18); -GEN_VXFORM(vsubudm, 0, 19); +GEN_VXFORM_V(vadduwm, MO_32, tcg_gen_gvec_add, 0, 2); +GEN_VXFORM_V(vaddudm, MO_64, tcg_gen_gvec_add, 0, 3); +GEN_VXFORM_V(vsububm, MO_8, tcg_gen_gvec_sub, 0, 16); +GEN_VXFORM_V(vsubuhm, MO_16, tcg_gen_gvec_sub, 0, 17); +GEN_VXFORM_V(vsubuwm, MO_32, tcg_gen_gvec_sub, 0, 18); +GEN_VXFORM_V(vsubudm, MO_64, tcg_gen_gvec_sub, 0, 19); GEN_VXFORM(vmaxub, 1, 0); GEN_VXFORM(vmaxuh, 1, 1); GEN_VXFORM(vmaxuw, 1, 2); -- 2.17.2
[Qemu-devel] [PATCH 22/34] target/ppc: convert VSX logical operations to vector operations
Signed-off-by: Richard Henderson --- target/ppc/translate/vsx-impl.inc.c | 43 - 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 1608ad48b1..8ab1290026 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -10,6 +10,11 @@ static inline void set_vsr(int n, TCGv_i64 src) tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1])); } +static inline int vsr_full_offset(int n) +{ +return offsetof(CPUPPCState, vsr[n].u64[0]); +} + static inline void get_cpu_vsrh(TCGv_i64 dst, int n) { if (n < 32) { @@ -1214,40 +1219,26 @@ static void gen_xxbrw(DisasContext *ctx) tcg_temp_free_i64(xbl); } -#define VSX_LOGICAL(name, tcg_op)\ +#define VSX_LOGICAL(name, vece, tcg_op) \ static void glue(gen_, name)(DisasContext * ctx) \ {\ -TCGv_i64 t0; \ -TCGv_i64 t1; \ -TCGv_i64 t2; \ if (unlikely(!ctx->vsx_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_VSXU); \ return; \ }\ -t0 = tcg_temp_new_i64(); \ -t1 = tcg_temp_new_i64(); \ -t2 = tcg_temp_new_i64(); \ -get_cpu_vsrh(t0, xA(ctx->opcode)); \ -get_cpu_vsrh(t1, xB(ctx->opcode)); \ -tcg_op(t2, t0, t1); \ -set_cpu_vsrh(xT(ctx->opcode), t2); \ -get_cpu_vsrl(t0, xA(ctx->opcode)); \ -get_cpu_vsrl(t1, xB(ctx->opcode)); \ -tcg_op(t2, t0, t1); \ -set_cpu_vsrl(xT(ctx->opcode), t2); \ -tcg_temp_free_i64(t0); \ -tcg_temp_free_i64(t1); \ -tcg_temp_free_i64(t2); \ +tcg_op(vece, vsr_full_offset(xT(ctx->opcode)), \ + vsr_full_offset(xA(ctx->opcode)), \ + vsr_full_offset(xB(ctx->opcode)), 16, 16);\ } -VSX_LOGICAL(xxland, tcg_gen_and_i64) -VSX_LOGICAL(xxlandc, tcg_gen_andc_i64) -VSX_LOGICAL(xxlor, tcg_gen_or_i64) -VSX_LOGICAL(xxlxor, tcg_gen_xor_i64) -VSX_LOGICAL(xxlnor, tcg_gen_nor_i64) -VSX_LOGICAL(xxleqv, tcg_gen_eqv_i64) -VSX_LOGICAL(xxlnand, tcg_gen_nand_i64) -VSX_LOGICAL(xxlorc, tcg_gen_orc_i64) +VSX_LOGICAL(xxland, MO_64, tcg_gen_gvec_and) +VSX_LOGICAL(xxlandc, MO_64, tcg_gen_gvec_andc) +VSX_LOGICAL(xxlor, MO_64, tcg_gen_gvec_or) +VSX_LOGICAL(xxlxor, MO_64, tcg_gen_gvec_xor) +VSX_LOGICAL(xxlnor, MO_64, tcg_gen_gvec_nor) +VSX_LOGICAL(xxleqv, MO_64, tcg_gen_gvec_eqv) +VSX_LOGICAL(xxlnand, MO_64, tcg_gen_gvec_nand) +VSX_LOGICAL(xxlorc, MO_64, tcg_gen_gvec_orc) #define VSX_XXMRG(name, high) \ static void glue(gen_, name)(DisasContext * ctx)\ -- 2.17.2
[Qemu-devel] [PATCH 02/34] target/arm: Rely on optimization within tcg_gen_gvec_or
Since we're now handling a == b generically, we no longer need to do it by hand within target/arm/. Signed-off-by: Richard Henderson --- target/arm/translate-a64.c | 6 +- target/arm/translate-sve.c | 6 +- target/arm/translate.c | 12 +++- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index e1da1e4d6f..2d6f8c1b4f 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -10152,11 +10152,7 @@ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn) gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_andc, 0); return; case 2: /* ORR */ -if (rn == rm) { /* MOV */ -gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_mov, 0); -} else { -gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0); -} +gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0); return; case 3: /* ORN */ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0); diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c index b15b615ceb..3a2eb51566 100644 --- a/target/arm/translate-sve.c +++ b/target/arm/translate-sve.c @@ -280,11 +280,7 @@ static bool trans_AND_zzz(DisasContext *s, arg_rrr_esz *a) static bool trans_ORR_zzz(DisasContext *s, arg_rrr_esz *a) { -if (a->rn == a->rm) { /* MOV */ -return do_mov_z(s, a->rd, a->rn); -} else { -return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm); -} +return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm); } static bool trans_EOR_zzz(DisasContext *s, arg_rrr_esz *a) diff --git a/target/arm/translate.c b/target/arm/translate.c index 7c4675ffd8..33b1860148 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -6294,15 +6294,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size); break; -case 2: -if (rn == rm) { -/* VMOV */ -tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size); -} else { -/* VORR */ -tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs, -vec_size, vec_size); -} +case 2: /* VORR */ +tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs, +vec_size, vec_size); break; case 3: /* VORN */ tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs, -- 2.17.2
[Qemu-devel] [PATCH 13/34] target/ppc: introduce get_cpu_vsr{l, h}() and set_cpu_vsr{l, h}() helpers for VSR register access
From: Mark Cave-Ayland These helpers allow us to move VSR register values to/from the specified TCGv_i64 argument. To prevent VSX helpers accessing the cpu_vsr array directly, add extra TCG temporaries as required. Signed-off-by: Mark Cave-Ayland Message-Id: <20181217122405.18732-4-mark.cave-ayl...@ilande.co.uk> --- target/ppc/translate/vsx-impl.inc.c | 782 1 file changed, 561 insertions(+), 221 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 85ed135d44..e9a05d66f7 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1,20 +1,48 @@ /*** VSX extension ***/ -static inline TCGv_i64 cpu_vsrh(int n) +static inline void get_vsr(TCGv_i64 dst, int n) +{ +tcg_gen_mov_i64(dst, cpu_vsr[n]); +} + +static inline void set_vsr(int n, TCGv_i64 src) +{ +tcg_gen_mov_i64(cpu_vsr[n], src); +} + +static inline void get_cpu_vsrh(TCGv_i64 dst, int n) { if (n < 32) { -return cpu_fpr[n]; +get_fpr(dst, n); } else { -return cpu_avrh[n-32]; +get_avr64(dst, n - 32, true); } } -static inline TCGv_i64 cpu_vsrl(int n) +static inline void get_cpu_vsrl(TCGv_i64 dst, int n) { if (n < 32) { -return cpu_vsr[n]; +get_vsr(dst, n); } else { -return cpu_avrl[n-32]; +get_avr64(dst, n - 32, false); +} +} + +static inline void set_cpu_vsrh(int n, TCGv_i64 src) +{ +if (n < 32) { +set_fpr(n, src); +} else { +set_avr64(n - 32, src, true); +} +} + +static inline void set_cpu_vsrl(int n, TCGv_i64 src) +{ +if (n < 32) { +set_vsr(n, src); +} else { +set_avr64(n - 32, src, false); } } @@ -22,16 +50,20 @@ static inline TCGv_i64 cpu_vsrl(int n) static void gen_##name(DisasContext *ctx) \ { \ TCGv EA; \ +TCGv_i64 t0; \ if (unlikely(!ctx->vsx_enabled)) {\ gen_exception(ctx, POWERPC_EXCP_VSXU);\ return; \ } \ +t0 = tcg_temp_new_i64(); \ gen_set_access_type(ctx, ACCESS_INT); \ EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ -gen_qemu_##operation(ctx, cpu_vsrh(xT(ctx->opcode)), EA); \ +gen_qemu_##operation(ctx, t0, EA);\ +set_cpu_vsrh(xT(ctx->opcode), t0);\ /* NOTE: cpu_vsrl is undefined */ \ tcg_temp_free(EA);\ +tcg_temp_free_i64(t0);\ } VSX_LOAD_SCALAR(lxsdx, ld64_i64) @@ -44,39 +76,54 @@ VSX_LOAD_SCALAR(lxsspx, ld32fs) static void gen_lxvd2x(DisasContext *ctx) { TCGv EA; +TCGv_i64 t0; if (unlikely(!ctx->vsx_enabled)) { gen_exception(ctx, POWERPC_EXCP_VSXU); return; } +t0 = tcg_temp_new_i64(); gen_set_access_type(ctx, ACCESS_INT); EA = tcg_temp_new(); gen_addr_reg_index(ctx, EA); -gen_qemu_ld64_i64(ctx, cpu_vsrh(xT(ctx->opcode)), EA); +gen_qemu_ld64_i64(ctx, t0, EA); +set_cpu_vsrh(xT(ctx->opcode), t0); tcg_gen_addi_tl(EA, EA, 8); -gen_qemu_ld64_i64(ctx, cpu_vsrl(xT(ctx->opcode)), EA); +gen_qemu_ld64_i64(ctx, t0, EA); +set_cpu_vsrl(xT(ctx->opcode), t0); tcg_temp_free(EA); +tcg_temp_free_i64(t0); } static void gen_lxvdsx(DisasContext *ctx) { TCGv EA; +TCGv_i64 t0; +TCGv_i64 t1; if (unlikely(!ctx->vsx_enabled)) { gen_exception(ctx, POWERPC_EXCP_VSXU); return; } +t0 = tcg_temp_new_i64(); +t1 = tcg_temp_new_i64(); gen_set_access_type(ctx, ACCESS_INT); EA = tcg_temp_new(); gen_addr_reg_index(ctx, EA); -gen_qemu_ld64_i64(ctx, cpu_vsrh(xT(ctx->opcode)), EA); -tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode))); +gen_qemu_ld64_i64(ctx, t0, EA); +set_cpu_vsrh(xT(ctx->opcode), t0); +tcg_gen_mov_i64(t1, t0); +set_cpu_vsrl(xT(ctx->opcode), t1); tcg_temp_free(EA); +tcg_temp_free_i64(t0); +tcg_temp_free_i64(t1); } static void gen_lxvw4x(DisasContext *ctx) { TCGv EA; -TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode)); -TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode)); +TCGv_i64 xth = tcg_temp_new_i64(); +TCGv_i64 xtl = tcg_temp_new_i64(); +get_cpu_vsrh(xth, xT(ctx->opcode)); +get_cpu_vsrh(xtl, xT(ctx->opcode)); if (unlikely(!ctx->vsx_enabled)) { gen_exception(ctx, POWERPC_EXCP_VSXU); return; @@ -104,6
[Qemu-devel] [PATCH 31/34] target/ppc: Add set_vscr_sat
This is required before changing the representation of the register. Signed-off-by: Richard Henderson --- target/ppc/int_helper.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 75201bbba6..38aa3e85a6 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -480,6 +480,11 @@ uint32_t helper_mfvscr(CPUPPCState *env) return env->vscr; } +static inline void set_vscr_sat(CPUPPCState *env) +{ +env->vscr |= 1 << VSCR_SAT; +} + void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int i; @@ -593,7 +598,7 @@ VARITHFPFMA(nmsubfp, float_muladd_negate_result | float_muladd_negate_c); } \ } \ if (sat) { \ -env->vscr |= (1 << VSCR_SAT); \ +set_vscr_sat(env); \ } \ } #define VARITHSAT_SIGNED(suffix, element, optype, cvt) \ @@ -865,7 +870,7 @@ void helper_vcmpbfp_dot(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } \ } \ if (sat) { \ -env->vscr |= (1 << VSCR_SAT); \ +set_vscr_sat(env); \ } \ } VCT(uxs, cvtsduw, u32) @@ -916,7 +921,7 @@ void helper_vmhaddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -933,7 +938,7 @@ void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -1061,7 +1066,7 @@ void helper_vmsumshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -1114,7 +1119,7 @@ void helper_vmsumuhs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -1633,7 +1638,7 @@ void helper_vpkpx(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } \ *r = result;\ if (dosat && sat) { \ -env->vscr |= (1 << VSCR_SAT); \ +set_vscr_sat(env); \ } \ } #define I(x, y) (x) @@ -2106,7 +2111,7 @@ void helper_vsumsws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) *r = result; if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -2133,7 +2138,7 @@ void helper_vsum2sws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) *r = result; if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -2152,7 +2157,7 @@ void helper_vsum4sbs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -2169,7 +2174,7 @@ void helper_vsum4shs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } @@ -2188,7 +2193,7 @@ void helper_vsum4ubs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } if (sat) { -env->vscr |= (1 << VSCR_SAT); +set_vscr_sat(env); } } -- 2.17.2
[Qemu-devel] [PATCH 21/34] target/ppc: nand, nor, eqv are now generic vector operations
Signed-off-by: Richard Henderson --- target/ppc/translate/vmx-impl.inc.c | 26 +++--- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 529ae0e5f5..329131d30b 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -277,34 +277,14 @@ static void glue(gen_, name)(DisasContext *ctx) \ 16, 16); \ } -#define GEN_VXFORM_VN(name, vece, tcg_op, opc2, opc3) \ -static void glue(gen_, name)(DisasContext *ctx) \ -{ \ -if (unlikely(!ctx->altivec_enabled)) { \ -gen_exception(ctx, POWERPC_EXCP_VPU); \ -return; \ -} \ -\ -tcg_op(vece,\ - avr64_offset(rD(ctx->opcode), true), \ - avr64_offset(rA(ctx->opcode), true), \ - avr64_offset(rB(ctx->opcode), true), \ - 16, 16); \ -\ -tcg_gen_gvec_not(vece, \ - avr64_offset(rD(ctx->opcode), true), \ - avr64_offset(rD(ctx->opcode), true), \ - 16, 16); \ -} - /* Logical operations */ GEN_VXFORM_V(vand, MO_64, tcg_gen_gvec_and, 2, 16); GEN_VXFORM_V(vandc, MO_64, tcg_gen_gvec_andc, 2, 17); GEN_VXFORM_V(vor, MO_64, tcg_gen_gvec_or, 2, 18); GEN_VXFORM_V(vxor, MO_64, tcg_gen_gvec_xor, 2, 19); -GEN_VXFORM_VN(vnor, MO_64, tcg_gen_gvec_or, 2, 20); -GEN_VXFORM_VN(veqv, MO_64, tcg_gen_gvec_xor, 2, 26); -GEN_VXFORM_VN(vnand, MO_64, tcg_gen_gvec_and, 2, 22); +GEN_VXFORM_V(vnor, MO_64, tcg_gen_gvec_nor, 2, 20); +GEN_VXFORM_V(veqv, MO_64, tcg_gen_gvec_eqv, 2, 26); +GEN_VXFORM_V(vnand, MO_64, tcg_gen_gvec_nand, 2, 22); GEN_VXFORM_V(vorc, MO_64, tcg_gen_gvec_orc, 2, 21); #define GEN_VXFORM(name, opc2, opc3)\ -- 2.17.2
[Qemu-devel] [PATCH 16/34] target/ppc: move FP and VMX registers into aligned vsr register array
From: Mark Cave-Ayland The VSX register array is a block of 64 128-bit registers where the first 32 registers consist of the existing 64-bit FP registers extended to 128-bit using new VSR registers, and the last 32 registers are the VMX 128-bit registers as show below: 64-bit 64-bit +++ |FP0 || VSR0 +++ |FP1 || VSR1 +++ |... |... | ... +++ |FP30|| VSR30 +++ |FP31|| VSR31 +++ | VMX0 | VSR32 +-+ | VMX1 | VSR33 +-+ | ...| ... +-+ | VMX30 | VSR62 +-+ | VMX31 | VSR63 +-+ In order to allow for future conversion of VSX instructions to use TCG vector operations, recreate the same layout using an aligned version of the existing vsr register array. Since the old fpr and avr register arrays are removed, the existing callers must also be updated to use the correct offset in the vsr register array. This also includes switching the relevant VMState fields over to using subarrays to make sure that migration is preserved. Signed-off-by: Mark Cave-Ayland Message-Id: <20181217122405.18732-8-mark.cave-ayl...@ilande.co.uk> --- target/ppc/cpu.h| 9 ++-- target/ppc/internal.h | 18 ++-- linux-user/ppc/signal.c | 24 +- target/ppc/arch_dump.c | 12 ++--- target/ppc/gdbstub.c| 8 ++-- target/ppc/machine.c| 72 +++-- target/ppc/monitor.c| 4 +- target/ppc/translate.c | 14 +++--- target/ppc/translate/dfp-impl.inc.c | 2 +- target/ppc/translate/vmx-impl.inc.c | 7 ++- target/ppc/translate/vsx-impl.inc.c | 4 +- target/ppc/translate_init.inc.c | 24 +- 12 files changed, 126 insertions(+), 72 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 5445d4c3c1..c8f449081d 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1016,8 +1016,6 @@ struct CPUPPCState { /* Floating point execution context */ float_status fp_status; -/* floating point registers */ -float64 fpr[32]; /* floating point status and control register */ target_ulong fpscr; @@ -1067,11 +1065,10 @@ struct CPUPPCState { /* Special purpose registers */ target_ulong spr[1024]; ppc_spr_t spr_cb[1024]; -/* Altivec registers */ -ppc_avr_t avr[32]; +/* Vector status and control register */ uint32_t vscr; -/* VSX registers */ -uint64_t vsr[32]; +/* VSX registers (including FP and AVR) */ +ppc_vsr_t vsr[64] QEMU_ALIGNED(16); /* SPE registers */ uint64_t spe_acc; uint32_t spe_fscr; diff --git a/target/ppc/internal.h b/target/ppc/internal.h index b4b1f7b3db..b77d564a65 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -218,24 +218,14 @@ EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6); static inline void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) { -if (n < 32) { -vsr->VsrD(0) = env->fpr[n]; -vsr->VsrD(1) = env->vsr[n]; -} else { -vsr->u64[0] = env->avr[n - 32].u64[0]; -vsr->u64[1] = env->avr[n - 32].u64[1]; -} +vsr->VsrD(0) = env->vsr[n].u64[0]; +vsr->VsrD(1) = env->vsr[n].u64[1]; } static inline void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) { -if (n < 32) { -env->fpr[n] = vsr->VsrD(0); -env->vsr[n] = vsr->VsrD(1); -} else { -env->avr[n - 32].u64[0] = vsr->u64[0]; -env->avr[n - 32].u64[1] = vsr->u64[1]; -} +env->vsr[n].u64[0] = vsr->VsrD(0); +env->vsr[n].u64[1] = vsr->VsrD(1); } void helper_compute_fprf_float16(CPUPPCState *env, float16 arg); diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c index 2ae120a2bc..a053dd5b84 100644 --- a/linux-user/ppc/signal.c +++ b/linux-user/ppc/signal.c @@ -258,8 +258,8 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame) /* Save Altivec registers if necessary. */ if (env->insns_flags & PPC_ALTIVEC) { uint32_t *vrsave; -for (i = 0; i < ARRAY_SIZE(env->avr); i++) { -ppc_avr_t *avr = >avr[i]; +for (i = 0; i < 32; i++) { +
[Qemu-devel] [PATCH 05/34] tcg: Add opcodes for vector saturated arithmetic
Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.h | 1 + tcg/i386/tcg-target.h| 1 + tcg/tcg-op.h | 4 ++ tcg/tcg-opc.h| 4 ++ tcg/tcg.h| 1 + tcg/tcg-op-gvec.c| 84 ++-- tcg/tcg-op-vec.c | 34 ++-- tcg/tcg.c| 5 +++ 8 files changed, 110 insertions(+), 24 deletions(-) diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index f966a4fcb3..98556bcf22 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -135,6 +135,7 @@ typedef enum { #define TCG_TARGET_HAS_shv_vec 0 #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 +#define TCG_TARGET_HAS_sat_vec 0 #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_HAS_MEMORY_BSWAP 1 diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index f378d29568..44381062e6 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -185,6 +185,7 @@ extern bool have_avx2; #define TCG_TARGET_HAS_shv_vec 0 #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 +#define TCG_TARGET_HAS_sat_vec 0 #define TCG_TARGET_deposit_i32_valid(ofs, len) \ (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \ diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 1974bf1cae..90b3193bf3 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -966,6 +966,10 @@ void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a); void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a); +void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_shli_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i); void tcg_gen_shri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i); diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index e3a43aabb6..94691e849b 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -221,6 +221,10 @@ DEF(add_vec, 1, 2, 0, IMPLVEC) DEF(sub_vec, 1, 2, 0, IMPLVEC) DEF(mul_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_mul_vec)) DEF(neg_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_neg_vec)) +DEF(ssadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) +DEF(usadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) +DEF(sssub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) +DEF(ussub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec)) DEF(and_vec, 1, 2, 0, IMPLVEC) DEF(or_vec, 1, 2, 0, IMPLVEC) diff --git a/tcg/tcg.h b/tcg/tcg.h index ade692fdf5..c90f65a387 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -183,6 +183,7 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_shs_vec 0 #define TCG_TARGET_HAS_shv_vec 0 #define TCG_TARGET_HAS_mul_vec 0 +#define TCG_TARGET_HAS_sat_vec 0 #else #define TCG_TARGET_MAYBE_vec1 #endif diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c index c10d3d7b26..0a33f51065 100644 --- a/tcg/tcg-op-gvec.c +++ b/tcg/tcg-op-gvec.c @@ -1678,10 +1678,22 @@ void tcg_gen_gvec_ssadd(unsigned vece, uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t oprsz, uint32_t maxsz) { static const GVecGen3 g[4] = { -{ .fno = gen_helper_gvec_ssadd8, .vece = MO_8 }, -{ .fno = gen_helper_gvec_ssadd16, .vece = MO_16 }, -{ .fno = gen_helper_gvec_ssadd32, .vece = MO_32 }, -{ .fno = gen_helper_gvec_ssadd64, .vece = MO_64 } +{ .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd8, + .opc = INDEX_op_ssadd_vec, + .vece = MO_8 }, +{ .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd16, + .opc = INDEX_op_ssadd_vec, + .vece = MO_16 }, +{ .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd32, + .opc = INDEX_op_ssadd_vec, + .vece = MO_32 }, +{ .fniv = tcg_gen_ssadd_vec, + .fno = gen_helper_gvec_ssadd64, + .opc = INDEX_op_ssadd_vec, + .vece = MO_64 }, }; tcg_debug_assert(vece <= MO_64); tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, [vece]); @@ -1691,16 +1703,28 @@ void tcg_gen_gvec_sssub(unsigned vece, uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t oprsz, uint32_t maxsz) { static const GVecGen3 g[4] = { -{ .fno = gen_helper_gvec_sssub8, .vece = MO_8 }, -{ .fno = gen_helper_gvec_sssub16, .vece = MO_16 }, -{ .fno = gen_helper_gvec_sssub32, .vece = MO_32 }, -{ .fno = gen_helper_gvec_sssub64, .vece = MO_64 } +{ .fniv = tcg_gen_sssub_vec, +
[Qemu-devel] [PATCH 10/34] target/arm: Use vector minmax expanders for aarch32
Signed-off-by: Richard Henderson --- target/arm/translate.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index 33b1860148..f3f172f384 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -6368,6 +6368,25 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size); return 0; + +case NEON_3R_VMAX: +if (u) { +tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs, + vec_size, vec_size); +} else { +tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs, + vec_size, vec_size); +} +return 0; +case NEON_3R_VMIN: +if (u) { +tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs, + vec_size, vec_size); +} else { +tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs, + vec_size, vec_size); +} +return 0; } if (size == 3) { @@ -6533,12 +6552,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) case NEON_3R_VQRSHL: GEN_NEON_INTEGER_OP_ENV(qrshl); break; -case NEON_3R_VMAX: -GEN_NEON_INTEGER_OP(max); -break; -case NEON_3R_VMIN: -GEN_NEON_INTEGER_OP(min); -break; case NEON_3R_VABD: GEN_NEON_INTEGER_OP(abd); break; -- 2.17.2
[Qemu-devel] [PATCH 23/34] target/ppc: convert xxspltib to vector operations
Signed-off-by: Richard Henderson --- target/ppc/translate/vsx-impl.inc.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 8ab1290026..d88d6bbd74 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1356,9 +1356,10 @@ static void gen_xxspltw(DisasContext *ctx) static void gen_xxspltib(DisasContext *ctx) { -unsigned char uim8 = IMM8(ctx->opcode); -TCGv_i64 vsr = tcg_temp_new_i64(); -if (xS(ctx->opcode) < 32) { +uint8_t uim8 = IMM8(ctx->opcode); +int rt = xT(ctx->opcode); + +if (rt < 32) { if (unlikely(!ctx->altivec_enabled)) { gen_exception(ctx, POWERPC_EXCP_VPU); return; @@ -1369,10 +1370,7 @@ static void gen_xxspltib(DisasContext *ctx) return; } } -tcg_gen_movi_i64(vsr, pattern(uim8)); -set_cpu_vsrh(xT(ctx->opcode), vsr); -set_cpu_vsrl(xT(ctx->opcode), vsr); -tcg_temp_free_i64(vsr); +tcg_gen_gvec_dup8i(vsr_full_offset(rt), 16, 16, uim8); } static void gen_xxsldwi(DisasContext *ctx) -- 2.17.2
[Qemu-devel] [PATCH 00/34] tcg, target/ppc vector improvements
This implements some of the things that I talked about with Mark this morning / yesterday. In particular: (0) Implement expanders for nand, nor, eqv logical operations. (1) Implement saturating arithmetic for the tcg backend. While I had expanders for these, they always went to helpers. It's easy enough to expand byte and half-word operations for x86. Beyond that, 32 and 64-bit operations can be expanded with integers. (2) Implement minmax arithmetic for the tcg backend. While I had integral minmax operations, I had not yet added any vector expanders for this. (The integral stuff came in for atomic minmax.) (3) Trivial conversions to minmax for target/arm. (4) Patches 11-18 are identical to Mark's. (5) Patches 19-25 implement splat and logicals for VMX and VSX. VSX is no more difficult than VMX for these. It does seem to be just about everything that we can do for VSX at the momement. (6) Patches 26-33 implement saturating arithmetic for VMX. (7) Patch 34 implements minmax arithmetic for VMX. I've tested the new operations via aarch64 guest, as that's the set of risu test cases I've got handy. The rest is untested so far. r~ Mark Cave-Ayland (8): target/ppc: introduce get_fpr() and set_fpr() helpers for FP register access target/ppc: introduce get_avr64() and set_avr64() helpers for VMX register access target/ppc: introduce get_cpu_vsr{l,h}() and set_cpu_vsr{l,h}() helpers for VSR register access target/ppc: switch FPR, VMX and VSX helpers to access data directly from cpu_env target/ppc: merge ppc_vsr_t and ppc_avr_t union types target/ppc: move FP and VMX registers into aligned vsr register array target/ppc: convert VMX logical instructions to use vector operations target/ppc: convert vaddu[b,h,w,d] and vsubu[b,h,w,d] over to use vector operations Richard Henderson (26): tcg: Add logical simplifications during gvec expand target/arm: Rely on optimization within tcg_gen_gvec_or tcg: Add gvec expanders for nand, nor, eqv tcg: Add write_aofs to GVecGen4 tcg: Add opcodes for vector saturated arithmetic tcg/i386: Implement vector saturating arithmetic tcg: Add opcodes for vector minmax arithmetic tcg/i386: Implement vector minmax arithmetic target/arm: Use vector minmax expanders for aarch64 target/arm: Use vector minmax expanders for aarch32 target/ppc: convert vspltis[bhw] to use vector operations target/ppc: convert vsplt[bhw] to use vector operations target/ppc: nand, nor, eqv are now generic vector operations target/ppc: convert VSX logical operations to vector operations target/ppc: convert xxspltib to vector operations target/ppc: convert xxspltw to vector operations target/ppc: convert xxsel to vector operations target/ppc: Pass integer to helper_mtvscr target/ppc: Use helper_mtvscr for reset and gdb target/ppc: Remove vscr_nj and vscr_sat target/ppc: Add helper_mfvscr target/ppc: Use mtvscr/mfvscr for vmstate target/ppc: Add set_vscr_sat target/ppc: Split out VSCR_SAT to a vector field target/ppc: convert vadd*s and vsub*s to vector operations target/ppc: convert vmin* and vmax* to vector operations accel/tcg/tcg-runtime.h | 23 + target/ppc/cpu.h| 30 +- target/ppc/helper.h | 57 +- target/ppc/internal.h | 29 +- tcg/aarch64/tcg-target.h| 2 + tcg/i386/tcg-target.h | 2 + tcg/tcg-op-gvec.h | 18 + tcg/tcg-op.h| 11 + tcg/tcg-opc.h | 8 + tcg/tcg.h | 2 + accel/tcg/tcg-runtime-gvec.c| 257 + linux-user/ppc/signal.c | 24 +- target/arm/translate-a64.c | 41 +- target/arm/translate-sve.c | 6 +- target/arm/translate.c | 37 +- target/ppc/arch_dump.c | 15 +- target/ppc/gdbstub.c| 8 +- target/ppc/int_helper.c | 194 +++ target/ppc/machine.c| 116 +++- target/ppc/monitor.c| 4 +- target/ppc/translate.c | 74 ++- target/ppc/translate/dfp-impl.inc.c | 2 +- target/ppc/translate/fp-impl.inc.c | 490 target/ppc/translate/vmx-impl.inc.c | 349 +++- target/ppc/translate/vsx-impl.inc.c | 834 +++- target/ppc/translate_init.inc.c | 31 +- tcg/i386/tcg-target.inc.c | 106 tcg/tcg-op-gvec.c | 305 -- tcg/tcg-op-vec.c| 75 ++- tcg/tcg.c | 10 + 30 files changed, 2275 insertions(+), 885 deletions(-) -- 2.17.2
[Qemu-devel] [PATCH 26/34] target/ppc: Pass integer to helper_mtvscr
We can re-use this helper elsewhere if we're not passing in an entire vector register. Signed-off-by: Richard Henderson --- target/ppc/helper.h | 2 +- target/ppc/int_helper.c | 10 +++--- target/ppc/translate/vmx-impl.inc.c | 17 + 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 069daa9883..b3ffe28103 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -294,7 +294,7 @@ DEF_HELPER_5(vmsumuhs, void, env, avr, avr, avr, avr) DEF_HELPER_5(vmsumshm, void, env, avr, avr, avr, avr) DEF_HELPER_5(vmsumshs, void, env, avr, avr, avr, avr) DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr) -DEF_HELPER_2(mtvscr, void, env, avr) +DEF_HELPER_FLAGS_2(mtvscr, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_3(lvebx, void, env, avr, tl) DEF_HELPER_3(lvehx, void, env, avr, tl) DEF_HELPER_3(lvewx, void, env, avr, tl) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 3bf0fdb6c5..0443f33cd2 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -469,14 +469,10 @@ void helper_lvsr(ppc_avr_t *r, target_ulong sh) } } -void helper_mtvscr(CPUPPCState *env, ppc_avr_t *r) +void helper_mtvscr(CPUPPCState *env, uint32_t vscr) { -#if defined(HOST_WORDS_BIGENDIAN) -env->vscr = r->u32[3]; -#else -env->vscr = r->u32[0]; -#endif -set_flush_to_zero(vscr_nj, >vec_status); +env->vscr = vscr; +set_flush_to_zero((vscr >> VSCR_NJ) & 1, >vec_status); } void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 329131d30b..ab6da3aa55 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -196,14 +196,23 @@ static void gen_mfvscr(DisasContext *ctx) static void gen_mtvscr(DisasContext *ctx) { -TCGv_ptr p; +TCGv_i32 val; +int bofs; + if (unlikely(!ctx->altivec_enabled)) { gen_exception(ctx, POWERPC_EXCP_VPU); return; } -p = gen_avr_ptr(rB(ctx->opcode)); -gen_helper_mtvscr(cpu_env, p); -tcg_temp_free_ptr(p); + +val = tcg_temp_new_i32(); +bofs = avr64_offset(rB(ctx->opcode), true); +#ifdef HOST_WORDS_BIGENDIAN +bofs += 3 * 4; +#endif + +tcg_gen_ld_i32(val, cpu_env, bofs); +gen_helper_mtvscr(cpu_env, val); +tcg_temp_free_i32(val); } #define GEN_VX_VMUL10(name, add_cin, ret_carry) \ -- 2.17.2
[Qemu-devel] [PATCH 12/34] target/ppc: introduce get_avr64() and set_avr64() helpers for VMX register access
From: Mark Cave-Ayland These helpers allow us to move AVR register values to/from the specified TCGv_i64 argument. To prevent VMX helpers accessing the cpu_avr{l,h} arrays directly, add extra TCG temporaries as required. Signed-off-by: Mark Cave-Ayland Reviewed-by: Richard Henderson Message-Id: <20181217122405.18732-3-mark.cave-ayl...@ilande.co.uk> --- target/ppc/translate.c | 10 +++ target/ppc/translate/vmx-impl.inc.c | 128 ++-- 2 files changed, 110 insertions(+), 28 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 1d4bf624a3..fa3e8dc114 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6704,6 +6704,16 @@ static inline void set_fpr(int regno, TCGv_i64 src) tcg_gen_mov_i64(cpu_fpr[regno], src); } +static inline void get_avr64(TCGv_i64 dst, int regno, bool high) +{ +tcg_gen_mov_i64(dst, (high ? cpu_avrh : cpu_avrl)[regno]); +} + +static inline void set_avr64(int regno, TCGv_i64 src, bool high) +{ +tcg_gen_mov_i64((high ? cpu_avrh : cpu_avrl)[regno], src); +} + #include "translate/fp-impl.inc.c" #include "translate/vmx-impl.inc.c" diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 3cb6fc2926..30046c6e31 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -18,52 +18,66 @@ static inline TCGv_ptr gen_avr_ptr(int reg) static void glue(gen_, name)(DisasContext *ctx) \ { \ TCGv EA; \ +TCGv_i64 avr; \ if (unlikely(!ctx->altivec_enabled)) {\ gen_exception(ctx, POWERPC_EXCP_VPU); \ return; \ } \ gen_set_access_type(ctx, ACCESS_INT); \ +avr = tcg_temp_new_i64(); \ EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ tcg_gen_andi_tl(EA, EA, ~0xf);\ /* We only need to swap high and low halves. gen_qemu_ld64_i64 does \ necessary 64-bit byteswap already. */ \ if (ctx->le_mode) { \ -gen_qemu_ld64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA);\ +gen_qemu_ld64_i64(ctx, avr, EA); \ +set_avr64(rD(ctx->opcode), avr, false); \ tcg_gen_addi_tl(EA, EA, 8); \ -gen_qemu_ld64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA);\ +gen_qemu_ld64_i64(ctx, avr, EA); \ +set_avr64(rD(ctx->opcode), avr, true);\ } else { \ -gen_qemu_ld64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA);\ +gen_qemu_ld64_i64(ctx, avr, EA); \ +set_avr64(rD(ctx->opcode), avr, true);\ tcg_gen_addi_tl(EA, EA, 8); \ -gen_qemu_ld64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA);\ +gen_qemu_ld64_i64(ctx, avr, EA); \ +set_avr64(rD(ctx->opcode), avr, false); \ } \ tcg_temp_free(EA);\ +tcg_temp_free_i64(avr); \ } #define GEN_VR_STX(name, opc2, opc3) \ static void gen_st##name(DisasContext *ctx) \ { \ TCGv EA; \ +TCGv_i64 avr; \ if (unlikely(!ctx->altivec_enabled)) {\ gen_exception(ctx, POWERPC_EXCP_VPU); \ return; \ } \ gen_set_access_type(ctx, ACCESS_INT);
[Qemu-devel] [PATCH 33/34] target/ppc: convert vadd*s and vsub*s to vector operations
Signed-off-by: Richard Henderson --- target/ppc/helper.h | 24 ++-- target/ppc/int_helper.c | 18 ++--- target/ppc/translate/vmx-impl.inc.c | 57 +++-- 3 files changed, 61 insertions(+), 38 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 7dbb08b9dd..3daf6bf863 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -219,18 +219,18 @@ DEF_HELPER_2(vprtybq, void, avr, avr) DEF_HELPER_3(vsubcuw, void, avr, avr, avr) DEF_HELPER_2(lvsl, void, avr, tl) DEF_HELPER_2(lvsr, void, avr, tl) -DEF_HELPER_4(vaddsbs, void, env, avr, avr, avr) -DEF_HELPER_4(vaddshs, void, env, avr, avr, avr) -DEF_HELPER_4(vaddsws, void, env, avr, avr, avr) -DEF_HELPER_4(vsubsbs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubshs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubsws, void, env, avr, avr, avr) -DEF_HELPER_4(vaddubs, void, env, avr, avr, avr) -DEF_HELPER_4(vadduhs, void, env, avr, avr, avr) -DEF_HELPER_4(vadduws, void, env, avr, avr, avr) -DEF_HELPER_4(vsububs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubuhs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubuws, void, env, avr, avr, avr) +DEF_HELPER_FLAGS_5(vaddsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vaddshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vaddsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vaddubs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vadduhs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vadduws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsububs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubuhs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubuws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_3(vadduqm, void, avr, avr, avr) DEF_HELPER_4(vaddecuq, void, avr, avr, avr, avr) DEF_HELPER_4(vaddeuqm, void, avr, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 9dbcbcd87a..22671c71e5 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -583,27 +583,17 @@ VARITHFPFMA(nmsubfp, float_muladd_negate_result | float_muladd_negate_c); } #define VARITHSAT_DO(name, op, optype, cvt, element)\ -void helper_v##name(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, \ -ppc_avr_t *b) \ +void helper_v##name(ppc_avr_t *r, ppc_avr_t *vscr_sat, \ +ppc_avr_t *a, ppc_avr_t *b, uint32_t desc) \ { \ int sat = 0;\ int i; \ \ for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ -switch (sizeof(r->element[0])) {\ -case 1: \ -VARITHSAT_CASE(optype, op, cvt, element); \ -break; \ -case 2: \ -VARITHSAT_CASE(optype, op, cvt, element); \ -break; \ -case 4: \ -VARITHSAT_CASE(optype, op, cvt, element); \ -break; \ -} \ +VARITHSAT_CASE(optype, op, cvt, element); \ } \ if (sat) { \ -set_vscr_sat(env); \ +vscr_sat->u32[0] = 1; \ } \ } #define VARITHSAT_SIGNED(suffix, element, optype, cvt) \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 1c0c461241..c6a53a9f63 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -548,22 +548,55 @@ GEN_VXFORM(vslo, 6, 16); GEN_VXFORM(vsro, 6, 17); GEN_VXFORM(vaddcuw, 0, 6); GEN_VXFORM(vsubcuw, 0, 22); -GEN_VXFORM_ENV(vaddubs, 0, 8); + +#define
[Qemu-devel] [PATCH 28/34] target/ppc: Remove vscr_nj and vscr_sat
These macros are no longer used. Signed-off-by: Richard Henderson --- target/ppc/cpu.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index c8f449081d..a2fe6058b1 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -700,8 +700,6 @@ enum { /* Vector status and control register */ #define VSCR_NJ16 /* Vector non-java */ #define VSCR_SAT 0 /* Vector saturation */ -#define vscr_nj(((env->vscr) >> VSCR_NJ) & 0x1) -#define vscr_sat (((env->vscr) >> VSCR_SAT) & 0x1) /*/ /* BookE e500 MMU registers */ -- 2.17.2
[Qemu-devel] [PATCH 06/34] tcg/i386: Implement vector saturating arithmetic
Only MO_8 and MO_16 are implemented, since that's all the instruction set provides. Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.h | 2 +- tcg/i386/tcg-target.inc.c | 42 +++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index 44381062e6..f50234d97b 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -185,7 +185,7 @@ extern bool have_avx2; #define TCG_TARGET_HAS_shv_vec 0 #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 -#define TCG_TARGET_HAS_sat_vec 0 +#define TCG_TARGET_HAS_sat_vec 1 #define TCG_TARGET_deposit_i32_valid(ofs, len) \ (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \ diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index c21c3272f2..3571483bae 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -377,6 +377,10 @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type, #define OPC_PADDW (0xfd | P_EXT | P_DATA16) #define OPC_PADDD (0xfe | P_EXT | P_DATA16) #define OPC_PADDQ (0xd4 | P_EXT | P_DATA16) +#define OPC_PADDSB (0xec | P_EXT | P_DATA16) +#define OPC_PADDSW (0xed | P_EXT | P_DATA16) +#define OPC_PADDUB (0xdc | P_EXT | P_DATA16) +#define OPC_PADDUW (0xdd | P_EXT | P_DATA16) #define OPC_PAND(0xdb | P_EXT | P_DATA16) #define OPC_PANDN (0xdf | P_EXT | P_DATA16) #define OPC_PBLENDW (0x0e | P_EXT3A | P_DATA16) @@ -408,6 +412,10 @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type, #define OPC_PSUBW (0xf9 | P_EXT | P_DATA16) #define OPC_PSUBD (0xfa | P_EXT | P_DATA16) #define OPC_PSUBQ (0xfb | P_EXT | P_DATA16) +#define OPC_PSUBSB (0xe8 | P_EXT | P_DATA16) +#define OPC_PSUBSW (0xe9 | P_EXT | P_DATA16) +#define OPC_PSUBUB (0xd8 | P_EXT | P_DATA16) +#define OPC_PSUBUW (0xd9 | P_EXT | P_DATA16) #define OPC_PUNPCKLBW (0x60 | P_EXT | P_DATA16) #define OPC_PUNPCKLWD (0x61 | P_EXT | P_DATA16) #define OPC_PUNPCKLDQ (0x62 | P_EXT | P_DATA16) @@ -2591,9 +2599,21 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, static int const add_insn[4] = { OPC_PADDB, OPC_PADDW, OPC_PADDD, OPC_PADDQ }; +static int const ssadd_insn[4] = { +OPC_PADDSB, OPC_PADDSW, OPC_UD2, OPC_UD2 +}; +static int const usadd_insn[4] = { +OPC_PADDSB, OPC_PADDSW, OPC_UD2, OPC_UD2 +}; static int const sub_insn[4] = { OPC_PSUBB, OPC_PSUBW, OPC_PSUBD, OPC_PSUBQ }; +static int const sssub_insn[4] = { +OPC_PSUBSB, OPC_PSUBSW, OPC_UD2, OPC_UD2 +}; +static int const ussub_insn[4] = { +OPC_PSUBSB, OPC_PSUBSW, OPC_UD2, OPC_UD2 +}; static int const mul_insn[4] = { OPC_UD2, OPC_PMULLW, OPC_PMULLD, OPC_UD2 }; @@ -2631,9 +2651,21 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, case INDEX_op_add_vec: insn = add_insn[vece]; goto gen_simd; +case INDEX_op_ssadd_vec: +insn = ssadd_insn[vece]; +goto gen_simd; +case INDEX_op_usadd_vec: +insn = usadd_insn[vece]; +goto gen_simd; case INDEX_op_sub_vec: insn = sub_insn[vece]; goto gen_simd; +case INDEX_op_sssub_vec: +insn = sssub_insn[vece]; +goto gen_simd; +case INDEX_op_ussub_vec: +insn = ussub_insn[vece]; +goto gen_simd; case INDEX_op_mul_vec: insn = mul_insn[vece]; goto gen_simd; @@ -3007,6 +3039,10 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) case INDEX_op_or_vec: case INDEX_op_xor_vec: case INDEX_op_andc_vec: +case INDEX_op_ssadd_vec: +case INDEX_op_usadd_vec: +case INDEX_op_sssub_vec: +case INDEX_op_ussub_vec: case INDEX_op_cmp_vec: case INDEX_op_x86_shufps_vec: case INDEX_op_x86_blend_vec: @@ -3074,6 +3110,12 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece) } return 1; +case INDEX_op_ssadd_vec: +case INDEX_op_usadd_vec: +case INDEX_op_sssub_vec: +case INDEX_op_ussub_vec: +return vece <= MO_16; + default: return 0; } -- 2.17.2
[Qemu-devel] [PATCH 15/34] target/ppc: merge ppc_vsr_t and ppc_avr_t union types
From: Mark Cave-Ayland Since the VSX registers are actually a superset of the VMX registers then they can be represented by the same type. Merge ppc_avr_t into ppc_vsr_t and change ppc_avr_t to be a simple typedef alias. Note that due to a difference in the naming of the float32 member between ppc_avr_t and ppc_vsr_t, references to the ppc_avr_t f member must be replaced with f32 instead. Signed-off-by: Mark Cave-Ayland Message-Id: <20181217122405.18732-7-mark.cave-ayl...@ilande.co.uk> --- target/ppc/cpu.h| 17 +++-- target/ppc/internal.h | 11 target/ppc/int_helper.c | 56 + 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index ab68abe8a2..5445d4c3c1 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -230,7 +230,6 @@ typedef struct opc_handler_t opc_handler_t; /* Types used to describe some PowerPC registers etc. */ typedef struct DisasContext DisasContext; typedef struct ppc_spr_t ppc_spr_t; -typedef union ppc_avr_t ppc_avr_t; typedef union ppc_tlb_t ppc_tlb_t; typedef struct ppc_hash_pte64 ppc_hash_pte64_t; @@ -254,22 +253,26 @@ struct ppc_spr_t { #endif }; -/* Altivec registers (128 bits) */ -union ppc_avr_t { -float32 f[4]; +/* VSX/Altivec registers (128 bits) */ +typedef union _ppc_vsr_t { uint8_t u8[16]; uint16_t u16[8]; uint32_t u32[4]; +uint64_t u64[2]; int8_t s8[16]; int16_t s16[8]; int32_t s32[4]; -uint64_t u64[2]; int64_t s64[2]; +float32 f32[4]; +float64 f64[2]; +float128 f128; #ifdef CONFIG_INT128 __uint128_t u128; #endif -Int128 s128; -}; +Int128 s128; +} ppc_vsr_t; + +typedef ppc_vsr_t ppc_avr_t; #if !defined(CONFIG_USER_ONLY) /* Software TLB cache */ diff --git a/target/ppc/internal.h b/target/ppc/internal.h index a9bcadff42..b4b1f7b3db 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -204,17 +204,6 @@ EXTRACT_HELPER(IMM8, 11, 8); EXTRACT_HELPER(DCMX, 16, 7); EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6); -typedef union _ppc_vsr_t { -uint8_t u8[16]; -uint16_t u16[8]; -uint32_t u32[4]; -uint64_t u64[2]; -float32 f32[4]; -float64 f64[2]; -float128 f128; -Int128 s128; -} ppc_vsr_t; - #if defined(HOST_WORDS_BIGENDIAN) #define VsrB(i) u8[i] #define VsrH(i) u16[i] diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index fcac90a4a9..9d715be25c 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -548,8 +548,8 @@ VARITH_DO(muluwm, *, u32) { \ int i; \ \ -for (i = 0; i < ARRAY_SIZE(r->f); i++) {\ -r->f[i] = func(a->f[i], b->f[i], >vec_status); \ +for (i = 0; i < ARRAY_SIZE(r->f32); i++) { \ +r->f32[i] = func(a->f32[i], b->f32[i], >vec_status); \ } \ } VARITHFP(addfp, float32_add) @@ -563,9 +563,9 @@ VARITHFP(maxfp, float32_max) ppc_avr_t *b, ppc_avr_t *c) \ { \ int i; \ -for (i = 0; i < ARRAY_SIZE(r->f); i++) {\ -r->f[i] = float32_muladd(a->f[i], c->f[i], b->f[i], \ - type, >vec_status); \ +for (i = 0; i < ARRAY_SIZE(r->f32); i++) { \ +r->f32[i] = float32_muladd(a->f32[i], c->f32[i], b->f32[i], \ + type, >vec_status); \ } \ } VARITHFPFMA(maddfp, 0); @@ -670,9 +670,9 @@ VABSDU(w, u32) { \ int i; \ \ -for (i = 0; i < ARRAY_SIZE(r->f); i++) {\ +for (i = 0; i < ARRAY_SIZE(r->f32); i++) { \ float32 t = cvt(b->element[i], >vec_status); \ -r->f[i] = float32_scalbn(t, -uim, >vec_status);\ +r->f32[i] = float32_scalbn(t, -uim, >vec_status); \ } \ } VCF(ux, uint32_to_float32, u32) @@ -782,9 +782,9 @@ VCMPNE(w, u32, uint32_t, 0) uint32_t none = 0; \ int i; \
[Qemu-devel] [PATCH 08/34] tcg/i386: Implement vector minmax arithmetic
The instruction set does not directly provide MO_64. We can still implement signed 64-bit with comparison and vpblendvb. Since the ISA has no unsigned comparison, it would take 4 insns to implement unsigned 64-bit, which is probably quicker as integers. Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.h | 2 +- tcg/i386/tcg-target.inc.c | 64 +++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index efbd5a6fc9..7995fe3eab 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -186,7 +186,7 @@ extern bool have_avx2; #define TCG_TARGET_HAS_cmp_vec 1 #define TCG_TARGET_HAS_mul_vec 1 #define TCG_TARGET_HAS_sat_vec 1 -#define TCG_TARGET_HAS_minmax_vec 0 +#define TCG_TARGET_HAS_minmax_vec 1 #define TCG_TARGET_deposit_i32_valid(ofs, len) \ (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \ diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index 3571483bae..c56753763a 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -392,6 +392,18 @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type, #define OPC_PCMPGTW (0x65 | P_EXT | P_DATA16) #define OPC_PCMPGTD (0x66 | P_EXT | P_DATA16) #define OPC_PCMPGTQ (0x37 | P_EXT38 | P_DATA16) +#define OPC_PMAXSB (0x3c | P_EXT38 | P_DATA16) +#define OPC_PMAXSW (0xee | P_EXT | P_DATA16) +#define OPC_PMAXSD (0x3d | P_EXT38 | P_DATA16) +#define OPC_PMAXUB (0xde | P_EXT | P_DATA16) +#define OPC_PMAXUW (0x3e | P_EXT38 | P_DATA16) +#define OPC_PMAXUD (0x3f | P_EXT38 | P_DATA16) +#define OPC_PMINSB (0x38 | P_EXT38 | P_DATA16) +#define OPC_PMINSW (0xea | P_EXT | P_DATA16) +#define OPC_PMINSD (0x39 | P_EXT38 | P_DATA16) +#define OPC_PMINUB (0xda | P_EXT | P_DATA16) +#define OPC_PMINUW (0x3a | P_EXT38 | P_DATA16) +#define OPC_PMINUD (0x3b | P_EXT38 | P_DATA16) #define OPC_PMOVSXBW(0x20 | P_EXT38 | P_DATA16) #define OPC_PMOVSXWD(0x23 | P_EXT38 | P_DATA16) #define OPC_PMOVSXDQ(0x25 | P_EXT38 | P_DATA16) @@ -2638,6 +2650,18 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, static int const packus_insn[4] = { OPC_PACKUSWB, OPC_PACKUSDW, OPC_UD2, OPC_UD2 }; +static int const smin_insn[4] = { +OPC_PMINSB, OPC_PMINSW, OPC_PMINSD, OPC_UD2 +}; +static int const smax_insn[4] = { +OPC_PMAXSB, OPC_PMAXSW, OPC_PMAXSD, OPC_UD2 +}; +static int const umin_insn[4] = { +OPC_PMINUB, OPC_PMINUW, OPC_PMINUD, OPC_UD2 +}; +static int const umax_insn[4] = { +OPC_PMAXUB, OPC_PMAXUW, OPC_PMAXUD, OPC_UD2 +}; TCGType type = vecl + TCG_TYPE_V64; int insn, sub; @@ -2678,6 +2702,18 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, case INDEX_op_xor_vec: insn = OPC_PXOR; goto gen_simd; +case INDEX_op_smin_vec: +insn = smin_insn[vece]; +goto gen_simd; +case INDEX_op_umin_vec: +insn = umin_insn[vece]; +goto gen_simd; +case INDEX_op_smax_vec: +insn = smax_insn[vece]; +goto gen_simd; +case INDEX_op_umax_vec: +insn = umax_insn[vece]; +goto gen_simd; case INDEX_op_x86_punpckl_vec: insn = punpckl_insn[vece]; goto gen_simd; @@ -3043,6 +3079,10 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) case INDEX_op_usadd_vec: case INDEX_op_sssub_vec: case INDEX_op_ussub_vec: +case INDEX_op_smin_vec: +case INDEX_op_umin_vec: +case INDEX_op_smax_vec: +case INDEX_op_umax_vec: case INDEX_op_cmp_vec: case INDEX_op_x86_shufps_vec: case INDEX_op_x86_blend_vec: @@ -3115,6 +3155,12 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece) case INDEX_op_sssub_vec: case INDEX_op_ussub_vec: return vece <= MO_16; +case INDEX_op_smin_vec: +case INDEX_op_smax_vec: +return vece <= MO_32 ? 1 : -1; +case INDEX_op_umin_vec: +case INDEX_op_umax_vec: +return vece <= MO_32; default: return 0; @@ -3370,6 +3416,24 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece, } break; +case INDEX_op_smin_vec: +case INDEX_op_smax_vec: +tcg_debug_assert(vece == MO_64); +a1 = va_arg(va, TCGArg); +a2 = va_arg(va, TCGArg); +t1 = tcg_temp_new_vec(type); +vec_gen_4(INDEX_op_cmp_vec, type, MO_64, + tcgv_vec_arg(t1), a1, a2, TCG_COND_GT); +if (opc == INDEX_op_smin_vec) { +vec_gen_4(INDEX_op_x86_vpblendvb_vec, type, MO_64, + tcgv_vec_arg(v0), a2, a1, tcgv_vec_arg(t1)); +} else { +vec_gen_4(INDEX_op_x86_vpblendvb_vec, type, MO_64, + tcgv_vec_arg(v0), a1, a2, tcgv_vec_arg(t1)); +} +
[Qemu-devel] [PATCH 25/34] target/ppc: convert xxsel to vector operations
Signed-off-by: Richard Henderson --- target/ppc/translate/vsx-impl.inc.c | 55 ++--- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index a040038ed4..dc32471cd7 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1280,40 +1280,39 @@ static void glue(gen_, name)(DisasContext * ctx) \ VSX_XXMRG(xxmrghw, 1) VSX_XXMRG(xxmrglw, 0) +static void xxsel_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c) +{ +tcg_gen_and_i64(b, b, c); +tcg_gen_andc_i64(a, a, c); +tcg_gen_or_i64(t, a, b); +} + +static void xxsel_vec(unsigned vece, TCGv_vec t, TCGv_vec a, + TCGv_vec b, TCGv_vec c) +{ +tcg_gen_and_vec(vece, b, b, c); +tcg_gen_andc_vec(vece, a, a, c); +tcg_gen_or_vec(vece, t, a, b); +} + static void gen_xxsel(DisasContext * ctx) { -TCGv_i64 a, b, c, tmp; +static const GVecGen4 g = { +.fni8 = xxsel_i64, +.fniv = xxsel_vec, +.vece = MO_64, +}; +int rt = xT(ctx->opcode); +int ra = xA(ctx->opcode); +int rb = xB(ctx->opcode); +int rc = xC(ctx->opcode); + if (unlikely(!ctx->vsx_enabled)) { gen_exception(ctx, POWERPC_EXCP_VSXU); return; } -a = tcg_temp_new_i64(); -b = tcg_temp_new_i64(); -c = tcg_temp_new_i64(); -tmp = tcg_temp_new_i64(); - -get_cpu_vsrh(a, xA(ctx->opcode)); -get_cpu_vsrh(b, xB(ctx->opcode)); -get_cpu_vsrh(c, xC(ctx->opcode)); - -tcg_gen_and_i64(b, b, c); -tcg_gen_andc_i64(a, a, c); -tcg_gen_or_i64(tmp, a, b); -set_cpu_vsrh(xT(ctx->opcode), tmp); - -get_cpu_vsrl(a, xA(ctx->opcode)); -get_cpu_vsrl(b, xB(ctx->opcode)); -get_cpu_vsrl(c, xC(ctx->opcode)); - -tcg_gen_and_i64(b, b, c); -tcg_gen_andc_i64(a, a, c); -tcg_gen_or_i64(tmp, a, b); -set_cpu_vsrl(xT(ctx->opcode), tmp); - -tcg_temp_free_i64(a); -tcg_temp_free_i64(b); -tcg_temp_free_i64(c); -tcg_temp_free_i64(tmp); +tcg_gen_gvec_4(vsr_full_offset(rt), vsr_full_offset(ra), + vsr_full_offset(rb), vsr_full_offset(rc), 16, 16, ); } static void gen_xxspltw(DisasContext *ctx) -- 2.17.2
[Qemu-devel] [PATCH 17/34] target/ppc: convert VMX logical instructions to use vector operations
From: Mark Cave-Ayland Signed-off-by: Mark Cave-Ayland Reviewed-by: Richard Henderson Message-Id: <20181217122405.18732-9-mark.cave-ayl...@ilande.co.uk> --- target/ppc/translate.c | 1 + target/ppc/translate/vmx-impl.inc.c | 63 - 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 8e89aec14d..1b61bfa093 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -24,6 +24,7 @@ #include "disas/disas.h" #include "exec/exec-all.h" #include "tcg-op.h" +#include "tcg-op-gvec.h" #include "qemu/host-utils.h" #include "exec/cpu_ldst.h" diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 75d2b2280f..c13828a09d 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -262,41 +262,50 @@ GEN_VX_VMUL10(vmul10euq, 1, 0); GEN_VX_VMUL10(vmul10cuq, 0, 1); GEN_VX_VMUL10(vmul10ecuq, 1, 1); -/* Logical operations */ -#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)\ -static void glue(gen_, name)(DisasContext *ctx) \ +#define GEN_VXFORM_V(name, vece, tcg_op, opc2, opc3)\ +static void glue(gen_, name)(DisasContext *ctx) \ { \ -TCGv_i64 t0 = tcg_temp_new_i64(); \ -TCGv_i64 t1 = tcg_temp_new_i64(); \ -TCGv_i64 avr = tcg_temp_new_i64(); \ -\ if (unlikely(!ctx->altivec_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_VPU); \ return; \ } \ -get_avr64(t0, rA(ctx->opcode), true); \ -get_avr64(t1, rB(ctx->opcode), true); \ -tcg_op(avr, t0, t1);\ -set_avr64(rD(ctx->opcode), avr, true); \ \ -get_avr64(t0, rA(ctx->opcode), false); \ -get_avr64(t1, rB(ctx->opcode), false); \ -tcg_op(avr, t0, t1);\ -set_avr64(rD(ctx->opcode), avr, false); \ -\ -tcg_temp_free_i64(t0); \ -tcg_temp_free_i64(t1); \ -tcg_temp_free_i64(avr); \ +tcg_op(vece,\ + avr64_offset(rD(ctx->opcode), true), \ + avr64_offset(rA(ctx->opcode), true), \ + avr64_offset(rB(ctx->opcode), true), \ + 16, 16); \ } -GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16); -GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17); -GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18); -GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19); -GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20); -GEN_VX_LOGICAL(veqv, tcg_gen_eqv_i64, 2, 26); -GEN_VX_LOGICAL(vnand, tcg_gen_nand_i64, 2, 22); -GEN_VX_LOGICAL(vorc, tcg_gen_orc_i64, 2, 21); +#define GEN_VXFORM_VN(name, vece, tcg_op, opc2, opc3) \ +static void glue(gen_, name)(DisasContext *ctx) \ +{ \ +if (unlikely(!ctx->altivec_enabled)) { \ +gen_exception(ctx, POWERPC_EXCP_VPU); \ +return; \ +} \ +\ +tcg_op(vece,\ + avr64_offset(rD(ctx->opcode), true), \ + avr64_offset(rA(ctx->opcode), true), \ + avr64_offset(rB(ctx->opcode), true), \ + 16, 16); \ +\ +tcg_gen_gvec_not(vece, \ + avr64_offset(rD(ctx->opcode), true), \ + avr64_offset(rD(ctx->opcode), true),
[Qemu-devel] [PATCH 09/34] target/arm: Use vector minmax expanders for aarch64
Signed-off-by: Richard Henderson --- target/arm/translate-a64.c | 35 ++- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 2d6f8c1b4f..bef21ada71 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -10452,6 +10452,20 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) } switch (opcode) { +case 0x0c: /* SMAX, UMAX */ +if (u) { +gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size); +} else { +gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smax, size); +} +return; +case 0x0d: /* SMIN, UMIN */ +if (u) { +gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umin, size); +} else { +gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size); +} +return; case 0x10: /* ADD, SUB */ if (u) { gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size); @@ -10613,27 +10627,6 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) genenvfn = fns[size][u]; break; } -case 0xc: /* SMAX, UMAX */ -{ -static NeonGenTwoOpFn * const fns[3][2] = { -{ gen_helper_neon_max_s8, gen_helper_neon_max_u8 }, -{ gen_helper_neon_max_s16, gen_helper_neon_max_u16 }, -{ tcg_gen_smax_i32, tcg_gen_umax_i32 }, -}; -genfn = fns[size][u]; -break; -} - -case 0xd: /* SMIN, UMIN */ -{ -static NeonGenTwoOpFn * const fns[3][2] = { -{ gen_helper_neon_min_s8, gen_helper_neon_min_u8 }, -{ gen_helper_neon_min_s16, gen_helper_neon_min_u16 }, -{ tcg_gen_smin_i32, tcg_gen_umin_i32 }, -}; -genfn = fns[size][u]; -break; -} case 0xe: /* SABD, UABD */ case 0xf: /* SABA, UABA */ { -- 2.17.2
[Qemu-devel] [PATCH 03/34] tcg: Add gvec expanders for nand, nor, eqv
Signed-off-by: Richard Henderson --- accel/tcg/tcg-runtime.h | 3 +++ tcg/tcg-op-gvec.h| 6 + tcg/tcg-op.h | 3 +++ accel/tcg/tcg-runtime-gvec.c | 33 +++ tcg/tcg-op-gvec.c| 51 tcg/tcg-op-vec.c | 21 +++ 6 files changed, 117 insertions(+) diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h index 1bd39d136d..835ddfebb2 100644 --- a/accel/tcg/tcg-runtime.h +++ b/accel/tcg/tcg-runtime.h @@ -211,6 +211,9 @@ DEF_HELPER_FLAGS_4(gvec_or, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_xor, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_andc, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_orc, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_nand, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_nor, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_eqv, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_ands, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32) DEF_HELPER_FLAGS_4(gvec_xors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32) diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h index ff43a29a0b..d65b9d9d4c 100644 --- a/tcg/tcg-op-gvec.h +++ b/tcg/tcg-op-gvec.h @@ -242,6 +242,12 @@ void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t oprsz, uint32_t maxsz); void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t oprsz, uint32_t maxsz); +void tcg_gen_gvec_nand(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz); +void tcg_gen_gvec_nor(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz); +void tcg_gen_gvec_eqv(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz); void tcg_gen_gvec_andi(unsigned vece, uint32_t dofs, uint32_t aofs, int64_t c, uint32_t oprsz, uint32_t maxsz); diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index db4e9188f4..1974bf1cae 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -961,6 +961,9 @@ void tcg_gen_or_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_andc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); +void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a); void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a); diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c index 90340e56e0..d1802467d5 100644 --- a/accel/tcg/tcg-runtime-gvec.c +++ b/accel/tcg/tcg-runtime-gvec.c @@ -512,6 +512,39 @@ void HELPER(gvec_orc)(void *d, void *a, void *b, uint32_t desc) clear_high(d, oprsz, desc); } +void HELPER(gvec_nand)(void *d, void *a, void *b, uint32_t desc) +{ +intptr_t oprsz = simd_oprsz(desc); +intptr_t i; + +for (i = 0; i < oprsz; i += sizeof(vec64)) { +*(vec64 *)(d + i) = ~(*(vec64 *)(a + i) & *(vec64 *)(b + i)); +} +clear_high(d, oprsz, desc); +} + +void HELPER(gvec_nor)(void *d, void *a, void *b, uint32_t desc) +{ +intptr_t oprsz = simd_oprsz(desc); +intptr_t i; + +for (i = 0; i < oprsz; i += sizeof(vec64)) { +*(vec64 *)(d + i) = ~(*(vec64 *)(a + i) | *(vec64 *)(b + i)); +} +clear_high(d, oprsz, desc); +} + +void HELPER(gvec_eqv)(void *d, void *a, void *b, uint32_t desc) +{ +intptr_t oprsz = simd_oprsz(desc); +intptr_t i; + +for (i = 0; i < oprsz; i += sizeof(vec64)) { +*(vec64 *)(d + i) = ~(*(vec64 *)(a + i) ^ *(vec64 *)(b + i)); +} +clear_high(d, oprsz, desc); +} + void HELPER(gvec_ands)(void *d, void *a, uint64_t b, uint32_t desc) { intptr_t oprsz = simd_oprsz(desc); diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c index ec231b78fb..81689d02f7 100644 --- a/tcg/tcg-op-gvec.c +++ b/tcg/tcg-op-gvec.c @@ -1920,6 +1920,57 @@ void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs, } } +void tcg_gen_gvec_nand(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz) +{ +static const GVecGen3 g = { +.fni8 = tcg_gen_nand_i64, +.fniv = tcg_gen_nand_vec, +.fno = gen_helper_gvec_nand, +.prefer_i64 = TCG_TARGET_REG_BITS == 64, +}; + +if (aofs == bofs) { +tcg_gen_gvec_not(vece, dofs, aofs, oprsz, maxsz); +} else { +tcg_gen_gvec_3(dofs,
[Qemu-devel] [PATCH 04/34] tcg: Add write_aofs to GVecGen4
This allows writing 2 output, 3 input operations. Signed-off-by: Richard Henderson --- tcg/tcg-op-gvec.h | 2 ++ tcg/tcg-op-gvec.c | 27 +++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h index d65b9d9d4c..2cb447112e 100644 --- a/tcg/tcg-op-gvec.h +++ b/tcg/tcg-op-gvec.h @@ -181,6 +181,8 @@ typedef struct { uint8_t vece; /* Prefer i64 to v64. */ bool prefer_i64; +/* Write aofs as a 2nd dest operand. */ +bool write_aofs; } GVecGen4; void tcg_gen_gvec_2(uint32_t dofs, uint32_t aofs, diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c index 81689d02f7..c10d3d7b26 100644 --- a/tcg/tcg-op-gvec.c +++ b/tcg/tcg-op-gvec.c @@ -665,7 +665,7 @@ static void expand_3_i32(uint32_t dofs, uint32_t aofs, /* Expand OPSZ bytes worth of three-operand operations using i32 elements. */ static void expand_4_i32(uint32_t dofs, uint32_t aofs, uint32_t bofs, - uint32_t cofs, uint32_t oprsz, + uint32_t cofs, uint32_t oprsz, bool write_aofs, void (*fni)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32)) { TCGv_i32 t0 = tcg_temp_new_i32(); @@ -680,6 +680,9 @@ static void expand_4_i32(uint32_t dofs, uint32_t aofs, uint32_t bofs, tcg_gen_ld_i32(t3, cpu_env, cofs + i); fni(t0, t1, t2, t3); tcg_gen_st_i32(t0, cpu_env, dofs + i); +if (write_aofs) { +tcg_gen_st_i32(t1, cpu_env, aofs + i); +} } tcg_temp_free_i32(t3); tcg_temp_free_i32(t2); @@ -769,7 +772,7 @@ static void expand_3_i64(uint32_t dofs, uint32_t aofs, /* Expand OPSZ bytes worth of three-operand operations using i64 elements. */ static void expand_4_i64(uint32_t dofs, uint32_t aofs, uint32_t bofs, - uint32_t cofs, uint32_t oprsz, + uint32_t cofs, uint32_t oprsz, bool write_aofs, void (*fni)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) { TCGv_i64 t0 = tcg_temp_new_i64(); @@ -784,6 +787,9 @@ static void expand_4_i64(uint32_t dofs, uint32_t aofs, uint32_t bofs, tcg_gen_ld_i64(t3, cpu_env, cofs + i); fni(t0, t1, t2, t3); tcg_gen_st_i64(t0, cpu_env, dofs + i); +if (write_aofs) { +tcg_gen_st_i64(t1, cpu_env, aofs + i); +} } tcg_temp_free_i64(t3); tcg_temp_free_i64(t2); @@ -880,7 +886,7 @@ static void expand_3_vec(unsigned vece, uint32_t dofs, uint32_t aofs, /* Expand OPSZ bytes worth of four-operand operations using host vectors. */ static void expand_4_vec(unsigned vece, uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs, uint32_t oprsz, - uint32_t tysz, TCGType type, + uint32_t tysz, TCGType type, bool write_aofs, void (*fni)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, TCGv_vec)) { @@ -896,6 +902,9 @@ static void expand_4_vec(unsigned vece, uint32_t dofs, uint32_t aofs, tcg_gen_ld_vec(t3, cpu_env, cofs + i); fni(vece, t0, t1, t2, t3); tcg_gen_st_vec(t0, cpu_env, dofs + i); +if (write_aofs) { +tcg_gen_st_vec(t1, cpu_env, aofs + i); +} } tcg_temp_free_vec(t3); tcg_temp_free_vec(t2); @@ -1187,7 +1196,7 @@ void tcg_gen_gvec_4(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs, */ some = QEMU_ALIGN_DOWN(oprsz, 32); expand_4_vec(g->vece, dofs, aofs, bofs, cofs, some, - 32, TCG_TYPE_V256, g->fniv); + 32, TCG_TYPE_V256, g->write_aofs, g->fniv); if (some == oprsz) { break; } @@ -1200,18 +1209,20 @@ void tcg_gen_gvec_4(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs, /* fallthru */ case TCG_TYPE_V128: expand_4_vec(g->vece, dofs, aofs, bofs, cofs, oprsz, - 16, TCG_TYPE_V128, g->fniv); + 16, TCG_TYPE_V128, g->write_aofs, g->fniv); break; case TCG_TYPE_V64: expand_4_vec(g->vece, dofs, aofs, bofs, cofs, oprsz, - 8, TCG_TYPE_V64, g->fniv); + 8, TCG_TYPE_V64, g->write_aofs, g->fniv); break; case 0: if (g->fni8 && check_size_impl(oprsz, 8)) { -expand_4_i64(dofs, aofs, bofs, cofs, oprsz, g->fni8); +expand_4_i64(dofs, aofs, bofs, cofs, oprsz, + g->write_aofs, g->fni8); } else if (g->fni4 && check_size_impl(oprsz, 4)) { -expand_4_i32(dofs, aofs, bofs, cofs, oprsz, g->fni4); +expand_4_i32(dofs, aofs, bofs, cofs, oprsz, + g->write_aofs, g->fni4); } else { assert(g->fno != NULL); tcg_gen_gvec_4_ool(dofs, aofs, bofs, cofs, -- 2.17.2
Re: [Qemu-devel] [PATCH 2/3] mac_newworld: enable access to EDID data for the VGA device
Hi, > >> Otherwise a guest driver that assumes it is always present and tries > >> to read from that area of memory will crash. > > > > Oh, reading should work no matter what. You just don't find valid edid > > data there if it is turned off. > > Thanks for the info. My current use case for this is passing a set of > possible guest > display resolutions from the host to the guest driver, rather than using an > internal > hard-coded list. I guess that over time QEMU could become "smarter" about > building > the list of supported resolutions depending upon the capabilities of the host? Yes, that is the plan. There are xres and yres properties already, which will show up as preferred resolution in the edid blob. The generator also supports to set the maximum display resolution, and the display dpi (needed when we add hidpi support some day). stdvga doesn't support to change the edid dynamically (i.e. on window resize) because the hardware doesn't support interrupts, so we can't easily signal edid updates to the guest. cheers, Gerd
Re: [Qemu-devel] Monitor and serial output window broken with SDL2
Hi, > > > > > Doesn't reproduce too. It's also not clear why x86_64 should behave > > > > > different that ppc. There is no arch-specific code ui/, so there > > > > > should > > > > > be no difference, exept for hardware like paralle ports which are not > > > > > supported by all machine types. > > > > > > > > > > Any chance you have tested an old ppc binary? > > > > > > > > Not likely because I did make distclean and a clean build before testing > > > > to avoid any possible mismatch. It still does not work for me though. > > > > While > > > > > > I still have this problem after updating everything on my machine, latest > > > QEMU and SDL 2.0.9 so it's not likely to be a bug in some external > > > component. If I just start qemu-system-ppc (compiled with --disable-gtk) > > > and > > > try to open monitor console with Ctrl-Alt-2 I see QEMU monitor but when I > > > type in this window the serial output window contents flash in this > > > window. > > > At the same time the window that opens for Ctrl-Alt-3 which should have > > > the > > > serial output is empty. It looks like an index may be off somewhere or > > > window contents are not associated with the right window but I have no > > > idea > > > where to look for it. Can you reproduce it now and do you have any idea > > > what > > > could cause this? > > > > Could you share an example command line which can be used to reproduce > > the problem. > > As I wrote above ust "qemu-system-ppc" without any options reproduces the > problem here. Still doesn't reproduce, using "qemu-system-ppc -display sdl". x86_64 is fine too. Also using SDL 2.0.9. "struct sdl2_console" holds the per-window state, you could try to sprinkle some debug printfs (or add trace points) to sdl2_window_create, sdl2_redraw, ... HTH, Gerd
[Qemu-devel] [PULL 31/31] hw/i386: Remove deprecated machines pc-0.10 and pc-0.11
From: Thomas Huth They've been deprecated for two releases and nobody complained that they are still required anymore, so it's time to remove these now. And while we're at it, mark the other remaining old 0.x machine types as deprecated (since they can not properly be used for live-migration anyway). Signed-off-by: Thomas Huth Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Eduardo Habkost --- hw/i386/pc_piix.c | 70 ++- tests/cpu-plug-test.c | 4 +-- qemu-deprecated.texi | 2 +- 3 files changed, 4 insertions(+), 72 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e000c7511a..7f1cb527b5 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -368,7 +368,7 @@ static void pc_compat_1_2(MachineState *machine) x86_cpu_change_kvm_default("kvm-pv-eoi", NULL); } -/* PC compat function for pc-0.10 to pc-0.13 */ +/* PC compat function for pc-0.12 and pc-0.13 */ static void pc_compat_0_13(MachineState *machine) { pc_compat_1_2(machine); @@ -834,6 +834,7 @@ static void pc_i440fx_0_15_machine_options(MachineClass *m) { pc_i440fx_1_0_machine_options(m); m->hw_version = "0.15"; +m->deprecation_reason = "use a newer machine type instead"; SET_MACHINE_COMPAT(m, PC_COMPAT_0_15); } @@ -951,73 +952,6 @@ static void pc_i440fx_0_12_machine_options(MachineClass *m) DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13, pc_i440fx_0_12_machine_options); - -#define PC_COMPAT_0_11 \ -PC_CPU_MODEL_IDS("0.11") \ -{\ -.driver = "virtio-blk-pci",\ -.property = "vectors",\ -.value= stringify(0),\ -},{\ -.driver = TYPE_PCI_DEVICE,\ -.property = "rombar",\ -.value= stringify(0),\ -},{\ -.driver = "ide-drive",\ -.property = "ver",\ -.value= "0.11",\ -},{\ -.driver = "scsi-disk",\ -.property = "ver",\ -.value= "0.11",\ -}, - -static void pc_i440fx_0_11_machine_options(MachineClass *m) -{ -pc_i440fx_0_12_machine_options(m); -m->hw_version = "0.11"; -m->deprecation_reason = "use a newer machine type instead"; -SET_MACHINE_COMPAT(m, PC_COMPAT_0_11); -} - -DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13, - pc_i440fx_0_11_machine_options); - - -#define PC_COMPAT_0_10 \ -PC_CPU_MODEL_IDS("0.10") \ -{\ -.driver = "virtio-blk-pci",\ -.property = "class",\ -.value= stringify(PCI_CLASS_STORAGE_OTHER),\ -},{\ -.driver = "virtio-serial-pci",\ -.property = "class",\ -.value= stringify(PCI_CLASS_DISPLAY_OTHER),\ -},{\ -.driver = "virtio-net-pci",\ -.property = "vectors",\ -.value= stringify(0),\ -},{\ -.driver = "ide-drive",\ -.property = "ver",\ -.value= "0.10",\ -},{\ -.driver = "scsi-disk",\ -.property = "ver",\ -.value= "0.10",\ -}, - -static void pc_i440fx_0_10_machine_options(MachineClass *m) -{ -pc_i440fx_0_11_machine_options(m); -m->hw_version = "0.10"; -SET_MACHINE_COMPAT(m, PC_COMPAT_0_10); -} - -DEFINE_I440FX_MACHINE(v0_10, "pc-0.10", pc_compat_0_13, - pc_i440fx_0_10_machine_options); - typedef struct { uint16_t gpu_device_id; uint16_t pch_device_id; diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c index f4a677d238..668f00144e 100644 --- a/tests/cpu-plug-test.c +++ b/tests/cpu-plug-test.c @@ -157,9 +157,7 @@ static void add_pc_test_case(const char *mname) (strcmp(mname, "pc-0.15") == 0) || (strcmp(mname, "pc-0.14") == 0) || (strcmp(mname, "pc-0.13") == 0) || -(strcmp(mname, "pc-0.12") == 0) || -(strcmp(mname, "pc-0.11") == 0) || -(strcmp(mname, "pc-0.10") == 0)) { +(strcmp(mname, "pc-0.12") == 0)) { path = g_strdup_printf("cpu-plug/%s/init/%ux%ux%u=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index e362d37225..c3735b698e 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -134,7 +134,7 @@ their usecases. @section System emulator machines -@subsection pc-0.10 and pc-0.11 (since 3.0) +@subsection pc-0.12, pc-0.13, pc-0.14 and pc-0.15 (since 4.0) These machine types are very old and likely can not be used for live migration from old QEMU versions anymore. A newer machine type should be used instead. -- MST
[Qemu-devel] [PULL 30/31] hw: acpi: Remove AcpiRsdpDescriptor and fix tests
From: Samuel Ortiz The only remaining AcpiRsdpDescriptor users are the ACPI utils for the BIOS table tests. We remove that dependency and can thus remove the structure itself. Signed-off-by: Samuel Ortiz Reviewed-by: Igor Mammedov Reviewed-by: Andrew Jones Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/acpi/acpi-defs.h | 13 --- tests/acpi-utils.h | 4 +++- tests/acpi-utils.c | 46 ++--- tests/bios-tables-test.c| 22 ++ tests/vmgenid-test.c| 8 --- 5 files changed, 63 insertions(+), 30 deletions(-) diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index 8425ecb8c6..5021cb9e79 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -40,19 +40,6 @@ enum { ACPI_FADT_F_LOW_POWER_S0_IDLE_CAPABLE, }; -struct AcpiRsdpDescriptor {/* Root System Descriptor Pointer */ -uint64_t signature; /* ACPI signature, contains "RSD PTR " */ -uint8_t checksum; /* To make sum of struct == 0 */ -uint8_t oem_id [6]; /* OEM identification */ -uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */ -uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */ -uint32_t length; /* XSDT Length in bytes including hdr */ -uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */ -uint8_t extended_checksum; /* Checksum of entire table */ -uint8_t reserved [3]; /* Reserved field must be 0 */ -} QEMU_PACKED; -typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor; - typedef struct AcpiRsdpData { uint8_t oem_id[6]; /* OEM identification */ uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */ diff --git a/tests/acpi-utils.h b/tests/acpi-utils.h index ac52abd0dd..4f4899deb5 100644 --- a/tests/acpi-utils.h +++ b/tests/acpi-utils.h @@ -82,6 +82,8 @@ typedef struct { uint8_t acpi_calc_checksum(const uint8_t *data, int len); uint32_t acpi_find_rsdp_address(void); -void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table); +uint32_t acpi_get_rsdt_address(uint8_t *rsdp_table); +uint64_t acpi_get_xsdt_address(uint8_t *rsdp_table); +void acpi_parse_rsdp_table(uint32_t addr, uint8_t *rsdp_table); #endif /* TEST_ACPI_UTILS_H */ diff --git a/tests/acpi-utils.c b/tests/acpi-utils.c index 297af55d39..6374f10ac3 100644 --- a/tests/acpi-utils.c +++ b/tests/acpi-utils.c @@ -51,14 +51,44 @@ uint32_t acpi_find_rsdp_address(void) return off; } -void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table) +uint32_t acpi_get_rsdt_address(uint8_t *rsdp_table) { -ACPI_READ_FIELD(rsdp_table->signature, addr); -ACPI_ASSERT_CMP64(rsdp_table->signature, "RSD PTR "); +uint32_t rsdt_physical_address; -ACPI_READ_FIELD(rsdp_table->checksum, addr); -ACPI_READ_ARRAY(rsdp_table->oem_id, addr); -ACPI_READ_FIELD(rsdp_table->revision, addr); -ACPI_READ_FIELD(rsdp_table->rsdt_physical_address, addr); -ACPI_READ_FIELD(rsdp_table->length, addr); +memcpy(_physical_address, _table[16 /* RsdtAddress offset */], 4); +return le32_to_cpu(rsdt_physical_address); +} + +uint64_t acpi_get_xsdt_address(uint8_t *rsdp_table) +{ +uint64_t xsdt_physical_address; +uint8_t revision = rsdp_table[15 /* Revision offset */]; + +/* We must have revision 2 if we're looking for an XSDT pointer */ +g_assert(revision == 2); + +memcpy(_physical_address, _table[24 /* XsdtAddress offset */], 8); +return le64_to_cpu(xsdt_physical_address); +} + +void acpi_parse_rsdp_table(uint32_t addr, uint8_t *rsdp_table) +{ +uint8_t revision; + +/* Read mandatory revision 0 table data (20 bytes) first */ +memread(addr, rsdp_table, 20); +revision = rsdp_table[15 /* Revision offset */]; + +switch (revision) { +case 0: /* ACPI 1.0 RSDP */ +break; +case 2: /* ACPI 2.0+ RSDP */ +/* Read the rest of the RSDP table */ +memread(addr + 20, rsdp_table + 20, 16); +break; +default: +g_assert_not_reached(); +} + +ACPI_ASSERT_CMP64(*((uint64_t *)(rsdp_table)), "RSD PTR "); } diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index dfa74a5bec..f531241018 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -27,7 +27,7 @@ typedef struct { const char *machine; const char *variant; uint32_t rsdp_addr; -AcpiRsdpDescriptor rsdp_table; +uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */]; AcpiRsdtDescriptorRev1 rsdt_table; uint32_t dsdt_addr; uint32_t facs_addr; @@ -85,19 +85,31 @@ static void test_acpi_rsdp_address(test_data *data) static void test_acpi_rsdp_table(test_data *data) { -AcpiRsdpDescriptor *rsdp_table = >rsdp_table; +uint8_t *rsdp_table = data->rsdp_table, revision; uint32_t addr = data->rsdp_addr;
[Qemu-devel] [PULL 24/31] hw: arm: acpi: Fix incorrect checksums in RSDP
From: Igor Mammedov When RSDP table was introduced (d4bec5d87), we calculated only legacy checksum, and that was incorrect as it - specified rev=2 and forgot about extended checksum. - legacy checksum calculated on full table instead of the 1st 20 bytes Fix it by adding extended checksum calculation and using correct size for legacy checksum. While at it use explicit constants to specify sub/full tables sizes instead of relying on AcpiRsdpDescriptor size and fields offsets. The follow up commits will convert this table to build_append_int_noprefix() API, will use constants anyway and remove unused AcpiRsdpDescriptor structure. Based on "[PATCH v5 05/24] hw: acpi: Implement XSDT support for RSDP" by Samuel Ortiz, who did it right in his impl. Fixes: d4bec5d87 ("hw/arm/virt-acpi-build: Generate RSDP table") Signed-off-by: Igor Mammedov CC: Ard Biesheuvel CC: Shannon Zhao Reviewed-by: Andrew Jones Reviewed-by: Samuel Ortiz Signed-off-by: Samuel Ortiz Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/arm/virt-acpi-build.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index fcaa350892..0835900052 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -390,8 +390,13 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset) /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, -(char *)rsdp - rsdp_table->data, sizeof *rsdp, +(char *)rsdp - rsdp_table->data, 20 /* ACPI rev 1.0 RSDP size */, (char *)>checksum - rsdp_table->data); + +/* Extended checksum to be filled by Guest linker */ +bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, +(char *)rsdp - rsdp_table->data, 36 /* ACPI rev 2.0 RSDP size */, +(char *)>extended_checksum - rsdp_table->data); } static void -- MST
[Qemu-devel] [PULL 25/31] hw: i386: Use correct RSDT length for checksum
From: Igor Mammedov AcpiRsdpDescriptor describes revision 2 RSDP table so using sizeof(*rsdp) for checksum calculation isn't correct since we are adding extra 16 bytes. But acpi_data_push() zeroes out table, so just by luck we are summing up exta zeros which still yelds correct checksum. Fix it up by explicitly stating table size instead of using pointer arithmetics on stucture. PS: Extra 16 bytes are still wasted, but droping them will break migration for machines older than 2.3 due to size mismatch, for 2.3 and older it's not an issue since they are using resizable memory regions (a1666142d) for ACPI blobs. So keep wasting memory to avoid breaking old machines. Fixes: 72c194f7e (i386: ACPI table generation code from seabios) Signed-off-by: Igor Mammedov Reviewed-by: Samuel Ortiz Signed-off-by: Samuel Ortiz Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 35f17d0d91..fb877648ac 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2550,6 +2550,11 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker) static void build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) { +/* AcpiRsdpDescriptor describes revision 2 RSDP table and as result we + * allocate extra 16 bytes for pc/q35 RSDP rev1 as well. Keep extra 16 bytes + * wasted to make sure we won't breake migration for machine types older + * than 2.3 due to size mismatch. + */ AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address); unsigned rsdt_pa_offset = @@ -2567,7 +2572,7 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, -(char *)rsdp - rsdp_table->data, sizeof *rsdp, +(char *)rsdp - rsdp_table->data, 20 /* ACPI rev 1.0 RSDP size */, (char *)>checksum - rsdp_table->data); } -- MST
[Qemu-devel] [PULL 19/31] intel_iommu: convert invalid traces into error reports
From: Peter Xu Report more *_invalid() tracepoints to error_report_once() so that we can detect issues even without tracing enabled. Drop those tracepoints. Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 58 --- hw/i386/trace-events | 6 - 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index f21988f396..4806d7edb4 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -524,7 +524,6 @@ static int vtd_get_root_entry(IntelIOMMUState *s, uint8_t index, addr = s->root + index * sizeof(*re); if (dma_memory_read(_space_memory, addr, re, sizeof(*re))) { -trace_vtd_re_invalid(re->rsvd, re->val); re->val = 0; return -VTD_FR_ROOT_TABLE_INV; } @@ -545,7 +544,6 @@ static int vtd_get_context_entry_from_root(VTDRootEntry *root, uint8_t index, /* we have checked that root entry is present */ addr = (root->val & VTD_ROOT_ENTRY_CTP) + index * sizeof(*ce); if (dma_memory_read(_space_memory, addr, ce, sizeof(*ce))) { -trace_vtd_re_invalid(root->rsvd, root->val); return -VTD_FR_CONTEXT_TABLE_INV; } ce->lo = le64_to_cpu(ce->lo); @@ -630,16 +628,20 @@ static inline bool vtd_ce_type_check(X86IOMMUState *x86_iommu, break; case VTD_CONTEXT_TT_DEV_IOTLB: if (!x86_iommu->dt_supported) { +error_report_once("%s: DT specified but not supported", __func__); return false; } break; case VTD_CONTEXT_TT_PASS_THROUGH: if (!x86_iommu->pt_supported) { +error_report_once("%s: PT specified but not supported", __func__); return false; } break; default: /* Unknwon type */ +error_report_once("%s: unknown ce type: %"PRIu32, __func__, + vtd_ce_get_type(ce)); return false; } return true; @@ -1003,7 +1005,9 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num, } if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD(s->aw_bits))) { -trace_vtd_re_invalid(re.rsvd, re.val); +error_report_once("%s: invalid root entry: rsvd=0x%"PRIx64 + ", val=0x%"PRIx64" (reserved nonzero)", + __func__, re.rsvd, re.val); return -VTD_FR_ROOT_ENTRY_RSVD; } @@ -1020,19 +1024,23 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num, if ((ce->hi & VTD_CONTEXT_ENTRY_RSVD_HI) || (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO(s->aw_bits))) { -trace_vtd_ce_invalid(ce->hi, ce->lo); +error_report_once("%s: invalid context entry: hi=%"PRIx64 + ", lo=%"PRIx64" (reserved nonzero)", + __func__, ce->hi, ce->lo); return -VTD_FR_CONTEXT_ENTRY_RSVD; } /* Check if the programming of context-entry is valid */ if (!vtd_is_level_supported(s, vtd_ce_get_level(ce))) { -trace_vtd_ce_invalid(ce->hi, ce->lo); +error_report_once("%s: invalid context entry: hi=%"PRIx64 + ", lo=%"PRIx64" (level %d not supported)", + __func__, ce->hi, ce->lo, vtd_ce_get_level(ce)); return -VTD_FR_CONTEXT_ENTRY_INV; } /* Do translation type check */ if (!vtd_ce_type_check(x86_iommu, ce)) { -trace_vtd_ce_invalid(ce->hi, ce->lo); +/* Errors dumped in vtd_ce_type_check() */ return -VTD_FR_CONTEXT_ENTRY_INV; } @@ -1878,7 +1886,9 @@ static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) { if ((inv_desc->hi & VTD_INV_DESC_WAIT_RSVD_HI) || (inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO)) { -trace_vtd_inv_desc_wait_invalid(inv_desc->hi, inv_desc->lo); +error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64 + " (reserved nonzero)", __func__, inv_desc->hi, + inv_desc->lo); return false; } if (inv_desc->lo & VTD_INV_DESC_WAIT_SW) { @@ -1901,7 +1911,9 @@ static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) /* Interrupt flag */ vtd_generate_completion_event(s); } else { -trace_vtd_inv_desc_wait_invalid(inv_desc->hi, inv_desc->lo); +error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64 + " (unknown type)", __func__, inv_desc->hi, + inv_desc->lo); return false; } return true; @@ -1913,7 +1925,9 @@ static bool vtd_process_context_cache_desc(IntelIOMMUState *s, uint16_t sid, fmask; if ((inv_desc->lo & VTD_INV_DESC_CC_RSVD) || inv_desc->hi) { -trace_vtd_inv_desc_cc_invalid(inv_desc->hi, inv_desc->lo); +
Re: [Qemu-devel] [PULL 00/31] pci, pc, virtio: fixes, features
On Mon, Dec 17, 2018 at 11:16:42PM -0500, Michael S. Tsirkin wrote: > The following changes since commit f163448536e5f7ae8905b14547eab37a41a75f6c: > > Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20181216' into > staging (2018-12-17 13:04:25 +) > > are available in the Git repository at: > > git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream > > for you to fetch changes up to 562774d542e9be84411de0233308da380256f631: > > hw/i386: Remove deprecated machines pc-0.10 and pc-0.11 (2018-12-17 > 22:45:59 -0500) oops issue found. Pls ignore. Will resend tomorrow. > > pci, pc, virtio: fixes, features > > VTD fixes > ACPI refactoring > new names for virtio devices > multiple pcie link width/speeds > > Signed-off-by: Michael S. Tsirkin > > > Alex Williamson (8): > pcie: Create enums for link speed and width > pci: Sync PCIe downstream port LNKSTA on read > qapi: Define PCIe link speed and width properties > pcie: Add link speed and width fields to PCIESlot > pcie: Fill PCIESlot link fields to support higher speeds and widths > pcie: Allow generic PCIe root port to specify link speed and width > vfio/pci: Remove PCIe Link Status emulation > pcie: Fast PCIe root ports for new machines > > Corey Minyard (1): > pc:piix4: Update smbus I/O space after a migration > > Eduardo Habkost (2): > virtio: Helper for registering virtio device types > virtio: Provide version-specific variants of virtio PCI devices > > Igor Mammedov (2): > hw: arm: acpi: Fix incorrect checksums in RSDP > hw: i386: Use correct RSDT length for checksum > > Matthias Weckbecker (1): > hw/pci-bridge: Fix invalid free() > > Peter Xu (5): > intel_iommu: dump correct iova when failed > intel_iommu: convert invalid traces into error reports > intel_iommu: dma read/write draining support > intel_iommu: remove "x-" prefix for "aw-bits" > intel_iommu: turn on IR by default > > Philippe Mathieu-Daudé (4): > tests: Remove unused include > hw/smbios: Restrict access to "hw/smbios/ipmi.h" > hw/smbios: Remove "smbios_ipmi.h" > hw/smbios: Move to the hw/firmware/ subdirectory > > Samuel Ortiz (6): > hw: acpi: The RSDP build API can return void > hw: arm: Carry RSDP specific data through AcpiRsdpData > hw: arm: Convert the RSDP build to the buid_append_foo() API > hw: arm: Support both legacy and current RSDP build > hw: acpi: Export and share the ARM RSDP build > hw: acpi: Remove AcpiRsdpDescriptor and fix tests > > Thomas Huth (1): > hw/i386: Remove deprecated machines pc-0.10 and pc-0.11 > > Zheng Xiang (1): > pcie: set link state inactive/active after hot unplug/plug > > qapi/common.json | 42 + > hw/i386/intel_iommu_internal.h | 3 + > hw/smbios/smbios_build.h | 4 + > hw/virtio/virtio-pci.h | 78 +++-- > include/hw/acpi/acpi-defs.h | 19 +-- > include/hw/acpi/aml-build.h | 2 + > include/hw/compat.h | 10 +- > include/hw/{smbios => firmware}/smbios.h | 0 > include/hw/i386/intel_iommu.h| 1 + > include/hw/i386/pc.h | 9 + > include/hw/pci/pci.h | 13 ++ > include/hw/pci/pcie.h| 1 + > include/hw/pci/pcie_port.h | 4 + > include/hw/pci/pcie_regs.h | 23 ++- > include/hw/qdev-properties.h | 8 + > include/hw/smbios/ipmi.h | 15 -- > tests/acpi-utils.h | 4 +- > hw/acpi/aml-build.c | 68 > hw/acpi/piix4.c | 1 + > hw/arm/virt-acpi-build.c | 40 + > hw/arm/virt.c| 2 +- > hw/core/qdev-properties.c| 176 > hw/display/virtio-gpu-pci.c | 7 +- > hw/display/virtio-vga.c | 7 +- > hw/i386/acpi-build.c | 46 +++--- > hw/i386/intel_iommu.c| 66 ++-- > hw/i386/pc.c | 2 +- > hw/i386/pc_piix.c| 72 +--- > hw/i386/pc_q35.c | 2 +- > hw/i386/x86-iommu.c | 2 +- > hw/pci-bridge/gen_pcie_root_port.c | 4 + > hw/pci-bridge/pcie_root_port.c | 14 ++ > hw/pci/pci.c | 4 + > hw/pci/pci_bridge.c | 2 +- > hw/pci/pcie.c| 132 ++- > hw/smbios/smbios-stub.c | 2 +- > hw/smbios/smbios.c | 3 +- > hw/smbios/smbios_type_38-stub.c |
[Qemu-devel] [PULL 18/31] intel_iommu: dump correct iova when failed
From: Peter Xu The iotlb.iova can be zero if failure really happened. Dump the addr instead. Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index d97bcbc2f7..f21988f396 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2540,7 +2540,7 @@ static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr, __func__, pci_bus_num(vtd_as->bus), VTD_PCI_SLOT(vtd_as->devfn), VTD_PCI_FUNC(vtd_as->devfn), - iotlb.iova); + addr); } return iotlb; -- MST
[Qemu-devel] [PULL 29/31] hw: acpi: Export and share the ARM RSDP build
From: Samuel Ortiz Now that build_rsdp() supports building both legacy and current RSDP tables, we can move it to a generic folder (hw/acpi) and have the i386 ACPI code reuse it in order to reduce code duplication. Signed-off-by: Samuel Ortiz Reviewed-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Andrew Jones --- include/hw/acpi/aml-build.h | 2 ++ hw/acpi/aml-build.c | 68 + hw/arm/virt-acpi-build.c| 65 --- hw/i386/acpi-build.c| 49 +++--- 4 files changed, 89 insertions(+), 95 deletions(-) diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 6c36903c0a..1a563ad756 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -388,6 +388,8 @@ void acpi_add_table(GArray *table_offsets, GArray *table_data); void acpi_build_tables_init(AcpiBuildTables *tables); void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre); void +build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data); +void build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, const char *oem_id, const char *oem_table_id); void diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 1e43cd736d..555c24f21d 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1589,6 +1589,74 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) g_array_free(tables->vmgenid, mfre); } +/* + * ACPI spec 5.2.5.3 Root System Description Pointer (RSDP). + * (Revision 1.0 or later) + */ +void +build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data) +{ +int tbl_off = tbl->len; /* Table offset in the RSDP file */ + +switch (rsdp_data->revision) { +case 0: +/* With ACPI 1.0, we must have an RSDT pointer */ +g_assert(rsdp_data->rsdt_tbl_offset); +break; +case 2: +/* With ACPI 2.0+, we must have an XSDT pointer */ +g_assert(rsdp_data->xsdt_tbl_offset); +break; +default: +/* Only revisions 0 (ACPI 1.0) and 2 (ACPI 2.0+) are valid for RSDP */ +g_assert_not_reached(); +} + +bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16, + true /* fseg memory */); + +g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */ +build_append_int_noprefix(tbl, 0, 1); /* Checksum */ +g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */ +build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */ +build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */ +if (rsdp_data->rsdt_tbl_offset) { +/* RSDT address to be filled by guest linker */ +bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, + tbl_off + 16, 4, + ACPI_BUILD_TABLE_FILE, + *rsdp_data->rsdt_tbl_offset); +} + +/* Checksum to be filled by guest linker */ +bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, +tbl_off, 20, /* ACPI rev 1.0 RSDP size */ +8); + +if (rsdp_data->revision == 0) { +/* ACPI 1.0 RSDP, we're done */ +return; +} + +build_append_int_noprefix(tbl, 36, 4); /* Length */ + +/* XSDT address to be filled by guest linker */ +build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */ +/* We already validated our xsdt pointer */ +bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, + tbl_off + 24, 8, + ACPI_BUILD_TABLE_FILE, + *rsdp_data->xsdt_tbl_offset); + +build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */ +build_append_int_noprefix(tbl, 0, 3); /* Reserved */ + +/* Extended checksum to be filled by Guest linker */ +bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, +tbl_off, 36, /* ACPI rev 2.0 RSDP size */ +32); +} + /* Build rsdt table */ void build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 05f6654371..95fad6f0ce 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -366,71 +366,6 @@ static void acpi_dsdt_add_power_button(Aml *scope) aml_append(scope, dev); } -/* RSDP */ -static void -build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data) -{ -int tbl_off = tbl->len; /* Table offset in the RSDP file */ - -switch (rsdp_data->revision) { -case 0: -/* With ACPI 1.0, we must have an RSDT pointer */ -g_assert(rsdp_data->rsdt_tbl_offset); -break; -case 2: -/* With ACPI 2.0+, we
Re: [Qemu-devel] [PATCH] spapr: Add H-Call H_HOME_NODE_ASSOCIATIVITY
On Mon, Dec 17, 2018 at 03:00:55PM +0100, Laurent Vivier wrote: > H_HOME_NODE_ASSOCIATIVITY H-Call returns the associativity domain > designation associated with the identifier input parameter. > > Remove the warning message from the kernel: > VPHN is not supported. Disabling polling.. > > Signed-off-by: Laurent Vivier From the looks of PAPR, I suspect this call isn't of much use outside PowerVM guests, though it probably wouldn't do any harm. BenH, Paulus, any thoughts? One nit in implementation: if you implement this hcall, it's supposed to be advertised by adding hcall-vphn to ibm,hypertas-functions. > --- > Based-on: <20181213040126.6768-1-da...@gibson.dropbear.id.au> > "[PULL 00/27] ppc-for-4.0 queue 20181213" > > hw/ppc/spapr_hcall.c | 39 +++ > include/hw/ppc/spapr.h | 1 + > 2 files changed, 40 insertions(+) > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index 78fecc8fe9..454ec594fd 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -1663,6 +1663,41 @@ static target_ulong > h_client_architecture_support(PowerPCCPU *cpu, > return H_SUCCESS; > } > > +static target_ulong h_home_node_associativity(PowerPCCPU *cpu, > + sPAPRMachineState *spapr, > + target_ulong opcode, > + target_ulong *args) > +{ > +target_ulong flags = args[0]; > +target_ulong procno = args[1]; > +PowerPCCPU *tcpu; > +int idx; > + > +/* only support procno from H_REGISTER_VPA */ > +if ((flags & 0x1) == 0) { > +return H_PARAMETER; > +} > + > +tcpu = spapr_find_cpu(procno); > +if (tcpu == NULL) { > +return H_P2; > +} > + > +/* sequence is the same as in the "ibm,associativity" property */ > + > +idx = 0; > +#define ASSOCIATIVITY(a, b) (((uint64_t)a << 32) | ((uint64_t)b & > 0x)) > +args[idx++] = ASSOCIATIVITY(0, 0); > +args[idx++] = ASSOCIATIVITY(0, tcpu->node_id); > +args[idx++] = ASSOCIATIVITY(procno, -1); > +for ( ; idx < 6; idx++) { > +args[idx] = -1; > +} > +#undef ASSOCIATIVITY > + > +return H_SUCCESS; > +} > + > static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu, >sPAPRMachineState *spapr, >target_ulong opcode, > @@ -1864,6 +1899,10 @@ static void hypercall_register_types(void) > spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support); > > spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt); > + > +/* Virtual Processor Home Node */ > +spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY, > + h_home_node_associativity); > } > > type_init(hypercall_register_types) > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index b1a2515107..eb13e2b614 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -447,6 +447,7 @@ struct sPAPRMachineState { > #define H_GET_EM_PARMS 0x2B8 > #define H_SET_MPP 0x2D0 > #define H_GET_MPP 0x2D4 > +#define H_HOME_NODE_ASSOCIATIVITY 0x2EC > #define H_XIRR_X0x2FC > #define H_RANDOM0x300 > #define H_SET_MODE 0x31C -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH qemu v3] ppc/spapr: Receive and store device tree blob from SLOF
On 18/12/2018 14:49, David Gibson wrote: > On Tue, Dec 18, 2018 at 02:04:54PM +1100, Alexey Kardashevskiy wrote: >> >> >> On 18/12/2018 13:09, David Gibson wrote: >>> On Mon, Dec 17, 2018 at 05:21:33PM +1100, David Gibson wrote: On Fri, Dec 14, 2018 at 12:55:20PM +1100, Alexey Kardashevskiy wrote: > SLOF receives a device tree and updates it with various properties > before switching to the guest kernel and QEMU is not aware of any changes > made by SLOF. Since there is no real RTAS (QEMU implements it), it makes > sense to pass the SLOF final device tree to QEMU to let it implement > RTAS related tasks better, such as PCI host bus adapter hotplug. > > Specifially, now QEMU can find out the actual XICS phandle (for PHB > hotplug) and the RTAS linux,rtas-entry/base properties (for firmware > assisted NMI - FWNMI). > > This stores the initial DT blob in the sPAPR machine and replaces it > in the KVMPPC_H_UPDATE_DT (new private hypercall) handler. > > This adds an @update_dt_enabled machine property to allow backward > migration. > > SLOF already has a hypercall since > https://github.com/aik/SLOF/commit/e6fc84652c9c0073f9183 > > This makes use of the new fdt_check_full() helper. In order to allow > the configure script to pick the correct DTC version, this adjusts > the DTC presense test. > > Signed-off-by: Alexey Kardashevskiy Applied, thanks. >>> >>> And now, unapplied. >>> >>> I don't know quite how, but somehow this patch is causing aarch64 >>> tests to SEGV. >> >> >> /home/aik/p/qemu/configure --target-list=aarch64-softmmu >> --source-path=/home/aik/p/qemu/ --disable-git-update --with-git=false >>--enable-trace-backend=log >> >> and >> >> make -C /home/aik/pbuild/qemu-localhost-aarch64-rel/ -j24 check >> >> did not produce segv. I am running this all on a power8 box + ubuntu >> 1804, what is your config? > > Hm, curious. I'm using Fedora 29 on an x86 host. Fedora 27 on x86_64 is all right too :-/ Let's upgrade... -- Alexey
[Qemu-devel] [PULL 17/31] pcie: Fast PCIe root ports for new machines
From: Alex Williamson Change the default speed and width for new machine types to the fastest and widest currently supported. This should be compatible to the PCIe 4.0 spec. Pre-QEMU-4.0 machine types remain at 2.5GT/s, x1 width. Cc: Marcel Apfelbaum Reviewed-by: Eric Auger Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/compat.h| 10 +- hw/pci-bridge/gen_pcie_root_port.c | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/hw/compat.h b/include/hw/compat.h index 70958328fe..3ca85b037c 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -2,7 +2,15 @@ #define HW_COMPAT_H #define HW_COMPAT_3_1 \ -/* empty */ +{\ +.driver = "pcie-root-port",\ +.property = "x-speed",\ +.value= "2_5",\ +},{\ +.driver = "pcie-root-port",\ +.property = "x-width",\ +.value= "1",\ +}, #define HW_COMPAT_3_0 \ /* empty */ diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c index ca5418a89d..9766edb445 100644 --- a/hw/pci-bridge/gen_pcie_root_port.c +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -125,9 +125,9 @@ static Property gen_rp_props[] = { DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, res_reserve.mem_pref_64, -1), DEFINE_PROP_PCIE_LINK_SPEED("x-speed", PCIESlot, -speed, PCIE_LINK_SPEED_2_5), +speed, PCIE_LINK_SPEED_16), DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot, -width, PCIE_LINK_WIDTH_1), +width, PCIE_LINK_WIDTH_32), DEFINE_PROP_END_OF_LIST() }; -- MST
[Qemu-devel] [PULL 20/31] intel_iommu: dma read/write draining support
From: Peter Xu Support DMA read/write draining should be easy for existing VT-d emulation since the emulation itself does not have any request queue there so we don't need to do anything to flush the un-commited queue. What we need to do is to declare the support. These capabilities are required to pass Windows SVVP test program. It is verified that when with parameters "x-aw-bits=48,caching-mode=off" we can pass the Windows SVVP test with this patch applied. Otherwise we'll fail with: IOMMU[0] - DWD (DMA write draining) not supported IOMMU[0] - DWD (DMA read draining) not supported Segment 0 has no DMA remapping capable IOMMU units However since these bits are not declared support for QEMU<=3.1, we'll need a compatibility bit for it and we turn this on by default only for QEMU>=4.0. Please refer to VT-d spec 6.5.4 for more information. CC: Yu Wang Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1654550 Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu_internal.h | 3 +++ include/hw/i386/intel_iommu.h | 1 + include/hw/i386/pc.h | 5 + hw/i386/intel_iommu.c | 4 4 files changed, 13 insertions(+) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index d084099ed9..00e9edbc66 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -203,6 +203,9 @@ #define VTD_CAP_MAMV(VTD_MAMV << 48) #define VTD_CAP_PSI (1ULL << 39) #define VTD_CAP_SLLPS ((1ULL << 34) | (1ULL << 35)) +#define VTD_CAP_DRAIN_WRITE (1ULL << 54) +#define VTD_CAP_DRAIN_READ (1ULL << 55) +#define VTD_CAP_DRAIN (VTD_CAP_DRAIN_READ | VTD_CAP_DRAIN_WRITE) #define VTD_CAP_CM (1ULL << 7) /* Supported Adjusted Guest Address Widths */ diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index ed4e758273..a321cc9691 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -245,6 +245,7 @@ struct IntelIOMMUState { OnOffAuto intr_eim; /* Toggle for EIM cabability */ bool buggy_eim; /* Force buggy EIM unless eim=off */ uint8_t aw_bits;/* Host/IOVA address width (in bits) */ +bool dma_drain; /* Whether DMA r/w draining enabled */ /* * Protects IOMMU states in general. Currently it protects the diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9d29c4b1df..c7c0c944e8 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -296,6 +296,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_3_1 \ HW_COMPAT_3_1 \ +{\ +.driver = "intel-iommu",\ +.property = "dma-drain",\ +.value= "off",\ +}, #define PC_COMPAT_3_0 \ HW_COMPAT_3_0 \ diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 4806d7edb4..26cc731c7b 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2659,6 +2659,7 @@ static Property vtd_properties[] = { DEFINE_PROP_UINT8("x-aw-bits", IntelIOMMUState, aw_bits, VTD_HOST_ADDRESS_WIDTH), DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE), +DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true), DEFINE_PROP_END_OF_LIST(), }; @@ -3147,6 +3148,9 @@ static void vtd_init(IntelIOMMUState *s) s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS | VTD_CAP_SAGAW_39bit | VTD_CAP_MGAW(s->aw_bits); +if (s->dma_drain) { +s->cap |= VTD_CAP_DRAIN; +} if (s->aw_bits == VTD_HOST_AW_48BIT) { s->cap |= VTD_CAP_SAGAW_48bit; } -- MST
[Qemu-devel] [PULL 26/31] hw: arm: Carry RSDP specific data through AcpiRsdpData
From: Samuel Ortiz That will allow us to generalize the ARM build_rsdp() routine to support both legacy RSDP (The current i386 implementation) and extended RSDP (The ARM implementation). Signed-off-by: Samuel Ortiz Reviewed-by: Igor Mammedov Reviewed-by: Andrew Jones Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/acpi/acpi-defs.h | 8 hw/arm/virt-acpi-build.c| 18 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index af8e023968..8425ecb8c6 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -53,6 +53,14 @@ struct AcpiRsdpDescriptor {/* Root System Descriptor Pointer */ } QEMU_PACKED; typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor; +typedef struct AcpiRsdpData { +uint8_t oem_id[6]; /* OEM identification */ +uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */ + +unsigned *rsdt_tbl_offset; +unsigned *xsdt_tbl_offset; +} AcpiRsdpData; + /* Table structure from Linux kernel (the ACPI tables are under the BSD license) */ diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 0835900052..ce8bfa5a37 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -368,7 +368,7 @@ static void acpi_dsdt_add_power_button(Aml *scope) /* RSDP */ static void -build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset) +build_rsdp(GArray *rsdp_table, BIOSLinker *linker, AcpiRsdpData *rsdp_data) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address); @@ -379,14 +379,14 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset) true /* fseg memory */); memcpy(>signature, "RSD PTR ", sizeof(rsdp->signature)); -memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id)); +memcpy(rsdp->oem_id, rsdp_data->oem_id, sizeof(rsdp->oem_id)); rsdp->length = cpu_to_le32(sizeof(*rsdp)); -rsdp->revision = 0x02; +rsdp->revision = rsdp_data->revision; /* Address to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size, -ACPI_BUILD_TABLE_FILE, xsdt_tbl_offset); +ACPI_BUILD_TABLE_FILE, *rsdp_data->xsdt_tbl_offset); /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, @@ -857,7 +857,15 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) build_xsdt(tables_blob, tables->linker, table_offsets, NULL, NULL); /* RSDP is in FSEG memory, so allocate it separately */ -build_rsdp(tables->rsdp, tables->linker, xsdt); +{ +AcpiRsdpData rsdp_data = { +.revision = 2, +.oem_id = ACPI_BUILD_APPNAME6, +.xsdt_tbl_offset = , +.rsdt_tbl_offset = NULL, +}; +build_rsdp(tables->rsdp, tables->linker, _data); +} /* Cleanup memory that's no longer used. */ g_array_free(table_offsets, true); -- MST
[Qemu-devel] [PULL 08/31] hw/smbios: Move to the hw/firmware/ subdirectory
From: Philippe Mathieu-Daudé SMBIOS is just another firmware interface used by some QEMU models. We will later introduce more firmware interfaces in this subdirectory. Reviewed-by: Laszlo Ersek Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/{smbios => firmware}/smbios.h | 0 hw/arm/virt.c| 2 +- hw/i386/pc.c | 2 +- hw/i386/pc_piix.c| 2 +- hw/i386/pc_q35.c | 2 +- hw/smbios/smbios-stub.c | 2 +- hw/smbios/smbios.c | 2 +- hw/smbios/smbios_type_38.c | 2 +- tests/bios-tables-test.c | 2 +- vl.c | 2 +- MAINTAINERS | 2 +- 11 files changed, 10 insertions(+), 10 deletions(-) rename include/hw/{smbios => firmware}/smbios.h (100%) diff --git a/include/hw/smbios/smbios.h b/include/hw/firmware/smbios.h similarity index 100% rename from include/hw/smbios/smbios.h rename to include/hw/firmware/smbios.h diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 5b678237b7..c2641e56ea 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -55,7 +55,7 @@ #include "hw/intc/arm_gic.h" #include "hw/intc/arm_gicv3_common.h" #include "kvm_arm.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "qapi/visitor.h" #include "standard-headers/linux/input.h" #include "hw/arm/smmuv3.h" diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 115bc2825c..470cc5daf9 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -37,7 +37,7 @@ #include "hw/pci/pci_bus.h" #include "hw/nvram/fw_cfg.h" #include "hw/timer/hpet.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "hw/loader.h" #include "elf.h" #include "multiboot.h" diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 6981cfa740..e000c7511a 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -30,7 +30,7 @@ #include "hw/i386/pc.h" #include "hw/i386/apic.h" #include "hw/display/ramfb.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "hw/pci/pci.h" #include "hw/pci/pci_ids.h" #include "hw/usb.h" diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 58459bdab5..8836d21485 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -47,7 +47,7 @@ #include "hw/i386/amd_iommu.h" #include "hw/i386/intel_iommu.h" #include "hw/display/ramfb.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/usb.h" diff --git a/hw/smbios/smbios-stub.c b/hw/smbios/smbios-stub.c index d3a385441a..64e5ba93ec 100644 --- a/hw/smbios/smbios-stub.c +++ b/hw/smbios/smbios-stub.c @@ -23,7 +23,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" void smbios_entry_add(QemuOpts *opts, Error **errp) { diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index 4bff9b5ea4..818be8a838 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -24,7 +24,7 @@ #include "sysemu/sysemu.h" #include "qemu/uuid.h" #include "sysemu/cpus.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "hw/loader.h" #include "exec/cpu-common.h" #include "smbios_build.h" diff --git a/hw/smbios/smbios_type_38.c b/hw/smbios/smbios_type_38.c index a1ad28d059..0c08f282de 100644 --- a/hw/smbios/smbios_type_38.c +++ b/hw/smbios/smbios_type_38.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "hw/ipmi/ipmi.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "qemu/error-report.h" #include "smbios_build.h" diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index d661d9be62..dfa74a5bec 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include #include "qemu-common.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "qemu/bitmap.h" #include "acpi-utils.h" #include "boot-sector.h" diff --git a/vl.c b/vl.c index 2a8b2ee16d..522f0131f4 100644 --- a/vl.c +++ b/vl.c @@ -61,7 +61,7 @@ int main(int argc, char **argv) #include "hw/display/vga.h" #include "hw/bt.h" #include "sysemu/watchdog.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "hw/acpi/acpi.h" #include "hw/xen/xen.h" #include "hw/qdev.h" diff --git a/MAINTAINERS b/MAINTAINERS index 83c127f0d6..5d83b59542 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1260,7 +1260,7 @@ M: Michael S. Tsirkin M: Igor Mammedov S: Supported F: include/hw/acpi/* -F: include/hw/smbios/* +F: include/hw/firmware/smbios.h F: hw/mem/* F: hw/acpi/* F: hw/smbios/* -- MST
[Qemu-devel] [PULL 28/31] hw: arm: Support both legacy and current RSDP build
From: Samuel Ortiz We add the ability to build legacy or current RSDP tables, based on the AcpiRsdpData revision field passed to build_rsdp(). Although arm/virt only uses RSDP v2, adding that capability to build_rsdp will allow us to share the RSDP build code between ARM and x86. Signed-off-by: Samuel Ortiz Reviewed-by: Igor Mammedov Reviewed-by: Andrew Jones Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/arm/virt-acpi-build.c | 38 +- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 4a6b53fbfc..05f6654371 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -372,6 +372,20 @@ build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data) { int tbl_off = tbl->len; /* Table offset in the RSDP file */ +switch (rsdp_data->revision) { +case 0: +/* With ACPI 1.0, we must have an RSDT pointer */ +g_assert(rsdp_data->rsdt_tbl_offset); +break; +case 2: +/* With ACPI 2.0+, we must have an XSDT pointer */ +g_assert(rsdp_data->xsdt_tbl_offset); +break; +default: +/* Only revisions 0 (ACPI 1.0) and 2 (ACPI 2.0+) are valid for RSDP */ +g_assert_not_reached(); +} + bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16, true /* fseg memory */); @@ -380,10 +394,29 @@ build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data) g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */ build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */ build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */ +if (rsdp_data->rsdt_tbl_offset) { +/* RSDT address to be filled by guest linker */ +bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, + tbl_off + 16, 4, + ACPI_BUILD_TABLE_FILE, + *rsdp_data->rsdt_tbl_offset); +} + +/* Checksum to be filled by guest linker */ +bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, +tbl_off, 20, /* ACPI rev 1.0 RSDP size */ +8); + +if (rsdp_data->revision == 0) { +/* ACPI 1.0 RSDP, we're done */ +return; +} + build_append_int_noprefix(tbl, 36, 4); /* Length */ /* XSDT address to be filled by guest linker */ build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */ +/* We already validated our xsdt pointer */ bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, tbl_off + 24, 8, ACPI_BUILD_TABLE_FILE, @@ -392,11 +425,6 @@ build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data) build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */ build_append_int_noprefix(tbl, 0, 3); /* Reserved */ -/* Checksum to be filled by guest linker */ -bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, -tbl_off, 20, /* ACPI rev 1.0 RSDP size */ -8); - /* Extended checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, tbl_off, 36, /* ACPI rev 2.0 RSDP size */ -- MST
[Qemu-devel] [PULL 13/31] pcie: Add link speed and width fields to PCIESlot
From: Alex Williamson Add fields allowing the PCIe link speed and width of a PCIESlot to be configured, with an instance_post_init callback on the root port parent class to set defaults. This allows child classes to set these via properties or via their own instance_init callback, without requiring all implementions to support arbitrary user selected values. Cc: Marcel Apfelbaum Tested-by: Geoffrey McRae Reviewed-by: Eric Auger Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/pci/pcie_port.h | 4 hw/pci-bridge/pcie_root_port.c | 14 ++ 2 files changed, 18 insertions(+) diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index 0736014bfd..df242a0caf 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -49,6 +49,10 @@ struct PCIESlot { /* pci express switch port with slot */ uint8_t chassis; uint16_tslot; + +PCIExpLinkSpeed speed; +PCIExpLinkWidth width; + QLIST_ENTRY(PCIESlot) next; }; diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c index 45f9e8cd4a..34ad76743c 100644 --- a/hw/pci-bridge/pcie_root_port.c +++ b/hw/pci-bridge/pcie_root_port.c @@ -140,6 +140,19 @@ static Property rp_props[] = { DEFINE_PROP_END_OF_LIST() }; +static void rp_instance_post_init(Object *obj) +{ +PCIESlot *s = PCIE_SLOT(obj); + +if (!s->speed) { +s->speed = QEMU_PCI_EXP_LNK_2_5GT; +} + +if (!s->width) { +s->width = QEMU_PCI_EXP_LNK_X1; +} +} + static void rp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -157,6 +170,7 @@ static void rp_class_init(ObjectClass *klass, void *data) static const TypeInfo rp_info = { .name = TYPE_PCIE_ROOT_PORT, .parent= TYPE_PCIE_SLOT, +.instance_post_init = rp_instance_post_init, .class_init= rp_class_init, .abstract = true, .class_size = sizeof(PCIERootPortClass), -- MST
[Qemu-devel] [PULL 23/31] hw: acpi: The RSDP build API can return void
From: Samuel Ortiz For both x86 and ARM architectures, the internal RSDP build API can return void as the current return value is unused. Signed-off-by: Samuel Ortiz Reviewed-by: Igor Mammedov Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Reviewed-by: Andrew Jones Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/arm/virt-acpi-build.c | 4 +--- hw/i386/acpi-build.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 5785fb697c..fcaa350892 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -367,7 +367,7 @@ static void acpi_dsdt_add_power_button(Aml *scope) } /* RSDP */ -static GArray * +static void build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); @@ -392,8 +392,6 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset) bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, (char *)rsdp - rsdp_table->data, sizeof *rsdp, (char *)>checksum - rsdp_table->data); - -return rsdp_table; } static void diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 236a20eaa8..35f17d0d91 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2547,7 +2547,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker) "IVRS", table_data->len - iommu_start, 1, NULL, NULL); } -static GArray * +static void build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); @@ -2569,8 +2569,6 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, (char *)rsdp - rsdp_table->data, sizeof *rsdp, (char *)>checksum - rsdp_table->data); - -return rsdp_table; } typedef -- MST
[Qemu-devel] [PULL 09/31] hw/pci-bridge: Fix invalid free()
From: Matthias Weckbecker When loadvm'ing a *running* snapshot qemu crashes due to an invalid free. It's fortunately caught early by glibc heap memory corruption protection and qemu gets killed with SIGABRT. Steps to reproduce: 1) Create VM (e.g w/ virsh define) 2) Start the VM and take a snapshot while it's running and having a PCI bridge attached 3) Destroy the VM and revert the running snapshot. This commit fixes the issue. Signed-off-by: Matthias Weckbecker Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pci_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index ee9dff2d3a..b9143ac88b 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -241,9 +241,9 @@ void pci_bridge_update_mappings(PCIBridge *br) * while another accesses an unaffected region. */ memory_region_transaction_begin(); pci_bridge_region_del(br, br->windows); +pci_bridge_region_cleanup(br, w); br->windows = pci_bridge_region_init(br); memory_region_transaction_commit(); -pci_bridge_region_cleanup(br, w); } /* default write_config function for PCI-to-PCI bridge */ -- MST
[Qemu-devel] [PULL 27/31] hw: arm: Convert the RSDP build to the buid_append_foo() API
From: Samuel Ortiz Instead of filling a mapped and packed C structure field in random order and being careful about endianness and sizes, build_rsdp() now uses build_append_int_noprefix() to compose RSDP table. This makes reviewing and maintaining code easier as this is almost matching 1:1 the ACPI spec itself. Signed-off-by: Samuel Ortiz Reviewed-by: Igor Mammedov Reviewed-by: Andrew Jones Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/arm/virt-acpi-build.c | 42 ++-- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index ce8bfa5a37..4a6b53fbfc 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -368,35 +368,39 @@ static void acpi_dsdt_add_power_button(Aml *scope) /* RSDP */ static void -build_rsdp(GArray *rsdp_table, BIOSLinker *linker, AcpiRsdpData *rsdp_data) +build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data) { -AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); -unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address); -unsigned xsdt_pa_offset = -(char *)>xsdt_physical_address - rsdp_table->data; +int tbl_off = tbl->len; /* Table offset in the RSDP file */ -bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16, +bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16, true /* fseg memory */); -memcpy(>signature, "RSD PTR ", sizeof(rsdp->signature)); -memcpy(rsdp->oem_id, rsdp_data->oem_id, sizeof(rsdp->oem_id)); -rsdp->length = cpu_to_le32(sizeof(*rsdp)); -rsdp->revision = rsdp_data->revision; +g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */ +build_append_int_noprefix(tbl, 0, 1); /* Checksum */ +g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */ +build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */ +build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */ +build_append_int_noprefix(tbl, 36, 4); /* Length */ -/* Address to be filled by Guest linker */ -bios_linker_loader_add_pointer(linker, -ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size, -ACPI_BUILD_TABLE_FILE, *rsdp_data->xsdt_tbl_offset); +/* XSDT address to be filled by guest linker */ +build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */ +bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, + tbl_off + 24, 8, + ACPI_BUILD_TABLE_FILE, + *rsdp_data->xsdt_tbl_offset); -/* Checksum to be filled by Guest linker */ +build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */ +build_append_int_noprefix(tbl, 0, 3); /* Reserved */ + +/* Checksum to be filled by guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, -(char *)rsdp - rsdp_table->data, 20 /* ACPI rev 1.0 RSDP size */, -(char *)>checksum - rsdp_table->data); +tbl_off, 20, /* ACPI rev 1.0 RSDP size */ +8); /* Extended checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, -(char *)rsdp - rsdp_table->data, 36 /* ACPI rev 2.0 RSDP size */, -(char *)>extended_checksum - rsdp_table->data); +tbl_off, 36, /* ACPI rev 2.0 RSDP size */ +32); } static void -- MST
[Qemu-devel] [PULL 03/31] virtio: Helper for registering virtio device types
From: Eduardo Habkost Introduce a helper for registering different flavours of virtio devices. Convert code to use the helper, but keep only the existing generic types. Transitional and non-transitional device types will be added by another patch. Acked-by: Andrea Bolognani Reviewed-by: Cornelia Huck Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-pci.h| 54 hw/display/virtio-gpu-pci.c | 7 +- hw/display/virtio-vga.c | 7 +- hw/virtio/virtio-crypto-pci.c | 7 +- hw/virtio/virtio-pci.c| 235 -- 5 files changed, 230 insertions(+), 80 deletions(-) diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 813082b0d7..8cd546608e 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -417,4 +417,58 @@ struct VirtIOCryptoPCI { /* Virtio ABI version, if we increment this, we break the guest driver. */ #define VIRTIO_PCI_ABI_VERSION 0 +/* Input for virtio_pci_types_register() */ +typedef struct VirtioPCIDeviceTypeInfo { +/* + * Common base class for the subclasses below. + * + * Required only if transitional_name or non_transitional_name is set. + * + * We need a separate base type instead of making all types + * inherit from generic_name for two reasons: + * 1) generic_name implements INTERFACE_PCIE_DEVICE, but + *transitional_name does not. + * 2) generic_name has the "disable-legacy" and "disable-modern" + *properties, transitional_name and non_transitional name don't. + */ +const char *base_name; +/* + * Generic device type. Optional. + * + * Supports both transitional and non-transitional modes, + * using the disable-legacy and disable-modern properties. + * If disable-legacy=auto, (non-)transitional mode is selected + * depending on the bus where the device is plugged. + * + * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE, + * but PCI Express is supported only in non-transitional mode. + * + * The only type implemented by QEMU 3.1 and older. + */ +const char *generic_name; +/* + * The transitional device type. Optional. + * + * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE. + */ +const char *transitional_name; +/* + * The non-transitional device type. Optional. + * + * Implements INTERFACE_CONVENTIONAL_PCI_DEVICE only. + */ +const char *non_transitional_name; + +/* Parent type. If NULL, TYPE_VIRTIO_PCI is used */ +const char *parent; + +/* Same as TypeInfo fields: */ +size_t instance_size; +void (*instance_init)(Object *obj); +void (*class_init)(ObjectClass *klass, void *data); +} VirtioPCIDeviceTypeInfo; + +/* Register virtio-pci type(s). @t must be static. */ +void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t); + #endif diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c index cece4aa495..faf76a8bc4 100644 --- a/hw/display/virtio-gpu-pci.c +++ b/hw/display/virtio-gpu-pci.c @@ -69,9 +69,8 @@ static void virtio_gpu_initfn(Object *obj) TYPE_VIRTIO_GPU); } -static const TypeInfo virtio_gpu_pci_info = { -.name = TYPE_VIRTIO_GPU_PCI, -.parent = TYPE_VIRTIO_PCI, +static const VirtioPCIDeviceTypeInfo virtio_gpu_pci_info = { +.generic_name = TYPE_VIRTIO_GPU_PCI, .instance_size = sizeof(VirtIOGPUPCI), .instance_init = virtio_gpu_initfn, .class_init = virtio_gpu_pci_class_init, @@ -79,6 +78,6 @@ static const TypeInfo virtio_gpu_pci_info = { static void virtio_gpu_pci_register_types(void) { -type_register_static(_gpu_pci_info); +virtio_pci_types_register(_gpu_pci_info); } type_init(virtio_gpu_pci_register_types) diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index ab2e369b28..8db4d916f2 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -207,9 +207,8 @@ static void virtio_vga_inst_initfn(Object *obj) TYPE_VIRTIO_GPU); } -static TypeInfo virtio_vga_info = { -.name = TYPE_VIRTIO_VGA, -.parent= TYPE_VIRTIO_PCI, +static VirtioPCIDeviceTypeInfo virtio_vga_info = { +.generic_name = TYPE_VIRTIO_VGA, .instance_size = sizeof(struct VirtIOVGA), .instance_init = virtio_vga_inst_initfn, .class_init= virtio_vga_class_init, @@ -217,7 +216,7 @@ static TypeInfo virtio_vga_info = { static void virtio_vga_register_types(void) { -type_register_static(_vga_info); +virtio_pci_types_register(_vga_info); } type_init(virtio_vga_register_types) diff --git a/hw/virtio/virtio-crypto-pci.c b/hw/virtio/virtio-crypto-pci.c index bf64996e48..8cc3fa3ef7 100644 --- a/hw/virtio/virtio-crypto-pci.c +++ b/hw/virtio/virtio-crypto-pci.c @@ -64,9 +64,8 @@ static void
[Qemu-devel] [PULL 07/31] hw/smbios: Remove "smbios_ipmi.h"
From: Philippe Mathieu-Daudé This header only declare a single function: smbios_build_type_38_table(). We already have a header that declares such functions: "smbios_build.h". Move the declaration and remove the header. Reviewed-by: Corey Minyard Reviewed-by: Laszlo Ersek Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/smbios/smbios_build.h| 4 hw/smbios/smbios_ipmi.h | 15 --- hw/smbios/smbios.c | 1 - hw/smbios/smbios_type_38-stub.c | 2 +- hw/smbios/smbios_type_38.c | 1 - 5 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 hw/smbios/smbios_ipmi.h diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h index 93b360d520..56b5a1e3f3 100644 --- a/hw/smbios/smbios_build.h +++ b/hw/smbios/smbios_build.h @@ -3,6 +3,7 @@ * * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. * Copyright (C) 2013 Red Hat, Inc. + * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC * * Authors: * Alex Williamson @@ -96,4 +97,7 @@ extern unsigned smbios_table_cnt; smbios_table_cnt++; \ } while (0) +/* IPMI SMBIOS firmware handling */ +void smbios_build_type_38_table(void); + #endif /* QEMU_SMBIOS_BUILD_H */ diff --git a/hw/smbios/smbios_ipmi.h b/hw/smbios/smbios_ipmi.h deleted file mode 100644 index 1c9aae38f2..00 --- a/hw/smbios/smbios_ipmi.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * IPMI SMBIOS firmware handling - * - * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef QEMU_SMBIOS_IPMI_H -#define QEMU_SMBIOS_IPMI_H - -void smbios_build_type_38_table(void); - -#endif /* QEMU_SMBIOS_IPMI_H */ diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index 6fe5be3586..4bff9b5ea4 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -28,7 +28,6 @@ #include "hw/loader.h" #include "exec/cpu-common.h" #include "smbios_build.h" -#include "smbios_ipmi.h" /* legacy structures and constants for <= 2.0 machines */ struct smbios_header { diff --git a/hw/smbios/smbios_type_38-stub.c b/hw/smbios/smbios_type_38-stub.c index fc4516bc8a..14b53d004b 100644 --- a/hw/smbios/smbios_type_38-stub.c +++ b/hw/smbios/smbios_type_38-stub.c @@ -8,7 +8,7 @@ */ #include "qemu/osdep.h" -#include "smbios_ipmi.h" +#include "smbios_build.h" void smbios_build_type_38_table(void) { diff --git a/hw/smbios/smbios_type_38.c b/hw/smbios/smbios_type_38.c index d84e87d608..a1ad28d059 100644 --- a/hw/smbios/smbios_type_38.c +++ b/hw/smbios/smbios_type_38.c @@ -12,7 +12,6 @@ #include "hw/smbios/smbios.h" #include "qemu/error-report.h" #include "smbios_build.h" -#include "smbios_ipmi.h" /* SMBIOS type 38 - IPMI */ struct smbios_type_38 { -- MST
[Qemu-devel] [PULL 22/31] intel_iommu: turn on IR by default
From: Peter Xu IR has been there for a long time and long time no bug reported. Let's turn it on by default to match general hardwares. Providing compatibility bit for QEMU<=3.1. Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/i386/pc.h | 4 hw/i386/x86-iommu.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index c7c0c944e8..ed958b9af1 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -300,6 +300,10 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "intel-iommu",\ .property = "dma-drain",\ .value= "off",\ +},{\ +.driver = "x86-iommu",\ +.property = "intremap",\ +.value= "off",\ }, #define PC_COMPAT_3_0 \ diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c index abc3c03158..0150ceda14 100644 --- a/hw/i386/x86-iommu.c +++ b/hw/i386/x86-iommu.c @@ -135,7 +135,7 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp) } static Property x86_iommu_properties[] = { -DEFINE_PROP_BOOL("intremap", X86IOMMUState, intr_supported, false), +DEFINE_PROP_BOOL("intremap", X86IOMMUState, intr_supported, true), DEFINE_PROP_BOOL("device-iotlb", X86IOMMUState, dt_supported, false), DEFINE_PROP_BOOL("pt", X86IOMMUState, pt_supported, true), DEFINE_PROP_END_OF_LIST(), -- MST
[Qemu-devel] [PULL 14/31] pcie: Fill PCIESlot link fields to support higher speeds and widths
From: Alex Williamson Make use of the PCIESlot speed and width fields to update link information beyond those configured in pcie_cap_v1_fill(). This is only called for devices supporting a version 2 capability and automatically skips any non-PCIESlot devices. Only devices with increased link values generate any visible config space differences. Cc: Marcel Apfelbaum Tested-by: Geoffrey McRae Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pcie.c | 74 +++ 1 file changed, 74 insertions(+) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 6891deb711..d91a615193 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -27,6 +27,7 @@ #include "hw/pci/msi.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pcie_regs.h" +#include "hw/pci/pcie_port.h" #include "qemu/range.h" //#define DEBUG_PCIE @@ -87,6 +88,76 @@ pcie_cap_v1_fill(PCIDevice *dev, uint8_t port, uint8_t type, uint8_t version) pci_set_word(cmask + PCI_EXP_LNKSTA, 0); } +static void pcie_cap_fill_slot_lnk(PCIDevice *dev) +{ +PCIESlot *s = (PCIESlot *)object_dynamic_cast(OBJECT(dev), TYPE_PCIE_SLOT); +uint8_t *exp_cap = dev->config + dev->exp.exp_cap; + +/* Skip anything that isn't a PCIESlot */ +if (!s) { +return; +} + +/* Clear and fill LNKCAP from what was configured above */ +pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP, + PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); +pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, + QEMU_PCI_EXP_LNKCAP_MLW(s->width) | + QEMU_PCI_EXP_LNKCAP_MLS(s->speed)); + +/* + * Link bandwidth notification is required for all root ports and + * downstream ports supporting links wider than x1 or multiple link + * speeds. + */ +if (s->width > QEMU_PCI_EXP_LNK_X1 || +s->speed > QEMU_PCI_EXP_LNK_2_5GT) { +pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, + PCI_EXP_LNKCAP_LBNC); +} + +if (s->speed > QEMU_PCI_EXP_LNK_2_5GT) { +/* + * Hot-plug capable downstream ports and downstream ports supporting + * link speeds greater than 5GT/s must hardwire PCI_EXP_LNKCAP_DLLLARC + * to 1b. PCI_EXP_LNKCAP_DLLLARC implies PCI_EXP_LNKSTA_DLLLA, which + * we also hardwire to 1b here. 2.5GT/s hot-plug slots should also + * technically implement this, but it's not done here for compatibility. + */ +pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, + PCI_EXP_LNKCAP_DLLLARC); +pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_DLLLA); + +/* + * Target Link Speed defaults to the highest link speed supported by + * the component. 2.5GT/s devices are permitted to hardwire to zero. + */ +pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS); +pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKCTL2, + QEMU_PCI_EXP_LNKCAP_MLS(s->speed) & + PCI_EXP_LNKCTL2_TLS); +} + +/* + * 2.5 & 5.0GT/s can be fully described by LNKCAP, but 8.0GT/s is + * actually a reference to the highest bit supported in this register. + * We assume the device supports all link speeds. + */ +if (s->speed > QEMU_PCI_EXP_LNK_5GT) { +pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP2, ~0U); +pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP2, + PCI_EXP_LNKCAP2_SLS_2_5GB | + PCI_EXP_LNKCAP2_SLS_5_0GB | + PCI_EXP_LNKCAP2_SLS_8_0GB); +if (s->speed > QEMU_PCI_EXP_LNK_8GT) { +pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP2, + PCI_EXP_LNKCAP2_SLS_16_0GB); +} +} +} + int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port, Error **errp) @@ -108,6 +179,9 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, /* Filling values common with v1 */ pcie_cap_v1_fill(dev, port, type, PCI_EXP_FLAGS_VER2); +/* Fill link speed and width options */ +pcie_cap_fill_slot_lnk(dev); + /* Filling v2 specific values */ pci_set_long(exp_cap + PCI_EXP_DEVCAP2, PCI_EXP_DEVCAP2_EFF | PCI_EXP_DEVCAP2_EETLPP); -- MST
Re: [Qemu-devel] sheepdog build warning
On Mon, Dec 17, 2018 at 11:03:11PM -0500, Michael S. Tsirkin wrote: > mingw32 build on fedora fails with this warning: > > /scm/qemu/block/sheepdog.c: In function 'find_vdi_name': > /scm/qemu/block/sheepdog.c:1239:5: error: 'strncpy' specified bound 256 > equals destination size [-Werror=stringop-truncation] > strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN); > ^~ > cc1: all warnings being treated as errors > make: *** [/scm/qemu/rules.mak:69: block/sheepdog.o] Error 1 > make: *** Waiting for unfinished jobs > > > Reading the code one sees it's working as intended: > > > static int find_vdi_name(BDRVSheepdogState *s, const char *filename, > uint32_t snapid, const char *tag, uint32_t *vid, > bool lock, Error **errp) > { > int ret, fd; > SheepdogVdiReq hdr; > SheepdogVdiRsp *rsp = (SheepdogVdiRsp *) > unsigned int wlen, rlen = 0; > char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN]; > > fd = connect_to_sdog(s, errp); > if (fd < 0) { > return fd; > } > > /* This pair of strncpy calls ensures that the buffer is zero-filled, > * which is desirable since we'll soon be sending those bytes, and > * don't want the send_req to read uninitialized data. > */ > strncpy(buf, filename, SD_MAX_VDI_LEN); > strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN); > > > . > > } > > > > so this seems to be the case of GCC developers deciding that > strncpy is simply a bad API and a correct use of it should be > warned against. > > I propose either > > 1. simply adding > > #pragma GCC diagnostic ignored "-Wstringop-truncation" > > in osdep. > > 2. adding an inline wrapper with said pragma in there. > > 3. -Wno-stringop-truncation is the makefile > > Thoughts? > > -- So here's approach 2. However I note that a newer gcc 8.2.1 does not give this warning. Maybe detect at configure time and suppress (option 3)? diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 3bf48bcdec..64d8258529 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -134,6 +134,22 @@ extern int daemon(int, int); #define assert(x) g_assert(x) #endif +/* + * GCC 8.0 declared war on strncpy. Admittedly it's a tricky interface + * with unintuitive semantics, but we use it widely. + */ +#if defined(__GNUC__) && __GNUC__ >= 8 +static inline void qemu_strncpy(char *to, const char *from, int n) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-truncation" +strncpy(to, from, n); +#pragma GCC diagnostic pop +} + +#define strncpy qemu_strncpy +#endif + /* * According to waitpid man page: * WCOREDUMP
[Qemu-devel] [PULL 06/31] hw/smbios: Restrict access to "hw/smbios/ipmi.h"
From: Philippe Mathieu-Daudé All the consumers of "hw/smbios/ipmi.h" are located in hw/smbios/. There is no need to have this include publicly exposed, reduce the visibility by moving it in hw/smbios/. Reviewed-by: Laszlo Ersek Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/smbios/ipmi.h => hw/smbios/smbios_ipmi.h | 0 hw/smbios/smbios.c | 2 +- hw/smbios/smbios_type_38-stub.c | 2 +- hw/smbios/smbios_type_38.c | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename include/hw/smbios/ipmi.h => hw/smbios/smbios_ipmi.h (100%) diff --git a/include/hw/smbios/ipmi.h b/hw/smbios/smbios_ipmi.h similarity index 100% rename from include/hw/smbios/ipmi.h rename to hw/smbios/smbios_ipmi.h diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index 04811279a0..6fe5be3586 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -28,7 +28,7 @@ #include "hw/loader.h" #include "exec/cpu-common.h" #include "smbios_build.h" -#include "hw/smbios/ipmi.h" +#include "smbios_ipmi.h" /* legacy structures and constants for <= 2.0 machines */ struct smbios_header { diff --git a/hw/smbios/smbios_type_38-stub.c b/hw/smbios/smbios_type_38-stub.c index 5b83c9b1f1..fc4516bc8a 100644 --- a/hw/smbios/smbios_type_38-stub.c +++ b/hw/smbios/smbios_type_38-stub.c @@ -8,7 +8,7 @@ */ #include "qemu/osdep.h" -#include "hw/smbios/ipmi.h" +#include "smbios_ipmi.h" void smbios_build_type_38_table(void) { diff --git a/hw/smbios/smbios_type_38.c b/hw/smbios/smbios_type_38.c index 56e8609c00..d84e87d608 100644 --- a/hw/smbios/smbios_type_38.c +++ b/hw/smbios/smbios_type_38.c @@ -9,10 +9,10 @@ #include "qemu/osdep.h" #include "hw/ipmi/ipmi.h" -#include "hw/smbios/ipmi.h" #include "hw/smbios/smbios.h" #include "qemu/error-report.h" #include "smbios_build.h" +#include "smbios_ipmi.h" /* SMBIOS type 38 - IPMI */ struct smbios_type_38 { -- MST
[Qemu-devel] [PULL 16/31] vfio/pci: Remove PCIe Link Status emulation
From: Alex Williamson Now that the downstream port will virtually negotiate itself to the link status of the downstream device, we can remove this emulation. It's not clear that it was every terribly useful anyway. Tested-by: Geoffrey McRae Reviewed-by: Eric Auger Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/vfio/pci.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 74f9a46b4b..c0cb1ec289 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1901,12 +1901,6 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size, QEMU_PCI_EXP_LNKCAP_MLS(QEMU_PCI_EXP_LNK_2_5GT), ~0); vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL, 0, ~0); } - -/* Mark the Link Status bits as emulated to allow virtual negotiation */ -vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKSTA, - pci_get_word(vdev->pdev.config + pos + -PCI_EXP_LNKSTA), - PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); } /* -- MST
[Qemu-devel] [PULL 21/31] intel_iommu: remove "x-" prefix for "aw-bits"
From: Peter Xu We're going to have 57bits aw-bits support sooner. It's possibly time to remove the "x-" prefix. Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 26cc731c7b..96ef31eb7e 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2656,7 +2656,7 @@ static Property vtd_properties[] = { DEFINE_PROP_ON_OFF_AUTO("eim", IntelIOMMUState, intr_eim, ON_OFF_AUTO_AUTO), DEFINE_PROP_BOOL("x-buggy-eim", IntelIOMMUState, buggy_eim, false), -DEFINE_PROP_UINT8("x-aw-bits", IntelIOMMUState, aw_bits, +DEFINE_PROP_UINT8("aw-bits", IntelIOMMUState, aw_bits, VTD_HOST_ADDRESS_WIDTH), DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE), DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true), -- MST
[Qemu-devel] [PULL 02/31] pc:piix4: Update smbus I/O space after a migration
From: Corey Minyard Otherwise it won't be set up correctly and won't work after miigration. Signed-off-by: Corey Minyard Cc: Igor Mammedov Cc: qemu-sta...@nongnu.org Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/piix4.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index e330f24c71..2f4dd03b83 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -173,6 +173,7 @@ static int vmstate_acpi_post_load(void *opaque, int version_id) PIIX4PMState *s = opaque; pm_io_space_update(s); +smbus_io_space_update(s); return 0; } -- MST
[Qemu-devel] [PULL 05/31] tests: Remove unused include
From: Philippe Mathieu-Daudé The "hw/smbios/smbios.h" include is not used, remove it. Reviewed-by: Laszlo Ersek Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/acpi-utils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/acpi-utils.c b/tests/acpi-utils.c index 41dc1ea9b4..297af55d39 100644 --- a/tests/acpi-utils.c +++ b/tests/acpi-utils.c @@ -15,7 +15,6 @@ #include "qemu/osdep.h" #include #include "qemu-common.h" -#include "hw/smbios/smbios.h" #include "qemu/bitmap.h" #include "acpi-utils.h" #include "boot-sector.h" -- MST
[Qemu-devel] [PULL 12/31] qapi: Define PCIe link speed and width properties
From: Alex Williamson Create properties to be able to define speeds and widths for PCIe links. The only tricky bit here is that our get and set callbacks translate from the fixed QAPI automagic enums to those we define in PCI code to represent the actual register segment value. Cc: Eric Blake Tested-by: Geoffrey McRae Reviewed-by: Markus Armbruster Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- qapi/common.json | 42 + include/hw/qdev-properties.h | 8 ++ hw/core/qdev-properties.c| 176 +++ 3 files changed, 226 insertions(+) diff --git a/qapi/common.json b/qapi/common.json index 021174f04e..99d313ef3b 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -127,6 +127,48 @@ { 'enum': 'OffAutoPCIBAR', 'data': [ 'off', 'auto', 'bar0', 'bar1', 'bar2', 'bar3', 'bar4', 'bar5' ] } +## +# @PCIELinkSpeed: +# +# An enumeration of PCIe link speeds in units of GT/s +# +# @2_5: 2.5GT/s +# +# @5: 5.0GT/s +# +# @8: 8.0GT/s +# +# @16: 16.0GT/s +# +# Since: 4.0 +## +{ 'enum': 'PCIELinkSpeed', + 'data': [ '2_5', '5', '8', '16' ] } + +## +# @PCIELinkWidth: +# +# An enumeration of PCIe link width +# +# @1: x1 +# +# @2: x2 +# +# @4: x4 +# +# @8: x8 +# +# @12: x12 +# +# @16: x16 +# +# @32: x32 +# +# Since: 4.0 +## +{ 'enum': 'PCIELinkWidth', + 'data': [ '1', '2', '4', '8', '12', '16', '32' ] } + ## # @SysEmuTarget: # diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 3ab9cd2eb6..b6758c852e 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -36,6 +36,8 @@ extern const PropertyInfo qdev_prop_uuid; extern const PropertyInfo qdev_prop_arraylen; extern const PropertyInfo qdev_prop_link; extern const PropertyInfo qdev_prop_off_auto_pcibar; +extern const PropertyInfo qdev_prop_pcie_link_speed; +extern const PropertyInfo qdev_prop_pcie_link_width; #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ .name = (_name),\ @@ -217,6 +219,12 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar; #define DEFINE_PROP_OFF_AUTO_PCIBAR(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_off_auto_pcibar, \ OffAutoPCIBAR) +#define DEFINE_PROP_PCIE_LINK_SPEED(_n, _s, _f, _d) \ +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_speed, \ +PCIExpLinkSpeed) +#define DEFINE_PROP_PCIE_LINK_WIDTH(_n, _s, _f, _d) \ +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \ +PCIExpLinkWidth) #define DEFINE_PROP_UUID(_name, _state, _field) { \ .name = (_name), \ diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index bd84c4ea4c..943dc2654b 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -1297,3 +1297,179 @@ const PropertyInfo qdev_prop_off_auto_pcibar = { .set = set_enum, .set_default_value = set_default_value_enum, }; + +/* --- PCIELinkSpeed 2_5/5/8/16 -- */ + +static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ +DeviceState *dev = DEVICE(obj); +Property *prop = opaque; +PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); +int speed; + +switch (*p) { +case QEMU_PCI_EXP_LNK_2_5GT: +speed = PCIE_LINK_SPEED_2_5; +break; +case QEMU_PCI_EXP_LNK_5GT: +speed = PCIE_LINK_SPEED_5; +break; +case QEMU_PCI_EXP_LNK_8GT: +speed = PCIE_LINK_SPEED_8; +break; +case QEMU_PCI_EXP_LNK_16GT: +speed = PCIE_LINK_SPEED_16; +break; +default: +/* Unreachable */ +abort(); +} + +visit_type_enum(v, prop->name, , prop->info->enum_table, errp); +} + +static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ +DeviceState *dev = DEVICE(obj); +Property *prop = opaque; +PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); +int speed; +Error *local_err = NULL; + +if (dev->realized) { +qdev_prop_set_after_realize(dev, name, errp); +return; +} + +visit_type_enum(v, prop->name, , prop->info->enum_table, _err); +if (local_err) { +error_propagate(errp, local_err); +return; +} + +switch (speed) { +case PCIE_LINK_SPEED_2_5: +*p = QEMU_PCI_EXP_LNK_2_5GT; +break; +case PCIE_LINK_SPEED_5: +*p = QEMU_PCI_EXP_LNK_5GT; +break; +case PCIE_LINK_SPEED_8: +*p = QEMU_PCI_EXP_LNK_8GT; +break; +case PCIE_LINK_SPEED_16: +*p = QEMU_PCI_EXP_LNK_16GT; +break; +default: +/* Unreachable */ +abort(); +} +} + +const PropertyInfo qdev_prop_pcie_link_speed = { +
[Qemu-devel] [PULL 15/31] pcie: Allow generic PCIe root port to specify link speed and width
From: Alex Williamson Allow users to experimentally specify speed and width values for the generic PCIe root port. Defaults remain at 2.5GT/s & x1 for compatiblity with the intent to only support changing defaults via machine types for now. Note for libvirt testing that pcie-root-port controllers are given default names like "pci.7" which don't play well with using the "-set device.$name.$prop=$value" options accessible to us via options. The solution is to add an to the pcie-root-port , for example: The "ua-" here is a mandatory prefix. We can then use: or, without an alias, set globals such as: Cc: Marcel Apfelbaum Tested-by: Geoffrey McRae Reviewed-by: Eric Auger Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-bridge/gen_pcie_root_port.c | 4 1 file changed, 4 insertions(+) diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c index 299de429ec..ca5418a89d 100644 --- a/hw/pci-bridge/gen_pcie_root_port.c +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -124,6 +124,10 @@ static Property gen_rp_props[] = { res_reserve.mem_pref_32, -1), DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, res_reserve.mem_pref_64, -1), +DEFINE_PROP_PCIE_LINK_SPEED("x-speed", PCIESlot, +speed, PCIE_LINK_SPEED_2_5), +DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot, +width, PCIE_LINK_WIDTH_1), DEFINE_PROP_END_OF_LIST() }; -- MST
[Qemu-devel] [PULL 00/31] pci, pc, virtio: fixes, features
The following changes since commit f163448536e5f7ae8905b14547eab37a41a75f6c: Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20181216' into staging (2018-12-17 13:04:25 +) are available in the Git repository at: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream for you to fetch changes up to 562774d542e9be84411de0233308da380256f631: hw/i386: Remove deprecated machines pc-0.10 and pc-0.11 (2018-12-17 22:45:59 -0500) pci, pc, virtio: fixes, features VTD fixes ACPI refactoring new names for virtio devices multiple pcie link width/speeds Signed-off-by: Michael S. Tsirkin Alex Williamson (8): pcie: Create enums for link speed and width pci: Sync PCIe downstream port LNKSTA on read qapi: Define PCIe link speed and width properties pcie: Add link speed and width fields to PCIESlot pcie: Fill PCIESlot link fields to support higher speeds and widths pcie: Allow generic PCIe root port to specify link speed and width vfio/pci: Remove PCIe Link Status emulation pcie: Fast PCIe root ports for new machines Corey Minyard (1): pc:piix4: Update smbus I/O space after a migration Eduardo Habkost (2): virtio: Helper for registering virtio device types virtio: Provide version-specific variants of virtio PCI devices Igor Mammedov (2): hw: arm: acpi: Fix incorrect checksums in RSDP hw: i386: Use correct RSDT length for checksum Matthias Weckbecker (1): hw/pci-bridge: Fix invalid free() Peter Xu (5): intel_iommu: dump correct iova when failed intel_iommu: convert invalid traces into error reports intel_iommu: dma read/write draining support intel_iommu: remove "x-" prefix for "aw-bits" intel_iommu: turn on IR by default Philippe Mathieu-Daudé (4): tests: Remove unused include hw/smbios: Restrict access to "hw/smbios/ipmi.h" hw/smbios: Remove "smbios_ipmi.h" hw/smbios: Move to the hw/firmware/ subdirectory Samuel Ortiz (6): hw: acpi: The RSDP build API can return void hw: arm: Carry RSDP specific data through AcpiRsdpData hw: arm: Convert the RSDP build to the buid_append_foo() API hw: arm: Support both legacy and current RSDP build hw: acpi: Export and share the ARM RSDP build hw: acpi: Remove AcpiRsdpDescriptor and fix tests Thomas Huth (1): hw/i386: Remove deprecated machines pc-0.10 and pc-0.11 Zheng Xiang (1): pcie: set link state inactive/active after hot unplug/plug qapi/common.json | 42 + hw/i386/intel_iommu_internal.h | 3 + hw/smbios/smbios_build.h | 4 + hw/virtio/virtio-pci.h | 78 +++-- include/hw/acpi/acpi-defs.h | 19 +-- include/hw/acpi/aml-build.h | 2 + include/hw/compat.h | 10 +- include/hw/{smbios => firmware}/smbios.h | 0 include/hw/i386/intel_iommu.h| 1 + include/hw/i386/pc.h | 9 + include/hw/pci/pci.h | 13 ++ include/hw/pci/pcie.h| 1 + include/hw/pci/pcie_port.h | 4 + include/hw/pci/pcie_regs.h | 23 ++- include/hw/qdev-properties.h | 8 + include/hw/smbios/ipmi.h | 15 -- tests/acpi-utils.h | 4 +- hw/acpi/aml-build.c | 68 hw/acpi/piix4.c | 1 + hw/arm/virt-acpi-build.c | 40 + hw/arm/virt.c| 2 +- hw/core/qdev-properties.c| 176 hw/display/virtio-gpu-pci.c | 7 +- hw/display/virtio-vga.c | 7 +- hw/i386/acpi-build.c | 46 +++--- hw/i386/intel_iommu.c| 66 ++-- hw/i386/pc.c | 2 +- hw/i386/pc_piix.c| 72 +--- hw/i386/pc_q35.c | 2 +- hw/i386/x86-iommu.c | 2 +- hw/pci-bridge/gen_pcie_root_port.c | 4 + hw/pci-bridge/pcie_root_port.c | 14 ++ hw/pci/pci.c | 4 + hw/pci/pci_bridge.c | 2 +- hw/pci/pcie.c| 132 ++- hw/smbios/smbios-stub.c | 2 +- hw/smbios/smbios.c | 3 +- hw/smbios/smbios_type_38-stub.c | 2 +- hw/smbios/smbios_type_38.c | 3 +- hw/vfio/pci.c| 9 +- hw/virtio/virtio-crypto-pci.c| 7 +- hw/virtio/virtio-pci.c | 271 +++ tests/acpi-utils.c | 47 +- tests/bios-tables-test.c | 24 ++-
[Qemu-devel] [PULL 01/31] pcie: set link state inactive/active after hot unplug/plug
From: Zheng Xiang When VM boots from the latest version of linux kernel, after hot-unpluging virtio-blk disks which are hotplugged into pcie-root-port, the VM's dmesg log shows: [ 151.046242] pciehp :00:05.0:pcie004: pending interrupts 0x0001 from Slot Status [ 151.046365] pciehp :00:05.0:pcie004: Slot(0-3): Attention button pressed [ 151.046369] pciehp :00:05.0:pcie004: Slot(0-3): Powering off due to button press [ 151.046420] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 151.046425] pciehp :00:05.0:pcie004: pciehp_green_led_blink: SLOTCTRL a8 write cmd 200 [ 151.046464] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 151.046468] pciehp :00:05.0:pcie004: pciehp_set_attention_status: SLOTCTRL a8 write cmd c0 [ 156.163421] pciehp :00:05.0:pcie004: pciehp_get_power_status: SLOTCTRL a8 value read 2f1 [ 156.163427] pciehp :00:05.0:pcie004: pciehp_unconfigure_device: domain:bus:dev = :06:00 [ 156.198736] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 156.198772] pciehp :00:05.0:pcie004: pciehp_power_off_slot: SLOTCTRL a8 write cmd 400 [ 157.224124] pciehp :00:05.0:pcie004: pending interrupts 0x0018 from Slot Status [ 157.224194] pciehp :00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 write cmd 300 [ 157.224220] pciehp :00:05.0:pcie004: pciehp_check_link_active: lnk_status = 2011 [ 157.224223] pciehp :00:05.0:pcie004: Slot(0-3): Link Up [ 157.224233] pciehp :00:05.0:pcie004: pciehp_get_power_status: SLOTCTRL a8 value read 7f1 [ 157.224281] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 157.224285] pciehp :00:05.0:pcie004: pciehp_power_on_slot: SLOTCTRL a8 write cmd 0 [ 157.224300] pciehp :00:05.0:pcie004: __pciehp_link_set: lnk_ctrl = 0 [ 157.224336] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 157.224339] pciehp :00:05.0:pcie004: pciehp_green_led_blink: SLOTCTRL a8 write cmd 200 [ 159.739294] pci :06:00.0 id reading try 50 times with interval 20 ms to get [ 159.739315] pciehp :00:05.0:pcie004: pciehp_check_link_status: lnk_status = 2011 [ 159.739318] pciehp :00:05.0:pcie004: Failed to check link status [ 159.739371] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 159.739394] pciehp :00:05.0:pcie004: pciehp_power_off_slot: SLOTCTRL a8 write cmd 400 [ 160.771426] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 160.771452] pciehp :00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 write cmd 300 [ 160.771495] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 160.771499] pciehp :00:05.0:pcie004: pciehp_set_attention_status: SLOTCTRL a8 write cmd 40 [ 160.771535] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from Slot Status [ 160.771539] pciehp :00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 write cmd 300 After analyzing the log information, it seems that qemu doesn't change the Link Status from active to inactive after hot-unplug. This results in the abnormal log after the linux kernel commit d331710ea78fea merged. Furthermore, If I hotplug the same virtio-blk disk after hot-unplug, the virtio-blk would turn on and then back off. So this patch set the Link Status inactive after hot-unplug and active after hot-plug. Signed-off-by: Zheng Xiang Signed-off-by: Zheng Xiang Cc: Wang Haibin Cc: qemu-sta...@nongnu.org Reviewed-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pcie.c | 12 1 file changed, 12 insertions(+) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 6c91bd44a0..66b73b87c8 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -345,6 +345,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, if (!dev->hotplugged) { pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_PDS); +if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) { +pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_DLLLA); +} return; } @@ -355,6 +359,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, if (pci_get_function_0(pci_dev)) { pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_PDS); +if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) { +pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_DLLLA); +} pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP); } @@ -531,6 +539,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
[Qemu-devel] [PULL 10/31] pcie: Create enums for link speed and width
From: Alex Williamson In preparation for reporting higher virtual link speeds and widths, create enums and macros to help us manage them. Cc: Marcel Apfelbaum Tested-by: Geoffrey McRae Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Eric Auger Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/pci/pcie_regs.h | 23 +-- hw/pci/pcie.c | 7 --- hw/vfio/pci.c | 3 ++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h index a95522a13b..ad4e7808b8 100644 --- a/include/hw/pci/pcie_regs.h +++ b/include/hw/pci/pcie_regs.h @@ -34,10 +34,29 @@ /* PCI_EXP_LINK{CAP, STA} */ /* link speed */ -#define PCI_EXP_LNK_LS_25 1 +typedef enum PCIExpLinkSpeed { +QEMU_PCI_EXP_LNK_2_5GT = 1, +QEMU_PCI_EXP_LNK_5GT, +QEMU_PCI_EXP_LNK_8GT, +QEMU_PCI_EXP_LNK_16GT, +} PCIExpLinkSpeed; + +#define QEMU_PCI_EXP_LNKCAP_MLS(speed) (speed) +#define QEMU_PCI_EXP_LNKSTA_CLS QEMU_PCI_EXP_LNKCAP_MLS + +typedef enum PCIExpLinkWidth { +QEMU_PCI_EXP_LNK_X1 = 1, +QEMU_PCI_EXP_LNK_X2 = 2, +QEMU_PCI_EXP_LNK_X4 = 4, +QEMU_PCI_EXP_LNK_X8 = 8, +QEMU_PCI_EXP_LNK_X12 = 12, +QEMU_PCI_EXP_LNK_X16 = 16, +QEMU_PCI_EXP_LNK_X32 = 32, +} PCIExpLinkWidth; #define PCI_EXP_LNK_MLW_SHIFT ctz32(PCI_EXP_LNKCAP_MLW) -#define PCI_EXP_LNK_MLW_1 (1 << PCI_EXP_LNK_MLW_SHIFT) +#define QEMU_PCI_EXP_LNKCAP_MLW(width) (width << PCI_EXP_LNK_MLW_SHIFT) +#define QEMU_PCI_EXP_LNKSTA_NLW QEMU_PCI_EXP_LNKCAP_MLW /* PCI_EXP_LINKCAP */ #define PCI_EXP_LNKCAP_ASPMS_SHIFT ctz32(PCI_EXP_LNKCAP_ASPMS) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 66b73b87c8..aef84c665b 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -68,11 +68,12 @@ pcie_cap_v1_fill(PCIDevice *dev, uint8_t port, uint8_t type, uint8_t version) pci_set_long(exp_cap + PCI_EXP_LNKCAP, (port << PCI_EXP_LNKCAP_PN_SHIFT) | PCI_EXP_LNKCAP_ASPMS_0S | - PCI_EXP_LNK_MLW_1 | - PCI_EXP_LNK_LS_25); + QEMU_PCI_EXP_LNKCAP_MLW(QEMU_PCI_EXP_LNK_X1) | + QEMU_PCI_EXP_LNKCAP_MLS(QEMU_PCI_EXP_LNK_2_5GT)); pci_set_word(exp_cap + PCI_EXP_LNKSTA, - PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25); + QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1) | + QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT)); if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) { pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 5c7bd96984..74f9a46b4b 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1897,7 +1897,8 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size, PCI_EXP_TYPE_ENDPOINT << 4, PCI_EXP_FLAGS_TYPE); vfio_add_emulated_long(vdev, pos + PCI_EXP_LNKCAP, - PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25, ~0); + QEMU_PCI_EXP_LNKCAP_MLW(QEMU_PCI_EXP_LNK_X1) | + QEMU_PCI_EXP_LNKCAP_MLS(QEMU_PCI_EXP_LNK_2_5GT), ~0); vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL, 0, ~0); } -- MST
[Qemu-devel] [PULL 11/31] pci: Sync PCIe downstream port LNKSTA on read
From: Alex Williamson The PCIe link speed and width between a downstream device and its upstream port is negotiated on real hardware and susceptible to dynamic changes due to signal issues and power management. In the emulated device case there is no real hardware link, but we still might wish to have some consistency between endpoint and downstream port via a virtual negotiation. There is of course a real link for assigned devices and this same virtual negotiation allows the downstream port to match the endpoint, synchronizing on every read to support underlying physical hardware dynamically adjusting the link. This negotiation is intentionally unidirectional for compatibility. If the endpoint exceeds the capabilities of the downstream port or there is no endpoint device, the downstream port reports negotiation to its maximum speed and width, matching the previous case where negotiation was absent. De-tuning the endpoint to match a virtual link doesn't seem to benefit anyone and is a condition we've thus far reported without functional issues. Note that PCI_EXP_LNKSTA is already ignored for migration compatibility via pcie_cap_v1_fill(). Cc: Marcel Apfelbaum Tested-by: Geoffrey McRae Reviewed-by: Eric Auger Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/pci/pci.h | 13 + include/hw/pci/pcie.h | 1 + hw/pci/pci.c | 4 hw/pci/pcie.c | 39 +++ 4 files changed, 57 insertions(+) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index e6514bba23..eb12fa112e 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -737,6 +737,19 @@ static inline int pci_is_express(const PCIDevice *d) return d->cap_present & QEMU_PCI_CAP_EXPRESS; } +static inline int pci_is_express_downstream_port(const PCIDevice *d) +{ +uint8_t type; + +if (!pci_is_express(d) || !d->exp.exp_cap) { +return 0; +} + +type = pcie_cap_get_type(d); + +return type == PCI_EXP_TYPE_DOWNSTREAM || type == PCI_EXP_TYPE_ROOT_PORT; +} + static inline uint32_t pci_config_size(const PCIDevice *d) { return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE; diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index b71e369703..1976909ab4 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -126,6 +126,7 @@ uint16_t pcie_find_capability(PCIDevice *dev, uint16_t cap_id); void pcie_add_capability(PCIDevice *dev, uint16_t cap_id, uint8_t cap_ver, uint16_t offset, uint16_t size); +void pcie_sync_bridge_lnk(PCIDevice *dev); void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn); void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num); diff --git a/hw/pci/pci.c b/hw/pci/pci.c index efb5ce196f..d831fa0a36 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1353,6 +1353,10 @@ uint32_t pci_default_read_config(PCIDevice *d, { uint32_t val = 0; +if (pci_is_express_downstream_port(d) && +ranges_overlap(address, len, d->exp.exp_cap + PCI_EXP_LNKSTA, 2)) { +pcie_sync_bridge_lnk(d); +} memcpy(, d->config + address, len); return le32_to_cpu(val); } diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index aef84c665b..6891deb711 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -741,6 +741,45 @@ void pcie_add_capability(PCIDevice *dev, memset(dev->cmask + offset, 0xFF, size); } +/* + * Sync the PCIe Link Status negotiated speed and width of a bridge with the + * downstream device. If downstream device is not present, re-write with the + * Link Capability fields. Limit width and speed to bridge capabilities for + * compatibility. Use config_read to access the downstream device since it + * could be an assigned device with volatile link information. + */ +void pcie_sync_bridge_lnk(PCIDevice *bridge_dev) +{ +PCIBridge *br = PCI_BRIDGE(bridge_dev); +PCIBus *bus = pci_bridge_get_sec_bus(br); +PCIDevice *target = bus->devices[0]; +uint8_t *exp_cap = bridge_dev->config + bridge_dev->exp.exp_cap; +uint16_t lnksta, lnkcap = pci_get_word(exp_cap + PCI_EXP_LNKCAP); + +if (!target || !target->exp.exp_cap) { +lnksta = lnkcap; +} else { +lnksta = target->config_read(target, + target->exp.exp_cap + PCI_EXP_LNKSTA, + sizeof(lnksta)); + +if ((lnksta & PCI_EXP_LNKSTA_NLW) > (lnkcap & PCI_EXP_LNKCAP_MLW)) { +lnksta &= ~PCI_EXP_LNKSTA_NLW; +lnksta |= lnkcap & PCI_EXP_LNKCAP_MLW; +} + +if ((lnksta & PCI_EXP_LNKSTA_CLS) > (lnkcap & PCI_EXP_LNKCAP_SLS)) { +lnksta &= ~PCI_EXP_LNKSTA_CLS; +lnksta |= lnkcap & PCI_EXP_LNKCAP_SLS; +} +} + +pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA, +
Re: [Qemu-devel] [PATCH qemu v3] ppc/spapr: Receive and store device tree blob from SLOF
On Tue, Dec 18, 2018 at 02:04:54PM +1100, Alexey Kardashevskiy wrote: > > > On 18/12/2018 13:09, David Gibson wrote: > > On Mon, Dec 17, 2018 at 05:21:33PM +1100, David Gibson wrote: > >> On Fri, Dec 14, 2018 at 12:55:20PM +1100, Alexey Kardashevskiy wrote: > >>> SLOF receives a device tree and updates it with various properties > >>> before switching to the guest kernel and QEMU is not aware of any changes > >>> made by SLOF. Since there is no real RTAS (QEMU implements it), it makes > >>> sense to pass the SLOF final device tree to QEMU to let it implement > >>> RTAS related tasks better, such as PCI host bus adapter hotplug. > >>> > >>> Specifially, now QEMU can find out the actual XICS phandle (for PHB > >>> hotplug) and the RTAS linux,rtas-entry/base properties (for firmware > >>> assisted NMI - FWNMI). > >>> > >>> This stores the initial DT blob in the sPAPR machine and replaces it > >>> in the KVMPPC_H_UPDATE_DT (new private hypercall) handler. > >>> > >>> This adds an @update_dt_enabled machine property to allow backward > >>> migration. > >>> > >>> SLOF already has a hypercall since > >>> https://github.com/aik/SLOF/commit/e6fc84652c9c0073f9183 > >>> > >>> This makes use of the new fdt_check_full() helper. In order to allow > >>> the configure script to pick the correct DTC version, this adjusts > >>> the DTC presense test. > >>> > >>> Signed-off-by: Alexey Kardashevskiy > >> > >> Applied, thanks. > > > > And now, unapplied. > > > > I don't know quite how, but somehow this patch is causing aarch64 > > tests to SEGV. > > > /home/aik/p/qemu/configure --target-list=aarch64-softmmu > --source-path=/home/aik/p/qemu/ --disable-git-update --with-git=false >--enable-trace-backend=log > > and > > make -C /home/aik/pbuild/qemu-localhost-aarch64-rel/ -j24 check > > did not produce segv. I am running this all on a power8 box + ubuntu > 1804, what is your config? Hm, curious. I'm using Fedora 29 on an x86 host. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
[Qemu-devel] sheepdog build warning
mingw32 build on fedora fails with this warning: /scm/qemu/block/sheepdog.c: In function 'find_vdi_name': /scm/qemu/block/sheepdog.c:1239:5: error: 'strncpy' specified bound 256 equals destination size [-Werror=stringop-truncation] strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN); ^~ cc1: all warnings being treated as errors make: *** [/scm/qemu/rules.mak:69: block/sheepdog.o] Error 1 make: *** Waiting for unfinished jobs Reading the code one sees it's working as intended: static int find_vdi_name(BDRVSheepdogState *s, const char *filename, uint32_t snapid, const char *tag, uint32_t *vid, bool lock, Error **errp) { int ret, fd; SheepdogVdiReq hdr; SheepdogVdiRsp *rsp = (SheepdogVdiRsp *) unsigned int wlen, rlen = 0; char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN]; fd = connect_to_sdog(s, errp); if (fd < 0) { return fd; } /* This pair of strncpy calls ensures that the buffer is zero-filled, * which is desirable since we'll soon be sending those bytes, and * don't want the send_req to read uninitialized data. */ strncpy(buf, filename, SD_MAX_VDI_LEN); strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN); . } so this seems to be the case of GCC developers deciding that strncpy is simply a bad API and a correct use of it should be warned against. I propose either 1. simply adding #pragma GCC diagnostic ignored "-Wstringop-truncation" in osdep. 2. adding an inline wrapper with said pragma in there. 3. -Wno-stringop-truncation is the makefile Thoughts? -- MST
[Qemu-devel] [PULL 04/31] virtio: Provide version-specific variants of virtio PCI devices
From: Eduardo Habkost Many of the current virtio-*-pci device types actually represent 3 different types of devices: * virtio 1.0 non-transitional devices * virtio 1.0 transitional devices * virtio 0.9 ("legacy device" in virtio 1.0 terminology) That would be just an annoyance if it didn't break our device/bus compatibility QMP interfaces. With these multi-purpose device types, there's no way to tell management software that transitional devices and legacy devices require a Conventional PCI bus. The multi-purpose device types would also prevent us from telling management software what's the PCI vendor/device ID for them, because their PCI IDs change at runtime depending on the bus where they were plugged. This patch adds separate device types for each of those virtio device flavors: - virtio-*-pci: the existing multi-purpose device types - Configurable using `disable-legacy` and `disable-modern` properties - Legacy driver support is automatically enabled/disabled depending on the bus where it is plugged - Supports Conventional PCI and PCI Express buses (but Conventional PCI is incompatible with disable-legacy=off) - Changes PCI vendor/device IDs at runtime - virtio-*-pci-transitional: virtio-1.0 device supporting legacy drivers - Supports Conventional PCI buses only, because it has a PIO BAR - virtio-*-pci-non-transitional: modern-only - Supports both Conventional PCI and PCI Express buses The existing TYPE_* macros for these types will point to an abstract base type, so existing casts in the code will keep working for all variants. A simple test script (tests/acceptance/virtio_version.py) is included, to check if the new device types are equivalent to using the `disable-legacy` and `disable-modern` options. Acked-by: Andrea Bolognani Reviewed-by: Cornelia Huck Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-pci.h | 24 ++-- hw/virtio/virtio-pci.c | 60 -- tests/acceptance/virtio_version.py | 176 + 3 files changed, 236 insertions(+), 24 deletions(-) create mode 100644 tests/acceptance/virtio_version.py diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 8cd546608e..29b4216107 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -216,7 +216,7 @@ static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy) /* * virtio-scsi-pci: This extends VirtioPCIProxy. */ -#define TYPE_VIRTIO_SCSI_PCI "virtio-scsi-pci" +#define TYPE_VIRTIO_SCSI_PCI "virtio-scsi-pci-base" #define VIRTIO_SCSI_PCI(obj) \ OBJECT_CHECK(VirtIOSCSIPCI, (obj), TYPE_VIRTIO_SCSI_PCI) @@ -229,7 +229,7 @@ struct VirtIOSCSIPCI { /* * vhost-scsi-pci: This extends VirtioPCIProxy. */ -#define TYPE_VHOST_SCSI_PCI "vhost-scsi-pci" +#define TYPE_VHOST_SCSI_PCI "vhost-scsi-pci-base" #define VHOST_SCSI_PCI(obj) \ OBJECT_CHECK(VHostSCSIPCI, (obj), TYPE_VHOST_SCSI_PCI) @@ -239,7 +239,7 @@ struct VHostSCSIPCI { }; #endif -#define TYPE_VHOST_USER_SCSI_PCI "vhost-user-scsi-pci" +#define TYPE_VHOST_USER_SCSI_PCI "vhost-user-scsi-pci-base" #define VHOST_USER_SCSI_PCI(obj) \ OBJECT_CHECK(VHostUserSCSIPCI, (obj), TYPE_VHOST_USER_SCSI_PCI) @@ -252,7 +252,7 @@ struct VHostUserSCSIPCI { /* * vhost-user-blk-pci: This extends VirtioPCIProxy. */ -#define TYPE_VHOST_USER_BLK_PCI "vhost-user-blk-pci" +#define TYPE_VHOST_USER_BLK_PCI "vhost-user-blk-pci-base" #define VHOST_USER_BLK_PCI(obj) \ OBJECT_CHECK(VHostUserBlkPCI, (obj), TYPE_VHOST_USER_BLK_PCI) @@ -265,7 +265,7 @@ struct VHostUserBlkPCI { /* * virtio-blk-pci: This extends VirtioPCIProxy. */ -#define TYPE_VIRTIO_BLK_PCI "virtio-blk-pci" +#define TYPE_VIRTIO_BLK_PCI "virtio-blk-pci-base" #define VIRTIO_BLK_PCI(obj) \ OBJECT_CHECK(VirtIOBlkPCI, (obj), TYPE_VIRTIO_BLK_PCI) @@ -277,7 +277,7 @@ struct VirtIOBlkPCI { /* * virtio-balloon-pci: This extends VirtioPCIProxy. */ -#define TYPE_VIRTIO_BALLOON_PCI "virtio-balloon-pci" +#define TYPE_VIRTIO_BALLOON_PCI "virtio-balloon-pci-base" #define VIRTIO_BALLOON_PCI(obj) \ OBJECT_CHECK(VirtIOBalloonPCI, (obj), TYPE_VIRTIO_BALLOON_PCI) @@ -289,7 +289,7 @@ struct VirtIOBalloonPCI { /* * virtio-serial-pci: This extends VirtioPCIProxy. */ -#define TYPE_VIRTIO_SERIAL_PCI "virtio-serial-pci" +#define TYPE_VIRTIO_SERIAL_PCI "virtio-serial-pci-base" #define VIRTIO_SERIAL_PCI(obj) \ OBJECT_CHECK(VirtIOSerialPCI, (obj), TYPE_VIRTIO_SERIAL_PCI) @@ -301,7 +301,7 @@ struct VirtIOSerialPCI { /* * virtio-net-pci: This extends VirtioPCIProxy. */ -#define TYPE_VIRTIO_NET_PCI "virtio-net-pci" +#define TYPE_VIRTIO_NET_PCI "virtio-net-pci-base" #define VIRTIO_NET_PCI(obj) \ OBJECT_CHECK(VirtIONetPCI, (obj), TYPE_VIRTIO_NET_PCI) @@ -316,7 +316,7 @@ struct VirtIONetPCI { #ifdef CONFIG_VIRTFS -#define TYPE_VIRTIO_9P_PCI "virtio-9p-pci" +#define
Re: [Qemu-devel] [PATCH v9 6/7] spapr: change default CPU type to POWER9
On Mon, Dec 17, 2018 at 11:34:44PM +0100, Cédric Le Goater wrote: > Signed-off-by: Cédric Le Goater Fixed up for my removal of the update_dt patch, and applied. > --- > hw/ppc/spapr.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index aefa0f4ea430..8ea680fcde1e 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -3967,7 +3967,7 @@ static void spapr_machine_class_init(ObjectClass *oc, > void *data) > > smc->dr_lmb_enabled = true; > smc->update_dt_enabled = true; > -mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0"); > +mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0"); > mc->has_hotpluggable_cpus = true; > smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED; > fwc->get_dev_path = spapr_get_fw_dev_path; > @@ -4066,6 +4066,7 @@ static void > spapr_machine_3_1_class_options(MachineClass *mc) > > spapr_machine_4_0_class_options(mc); > SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_3_1); > +mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0"); > smc->update_dt_enabled = false; > } > -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH v9 0/7] ppc: support for the XIVE interrupt controller (POWER9)
On Mon, Dec 17, 2018 at 11:34:38PM +0100, Cédric Le Goater wrote: > Hello, > > Here is the version 9 of the QEMU models adding support for the XIVE > interrupt controller to the sPAPR machine, under TCG only. > > The 'dual' machine, supporting both interrupt modes, is nearly complete, > only remains the question on the qirq array, which will be addressed > in early 2019 with the support for KVM. Ok, I've applied most of this lot. I think that leaves my next pull request just waiting on the GETFIELD stuff. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH v9 3/7] spapr/xive: fix compilation breakage on windows
On Mon, Dec 17, 2018 at 11:34:41PM +0100, Cédric Le Goater wrote: > Signed-off-by: Cédric Le Goater Applied, and folded into "spapr: add hcalls support for the XIVE exploitation interrupt mode". > --- > hw/intc/spapr_xive.c | 46 +++- > 1 file changed, 28 insertions(+), 18 deletions(-) > > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c > index aaa5865c4080..3ceabe668b16 100644 > --- a/hw/intc/spapr_xive.c > +++ b/hw/intc/spapr_xive.c > @@ -589,12 +589,14 @@ static target_ulong h_int_get_source_info(PowerPCCPU > *cpu, > } > > if (lisn >= xive->nr_irqs) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > if (!xive_eas_is_valid(>eat[lisn])) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > @@ -701,13 +703,15 @@ static target_ulong h_int_set_source_config(PowerPCCPU > *cpu, > } > > if (lisn >= xive->nr_irqs) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > eas = xive->eat[lisn]; > if (!xive_eas_is_valid()) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > @@ -724,8 +728,8 @@ static target_ulong h_int_set_source_config(PowerPCCPU > *cpu, > } > > if (spapr_xive_priority_is_reserved(priority)) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority %ld is reserved\n", > - priority); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld > + " is reserved\n", priority); > return H_P4; > } > > @@ -793,13 +797,15 @@ static target_ulong h_int_get_source_config(PowerPCCPU > *cpu, > } > > if (lisn >= xive->nr_irqs) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > eas = xive->eat[lisn]; > if (!xive_eas_is_valid()) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > @@ -870,8 +876,8 @@ static target_ulong h_int_get_queue_info(PowerPCCPU *cpu, > */ > > if (spapr_xive_priority_is_reserved(priority)) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority %ld is reserved\n", > - priority); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld > + " is reserved\n", priority); > return H_P3; > } > > @@ -956,8 +962,8 @@ static target_ulong h_int_set_queue_config(PowerPCCPU > *cpu, > */ > > if (spapr_xive_priority_is_reserved(priority)) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority %ld is reserved\n", > - priority); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld > + " is reserved\n", priority); > return H_P3; > } > > @@ -1102,8 +1108,8 @@ static target_ulong h_int_get_queue_config(PowerPCCPU > *cpu, > */ > > if (spapr_xive_priority_is_reserved(priority)) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority %ld is reserved\n", > - priority); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld > + " is reserved\n", priority); > return H_P3; > } > > @@ -1268,13 +1274,15 @@ static target_ulong h_int_esb(PowerPCCPU *cpu, > } > > if (lisn >= xive->nr_irqs) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > eas = xive->eat[lisn]; > if (!xive_eas_is_valid()) { > -qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN %lx\n", lisn); > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx > "\n", > + lisn); > return H_P2; > } > > @@ -1330,13 +1338,15 @@ static target_ulong h_int_sync(PowerPCCPU *cpu, > } > > if (lisn >= xive->nr_irqs) { > -
Re: [Qemu-devel] [PATCH 5/5] intel_iommu: turn on IR by default
On Mon, Dec 17, 2018 at 03:31:14PM +0800, Peter Xu wrote: > IR has been there for a long time and long time no bug reported. > Let's turn it on by default to match general hardwares. Providing > compatibility bit for QEMU<=3.1. > > Signed-off-by: Peter Xu I forgot that IR will depend on split kernel irqchip and by default that's still "on" so "-M q35 -device intel-iommu" may not be able to boot correctly with all the default values and instead QEMU will ask user to turn on split irqchip. Paolo/Michael, do you think it would make any sense to turn the default kernel-irqchip machine parameter to split starting from qemu 4.0? Since AFAIU it should have little degradation to performance but at the same time it reduces kvm attack serface, which seems good. Thanks, > --- > hw/i386/x86-iommu.c | 2 +- > include/hw/i386/pc.h | 4 > 2 files changed, 5 insertions(+), 1 deletion(-) > > diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c > index abc3c03158..0150ceda14 100644 > --- a/hw/i386/x86-iommu.c > +++ b/hw/i386/x86-iommu.c > @@ -135,7 +135,7 @@ static void x86_iommu_realize(DeviceState *dev, Error > **errp) > } > > static Property x86_iommu_properties[] = { > -DEFINE_PROP_BOOL("intremap", X86IOMMUState, intr_supported, false), > +DEFINE_PROP_BOOL("intremap", X86IOMMUState, intr_supported, true), > DEFINE_PROP_BOOL("device-iotlb", X86IOMMUState, dt_supported, false), > DEFINE_PROP_BOOL("pt", X86IOMMUState, pt_supported, true), > DEFINE_PROP_END_OF_LIST(), > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h > index c7c0c944e8..ed958b9af1 100644 > --- a/include/hw/i386/pc.h > +++ b/include/hw/i386/pc.h > @@ -300,6 +300,10 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t > *); > .driver = "intel-iommu",\ > .property = "dma-drain",\ > .value= "off",\ > +},{\ > +.driver = "x86-iommu",\ > +.property = "intremap",\ > +.value= "off",\ > }, > > #define PC_COMPAT_3_0 \ > -- > 2.17.1 > Regards, -- Peter Xu
Re: [Qemu-devel] [PATCH qemu v3] ppc/spapr: Receive and store device tree blob from SLOF
On 18/12/2018 13:09, David Gibson wrote: > On Mon, Dec 17, 2018 at 05:21:33PM +1100, David Gibson wrote: >> On Fri, Dec 14, 2018 at 12:55:20PM +1100, Alexey Kardashevskiy wrote: >>> SLOF receives a device tree and updates it with various properties >>> before switching to the guest kernel and QEMU is not aware of any changes >>> made by SLOF. Since there is no real RTAS (QEMU implements it), it makes >>> sense to pass the SLOF final device tree to QEMU to let it implement >>> RTAS related tasks better, such as PCI host bus adapter hotplug. >>> >>> Specifially, now QEMU can find out the actual XICS phandle (for PHB >>> hotplug) and the RTAS linux,rtas-entry/base properties (for firmware >>> assisted NMI - FWNMI). >>> >>> This stores the initial DT blob in the sPAPR machine and replaces it >>> in the KVMPPC_H_UPDATE_DT (new private hypercall) handler. >>> >>> This adds an @update_dt_enabled machine property to allow backward >>> migration. >>> >>> SLOF already has a hypercall since >>> https://github.com/aik/SLOF/commit/e6fc84652c9c0073f9183 >>> >>> This makes use of the new fdt_check_full() helper. In order to allow >>> the configure script to pick the correct DTC version, this adjusts >>> the DTC presense test. >>> >>> Signed-off-by: Alexey Kardashevskiy >> >> Applied, thanks. > > And now, unapplied. > > I don't know quite how, but somehow this patch is causing aarch64 > tests to SEGV. /home/aik/p/qemu/configure --target-list=aarch64-softmmu --source-path=/home/aik/p/qemu/ --disable-git-update --with-git=false --enable-trace-backend=log and make -C /home/aik/pbuild/qemu-localhost-aarch64-rel/ -j24 check did not produce segv. I am running this all on a power8 box + ubuntu 1804, what is your config? -- Alexey
Re: [Qemu-devel] [PATCH v5 6/8] pcie: Allow generic PCIe root port to specify link speed and width
On Mon, Dec 17, 2018 at 06:54:32PM -0700, Alex Williamson wrote: > On Mon, 17 Dec 2018 20:47:26 -0500 > "Michael S. Tsirkin" wrote: > > > On Mon, Dec 17, 2018 at 06:44:04PM -0700, Alex Williamson wrote: > > > On Mon, 17 Dec 2018 20:29:37 -0500 > > > "Michael S. Tsirkin" wrote: > > > > > > > On Wed, Dec 12, 2018 at 12:39:43PM -0700, Alex Williamson wrote: > > > > > Allow users to experimentally specify speed and width values for the > > > > > generic PCIe root port. Defaults remain at 2.5GT/s & x1 for > > > > > compatiblity with the intent to only support changing defaults via > > > > > machine types for now. > > > > > > > > > > Note for libvirt testing that pcie-root-port controllers are given > > > > > default names like "pci.7" which don't play well with using the > > > > > "-set device.$name.$prop=$value" options accessible to us via > > > > > options. The solution is to add an to the > > > > > pcie-root-port , for example: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >> > > > function='0x5'/> > > > > > > > > > > > > > > > The "ua-" here is a mandatory prefix. We can then use: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > or, without an alias, set globals such as: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Cc: Michael S. Tsirkin > > > > > Cc: Marcel Apfelbaum > > > > > Tested-by: Geoffrey McRae > > > > > Reviewed-by: Eric Auger > > > > > Signed-off-by: Alex Williamson > > > > > --- > > > > > hw/pci-bridge/gen_pcie_root_port.c |4 > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > diff --git a/hw/pci-bridge/gen_pcie_root_port.c > > > > > b/hw/pci-bridge/gen_pcie_root_port.c > > > > > index 299de429ec1e..ca5418a89dd2 100644 > > > > > --- a/hw/pci-bridge/gen_pcie_root_port.c > > > > > +++ b/hw/pci-bridge/gen_pcie_root_port.c > > > > > @@ -124,6 +124,10 @@ static Property gen_rp_props[] = { > > > > > res_reserve.mem_pref_32, -1), > > > > > DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, > > > > > res_reserve.mem_pref_64, -1), > > > > > +DEFINE_PROP_PCIE_LINK_SPEED("x-speed", PCIESlot, > > > > > +speed, PCIE_LINK_SPEED_2_5), > > > > > +DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot, > > > > > +width, PCIE_LINK_WIDTH_1), > > > > > DEFINE_PROP_END_OF_LIST() > > > > > }; > > > > > > > > > > > > > Doesn't seem to build. > > > > Just where is DEFINE_PROP_PCIE_LINK_SPEED defined? > > > > > > In 3/8: > > > > > > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h > > > index 3ab9cd2eb69f..b6758c852e11 100644 > > > --- a/include/hw/qdev-properties.h > > > +++ b/include/hw/qdev-properties.h > > > @@ -36,6 +36,8 @@ extern const PropertyInfo qdev_prop_uuid; > > > extern const PropertyIn qdev_prop_arraylen; > > > extern const PropertyInfo qdev_prop_link; > > > extern const PropertyInfo qdev_prop_off_auto_pcibar; > > > +extern const PropertyInfo qdev_prop_pcie_link_speed; > > > +extern const PropertyInfo qdev_prop_pcie_link_width; > > > > > > #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ > > > .name = (_name),\ > > > @@ -217,6 +219,12 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar; > > > #define DEFINE_PROP_OFF_AUTO_PCIBAR(_n, _s, _f, _d) \ > > > DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_off_auto_pcibar, \ > > > OffAutoPCIBAR) > > > +#define DEFINE_PROP_PCIE_LINK_SPEED(_n, _s, _f, _d) \ > > > +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_speed, \ > > > +PCIExpLinkSpeed) > > > +#define DEFINE_PROP_PCIE_LINK_WIDTH(_n, _s, _f, _d) \ > > > +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \ > > > +PCIExpLinkWidth) > > > > > > #define DEFINE_PROP_UUID(_name, _state, _field) { \ > > > .name = (_name), \ > > > > > > Did something go wrong applying that patch? I'll double check on my > > > end. Thanks, > > > > > > Alex > > > > Oh I just wasn't copied. So I missed this patch when applying. > > Ah, sorry, I should have forced your Cc on all the patches. I'd also > welcome you to include 7/8 in the series to keep things altogether, > you're directly copied on all the others. Thanks, > > Alex Done. -- MST
Re: [Qemu-devel] [PATCH qemu v3] ppc/spapr: Receive and store device tree blob from SLOF
On Mon, Dec 17, 2018 at 05:21:33PM +1100, David Gibson wrote: > On Fri, Dec 14, 2018 at 12:55:20PM +1100, Alexey Kardashevskiy wrote: > > SLOF receives a device tree and updates it with various properties > > before switching to the guest kernel and QEMU is not aware of any changes > > made by SLOF. Since there is no real RTAS (QEMU implements it), it makes > > sense to pass the SLOF final device tree to QEMU to let it implement > > RTAS related tasks better, such as PCI host bus adapter hotplug. > > > > Specifially, now QEMU can find out the actual XICS phandle (for PHB > > hotplug) and the RTAS linux,rtas-entry/base properties (for firmware > > assisted NMI - FWNMI). > > > > This stores the initial DT blob in the sPAPR machine and replaces it > > in the KVMPPC_H_UPDATE_DT (new private hypercall) handler. > > > > This adds an @update_dt_enabled machine property to allow backward > > migration. > > > > SLOF already has a hypercall since > > https://github.com/aik/SLOF/commit/e6fc84652c9c0073f9183 > > > > This makes use of the new fdt_check_full() helper. In order to allow > > the configure script to pick the correct DTC version, this adjusts > > the DTC presense test. > > > > Signed-off-by: Alexey Kardashevskiy > > Applied, thanks. And now, unapplied. I don't know quite how, but somehow this patch is causing aarch64 tests to SEGV. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH v9 2/7] target/ppc: replace __builtin_ffssl() by the equivalent ctz routines
On Mon, Dec 17, 2018 at 11:34:40PM +0100, Cédric Le Goater wrote: > And remove the intermediate MASK_TO_LSH macro which does not add any value. > > This fixes a compile breakage on windows. > > Signed-off-by: Cédric Le Goater It's an improvement over what's there, but it still leaves macros whose primary use would be for guest registers, but are typed according to host values, which doesn't make much sense. I think instead we should redefine your BE64 / BE32 variants in terms of the existing extract*() and deposit*() primitives, and get rid of the GETFIELD / SETFIELD macros. > --- > target/ppc/cpu.h | 15 +-- > 1 file changed, 9 insertions(+), 6 deletions(-) > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > index 527181c0f09f..f4ef4f214564 100644 > --- a/target/ppc/cpu.h > +++ b/target/ppc/cpu.h > @@ -78,18 +78,21 @@ > PPC_BIT32(bs)) > #define PPC_BITMASK8(bs, be)((PPC_BIT8(bs) - PPC_BIT8(be)) | > PPC_BIT8(bs)) > > +/* > + * OPAL PPC bitmask field manipulation, used in XIVE, PHB3 and PHB4 > + */ > #if HOST_LONG_BITS == 32 > -# define MASK_TO_LSH(m) (__builtin_ffsll(m) - 1) > +# define GETFIELD(m, v)(((v) & (m)) >> ctz32(m)) > +# define SETFIELD(m, v, val) \ > +(((v) & ~(m)) | typeof(v))(val)) << ctz32(m)) & (m))) > #elif HOST_LONG_BITS == 64 > -# define MASK_TO_LSH(m) (__builtin_ffsl(m) - 1) > +# define GETFIELD(m, v)(((v) & (m)) >> ctz64(m)) > +# define SETFIELD(m, v, val) \ > +(((v) & ~(m)) | typeof(v))(val)) << ctz64(m)) & (m))) > #else > # error Unknown sizeof long > #endif > > -#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m)) > -#define SETFIELD(m, v, val) \ > -(((v) & ~(m)) | typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) > - > > /*/ > /* Exception vectors definitions > */ > enum { -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH v8 09/12] spapr: set the interrupt presenter at reset
On Mon, Dec 17, 2018 at 11:41:34PM +0100, Cédric Le Goater wrote: > On 12/17/18 7:01 AM, David Gibson wrote: > > On Thu, Dec 13, 2018 at 01:52:14PM +0100, Cédric Le Goater wrote: > >> On 12/11/18 11:38 PM, Cédric Le Goater wrote: > >>> Currently, the interrupt presenter of the vCPU is set at realize > >>> time. Setting it at reset will become necessary when the new machine > >>> supporting both interrupt modes is introduced. In this machine, the > >>> interrupt mode is chosen at CAS time and activated after a reset. > >> > >> I think we need a second '->intc' pointer specific to XIVE instead. > >> How about ->intc_xive ? > > > > Ah, interesting. If we're going to need that, we might as well go > > to specific ->icp and ->tctx pointers with the right types. > > Hmm, PowerPCCPU is defined under target/ppc and adding the type might > add some noise. I will check. It's a pointer, so you can just declare the type without a definition. That should be ok. > > I don't particularly like having those machine specific pointers > > within the cpu structure, but we can look at fixing that later by > > reviving my patches to move various machine specific stuff within the > > cpu into a separate sub-allocation. > > ok. > > Thanks, > > C. > > >> > >> We could just drop this patch and easly get rid of the XiveTCTX object > >> leak in spapr_unrealize_vcpu(). > >> > >> C. > >> > >>> Signed-off-by: Cédric Le Goater > >>> --- > >>> > >>> Changes since v7: > >>> > >>> - introduced spapr_irq_reset_xics(). > >>> > >>> include/hw/ppc/spapr_cpu_core.h | 2 ++ > >>> hw/ppc/spapr_cpu_core.c | 26 ++ > >>> hw/ppc/spapr_irq.c | 13 + > >>> 3 files changed, 41 insertions(+) > >>> > >>> diff --git a/include/hw/ppc/spapr_cpu_core.h > >>> b/include/hw/ppc/spapr_cpu_core.h > >>> index 9e2821e4b31f..fc8ea9021656 100644 > >>> --- a/include/hw/ppc/spapr_cpu_core.h > >>> +++ b/include/hw/ppc/spapr_cpu_core.h > >>> @@ -53,4 +53,6 @@ static inline sPAPRCPUState *spapr_cpu_state(PowerPCCPU > >>> *cpu) > >>> return (sPAPRCPUState *)cpu->machine_data; > >>> } > >>> > >>> +void spapr_cpu_core_set_intc(PowerPCCPU *cpu, const char *intc_type); > >>> + > >>> #endif > >>> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c > >>> index 82666436e9b4..afc5d4f4e739 100644 > >>> --- a/hw/ppc/spapr_cpu_core.c > >>> +++ b/hw/ppc/spapr_cpu_core.c > >>> @@ -397,3 +397,29 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { > >>> }; > >>> > >>> DEFINE_TYPES(spapr_cpu_core_type_infos) > >>> + > >>> +typedef struct ForeachFindIntCArgs { > >>> +const char *intc_type; > >>> +Object *intc; > >>> +} ForeachFindIntCArgs; > >>> + > >>> +static int spapr_cpu_core_find_intc(Object *child, void *opaque) > >>> +{ > >>> +ForeachFindIntCArgs *args = opaque; > >>> + > >>> +if (object_dynamic_cast(child, args->intc_type)) { > >>> +args->intc = child; > >>> +} > >>> + > >>> +return args->intc != NULL; > >>> +} > >>> + > >>> +void spapr_cpu_core_set_intc(PowerPCCPU *cpu, const char *intc_type) > >>> +{ > >>> +ForeachFindIntCArgs args = { intc_type, NULL }; > >>> + > >>> +object_child_foreach(OBJECT(cpu), spapr_cpu_core_find_intc, ); > >>> +g_assert(args.intc); > >>> + > >>> +cpu->intc = args.intc; > >>> +} > >>> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c > >>> index 0999a2b2d69c..814500f22d34 100644 > >>> --- a/hw/ppc/spapr_irq.c > >>> +++ b/hw/ppc/spapr_irq.c > >>> @@ -12,6 +12,7 @@ > >>> #include "qemu/error-report.h" > >>> #include "qapi/error.h" > >>> #include "hw/ppc/spapr.h" > >>> +#include "hw/ppc/spapr_cpu_core.h" > >>> #include "hw/ppc/spapr_xive.h" > >>> #include "hw/ppc/xics.h" > >>> #include "sysemu/kvm.h" > >>> @@ -208,6 +209,15 @@ static int > >>> spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id) > >>> return 0; > >>> } > >>> > >>> +static void spapr_irq_reset_xics(sPAPRMachineState *spapr, Error **errp) > >>> +{ > >>> + CPUState *cs; > >>> + > >>> +CPU_FOREACH(cs) { > >>> +spapr_cpu_core_set_intc(POWERPC_CPU(cs), spapr->icp_type); > >>> +} > >>> +} > >>> + > >>> #define SPAPR_IRQ_XICS_NR_IRQS 0x1000 > >>> #define SPAPR_IRQ_XICS_NR_MSIS \ > >>> (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI) > >>> @@ -225,6 +235,7 @@ sPAPRIrq spapr_irq_xics = { > >>> .dt_populate = spapr_dt_xics, > >>> .cpu_intc_create = spapr_irq_cpu_intc_create_xics, > >>> .post_load = spapr_irq_post_load_xics, > >>> +.reset = spapr_irq_reset_xics, > >>> }; > >>> > >>> /* > >>> @@ -325,6 +336,8 @@ static void spapr_irq_reset_xive(sPAPRMachineState > >>> *spapr, Error **errp) > >>> CPU_FOREACH(cs) { > >>> PowerPCCPU *cpu = POWERPC_CPU(cs); > >>> > >>> +spapr_cpu_core_set_intc(cpu, TYPE_XIVE_TCTX); > >>> + > >>> /* (TCG) Set the OS CAM line of the thread interrupt context. */ > >>>
Re: [Qemu-devel] [PATCH v9 1/7] target/ppc: fix the PPC_BIT definitions
On Mon, Dec 17, 2018 at 11:34:39PM +0100, Cédric Le Goater wrote: > Change the PPC_BIT macro to use ULL instead of UL and the PPC_BIT32 > and PPC_BIT8 not to use any suffix. > > This fixes a compile breakage on windows. > > Signed-off-by: Cédric Le Goater Applied (before the rest of the XIVE patches), thanks. > --- > target/ppc/cpu.h | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > index ab68abe8a23c..527181c0f09f 100644 > --- a/target/ppc/cpu.h > +++ b/target/ppc/cpu.h > @@ -70,9 +70,9 @@ > #define PPC_ELF_MACHINE EM_PPC > #endif > > -#define PPC_BIT(bit)(0x8000UL >> (bit)) > -#define PPC_BIT32(bit) (0x8000UL >> (bit)) > -#define PPC_BIT8(bit) (0x80UL >> (bit)) > +#define PPC_BIT(bit)(0x8000ULL >> (bit)) > +#define PPC_BIT32(bit) (0x8000 >> (bit)) > +#define PPC_BIT8(bit) (0x80 >> (bit)) > #define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) > #define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be)) | \ > PPC_BIT32(bs)) -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH] pcie: set link state inactive/active after hot unplug/plug
On Wed, Dec 05, 2018 at 08:23:35AM +0200, Marcel Apfelbaum wrote: > > > On 12/3/18 9:05 AM, Zheng Xiang wrote: > > When VM boots from the latest version of linux kernel, after > > hot-unpluging virtio-blk disks which are hotplugged into > > pcie-root-port, the VM's dmesg log shows: > > > > [ 151.046242] pciehp :00:05.0:pcie004: pending interrupts 0x0001 from > > Slot Status > > [ 151.046365] pciehp :00:05.0:pcie004: Slot(0-3): Attention button > > pressed > > [ 151.046369] pciehp :00:05.0:pcie004: Slot(0-3): Powering off due to > > button press > > [ 151.046420] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 151.046425] pciehp :00:05.0:pcie004: pciehp_green_led_blink: > > SLOTCTRL a8 write cmd 200 > > [ 151.046464] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 151.046468] pciehp :00:05.0:pcie004: pciehp_set_attention_status: > > SLOTCTRL a8 write cmd c0 > > [ 156.163421] pciehp :00:05.0:pcie004: pciehp_get_power_status: > > SLOTCTRL a8 value read 2f1 > > [ 156.163427] pciehp :00:05.0:pcie004: pciehp_unconfigure_device: > > domain:bus:dev = :06:00 > > [ 156.198736] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 156.198772] pciehp :00:05.0:pcie004: pciehp_power_off_slot: SLOTCTRL > > a8 write cmd 400 > > [ 157.224124] pciehp :00:05.0:pcie004: pending interrupts 0x0018 from > > Slot Status > > [ 157.224194] pciehp :00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL > > a8 write cmd 300 > > [ 157.224220] pciehp :00:05.0:pcie004: pciehp_check_link_active: > > lnk_status = 2011 > > [ 157.224223] pciehp :00:05.0:pcie004: Slot(0-3): Link Up > > [ 157.224233] pciehp :00:05.0:pcie004: pciehp_get_power_status: > > SLOTCTRL a8 value read 7f1 > > [ 157.224281] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 157.224285] pciehp :00:05.0:pcie004: pciehp_power_on_slot: SLOTCTRL > > a8 write cmd 0 > > [ 157.224300] pciehp :00:05.0:pcie004: __pciehp_link_set: lnk_ctrl = 0 > > [ 157.224336] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 157.224339] pciehp :00:05.0:pcie004: pciehp_green_led_blink: > > SLOTCTRL a8 write cmd 200 > > [ 159.739294] pci :06:00.0 id reading try 50 times with interval 20 ms > > to get > > [ 159.739315] pciehp :00:05.0:pcie004: pciehp_check_link_status: > > lnk_status = 2011 > > [ 159.739318] pciehp :00:05.0:pcie004: Failed to check link status > > [ 159.739371] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 159.739394] pciehp :00:05.0:pcie004: pciehp_power_off_slot: SLOTCTRL > > a8 write cmd 400 > > [ 160.771426] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 160.771452] pciehp :00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL > > a8 write cmd 300 > > [ 160.771495] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 160.771499] pciehp :00:05.0:pcie004: pciehp_set_attention_status: > > SLOTCTRL a8 write cmd 40 > > [ 160.771535] pciehp :00:05.0:pcie004: pending interrupts 0x0010 from > > Slot Status > > [ 160.771539] pciehp :00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL > > a8 write cmd 300 > > > > After analyzing the log information, it seems that qemu doesn't > > change the Link Status from active to inactive after hot-unplug. > > This results in the abnormal log after the linux kernel commit > > d331710ea78fea merged. > > > > Furthermore, If I hotplug the same virtio-blk disk after hot-unplug, > > the virtio-blk would turn on and then back off. > > > > So this patch set the Link Status inactive after hot-unplug and > > active after hot-plug. > > > > Signed-off-by: Zheng Xiang > > Signed-off-by: Zheng Xiang > > Cc: Wang Haibin > > --- > > hw/pci/pcie.c | 12 > > 1 file changed, 12 insertions(+) > > > > diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c > > index 6c91bd4..66b73b8 100644 > > --- a/hw/pci/pcie.c > > +++ b/hw/pci/pcie.c > > @@ -345,6 +345,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler > > *hotplug_dev, DeviceState *dev, > > if (!dev->hotplugged) { > > pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, > > PCI_EXP_SLTSTA_PDS); > > +if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) { > > +pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, > > + PCI_EXP_LNKSTA_DLLLA); > > +} > > return; > > } > > @@ -355,6 +359,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler > > *hotplug_dev, DeviceState *dev, > > if (pci_get_function_0(pci_dev)) { > > pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, > > PCI_EXP_SLTSTA_PDS); > > +if
Re: [Qemu-devel] [PATCH V6 0/6] nvdimm: support MAP_SYNC for memory-backend-file
On 2018-12-17 at 10:27:50 -0500, Michael S. Tsirkin wrote: > On Mon, Dec 17, 2018 at 01:53:54PM +0800, Yi Zhang wrote: > > On 2018-12-12 at 10:06:13 -0500, Michael S. Tsirkin wrote: > > > On Wed, Dec 12, 2018 at 04:11:44PM +0800, Zhang Yi wrote: > > > > Linux 4.15 introduces a new mmap flag MAP_SYNC, which can be used to > > > > guarantee the write persistence to mmap'ed files supporting DAX (e.g., > > > > files on ext4/xfs file system mounted with '-o dax'). > > > > > > > > A description of MAP_SYNC and MAP_SHARED_VALIDATE can be found at > > > > https://patchwork.kernel.org/patch/10028151/ > > > > > > > > In order to make sure that the file metadata is in sync after a fault > > > > while we are writing a shared DAX supporting backend files, this > > > > patch-set enables QEMU to use MAP_SYNC flag for memory-backend-dax-file. > > > > > > > > As the DAX vs DMA truncated issue was solved, we refined the code and > > > > send out this feature for the v5 version. > > > > > > > > A new auto on/off option 'sync' is added to memory-backend-file: > > > > - on: try to pass MAP_SYNC to mmap(2); if MAP_SYNC is not supported or > > > > 'share=off', QEMU will abort > > > > - off: never pass MAP_SYNC to mmap(2) > > > > - auto (default): if MAP_SYNC is supported and 'share=on', work as if > > > > 'sync=on'; otherwise, work as if 'sync=off' > > > > > > Can this change be limited to a real DAX device? > > > Then you won't need to bother with flags at all. > > Thanks Micheal's review, > > > > For real dax device, we still need to have a option to turn sync off. > > Not sure why really. Why use an nvdimm if you don't actually > want it to be persistent? > > > > > > > > And am I mistaken in thinking that this will affect all > > > guest memory with share=on? Or do I misunderstand? > > > > Only file-backend memory with share=on. > > Yes but that's everyone if e.g. vhost-user needs to be active. > > So frankly I don't think it's a good idea to change the default like this > unless it's limited to nvdimm in some way. Yes, fine, I will limit this flag only on an nvdimm backend. Thanks, Micheal. > > > > > > > > > > > > > > Changes in v6: > > > > * Pankaj: 3/7 are squashed with 2/7 > > > > * Pankaj: 7/7 update comments to "consistent filesystem metadata". > > > > * Pankaj, Igor: 1/7 Added Reviewed-by in patch-1/7 > > > > * Stefan, 4/7 move the include header from "/linux/mman.h" to "osdep.h" > > > > * Stefan, 5/7 Add missing "munmap" > > > > * Stefan, 2/7 refine the shared/flag. > > > > > > > > Changes in v5: > > > > * Add patch 1 to fix a memory leak issue. > > > > * Refine the patch 4-6 > > > > * Remove the patch 3 as we already change the parameter from "shared" > > > > to > > > >"flags" > > > > > > > > Changes in v4: > > > > * Add patch 1-3 to switch some functions to a single 'flags' > > > >parameters. (Michael S. Tsirkin) > > > > * v3 patch 1-3 become v4 patch 4-6. > > > > * Patch 4: move definitions of MAP_SYNC and MAP_SHARED_VALIDATE to a > > > >new header file under include/standard-headers/linux/. (Michael S. > > > > Tsirkin) > > > > * Patch 6: refine the description of the 'sync' option. (Michael S. > > > > Tsirkin) > > > > > > > > Changes in v3: > > > > * Patch 1: add MAP_SHARED_VALIDATE in both sync=on and sync=auto > > > >cases, and add back the retry mechanism. MAP_SYNC will be ignored > > > >by Linux kernel 4.15 if MAP_SHARED_VALIDATE is missed. > > > > * Patch 1: define MAP_SYNC and MAP_SHARED_VALIDATE as 0 on non-Linux > > > >platforms in order to make qemu_ram_mmap() compile on those > > > > platforms. > > > > * Patch 2&3: include more information in error messages of > > > >memory-backend in hope to help user to identify the error. > > > >(Dr. David Alan Gilbert) > > > > * Patch 3: fix typo in the commit message. (Dr. David Alan Gilbert) > > > > > > > > Changes in v2: > > > > * Add 'sync' option to control the use of MAP_SYNC. (Eduardo Habkost) > > > > * Remove the unnecessary set of MAP_SHARED_VALIDATE in some cases and > > > >the retry mechanism in qemu_ram_mmap(). (Michael S. Tsirkin) > > > > * Move OS dependent definitions of MAP_SYNC and MAP_SHARED_VALIDATE > > > >to osdep.h. (Michael S. Tsirkin) > > > > > > > > Zhang Yi (6): > > > > numa: Fixed the memory leak of numa error message > > > > util/mmap-alloc: switch qemu_ram_mmap() to 'flags' parameter > > > > util/mmap-alloc: support MAP_SYNC in qemu_ram_mmap() > > > > util/mmap-alloc: Switch the RAM_SYNC flags to OnOffAuto > > > > hostmem: add more information in error messages > > > > hostmem-file: add 'sync' option > > > > > > > > backends/hostmem-file.c | 45 > > > > +++-- > > > > backends/hostmem.c| 8 +--- > > > > docs/nvdimm.txt | 20 +++- > > > > exec.c| 9 + > > > > include/exec/memory.h | 18
Re: [Qemu-devel] [PATCH v5 6/8] pcie: Allow generic PCIe root port to specify link speed and width
On Mon, 17 Dec 2018 20:47:26 -0500 "Michael S. Tsirkin" wrote: > On Mon, Dec 17, 2018 at 06:44:04PM -0700, Alex Williamson wrote: > > On Mon, 17 Dec 2018 20:29:37 -0500 > > "Michael S. Tsirkin" wrote: > > > > > On Wed, Dec 12, 2018 at 12:39:43PM -0700, Alex Williamson wrote: > > > > Allow users to experimentally specify speed and width values for the > > > > generic PCIe root port. Defaults remain at 2.5GT/s & x1 for > > > > compatiblity with the intent to only support changing defaults via > > > > machine types for now. > > > > > > > > Note for libvirt testing that pcie-root-port controllers are given > > > > default names like "pci.7" which don't play well with using the > > > > "-set device.$name.$prop=$value" options accessible to us via > > > > options. The solution is to add an to the > > > > pcie-root-port , for example: > > > > > > > > > > > > > > > > > > > > > > > >> > > function='0x5'/> > > > > > > > > > > > > The "ua-" here is a mandatory prefix. We can then use: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > or, without an alias, set globals such as: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Cc: Michael S. Tsirkin > > > > Cc: Marcel Apfelbaum > > > > Tested-by: Geoffrey McRae > > > > Reviewed-by: Eric Auger > > > > Signed-off-by: Alex Williamson > > > > --- > > > > hw/pci-bridge/gen_pcie_root_port.c |4 > > > > 1 file changed, 4 insertions(+) > > > > > > > > diff --git a/hw/pci-bridge/gen_pcie_root_port.c > > > > b/hw/pci-bridge/gen_pcie_root_port.c > > > > index 299de429ec1e..ca5418a89dd2 100644 > > > > --- a/hw/pci-bridge/gen_pcie_root_port.c > > > > +++ b/hw/pci-bridge/gen_pcie_root_port.c > > > > @@ -124,6 +124,10 @@ static Property gen_rp_props[] = { > > > > res_reserve.mem_pref_32, -1), > > > > DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, > > > > res_reserve.mem_pref_64, -1), > > > > +DEFINE_PROP_PCIE_LINK_SPEED("x-speed", PCIESlot, > > > > +speed, PCIE_LINK_SPEED_2_5), > > > > +DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot, > > > > +width, PCIE_LINK_WIDTH_1), > > > > DEFINE_PROP_END_OF_LIST() > > > > }; > > > > > > > > > > Doesn't seem to build. > > > Just where is DEFINE_PROP_PCIE_LINK_SPEED defined? > > > > In 3/8: > > > > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h > > index 3ab9cd2eb69f..b6758c852e11 100644 > > --- a/include/hw/qdev-properties.h > > +++ b/include/hw/qdev-properties.h > > @@ -36,6 +36,8 @@ extern const PropertyInfo qdev_prop_uuid; > > extern const PropertyIn qdev_prop_arraylen; > > extern const PropertyInfo qdev_prop_link; > > extern const PropertyInfo qdev_prop_off_auto_pcibar; > > +extern const PropertyInfo qdev_prop_pcie_link_speed; > > +extern const PropertyInfo qdev_prop_pcie_link_width; > > > > #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ > > .name = (_name),\ > > @@ -217,6 +219,12 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar; > > #define DEFINE_PROP_OFF_AUTO_PCIBAR(_n, _s, _f, _d) \ > > DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_off_auto_pcibar, \ > > OffAutoPCIBAR) > > +#define DEFINE_PROP_PCIE_LINK_SPEED(_n, _s, _f, _d) \ > > +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_speed, \ > > +PCIExpLinkSpeed) > > +#define DEFINE_PROP_PCIE_LINK_WIDTH(_n, _s, _f, _d) \ > > +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \ > > +PCIExpLinkWidth) > > > > #define DEFINE_PROP_UUID(_name, _state, _field) { \ > > .name = (_name), \ > > > > Did something go wrong applying that patch? I'll double check on my > > end. Thanks, > > > > Alex > > Oh I just wasn't copied. So I missed this patch when applying. Ah, sorry, I should have forced your Cc on all the patches. I'd also welcome you to include 7/8 in the series to keep things altogether, you're directly copied on all the others. Thanks, Alex
Re: [Qemu-devel] [PATCH v5 6/8] pcie: Allow generic PCIe root port to specify link speed and width
On Mon, Dec 17, 2018 at 06:44:04PM -0700, Alex Williamson wrote: > On Mon, 17 Dec 2018 20:29:37 -0500 > "Michael S. Tsirkin" wrote: > > > On Wed, Dec 12, 2018 at 12:39:43PM -0700, Alex Williamson wrote: > > > Allow users to experimentally specify speed and width values for the > > > generic PCIe root port. Defaults remain at 2.5GT/s & x1 for > > > compatiblity with the intent to only support changing defaults via > > > machine types for now. > > > > > > Note for libvirt testing that pcie-root-port controllers are given > > > default names like "pci.7" which don't play well with using the > > > "-set device.$name.$prop=$value" options accessible to us via > > > options. The solution is to add an to the > > > pcie-root-port , for example: > > > > > > > > > > > > > > > > > >> > function='0x5'/> > > > > > > > > > The "ua-" here is a mandatory prefix. We can then use: > > > > > > > > > > > > > > > > > > > > > > > > > > > or, without an alias, set globals such as: > > > > > > > > > > > > > > > > > > > > > > > > > > > Cc: Michael S. Tsirkin > > > Cc: Marcel Apfelbaum > > > Tested-by: Geoffrey McRae > > > Reviewed-by: Eric Auger > > > Signed-off-by: Alex Williamson > > > --- > > > hw/pci-bridge/gen_pcie_root_port.c |4 > > > 1 file changed, 4 insertions(+) > > > > > > diff --git a/hw/pci-bridge/gen_pcie_root_port.c > > > b/hw/pci-bridge/gen_pcie_root_port.c > > > index 299de429ec1e..ca5418a89dd2 100644 > > > --- a/hw/pci-bridge/gen_pcie_root_port.c > > > +++ b/hw/pci-bridge/gen_pcie_root_port.c > > > @@ -124,6 +124,10 @@ static Property gen_rp_props[] = { > > > res_reserve.mem_pref_32, -1), > > > DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, > > > res_reserve.mem_pref_64, -1), > > > +DEFINE_PROP_PCIE_LINK_SPEED("x-speed", PCIESlot, > > > +speed, PCIE_LINK_SPEED_2_5), > > > +DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot, > > > +width, PCIE_LINK_WIDTH_1), > > > DEFINE_PROP_END_OF_LIST() > > > }; > > > > > > > Doesn't seem to build. > > Just where is DEFINE_PROP_PCIE_LINK_SPEED defined? > > In 3/8: > > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h > index 3ab9cd2eb69f..b6758c852e11 100644 > --- a/include/hw/qdev-properties.h > +++ b/include/hw/qdev-properties.h > @@ -36,6 +36,8 @@ extern const PropertyInfo qdev_prop_uuid; > extern const PropertyInfo qdev_prop_arraylen; > extern const PropertyInfo qdev_prop_link; > extern const PropertyInfo qdev_prop_off_auto_pcibar; > +extern const PropertyInfo qdev_prop_pcie_link_speed; > +extern const PropertyInfo qdev_prop_pcie_link_width; > > #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ > .name = (_name),\ > @@ -217,6 +219,12 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar; > #define DEFINE_PROP_OFF_AUTO_PCIBAR(_n, _s, _f, _d) \ > DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_off_auto_pcibar, \ > OffAutoPCIBAR) > +#define DEFINE_PROP_PCIE_LINK_SPEED(_n, _s, _f, _d) \ > +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_speed, \ > +PCIExpLinkSpeed) > +#define DEFINE_PROP_PCIE_LINK_WIDTH(_n, _s, _f, _d) \ > +DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \ > +PCIExpLinkWidth) > > #define DEFINE_PROP_UUID(_name, _state, _field) { \ > .name = (_name), \ > > Did something go wrong applying that patch? I'll double check on my > end. Thanks, > > Alex Oh I just wasn't copied. So I missed this patch when applying. -- MST
Re: [Qemu-devel] [PULL v3 08/15] tests/fp: add fp-bench
On Mon, Dec 17, 2018 at 10:56:43 +, Alex Bennée wrote: > From: "Emilio G. Cota" > +static void update_random_ops(int n_ops, enum precision prec) > +{ > +int i; > + > +for (i = 0; i < n_ops; i++) { > +uint64_t r = random_ops[i]; > + > +if (prec == PREC_SINGLE || PREC_FLOAT32) { > +do { > +r = xorshift64star(r); > +} while (!float32_is_normal(r)); > +} else if (prec == PREC_DOUBLE || PREC_FLOAT64) { I just noticed that there's a bug here (I was seeing non-normals where I didn't expect any): for (i = 0; i < n_ops; i++) { uint64_t r = random_ops[i]; -if (prec == PREC_SINGLE || PREC_FLOAT32) { +if (prec == PREC_SINGLE || prec == PREC_FLOAT32) { do { r = xorshift64star(r); } while (!float32_is_normal(r)); -} else if (prec == PREC_DOUBLE || PREC_FLOAT64) { +} else if (prec == PREC_DOUBLE || prec == PREC_FLOAT64) { do { r = xorshift64star(r); } while (!float64_is_normal(r)); Let me know if you want me to send a proper patch (this is non-critical so it's OK to fix after merging) or you'd rather fix it up directly. Thanks, E.