Re: [PATCH v2] Makefile: Remove generated files when doing 'distclean' (and 'clean')
- Original Message - > From: "Aleksandar Markovic" > Sent: Tuesday, October 22, 2019 10:35:51 PM > > On Tuesday, October 8, 2019, Thomas Huth wrote: > > > When running "make distclean" we currently leave a lot of generated > > files in the build directory. These should be completely removed. > > Some of the generated files are removed in the "clean" target (which > > is a prerequisite for the "distclean" target), since binary files > > should be removed in this step already. > > > > Signed-off-by: Thomas Huth > > --- > > v2: > > - Remove tests/qemu-iotests/common.env in "distclean", not in "clean" > > - Improved patch description > > > > Makefile | 6 +++--- > > tests/Makefile.include | 12 +++- > > 2 files changed, 14 insertions(+), 4 deletions(-) > > > > Hello, Thomas, > > Do you intend to send a new version of this patch? > > It looks to me this is a very nice clean up that definitely should go into > 4.2, no? I'm still planning to send a v3 of this patch, but currently I don't have time to work on this during the next two weeks. So this will likely miss the deadline for 4.2. Feel free to pick up my patch and send a fixed version if you think that this should still go into 4.2. Otherwise, I'll take care of it in 5.0. Thomas
Re: [PATCH V3 2/2] target/i386/kvm: Add Hyper-V direct tlb flush support
On 22/10/19 22:14, Roman Kagan wrote: > On Tue, Oct 22, 2019 at 07:04:11PM +0200, Paolo Bonzini wrote: >> On 16/10/19 15:07, lantianyu1...@gmail.com wrote: > > Somehow this patch never got through to me so I'll reply here. > >>> From: Tianyu Lan >>> >>> Hyper-V direct tlb flush targets KVM on Hyper-V guest. >>> Enable direct TLB flush for its guests meaning that TLB >>> flush hypercalls are handled by Level 0 hypervisor (Hyper-V) >>> bypassing KVM in Level 1. Due to the different ABI for hypercall >>> parameters between Hyper-V and KVM, KVM capabilities should be >>> hidden when enable Hyper-V direct tlb flush otherwise KVM >>> hypercalls may be intercepted by Hyper-V. Add new parameter >>> "hv-direct-tlbflush". Check expose_kvm and Hyper-V tlb flush >>> capability status before enabling the feature. >>> >>> Signed-off-by: Tianyu Lan >>> --- >>> Change sicne v2: >>>- Update new feature description and name. >>>- Change failure print log. >>> >>> Change since v1: >>>- Add direct tlb flush's Hyper-V property and use >>>hv_cpuid_check_and_set() to check the dependency of tlbflush >>>feature. >>>- Make new feature work with Hyper-V passthrough mode. >>> --- >>> docs/hyperv.txt | 10 ++ >>> target/i386/cpu.c | 2 ++ >>> target/i386/cpu.h | 1 + >>> target/i386/kvm.c | 24 >>> 4 files changed, 37 insertions(+) >>> >>> diff --git a/docs/hyperv.txt b/docs/hyperv.txt >>> index 8fdf25c829..140a5c7e44 100644 >>> --- a/docs/hyperv.txt >>> +++ b/docs/hyperv.txt >>> @@ -184,6 +184,16 @@ enabled. >>> >>> Requires: hv-vpindex, hv-synic, hv-time, hv-stimer >>> >>> +3.18. hv-direct-tlbflush >>> +=== >>> +Enable direct TLB flush for KVM when it is running as a nested >>> +hypervisor on top Hyper-V. When enabled, TLB flush hypercalls from L2 >>> +guests are being passed through to L0 (Hyper-V) for handling. Due to ABI >>> +differences between Hyper-V and KVM hypercalls, L2 guests will not be >>> +able to issue KVM hypercalls (as those could be mishanled by L0 >>> +Hyper-V), this requires KVM hypervisor signature to be hidden. >>> + >>> +Requires: hv-tlbflush, -kvm >>> >>> 4. Development features >>> >>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c >>> index 44f1bbdcac..7bc7fee512 100644 >>> --- a/target/i386/cpu.c >>> +++ b/target/i386/cpu.c >>> @@ -6156,6 +6156,8 @@ static Property x86_cpu_properties[] = { >>>HYPERV_FEAT_IPI, 0), >>> DEFINE_PROP_BIT64("hv-stimer-direct", X86CPU, hyperv_features, >>>HYPERV_FEAT_STIMER_DIRECT, 0), >>> +DEFINE_PROP_BIT64("hv-direct-tlbflush", X86CPU, hyperv_features, >>> + HYPERV_FEAT_DIRECT_TLBFLUSH, 0), >>> DEFINE_PROP_BOOL("hv-passthrough", X86CPU, hyperv_passthrough, false), >>> >>> DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true), >>> diff --git a/target/i386/cpu.h b/target/i386/cpu.h >>> index eaa5395aa5..3cb105f7d6 100644 >>> --- a/target/i386/cpu.h >>> +++ b/target/i386/cpu.h >>> @@ -907,6 +907,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; >>> #define HYPERV_FEAT_EVMCS 12 >>> #define HYPERV_FEAT_IPI 13 >>> #define HYPERV_FEAT_STIMER_DIRECT 14 >>> +#define HYPERV_FEAT_DIRECT_TLBFLUSH 15 >>> >>> #ifndef HYPERV_SPINLOCK_NEVER_RETRY >>> #define HYPERV_SPINLOCK_NEVER_RETRY 0x >>> diff --git a/target/i386/kvm.c b/target/i386/kvm.c >>> index 11b9c854b5..043b66ab22 100644 >>> --- a/target/i386/kvm.c >>> +++ b/target/i386/kvm.c >>> @@ -900,6 +900,10 @@ static struct { >>> }, >>> .dependencies = BIT(HYPERV_FEAT_STIMER) >>> }, >>> +[HYPERV_FEAT_DIRECT_TLBFLUSH] = { >>> +.desc = "direct paravirtualized TLB flush (hv-direct-tlbflush)", >>> +.dependencies = BIT(HYPERV_FEAT_TLBFLUSH) >>> +}, >>> }; >>> >>> static struct kvm_cpuid2 *try_get_hv_cpuid(CPUState *cs, int max) >>> @@ -1224,6 +1228,7 @@ static int hyperv_handle_properties(CPUState *cs, >>> r |= hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_EVMCS); >>> r |= hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_IPI); >>> r |= hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_STIMER_DIRECT); >>> +r |= hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_DIRECT_TLBFLUSH); > > AFAICS this will turn HYPERV_FEAT_DIRECT_TLBFLUSH on if > hyperv_passthrough is on, so ... > >>> >>> /* Additional dependencies not covered by kvm_hyperv_properties[] */ >>> if (hyperv_feat_enabled(cpu, HYPERV_FEAT_SYNIC) && >>> @@ -1243,6 +1248,25 @@ static int hyperv_handle_properties(CPUState *cs, >>> goto free; >>> } >>> >>> +if (hyperv_feat_enabled(cpu, HYPERV_FEAT_DIRECT_TLBFLUSH) || >>> +cpu->hyperv_passthrough) { > > ... the test for ->hyperv_passthrough is redundant, and ... > >>> +if (!cpu->expose_kvm) { >>> +r = kvm_vcpu_enable_cap(cs,
Re: [PATCH v2] net: add tulip (dec21143) driver
Patchew URL: https://patchew.org/QEMU/20191022155413.4619-1-sv...@stackframe.org/ Hi, This series failed the docker-mingw@fedora build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #! /bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-mingw@fedora J=14 NETWORK=1 === TEST SCRIPT END === CC hw/pci-bridge/pcie_pci_bridge.o In file included from /tmp/qemu-test/src/hw/net/tulip.c:10: /tmp/qemu-test/src/hw/net/tulip.c: In function 'tulip_read': /tmp/qemu-test/src/hw/net/tulip.c:544:44: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log_mask(LOG_GUEST_ERROR, "%s: read access add unknown address" ^ " %lx\n", __func__, addr); --- %llx In file included from /tmp/qemu-test/src/hw/net/tulip.c:10: /tmp/qemu-test/src/hw/net/tulip.c: In function 'tulip_write': /tmp/qemu-test/src/hw/net/tulip.c:833:40: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log_mask(LOG_GUEST_ERROR, "%s: write to CSR at unknown address " ^~ "0x%lx\n", __func__, addr); --- ~~^ %llx cc1: all warnings being treated as errors make: *** [/tmp/qemu-test/src/rules.mak:69: hw/net/tulip.o] Error 1 make: *** Waiting for unfinished jobs CC hw/pci-bridge/pci_expander_bridge.o Traceback (most recent call last): --- raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=a5d761d2dfab406ea53042f542b4b6fc', '-u', '1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-ut38bil8/src/docker-src.2019-10-23-03.24.09.4216:/var/tmp/qemu:z,ro', 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit status 2. filter=--filter=label=com.qemu.instance.uuid=a5d761d2dfab406ea53042f542b4b6fc make[1]: *** [docker-run] Error 1 make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-ut38bil8/src' make: *** [docker-run-test-mingw@fedora] Error 2 real2m28.426s user0m7.946s The full log is available at http://patchew.org/logs/20191022155413.4619-1-sv...@stackframe.org/testing.docker-mingw@fedora/?type=message. --- Email generated automatically by Patchew [https://patchew.org/]. Please send your feedback to patchew-de...@redhat.com
Re: [PATCH v1 07/19] cirrus.yml: reduce scope of MacOS build
- Original Message - > From: "Alex Bennée" > Sent: Tuesday, October 22, 2019 9:16:52 PM > > The MacOS build can time out on Cirrus running to almost an hour. > Reduce the scope to the historical MacOS architectures much the same > way we do on Travis. Oh, really? For me, the builds on Cirrus-CI work reasonable fast and almost always finish within 20 minutes, e.g.: https://cirrus-ci.com/build/4976412120842240 Also the last macos_task from the official QEMU mirror on github finished within 15 minutes: https://github.com/qemu/qemu/runs/269964092 ... so was your issue maybe just a temporary dropout? Thomas
Re: [PATCH for 4.2 v1 00/19] testing/next before softfreeze
- Original Message - > From: "Alex Bennée" > Sent: Tuesday, October 22, 2019 9:16:45 PM > > Hi, > > This is the current status of testing/next. I dropped the Travis arm64 > build due to stability concerns. As far as I can tell Thomas' latest > iotest updates are working fine. If there are any other patches worth > considering before the softfreeze now is the time to shout. Feel free to include: https://lists.nongnu.org/archive/html/qemu-devel/2019-10/msg03912.html ("gitlab-ci.yml: Use libvdeplug-dev to compile-test the VDE network backend") I'm not sure whether I'll find some spare time to send a pull request for that patch before/during KVM forum, so it would be nice if you could include it. Thomas
[PATCH] nvme: fix NSSRS offset in CAP register
Fix the offset of the NSSRS field the CAP register. Signed-off-by: Klaus Jensen Reported-by: Javier Gonzalez --- include/block/nvme.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/block/nvme.h b/include/block/nvme.h index 3ec8efcc435e..fa15b51c33bb 100644 --- a/include/block/nvme.h +++ b/include/block/nvme.h @@ -23,7 +23,7 @@ enum NvmeCapShift { CAP_AMS_SHIFT = 17, CAP_TO_SHIFT = 24, CAP_DSTRD_SHIFT= 32, -CAP_NSSRS_SHIFT= 33, +CAP_NSSRS_SHIFT= 36, CAP_CSS_SHIFT = 37, CAP_MPSMIN_SHIFT = 48, CAP_MPSMAX_SHIFT = 52, -- 2.23.0
Re: [PATCH v2 0/4] apic: Fix migration breakage of >255 vcpus
On Sat, Oct 19, 2019 at 11:41:53AM +0800, Peter Xu wrote: > On Wed, Oct 16, 2019 at 11:40:01AM -0300, Eduardo Habkost wrote: > > On Wed, Oct 16, 2019 at 10:29:29AM +0800, Peter Xu wrote: > > > v2: > > > - use uint32_t rather than int64_t [Juan] > > > - one more patch (patch 4) to check dup SaveStateEntry [Dave] > > > - one more patch to define a macro (patch 1) to simplify patch 2 > > > > > > Please review, thanks. > > > > I wonder how hard it is to write a simple test case to reproduce > > the original bug. We can extend tests/migration-test.c or > > tests/acceptance/migration.py. If using -device with explicit > > apic-id, we probably don't even need to create >255 VCPUs. > > I can give it a shot next week. :) When trying this, I probably noticed a block layer issue: q35 seems to have problem on booting from a very small block device (like 512B, which is the image size that currently used for migration-test.c). For example, this cmdline can boot successfully into the test image: $qemu -M pc -m 200m -accel kvm -nographic \ -drive file=$image,id=drive0,index=0,format=raw \ -device ide-hd,drive=drive0 While this cannot: $qemu -M q35 -m 200m -accel kvm -nographic \ -drive file=$image,id=drive0,index=0,format=raw \ -device ide-hd,drive=drive0 With error (BIOS debug messages on): Booting from Hard Disk..invalid basic_access:143: a=0201 b= c=0001 d=0080 ds= es=07c0 ss=d980 si= di= bp= sp=fd8e cs=f000 ip=cb81 f=0202 invalid basic_access:144: a=0201 b= c=0001 d=0080 ds= es=07c0 ss=d980 si= di= bp= sp=fd8e cs=f000 ip=cb81 f=0202 . Boot failed: could not read the boot disenter handle_18: NULL k This corresponds to this SeaBIOS check error: static void noinline basic_access(struct bregs *regs, struct drive_s *drive_fl, u16 command) { ... // sanity check on cyl heads, sec if (cylinder >= nlc || head >= nlh || sector > nls) { warn_invalid(regs); disk_ret(regs, DISK_RET_EPARAM); return; } ... } And... below cmdline will work even for q35 (as suggested by Fam when we talked offline): $qemu -M q35 -m 200m -accel kvm -nographic \ -drive file=$image,id=drive0,index=0,format=raw \ -device ide-hd,drive=drive0,secs=1,cyls=1,heads=1 I think for migration test we can workaround like above, but I'm also curious whether this is a real bug somewhere because I don't see a reason for q35 to refuse to boot on a one-sector image. Thanks, -- Peter Xu
Re: [PATCH v4 3/3] tests/migration:fix unreachable path in stress test
Le 04/10/2019 à 19:32, Mao Zhongyi a écrit : > If stressone() or stress() exits it's because of a failure > because the test runs forever otherwise, so change stressone > and stress type to void to make the exit_failure() as the exit > function of main(). > > Signed-off-by: Mao Zhongyi > --- > tests/migration/stress.c | 13 + > 1 file changed, 5 insertions(+), 8 deletions(-) > > diff --git a/tests/migration/stress.c b/tests/migration/stress.c > index f9626d50ee..a062ef6b55 100644 > --- a/tests/migration/stress.c > +++ b/tests/migration/stress.c > @@ -167,7 +167,7 @@ static unsigned long long now(void) > return (tv.tv_sec * 1000ull) + (tv.tv_usec / 1000ull); > } > > -static int stressone(unsigned long long ramsizeMB) > +static void stressone(unsigned long long ramsizeMB) > { > size_t pagesPerMB = 1024 * 1024 / PAGE_SIZE; > g_autofree char *ram = g_malloc(ramsizeMB * 1024 * 1024); > @@ -186,7 +186,7 @@ static int stressone(unsigned long long ramsizeMB) > memset(ram, 0xfe, ramsizeMB * 1024 * 1024); > > if (random_bytes(data, PAGE_SIZE) < 0) { > -return -1; > +return; > } > > before = now(); > @@ -225,7 +225,7 @@ static void *stressthread(void *arg) > return NULL; > } > > -static int stress(unsigned long long ramsizeGB, int ncpus) > +static void stress(unsigned long long ramsizeGB, int ncpus) > { > size_t i; > unsigned long long ramsizeMB = ramsizeGB * 1024 / ncpus; > @@ -238,8 +238,6 @@ static int stress(unsigned long long ramsizeGB, int ncpus) > } > > stressone(ramsizeMB); > - > -return 0; > } > > > @@ -335,8 +333,7 @@ int main(int argc, char **argv) > fprintf(stdout, "%s (%05d): INFO: RAM %llu GiB across %d CPUs\n", > argv0, gettid(), ramsizeGB, ncpus); > > -if (stress(ramsizeGB, ncpus) < 0) > -exit_failure(); > +stress(ramsizeGB, ncpus); > > -exit_success(); > +exit_failure(); > } > Reviewed-by: Laurent Vivier
Re: [PATCH v2] net: add tulip (dec21143) driver
On Tue, Oct 22, 2019 at 05:00:16PM +0100, Peter Maydell wrote: > > There are a couple of minor wrong-indent nits: > > > +static void tulip_update_ts(TULIPState *s, int state) > > +{ > > +s->csr[5] &= ~(CSR5_TS_MASK << CSR5_TS_SHIFT); > > +s->csr[5] |= (state & CSR5_TS_MASK) << CSR5_TS_SHIFT; > > +trace_tulip_tx_state(tulip_tx_state_name(state)); > > +} > > > +struct tulip_descriptor { > > +uint32_t status; > > +uint32_t control; > > +uint32_t buf_addr1; > > +uint32_t buf_addr2; > > +}; > > but maybe Jason can fix those up when he takes the patch ? I'll send an updated version soon - there are some other small things that i need to address. Thanks Sven
Re: [PATCH v4] migration: Support QLIST migration
Eric Auger wrote: > Support QLIST migration using the same principle as QTAILQ: > 94869d5c52 ("migration: migrate QTAILQ"). > > The VMSTATE_QLIST_V macro has the same proto as VMSTATE_QTAILQ_V. > The change mainly resides in QLIST RAW macros: QLIST_RAW_INSERT_HEAD > and QLIST_RAW_REVERSE. > > Tests also are provided. > > Signed-off-by: Eric Auger Reviewed-by: Juan Quintela With the minor fix found by peter.
[Bug 1846427] Re: 4.1.0: qcow2 corruption on savevm/quit/loadvm cycle
> So it's much more likely that is_zero_cow() has a side-effect that somehow > causes corruption later on even without handle_alloc_space() ever calling > bdrv_co_pwrite_zeroes(). Yes, looks like it. I think we have ruled out that a changing return value is the cause of the problems because the return code was completely ignored and it still broke for you. Basically the only other thing I see that our commit has changed is that qcow2_detect_metadata_preallocation() runs now. I assume that if you replace its call in qcow2_co_block_status() with a fixed ret = true or ret = false, the problem will still disappear. Now what is problematic inside qcow2_detect_metadata_preallocation()? At the moment I see two options: 1. qcow2_get_refcount() is the only thing that does something with the qcow2 internals, the other calls are about bs->file->bs (the raw image file), which is pretty certainly harmless. The interesting thing about the qcow2_get_refcount() call is that other code paths call it with s->lock locked, but this one is unlocked. I wonder if moving qemu_co_mutex_lock(&s->lock); in qcow2_co_block_status() to above the qcow2_detect_metadata_preallocation() call would change anything. 2. Or the problem isn't even related to what qcow2_detect_metadata_preallocation() does, but it's a race elsewhere that is just uncovered because of the timing - preallocation detection must be pretty slow because it checks the refcount of every single cluster in the image. In that case, replacing it with something like qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1); should have the same effect and cause corruption, too. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1846427 Title: 4.1.0: qcow2 corruption on savevm/quit/loadvm cycle Status in QEMU: New Bug description: I'm seeing massive corruption of qcow2 images with qemu 4.1.0 and git master as of 7f21573c822805a8e6be379d9bcf3ad9effef3dc after a few savevm/quit/loadvm cycles. I've narrowed it down to the following reproducer (further notes below): # qemu-img check debian.qcow2 No errors were found on the image. 251601/327680 = 76.78% allocated, 1.63% fragmented, 0.00% compressed clusters Image end offset: 18340446208 # bin/qemu/bin/qemu-system-x86_64 -machine pc-q35-4.0.1,accel=kvm -m 4096 -chardev stdio,id=charmonitor -mon chardev=charmonitor -drive file=debian.qcow2,id=d -S qemu-system-x86_64: warning: dbind: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken. QEMU 4.1.50 monitor - type 'help' for more information (qemu) loadvm foo (qemu) c (qemu) qcow2_free_clusters failed: Invalid argument qcow2_free_clusters failed: Invalid argument qcow2_free_clusters failed: Invalid argument qcow2_free_clusters failed: Invalid argument quit [m@nargothrond:~] qemu-img check debian.qcow2 Leaked cluster 85179 refcount=2 reference=1 Leaked cluster 85180 refcount=2 reference=1 ERROR cluster 266150 refcount=0 reference=2 [...] ERROR OFLAG_COPIED data cluster: l2_entry=42284 refcount=1 9493 errors were found on the image. Data may be corrupted, or further writes to the image may corrupt it. 2 leaked clusters were found on the image. This means waste of disk space, but no harm to data. 259266/327680 = 79.12% allocated, 1.67% fragmented, 0.00% compressed clusters Image end offset: 18340446208 This is on a x86_64 Linux 5.3.1 Gentoo host with qemu-system-x86_64 and accel=kvm. The compiler is gcc-9.2.0 with the rest of the system similarly current. Reproduced with qemu-4.1.0 from distribution package as well as vanilla git checkout of tag v4.1.0 and commit 7f21573c822805a8e6be379d9bcf3ad9effef3dc (today's master). Does not happen with qemu compiled from vanilla checkout of tag v4.0.0. Build sequence: ./configure --prefix=$HOME/bin/qemu-bisect --target-list=x86_64-softmmu --disable-werror --disable-docs [...] CFLAGS-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g [...] (can provide full configure output if helpful) make -j8 install The kind of guest OS does not matter: seen with Debian testing 64bit, Windows 7 x86/x64 BIOS and Windows 7 x64 EFI. The virtual storage controller does not seem to matter: seen with VirtIO SCSI, emulated SCSI and emulated SATA AHCI. Caching modes (none, directsync, writeback), aio mode (threads, native) or discard (ignore, unmap) or detect-zeroes (off, unmap) does not influence occurence either. Having more RAM in the guest seems to increase odds of corruption: With 512MB to the Debian guest problem hardly occurs at all, with 4GB RAM it happens almost instantly. An automated reproducer works as follows: - the guest *does* mount
RE: [PATCH v6 1/4] block/replication.c: Ignore requests after failover
> -Original Message- > From: Lukas Straub > Sent: Saturday, October 19, 2019 2:46 AM > To: qemu-devel > Cc: Zhang, Chen ; Jason Wang > ; Wen Congyang ; > Xie Changlong ; Kevin Wolf > ; Max Reitz ; qemu-block > > Subject: Re: [PATCH v6 1/4] block/replication.c: Ignore requests after > failover > > On Sat, 5 Oct 2019 15:05:23 +0200 > Lukas Straub wrote: > > > After failover the Secondary side of replication shouldn't change > > state, because it now functions as our primary disk. > > > > In replication_start, replication_do_checkpoint, replication_stop, > > ignore the request if current state is BLOCK_REPLICATION_DONE > > (sucessful failover) or BLOCK_REPLICATION_FAILOVER (failover in > > progres i.e. currently merging active and hidden images into the base > image). > > > > Signed-off-by: Lukas Straub > > Reviewed-by: Zhang Chen > > --- > > block/replication.c | 38 +++--- > > 1 file changed, 35 insertions(+), 3 deletions(-) > > > > diff --git a/block/replication.c b/block/replication.c index > > 3d4dedddfc..97cc65c0cf 100644 > > --- a/block/replication.c > > +++ b/block/replication.c > > @@ -454,6 +454,17 @@ static void replication_start(ReplicationState *rs, > ReplicationMode mode, > > aio_context_acquire(aio_context); > > s = bs->opaque; > > > > +if (s->stage == BLOCK_REPLICATION_DONE || > > +s->stage == BLOCK_REPLICATION_FAILOVER) { > > +/* > > + * This case happens when a secondary is promoted to primary. > > + * Ignore the request because the secondary side of replication > > + * doesn't have to do anything anymore. > > + */ > > +aio_context_release(aio_context); > > +return; > > +} > > + > > if (s->stage != BLOCK_REPLICATION_NONE) { > > error_setg(errp, "Block replication is running or done"); > > aio_context_release(aio_context); @@ -529,8 +540,7 @@ static > > void replication_start(ReplicationState *rs, ReplicationMode mode, > > "Block device is in use by internal backup job"); > > > > top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL); > > -if (!top_bs || !bdrv_is_root_node(top_bs) || > > -!check_top_bs(top_bs, bs)) { > > +if (!top_bs || !check_top_bs(top_bs, bs)) { > > error_setg(errp, "No top_bs or it is invalid"); > > reopen_backing_file(bs, false, NULL); > > aio_context_release(aio_context); @@ -577,6 +587,17 @@ > > static void replication_do_checkpoint(ReplicationState *rs, Error **errp) > > aio_context_acquire(aio_context); > > s = bs->opaque; > > > > +if (s->stage == BLOCK_REPLICATION_DONE || > > +s->stage == BLOCK_REPLICATION_FAILOVER) { > > +/* > > + * This case happens when a secondary was promoted to primary. > > + * Ignore the request because the secondary side of replication > > + * doesn't have to do anything anymore. > > + */ > > +aio_context_release(aio_context); > > +return; > > +} > > + > > if (s->mode == REPLICATION_MODE_SECONDARY) { > > secondary_do_checkpoint(s, errp); > > } > > @@ -593,7 +614,7 @@ static void replication_get_error(ReplicationState > *rs, Error **errp) > > aio_context_acquire(aio_context); > > s = bs->opaque; > > > > -if (s->stage != BLOCK_REPLICATION_RUNNING) { > > +if (s->stage == BLOCK_REPLICATION_NONE) { > > error_setg(errp, "Block replication is not running"); > > aio_context_release(aio_context); > > return; > > @@ -635,6 +656,17 @@ static void replication_stop(ReplicationState *rs, > bool failover, Error **errp) > > aio_context_acquire(aio_context); > > s = bs->opaque; > > > > +if (s->stage == BLOCK_REPLICATION_DONE || > > +s->stage == BLOCK_REPLICATION_FAILOVER) { > > +/* > > + * This case happens when a secondary was promoted to primary. > > + * Ignore the request because the secondary side of replication > > + * doesn't have to do anything anymore. > > + */ > > +aio_context_release(aio_context); > > +return; > > +} > > + > > if (s->stage != BLOCK_REPLICATION_RUNNING) { > > error_setg(errp, "Block replication is not running"); > > aio_context_release(aio_context); > > Hello Everyone, > Could the block people have a look at this patch? Add Dave, do you have time to review this series? Thanks Zhang Chen > > Regards, > Lukas Straub
[Bug 1192464] Re: udp checksum computed as 0 not converted to 0xffff, from guest os that share a common linux bridge among multiple guest os
Triaging old buck tickets ... can you still reproduce this issue with the latest version of QEMU? Is it only happening with e1000 or also with other NICs? What kind of network backend are you using (--netdev user ? tap ? ). Could you please provide the full command line that you use to run QEMU? Thanks! ** Changed in: qemu Status: New => Incomplete -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1192464 Title: udp checksum computed as 0 not converted to 0x, from guest os that share a common linux bridge among multiple guest os Status in QEMU: Incomplete Bug description: UDP checksum computed as '0' during transmission of packets that uses e1000 NIC in the Guest as well as emulated h/w in the qemu layer, That needs to be converted to 0x, This occurs only when Hardware checksum offload is been set in the guest OS NIC and made it as a transmitter. The guest O.S use the N/W interface that is been shared to the linux brige created in the host (used source=) in the xml tags of libvirt. As per RFC768(http://tools.ietf.org/html/rfc768 [^]), If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care). To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1192464/+subscriptions
[Bug 1192464] Re: udp checksum computed as 0 not converted to 0xffff, from guest os that share a common linux bridge among multiple guest os
Sorry, I meant "bug tickets", of course, not "buck tickets" ... need more coffee... -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1192464 Title: udp checksum computed as 0 not converted to 0x, from guest os that share a common linux bridge among multiple guest os Status in QEMU: Incomplete Bug description: UDP checksum computed as '0' during transmission of packets that uses e1000 NIC in the Guest as well as emulated h/w in the qemu layer, That needs to be converted to 0x, This occurs only when Hardware checksum offload is been set in the guest OS NIC and made it as a transmitter. The guest O.S use the N/W interface that is been shared to the linux brige created in the host (used source=) in the xml tags of libvirt. As per RFC768(http://tools.ietf.org/html/rfc768 [^]), If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care). To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1192464/+subscriptions
Re: [PATCH v2 0/4] apic: Fix migration breakage of >255 vcpus
Am 23.10.2019 um 09:57 hat Peter Xu geschrieben: > On Sat, Oct 19, 2019 at 11:41:53AM +0800, Peter Xu wrote: > > On Wed, Oct 16, 2019 at 11:40:01AM -0300, Eduardo Habkost wrote: > > > On Wed, Oct 16, 2019 at 10:29:29AM +0800, Peter Xu wrote: > > > > v2: > > > > - use uint32_t rather than int64_t [Juan] > > > > - one more patch (patch 4) to check dup SaveStateEntry [Dave] > > > > - one more patch to define a macro (patch 1) to simplify patch 2 > > > > > > > > Please review, thanks. > > > > > > I wonder how hard it is to write a simple test case to reproduce > > > the original bug. We can extend tests/migration-test.c or > > > tests/acceptance/migration.py. If using -device with explicit > > > apic-id, we probably don't even need to create >255 VCPUs. > > > > I can give it a shot next week. :) > > When trying this, I probably noticed a block layer issue: q35 seems to > have problem on booting from a very small block device (like 512B, > which is the image size that currently used for migration-test.c). > For example, this cmdline can boot successfully into the test image: > > $qemu -M pc -m 200m -accel kvm -nographic \ > -drive file=$image,id=drive0,index=0,format=raw \ > -device ide-hd,drive=drive0 > > While this cannot: > > $qemu -M q35 -m 200m -accel kvm -nographic \ > -drive file=$image,id=drive0,index=0,format=raw \ > -device ide-hd,drive=drive0 The important difference here is legacy IDE (which works) vs. AHCI (which doesn't work). If you add a -device ahci to the -M pc case, it starts failing, too. Not sure why AHCI fails, but I'll just CC John who is the lucky maintainer of this device. :-) Kevin > With error (BIOS debug messages on): > > Booting from Hard Disk..invalid basic_access:143: >a=0201 b= c=0001 d=0080 ds= es=07c0 ss=d980 > si= di= bp= sp=fd8e cs=f000 ip=cb81 f=0202 > invalid basic_access:144: >a=0201 b= c=0001 d=0080 ds= es=07c0 ss=d980 > si= di= bp= sp=fd8e cs=f000 ip=cb81 f=0202 > . > Boot failed: could not read the boot disenter handle_18: > NULL > k > > This corresponds to this SeaBIOS check error: > > static void noinline > basic_access(struct bregs *regs, struct drive_s *drive_fl, u16 command) > { > ... > // sanity check on cyl heads, sec > if (cylinder >= nlc || head >= nlh || sector > nls) { > warn_invalid(regs); > disk_ret(regs, DISK_RET_EPARAM); > return; > } > ... > } > > And... below cmdline will work even for q35 (as suggested by Fam when > we talked offline): > > $qemu -M q35 -m 200m -accel kvm -nographic \ > -drive file=$image,id=drive0,index=0,format=raw \ > -device ide-hd,drive=drive0,secs=1,cyls=1,heads=1 > > I think for migration test we can workaround like above, but I'm also > curious whether this is a real bug somewhere because I don't see a > reason for q35 to refuse to boot on a one-sector image. > > Thanks, > > -- > Peter Xu >
[PATCH] audio: fix missing break
Reported by Coverity (CID 1406449). Signed-off-by: Paolo Bonzini --- audio/paaudio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/audio/paaudio.c b/audio/paaudio.c index df541a72d3..55a91f8980 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -385,6 +385,7 @@ static pa_stream *qpa_simple_new ( map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT; map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT; map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT; +break; default: dolog("Internal error: unsupported channel count %d\n", ss->channels); -- 2.21.0
[PATCH v5 01/11] qdev/qbus: add hidden device support
This adds support for hiding a device to the qbus and qdev APIs. The first user of this will be the virtio-net failover feature but the API introduced with this patch could be used to implement other features as well, for example hiding pci devices when a pci bus is powered off. qdev_device_add() is modified to check for a net_failover_pair_id argument in the option string. A DeviceListener callback should_be_hidden() is added. It can be used by a standby device to inform qdev that this device should not be added now. The standby device handler can store the device options to plug the device in at a later point in time. One reason for hiding the device is that we don't want to expose both devices to the guest kernel until the respective virtio feature bit VIRTIO_NET_F_STANDBY was negotiated and we know that the devices will be handled correctly by the guest. More information on the kernel feature this is using: https://www.kernel.org/doc/html/latest/networking/net_failover.html An example where the primary device is a vfio-pci device and the standby device is a virtio-net device: A device is hidden when it has an "net_failover_pair_id" option, e.g. -device virtio-net-pci,...,failover=on,... -device vfio-pci,...,net_failover_pair_id=net1,... Signed-off-by: Jens Freimann Reviewed-by: Cornelia Huck --- hw/core/qdev.c | 23 +++ include/hw/qdev-core.h | 29 + qdev-monitor.c | 41 + vl.c | 6 -- 4 files changed, 93 insertions(+), 6 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index cbad6c1d55..f786650446 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -212,6 +212,29 @@ void device_listener_unregister(DeviceListener *listener) QTAILQ_REMOVE(&device_listeners, listener, link); } +bool qdev_should_hide_device(QemuOpts *opts) +{ +int rc = -1; +DeviceListener *listener; + +QTAILQ_FOREACH(listener, &device_listeners, link) { + if (listener->should_be_hidden) { +/* should_be_hidden_will return + * 1 if device matches opts and it should be hidden + * 0 if device matches opts and should not be hidden + * -1 if device doesn't match opts + */ +rc = listener->should_be_hidden(listener, opts); +} + +if (rc > 0) { +break; +} +} + +return rc > 0; +} + void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, int required_for_version) { diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index aa123f88cb..710981af36 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -78,6 +78,19 @@ typedef void (*BusUnrealize)(BusState *bus, Error **errp); * respective parent types. * * + * + * # Hiding a device # + * To hide a device, a DeviceListener function should_be_hidden() needs to + * be registered. + * It can be used to defer adding a device and therefore hide it from the + * guest. The handler registering to this DeviceListener can save the QOpts + * passed to it for re-using it later and must return that it wants the device + * to be/remain hidden or not. When the handler function decides the device + * shall not be hidden it will be added in qdev_device_add() and + * realized as any other device. Otherwise qdev_device_add() will return early + * without adding the device. The guest will not see a "hidden" device + * until it was marked don't hide and qdev_device_add called again. + * */ typedef struct DeviceClass { /*< private >*/ @@ -154,6 +167,12 @@ struct DeviceState { struct DeviceListener { void (*realize)(DeviceListener *listener, DeviceState *dev); void (*unrealize)(DeviceListener *listener, DeviceState *dev); +/* + * This callback is called upon init of the DeviceState and allows to + * inform qdev that a device should be hidden, depending on the device + * opts, for example, to hide a standby device. + */ +int (*should_be_hidden)(DeviceListener *listener, QemuOpts *device_opts); QTAILQ_ENTRY(DeviceListener) link; }; @@ -451,4 +470,14 @@ static inline bool qbus_is_hotpluggable(BusState *bus) void device_listener_register(DeviceListener *listener); void device_listener_unregister(DeviceListener *listener); +/** + * @qdev_should_hide_device: + * @opts: QemuOpts as passed on cmdline. + * + * Check if a device should be added. + * When a device is added via qdev_device_add() this will be called, + * and return if the device should be added now or not. + */ +bool qdev_should_hide_device(QemuOpts *opts); + #endif diff --git a/qdev-monitor.c b/qdev-monitor.c index 148df9cacf..676a759fb4 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -32,9 +32,11 @@ #include "qemu/help_option.h" #include "qemu/option.h" #include "qemu/qemu-print.h" +#include "qemu/option_int.h" #include "sysemu/block-backend.h
[PATCH v5 0/11] add failover feature for assigned network devices
This is implementing the host side of the net_failover concept (https://www.kernel.org/doc/html/latest/networking/net_failover.html) Changes since v4: * Patch 1, qdev, add comment to DeviceClass and qdev_should_hide_device function * Patch 2 pci, set flag that allows unplug during migration in qdev code (aw) * Patch 10 virtio, fix error handling * Patch 11 vfio, fix error handling in vfio_realize (Conny) move allow_unplug_during_migraton flag to generic PCI The general idea is that we have a pair of devices, a vfio-pci and a virtio-net device. Before migration the vfio device is unplugged and data flows to the virtio-net device, on the target side another vfio-pci device is plugged in to take over the data-path. In the guest the net_failover module will pair net devices with the same MAC address. * Patch 1 adds the infrastructure to hide the device for the qbus and qdev APIs * Patch 2 adds checks to PCIDevice for only allowing ethernet devices as failover primary and only PCIExpress capable devices * Patch 3 sets a new flag for PCIDevice 'partially_hotplugged' which we use to skip the unrealize code path when doing a unplug of the primary device * Patch 4 sets the pending_deleted_event before triggering the guest unplug request * Patch 5 and 6 add new qmp events, one sends the device id of a device that was just requested to be unplugged from the guest and another one to let libvirt know if VIRTIO_NET_F_STANDBY was negotiated * Patch 7 make sure that we can unplug the vfio-device before migration starts * Patch 8 adds a new migration state that is entered while we wait for devices to be unplugged by guest OS * Patch 9 just adds the new migration state to a check in libqos code * Patch 10 In the second patch the virtio-net uses the API to defer adding the vfio device until the VIRTIO_NET_F_STANDBY feature is acked. It also implements the migration handler to unplug the device from the guest and re-plug in case of migration failure * Patch 11 allows migration for failover vfio-pci devices Previous discussion: RFC v1 https://patchwork.ozlabs.org/cover/989098/ RFC v2 https://www.mail-archive.com/qemu-devel@nongnu.org/msg606906.html v1: https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg03968.html v2: https://www.mail-archive.com/qemu-devel@nongnu.org/msg635214.html v3: https://patchew.org/QEMU/2019102015.11785-1-jfreim...@redhat.com/ v4: https://patchew.org/QEMU/20191018202040.30349-1-jfreim...@redhat.com/ To summarize concerns/feedback from previous discussion: 1.- guest OS can reject or worse _delay_ unplug by any amount of time. Migration might get stuck for unpredictable time with unclear reason. This approach combines two tricky things, hot/unplug and migration. -> We need to let libvirt know what's happening. Add new qmp events and a new migration state. When a primary device is (partially) unplugged (only from guest) we send a qmp event with the device id. When it is unplugged from the guest the DEVICE_DELETED event is sent. Migration will enter the wait-unplug state while waiting for the guest os to unplug all primary devices and then move on with migration. 2. PCI devices are a precious ressource. The primary device should never be added to QEMU if it won't be used by guest instead of hiding it in QEMU. -> We only hotplug the device when the standby feature bit was negotiated. We save the device cmdline options until we need it for qdev_device_add() Hiding a device can be a useful concept to model. For example a pci device in a powered-off slot could be marked as hidden until the slot is powered on (mst). 3. Management layer software should handle this. Open Stack already has components/code to handle unplug/replug VFIO devices and metadata to provide to the guest for detecting which devices should be paired. -> An approach that includes all software from firmware to higher-level management software wasn't tried in the last years. This is an attempt to keep it simple and contained in QEMU as much as possible. One of the problems that stopped management software and libvirt from implementing this idea is that it can't be sure that it's possible to re-plug the primary device. By not freeing the devices resources in QEMU and only asking the guest OS to unplug it is possible to re-plug the device in case of a migration failure. 4. Hotplugging a device and then making it part of a failover setup is not possible -> addressed by extending qdev hotplug functions to check for hidden attribute, so e.g. device_add can be used to plug a device. I have tested this with a mlx5 and igb NIC and was able to migrate the VM. Command line example: qemu-system-x86_64 -enable-kvm -m 3072 -smp 3 \ -machine q35,kernel-irqchip=split -cpu host \ -serial stdio \ -net none \ -qmp unix:
[PATCH v5 03/11] pci: mark devices partially unplugged
Only the guest unplug request was triggered. This is needed for the failover feature. In case of a failed migration we need to plug the device back to the guest. Signed-off-by: Jens Freimann --- hw/pci/pcie.c| 3 +++ include/hw/pci/pci.h | 1 + 2 files changed, 4 insertions(+) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index a6beb567bd..19363ff8ce 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -456,6 +456,9 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque) { HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(dev)); +if (dev->partially_hotplugged) { +return; +} hotplug_handler_unplug(hotplug_ctrl, DEVICE(dev), &error_abort); object_unparent(OBJECT(dev)); } diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index def5435685..7b7eac845c 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -265,6 +265,7 @@ typedef struct PCIReqIDCache PCIReqIDCache; struct PCIDevice { DeviceState qdev; +bool partially_hotplugged; /* PCI config space */ uint8_t *config; -- 2.21.0
[PATCH v5 07/11] migration: allow unplug during migration for failover devices
In "b06424de62 migration: Disable hotplug/unplug during migration" we added a check to disable unplug for all devices until we have figured out what works. For failover primary devices qdev_unplug() is called from the migration handler, i.e. during migration. This patch adds a flag to DeviceState which is set to false for all devices and makes an exception for PCI devices that are also primary devices in a failover pair. Signed-off-by: Jens Freimann --- hw/core/qdev.c | 1 + hw/pci/pci.c | 1 + include/hw/qdev-core.h | 1 + qdev-monitor.c | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index f786650446..dc1289da86 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -995,6 +995,7 @@ static void device_initfn(Object *obj) dev->instance_id_alias = -1; dev->realized = false; +dev->allow_unplug_during_migration = false; object_property_add_bool(obj, "realized", device_get_realized, device_set_realized, NULL); diff --git a/hw/pci/pci.c b/hw/pci/pci.c index fa9b5219f8..8fbf32d68c 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2116,6 +2116,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) error_propagate(errp, local_err); return; } +qdev->allow_unplug_during_migration = true; } /* rom loading */ diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 710981af36..1518495b1e 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -156,6 +156,7 @@ struct DeviceState { bool pending_deleted_event; QemuOpts *opts; int hotplugged; +bool allow_unplug_during_migration; BusState *parent_bus; QLIST_HEAD(, NamedGPIOList) gpios; QLIST_HEAD(, BusState) child_bus; diff --git a/qdev-monitor.c b/qdev-monitor.c index 676a759fb4..bc6a41fa37 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -851,7 +851,7 @@ void qdev_unplug(DeviceState *dev, Error **errp) return; } -if (!migration_is_idle()) { +if (!migration_is_idle() && !dev->allow_unplug_during_migration) { error_setg(errp, "device_del not allowed while migrating"); return; } -- 2.21.0
[PATCH v5 02/11] pci: add option for net failover
This patch adds a net_failover_pair_id property to PCIDev which is used to link the primary device in a failover pair (the PCI dev) to a standby (a virtio-net-pci) device. It only supports ethernet devices. Also currently it only supports PCIe devices. QEMU will exit with an error message otherwise. Signed-off-by: Jens Freimann --- hw/pci/pci.c | 17 + include/hw/pci/pci.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index aa05c2b9b2..fa9b5219f8 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -75,6 +75,8 @@ static Property pci_props[] = { QEMU_PCIE_LNKSTA_DLLLA_BITNR, true), DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present, QEMU_PCIE_EXTCAP_INIT_BITNR, true), +DEFINE_PROP_STRING("net_failover_pair_id", PCIDevice, +net_failover_pair_id), DEFINE_PROP_END_OF_LIST() }; @@ -2077,6 +2079,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) ObjectClass *klass = OBJECT_CLASS(pc); Error *local_err = NULL; bool is_default_rom; +uint16_t class_id; /* initialize cap_present for pci_is_express() and pci_config_size(), * Note that hybrid PCIs are not set automatically and need to manage @@ -2101,6 +2104,20 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) } } +if (pci_dev->net_failover_pair_id) { +if (!pci_is_express(pci_dev)) { +error_setg(errp, "failover device is not a PCIExpress device"); +error_propagate(errp, local_err); +return; +} +class_id = pci_get_word(pci_dev->config + PCI_CLASS_DEVICE); +if (class_id != PCI_CLASS_NETWORK_ETHERNET) { +error_setg(errp, "failover device is not an Ethernet device"); +error_propagate(errp, local_err); +return; +} +} + /* rom loading */ is_default_rom = false; if (pci_dev->romfile == NULL && pc->romfile != NULL) { diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index f3f0ffd5fb..def5435685 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -352,6 +352,9 @@ struct PCIDevice { MSIVectorUseNotifier msix_vector_use_notifier; MSIVectorReleaseNotifier msix_vector_release_notifier; MSIVectorPollNotifier msix_vector_poll_notifier; + +/* ID of standby device in net_failover pair */ +char *net_failover_pair_id; }; void pci_register_bar(PCIDevice *pci_dev, int region_num, -- 2.21.0
[PATCH v5 04/11] pci: mark device having guest unplug request pending
Set pending_deleted_event in DeviceState for failover primary devices that were successfully unplugged by the Guest OS. Signed-off-by: Jens Freimann --- hw/pci/pcie.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 19363ff8ce..08718188bb 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -457,6 +457,7 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque) HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(dev)); if (dev->partially_hotplugged) { +dev->qdev.pending_deleted_event = false; return; } hotplug_handler_unplug(hotplug_ctrl, DEVICE(dev), &error_abort); @@ -476,6 +477,8 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, return; } +dev->pending_deleted_event = true; + /* In case user cancel the operation of multi-function hot-add, * remove the function that is unexposed to guest individually, * without interaction with guest. -- 2.21.0
Re: [PATCH v3 07/16] libqos: enforce Device Initialization order
On Tue, Oct 22, 2019 at 08:48:31PM +0200, Thomas Huth wrote: > On 22/10/2019 17.48, Stefan Hajnoczi wrote: > > On Mon, Oct 21, 2019 at 02:15:53PM +0200, Thomas Huth wrote: > >> On 19/10/2019 08.38, Stefan Hajnoczi wrote: > >>> According to VIRTIO 1.1 "3.1.1 Driver Requirements: Device > >>> Initialization", configuration space and virtqueues cannot be accessed > >>> before features have been negotiated. Enforce this requirement. > >>> > >>> Signed-off-by: Stefan Hajnoczi > >>> --- > >>> tests/libqos/virtio.c | 11 +++ > >>> 1 file changed, 11 insertions(+) > >>> > >>> diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c > >>> index 4f7e6bb8a1..2593996c98 100644 > >>> --- a/tests/libqos/virtio.c > >>> +++ b/tests/libqos/virtio.c > >>> @@ -13,23 +13,33 @@ > >>> #include "standard-headers/linux/virtio_config.h" > >>> #include "standard-headers/linux/virtio_ring.h" > >>> > >>> +/* Features must be negotiated before config space or virtqueue access */ > >>> +static void check_features_negotiated(QVirtioDevice *d) > >>> +{ > >>> +g_assert_cmphex(d->features, !=, 0); > >>> +} > >> > >> Isn't it "legal" to negotiate 0 feature bits, too (for legacy devices)? > > > > Yes, it's possible for Legacy devices. If someone ever does that > > they'll need to extend this code, but it's unlikely so I'd rather not > > complicate this. > > Could you please add at least a comment here with that explanation? I'll try adding a bool field in v4 so there are no problems with a 0 feature bit set. Stefan signature.asc Description: PGP signature
[PATCH v5 09/11] libqos: tolerate wait-unplug migration state
Signed-off-by: Jens Freimann --- tests/libqos/libqos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c index d71557c5cb..f229eb2cb8 100644 --- a/tests/libqos/libqos.c +++ b/tests/libqos/libqos.c @@ -125,7 +125,8 @@ void migrate(QOSState *from, QOSState *to, const char *uri) break; } -if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)) { +if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0) +|| (strcmp(st, "wait-unplug") == 0)) { qobject_unref(rsp); g_usleep(5000); continue; -- 2.21.0
[Bug 1575561] Re: config qemu virtio_queue_size to 1024,create vm boot from network failed
Which version of QEMU were you using here? Can you still reproduce this issue with the latest version of QEMU? If so, please also provide the full command line parameters that you used to start QEMU. ** Changed in: qemu Status: New => Incomplete -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1575561 Title: config qemu virtio_queue_size to 1024,create vm boot from network failed Status in QEMU: Incomplete Bug description: config qemu virtio_queue_size to 1024,create vm boot from network failed。 in the vm vncviewer,see the error log: “ERROR queue size 1024 > 256 could not open net0: no such file or directory" To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1575561/+subscriptions
[PATCH v5 06/11] qapi: add failover negotiated event
This event is sent to let libvirt know that VIRTIO_NET_F_STANDBY feature was not negotiated during virtio feature negotiation. If this event is received it means any primary devices hotplugged before this were were never really added to QEMU devices. Signed-off-by: Jens Freimann --- qapi/net.json | 16 1 file changed, 16 insertions(+) diff --git a/qapi/net.json b/qapi/net.json index 728990f4fb..8c5f3f1fb2 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -737,3 +737,19 @@ ## { 'command': 'announce-self', 'boxed': true, 'data' : 'AnnounceParameters'} + +## +# @FAILOVER_NEGOTIATED: +# +# Emitted when VIRTIO_NET_F_STANDBY was negotiated during feature negotiation +# +# Since: 4.2 +# +# Example: +# +# <- { "event": "FAILOVER_NEGOTIATED", +# "data": {} } +# +## +{ 'event': 'FAILOVER_NEGOTIATED', + 'data': {} } -- 2.21.0
[PATCH v5 05/11] qapi: add unplug primary event
This event is emitted when we sent a request to unplug a failover primary device from the Guest OS and it includes the device id of the primary device. Signed-off-by: Jens Freimann --- qapi/migration.json | 19 +++ 1 file changed, 19 insertions(+) diff --git a/qapi/migration.json b/qapi/migration.json index 82feb5bd39..52e69e2868 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1448,3 +1448,22 @@ # Since: 3.0 ## { 'command': 'migrate-pause', 'allow-oob': true } + +## +# @UNPLUG_PRIMARY: +# +# Emitted from source side of a migration when migration state is +# WAIT_UNPLUG. Device was unplugged by guest operating system. +# Device resources in QEMU are kept on standby to be able to re-plug it in case +# of migration failure. +# +# @device_id: QEMU device id of the unplugged device +# +# Since: 4.2 +# +# Example: +# {"event": "UNPLUG_PRIMARY", "data": {"device_id": "hostdev0"} } +# +## +{ 'event': 'UNPLUG_PRIMARY', + 'data': { 'device_id': 'str' } } -- 2.21.0
[PATCH v5 10/11] net/virtio: add failover support
This patch adds support to handle failover device pairs of a virtio-net device and a vfio-pci device, where the virtio-net acts as the standby device and the vfio-pci device as the primary. The general idea is that we have a pair of devices, a vfio-pci and a emulated (virtio-net) device. Before migration the vfio device is unplugged and data flows to the emulated device, on the target side another vfio-pci device is plugged in to take over the data-path. In the guest the net_failover module will pair net devices with the same MAC address. To achieve this we need: 1. Provide a callback function for the should_be_hidden DeviceListener. It is called when the primary device is plugged in. Evaluate the QOpt passed in to check if it is the matching primary device. It returns two values: - one to signal if the device to be added is the matching primary device - another one to signal to qdev if it should actually continue with adding the device or skip it. In the latter case it stores the device options in the VirtioNet struct and the device is added once the VIRTIO_NET_F_STANDBY feature is negotiated during virtio feature negotiation. If the virtio-net devices are not realized at the time the vfio-pci devices are realized, we need to connect the devices later. This way we make sure primary and standby devices can be specified in any order. 2. Register a callback for migration status notifier. When called it will unplug its primary device before the migration happens. 3. Register a callback for the migration code that checks if a device needs to be unplugged from the guest. Signed-off-by: Jens Freimann --- hw/net/virtio-net.c| 302 + include/hw/virtio/virtio-net.h | 12 ++ include/hw/virtio/virtio.h | 1 + 3 files changed, 315 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 9f11422337..cccaf77bde 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qemu/atomic.h" #include "qemu/iov.h" #include "qemu/main-loop.h" #include "qemu/module.h" @@ -21,6 +22,10 @@ #include "net/tap.h" #include "qemu/error-report.h" #include "qemu/timer.h" +#include "qemu/option.h" +#include "qemu/option_int.h" +#include "qemu/config-file.h" +#include "qapi/qmp/qdict.h" #include "hw/virtio/virtio-net.h" #include "net/vhost_net.h" #include "net/announce.h" @@ -28,11 +33,15 @@ #include "qapi/error.h" #include "qapi/qapi-events-net.h" #include "hw/qdev-properties.h" +#include "qapi/qapi-types-migration.h" +#include "qapi/qapi-events-migration.h" #include "hw/virtio/virtio-access.h" #include "migration/misc.h" #include "standard-headers/linux/ethtool.h" #include "sysemu/sysemu.h" #include "trace.h" +#include "monitor/qdev.h" +#include "hw/pci/pci.h" #define VIRTIO_NET_VM_VERSION11 @@ -746,9 +755,99 @@ static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n) return virtio_net_guest_offloads_by_features(vdev->guest_features); } +static void failover_add_primary(VirtIONet *n, Error **errp) +{ +Error *err = NULL; + +n->primary_device_opts = qemu_opts_find(qemu_find_opts("device"), +n->primary_device_id); +if (n->primary_device_opts) { +n->primary_dev = qdev_device_add(n->primary_device_opts, &err); +if (err) { +qemu_opts_del(n->primary_device_opts); +} +if (n->primary_dev) { +n->primary_bus = n->primary_dev->parent_bus; +if (err) { +qdev_unplug(n->primary_dev, &err); +qdev_set_id(n->primary_dev, ""); + +} +} +} else { +error_setg(errp, "Primary device not found"); +error_append_hint(errp, "Virtio-net failover will not work. Make " +"sure primary device has parameter" +" net_failover_pair_id=\n"); +} +if (err) { +error_propagate(errp, err); +} +} + +static int is_my_primary(void *opaque, QemuOpts *opts, Error **errp) +{ +VirtIONet *n = opaque; +int ret = 0; + +const char *standby_id = qemu_opt_get(opts, "net_failover_pair_id"); + +if (standby_id != NULL && (g_strcmp0(standby_id, n->netclient_name) == 0)) { +n->primary_device_id = g_strdup(opts->id); +ret = 1; +} + +return ret; +} + +static DeviceState *virtio_net_find_primary(VirtIONet *n, Error **errp) +{ +DeviceState *dev = NULL; +Error *err = NULL; + +if (qemu_opts_foreach(qemu_find_opts("device"), + is_my_primary, n, &err)) { +if (err) { +error_propagate(errp, err); +return NULL; +} +if (n->primary_device_id) { +dev = qdev_find_recursive(sysbus_get_default(), +n->primary_device_id); +} else { +error_setg(errp, "Primary device id not found"); +retur
[PATCH v5 08/11] migration: add new migration state wait-unplug
This patch adds a new migration state called wait-unplug. It is entered after the SETUP state if failover devices are present. It will transition into ACTIVE once all devices were succesfully unplugged from the guest. So if a guest doesn't respond or takes long to honor the unplug request the user will see the migration state 'wait-unplug'. In the migration thread we query failover devices if they're are still pending the guest unplug. When all are unplugged the migration continues. If one device won't unplug migration will stay in wait_unplug state. Signed-off-by: Jens Freimann --- include/migration/vmstate.h | 2 ++ migration/migration.c | 21 + migration/migration.h | 3 +++ migration/savevm.c | 36 migration/savevm.h | 2 ++ qapi/migration.json | 5 - 6 files changed, 68 insertions(+), 1 deletion(-) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index b9ee563aa4..ac4f46a67d 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -186,6 +186,8 @@ struct VMStateDescription { int (*pre_save)(void *opaque); int (*post_save)(void *opaque); bool (*needed)(void *opaque); +bool (*dev_unplug_pending)(void *opaque); + const VMStateField *fields; const VMStateDescription **subsections; }; diff --git a/migration/migration.c b/migration/migration.c index 3febd0f8f3..51764f2565 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -52,6 +52,7 @@ #include "hw/qdev-properties.h" #include "monitor/monitor.h" #include "net/announce.h" +#include "qemu/queue.h" #define MAX_THROTTLE (32 << 20) /* Migration transfer speed throttling */ @@ -819,6 +820,7 @@ bool migration_is_setup_or_active(int state) case MIGRATION_STATUS_SETUP: case MIGRATION_STATUS_PRE_SWITCHOVER: case MIGRATION_STATUS_DEVICE: +case MIGRATION_STATUS_WAIT_UNPLUG: return true; default: @@ -954,6 +956,9 @@ static void fill_source_migration_info(MigrationInfo *info) case MIGRATION_STATUS_CANCELLED: info->has_status = true; break; +case MIGRATION_STATUS_WAIT_UNPLUG: +info->has_status = true; +break; } info->status = s->state; } @@ -1694,6 +1699,7 @@ bool migration_is_idle(void) case MIGRATION_STATUS_COLO: case MIGRATION_STATUS_PRE_SWITCHOVER: case MIGRATION_STATUS_DEVICE: +case MIGRATION_STATUS_WAIT_UNPLUG: return false; case MIGRATION_STATUS__MAX: g_assert_not_reached(); @@ -3264,6 +3270,19 @@ static void *migration_thread(void *opaque) qemu_savevm_state_setup(s->to_dst_file); +if (qemu_savevm_nr_failover_devices()) { +migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, + MIGRATION_STATUS_WAIT_UNPLUG); + +while (s->state == MIGRATION_STATUS_WAIT_UNPLUG && +!qemu_savevm_state_guest_unplug_pending()) { +qemu_sem_timedwait(&s->wait_unplug_sem, 250); +} + +migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, +MIGRATION_STATUS_ACTIVE); +} + s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start; migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_ACTIVE); @@ -3511,6 +3530,7 @@ static void migration_instance_finalize(Object *obj) qemu_mutex_destroy(&ms->qemu_file_lock); g_free(params->tls_hostname); g_free(params->tls_creds); +qemu_sem_destroy(&ms->wait_unplug_sem); qemu_sem_destroy(&ms->rate_limit_sem); qemu_sem_destroy(&ms->pause_sem); qemu_sem_destroy(&ms->postcopy_pause_sem); @@ -3556,6 +3576,7 @@ static void migration_instance_init(Object *obj) qemu_sem_init(&ms->postcopy_pause_rp_sem, 0); qemu_sem_init(&ms->rp_state.rp_sem, 0); qemu_sem_init(&ms->rate_limit_sem, 0); +qemu_sem_init(&ms->wait_unplug_sem, 0); qemu_mutex_init(&ms->qemu_file_lock); } diff --git a/migration/migration.h b/migration/migration.h index 4f2fe193dc..79b3dda146 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -206,6 +206,9 @@ struct MigrationState /* Flag set once the migration thread called bdrv_inactivate_all */ bool block_inactive; +/* Migration is waiting for guest to unplug device */ +QemuSemaphore wait_unplug_sem; + /* Migration is paused due to pause-before-switchover */ QemuSemaphore pause_sem; diff --git a/migration/savevm.c b/migration/savevm.c index 8d95e261f6..0f18dea49e 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1113,6 +1113,42 @@ void qemu_savevm_state_header(QEMUFile *f) } } +int qemu_savevm_nr_failover_devices(void) +{ +SaveStateEntry *se; +int n = 0; + +QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { +if (se->vmsd && se->vmsd->dev_unplug_pending) { +n++; +} +} + +return
[Bug 1596579] Re: segfault upon reboot
Can you reproduce this problem with the latest upstream version of QEMU (currently version 4.1)? Or is it only reproducible in the qemu-kvm from your distribution? (In the latter case, please report this bug to your distro instead) ** Changed in: qemu Status: New => Incomplete -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1596579 Title: segfault upon reboot Status in QEMU: Incomplete Bug description: [ 31.167946] VFIO - User Level meta-driver version: 0.3 [ 34.969182] kvm: zapping shadow pages for mmio generation wraparound [ 43.095077] vfio-pci :1a:00.0: irq 50 for MSI/MSI-X [166493.891331] perf interrupt took too long (2506 > 2500), lowering kernel.perf_event_max_sample_rate to 5 [315765.858431] qemu-kvm[1385]: segfault at 0 ip (null) sp 7ffe5430db18 error 14 [315782.002077] vfio-pci :1a:00.0: transaction is not cleared; proceeding with reset anyway [315782.910854] mptsas :1a:00.0: Refused to change power state, currently in D3 [315782.911236] mptbase: ioc1: Initiating bringup [315782.911238] mptbase: ioc1: WARNING - Unexpected doorbell active! [315842.957613] mptbase: ioc1: ERROR - Failed to come READY after reset! IocState=f000 [315842.957670] mptbase: ioc1: WARNING - ResetHistory bit failed to clear! [315842.957675] mptbase: ioc1: ERROR - Diagnostic reset FAILED! (h) [315842.957717] mptbase: ioc1: WARNING - NOT READY WARNING! [315842.957720] mptbase: ioc1: ERROR - didn't initialize properly! (-1) [315842.957890] mptsas: probe of :1a:00.0 failed with error -1 The qemu-kvm segfault happens when I issue a reboot on the Windows VM. The card I have is: 1a:00.0 SCSI storage controller: LSI Logic / Symbios Logic SAS1068E PCI-Express Fusion-MPT SAS (rev ff) I have two of these cards (bought with many years difference), exact same model, and they fail the same way. I'm using PCI passthrough on this card for access to the tape drive. This is very easy to reproduce, so feel free to let me know what to try. Kernel 3.10.0-327.18.2.el7.x86_64 (Centos 7.2.1511). qemu-kvm-1.5.3-105.el7_2.4.x86_64 Reporting it here because of the segfault, but I guess I might have to open a bug report with mptbase as well? To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1596579/+subscriptions
[PATCH v5 11/11] vfio: unplug failover primary device before migration
As usual block all vfio-pci devices from being migrated, but make an exception for failover primary devices. This is achieved by setting unmigratable to 0 but also add a migration blocker for all vfio-pci devices except failover primary devices. These will be unplugged before migration happens by the migration handler of the corresponding virtio-net standby device. Signed-off-by: Jens Freimann --- hw/vfio/pci.c | 26 -- hw/vfio/pci.h | 1 + 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 12fac39804..5dadfec6e8 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -40,6 +40,7 @@ #include "pci.h" #include "trace.h" #include "qapi/error.h" +#include "migration/blocker.h" #define TYPE_VFIO_PCI "vfio-pci" #define PCI_VFIO(obj)OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI) @@ -2732,6 +2733,17 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) return; } +if (!pdev->net_failover_pair_id) { +error_setg(&vdev->migration_blocker, +"VFIO device doesn't support migration"); +ret = migrate_add_blocker(vdev->migration_blocker, &err); +if (err) { +error_propagate(errp, err); +error_free(vdev->migration_blocker); +return; +} +} + vdev->vbasedev.name = g_path_get_basename(vdev->vbasedev.sysfsdev); vdev->vbasedev.ops = &vfio_pci_ops; vdev->vbasedev.type = VFIO_DEVICE_TYPE_PCI; @@ -3008,6 +3020,10 @@ out_teardown: vfio_bars_exit(vdev); error: error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name); +if (vdev->migration_blocker) { +migrate_del_blocker(vdev->migration_blocker); +error_free(vdev->migration_blocker); +} } static void vfio_instance_finalize(Object *obj) @@ -3019,6 +3035,10 @@ static void vfio_instance_finalize(Object *obj) vfio_bars_finalize(vdev); g_free(vdev->emulated_config_bits); g_free(vdev->rom); +if (vdev->migration_blocker) { +migrate_del_blocker(vdev->migration_blocker); +error_free(vdev->migration_blocker); +} /* * XXX Leaking igd_opregion is not an oversight, we can't remove the * fw_cfg entry therefore leaking this allocation seems like the safest @@ -3151,11 +3171,6 @@ static Property vfio_pci_dev_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static const VMStateDescription vfio_pci_vmstate = { -.name = "vfio-pci", -.unmigratable = 1, -}; - static void vfio_pci_dev_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -3163,7 +3178,6 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data) dc->reset = vfio_pci_reset; dc->props = vfio_pci_dev_properties; -dc->vmsd = &vfio_pci_vmstate; dc->desc = "VFIO-based PCI device assignment"; set_bit(DEVICE_CATEGORY_MISC, dc->categories); pdc->realize = vfio_realize; diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index 834a90d646..b329d50338 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -168,6 +168,7 @@ typedef struct VFIOPCIDevice { bool no_vfio_ioeventfd; bool enable_ramfb; VFIODisplay *dpy; +Error *migration_blocker; } VFIOPCIDevice; uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); -- 2.21.0
Re: [PATCH v3 09/16] libqos: access VIRTIO 1.0 vring in little-endian
On Tue, Oct 22, 2019 at 06:51:39PM +0200, Christophe de Dinechin wrote: > > Stefan Hajnoczi writes: > [...] > > +static uint16_t qvirtio_readw(QVirtioDevice *d, QTestState *qts, uint64_t > > addr) > > +{ > > +uint16_t val = qtest_readw(qts, addr); > > + > > +if (d->features & (1ull << VIRTIO_F_VERSION_1) && > > qtest_big_endian(qts)) { > > For my education, I was wondering why tests use the (1ull << FEATURE) > notation and not an equivalent of virtio_has_feature()? Is this > intentional, or just legacy? It's historical, libqos never defined an equivalent helper function. Stefan signature.asc Description: PGP signature
Re: [PATCH v10 3/3] iotests: test nbd reconnect
23.10.2019 4:31, Eric Blake wrote: > On 10/9/19 3:41 AM, Vladimir Sementsov-Ogievskiy wrote: >> Add test, which starts backup to nbd target and restarts nbd server >> during backup. >> >> Signed-off-by: Vladimir Sementsov-Ogievskiy >> --- >> tests/qemu-iotests/264 | 95 +++ >> tests/qemu-iotests/264.out | 13 + >> tests/qemu-iotests/group | 1 + >> tests/qemu-iotests/iotests.py | 11 >> 4 files changed, 120 insertions(+) >> create mode 100755 tests/qemu-iotests/264 >> create mode 100644 tests/qemu-iotests/264.out >> >> diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264 >> new file mode 100755 >> index 00..c8cd97ae2b >> --- /dev/null >> +++ b/tests/qemu-iotests/264 > >> +import iotests >> +from iotests import qemu_img_create, qemu_io_silent_check, file_path, \ >> + qemu_nbd_popen, log >> + >> +disk_a, disk_b, nbd_sock = file_path('disk_a', 'disk_b', 'nbd-sock') >> +nbd_uri = 'nbd+unix:///?socket=' + nbd_sock > > Needs rebasing on top of Max's patches to stick sockets in SOCK_DIR: > > https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg04201.html > > [or, if my pull request lands first, Max needs to add this one to the list of > affected tests...] > > >> +vm.qmp_log('blockdev-add', filters=[iotests.filter_qmp_testfiles], >> + **{'node_name': 'backup0', >> + 'driver': 'raw', >> + 'file': {'driver': 'nbd', >> + 'server': {'type': 'unix', 'path': nbd_sock}, >> + 'reconnect-delay': 10}}) >> +vm.qmp_log('blockdev-backup', device='drive0', sync='full', >> target='backup0', >> + speed=(1 * 1024 * 1024)) > > This starts the job throttled, to give us time... > >> + >> +# Wait for some progress >> +t = 0 >> +while t < wait_limit: >> + jobs = vm.qmp('query-block-jobs')['return'] >> + if jobs and jobs[0]['offset'] > 0: >> + break >> + time.sleep(wait_step) >> + t += wait_step >> + >> +if jobs and jobs[0]['offset'] > 0: >> + log('Backup job is started') >> + >> +log('Kill NBD server') >> +srv.kill() >> +srv.wait() >> + >> +jobs = vm.qmp('query-block-jobs')['return'] >> +if jobs and jobs[0]['offset'] < jobs[0]['len']: >> + log('Backup job is still in progress') >> + >> +vm.qmp_log('block-job-set-speed', device='drive0', speed=0) >> + >> +# Emulate server down time for 1 second >> +time.sleep(1) > > ...but once we restart,... > >> + >> +log('Start NBD server') >> +srv = qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b) >> + >> +e = vm.event_wait('BLOCK_JOB_COMPLETED') > > ...should we unthrottle the job to allow the test to complete slightly faster > after the reconnect? But that can be done as an improvement on top, if it > helps. It is done above, before time.sleep(1) > > >> +++ b/tests/qemu-iotests/iotests.py >> @@ -165,6 +165,13 @@ def qemu_io_silent(*args): >> (-exitcode, ' '.join(args))) >> return exitcode >> +def qemu_io_silent_check(*args): >> + '''Run qemu-io and return the true if subprocess returned 0''' >> + args = qemu_io_args + list(args) >> + exitcode = subprocess.call(args, stdout=open('/dev/null', 'w'), >> + stderr=subprocess.STDOUT) > > This discards the stdout data, even on failure. Is there a smarter way to > grab the output into a variable, but only dump it to the log on failure, > rather than outright discarding it? > > But for the sake of getting this test in before freeze, that can be a > followup, if at all. > > Reviewed-by: Eric Blake > > I'll send a pull request soon. > Thank you!! -- Best regards, Vladimir
[PATCH v3] net: add tulip (dec21143) driver
This adds the basic functionality to emulate a Tulip NIC. Implemented are: - RX and TX functionality - Perfect Frame Filtering - Big/Little Endian descriptor support - 93C46 EEPROM support - LXT970 PHY Not implemented, mostly because i had no OS using these functions: - Imperfect frame filtering - General Purpose Timer - Transmit automatic polling - Boot ROM support - SIA interface - Big/Little Endian data buffer conversion Successfully tested with the following Operating Systems: - MSDOS with Microsoft Network Client 3.0 and DEC ODI drivers - HPPA Linux - Windows XP - HP-UX Signed-off-by: Sven Schnelle Message-Id: <20191022155413.4619-1-sv...@stackframe.org> Reviewed-by: Peter Maydell --- Changes in v3: - fix whitespace - fix format string in read/write functions Changes in v2: - changed tulip_desc_{read,write} to take a struct descriptor * and no longer use a single pci DMA write, instead write one struct member at a time. - fix _tulip_receive function name - fix reset function and provide tulip_qdev_reset() for dc->reset. - no longer write registers in the default case in tulip_write() - set .impl.min_access_size and .impl.max_access_size MAINTAINERS |6 + hw/net/Kconfig |5 + hw/net/Makefile.objs |1 + hw/net/trace-events | 14 + hw/net/tulip.c | 1029 ++ hw/net/tulip.h | 267 ++ include/hw/pci/pci_ids.h |1 + 7 files changed, 1323 insertions(+) create mode 100644 hw/net/tulip.c create mode 100644 hw/net/tulip.h diff --git a/MAINTAINERS b/MAINTAINERS index 250ce8e7a1..a12031c389 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1638,6 +1638,12 @@ M: Stefan Weil S: Maintained F: hw/net/eepro100.c +tulip +M: Sven Schnelle +S: Maintained +F: hw/net/tulip.c +F: hw/net/tulip.h + Generic Loader M: Alistair Francis S: Maintained diff --git a/hw/net/Kconfig b/hw/net/Kconfig index 4ef86dc3a5..3856417d42 100644 --- a/hw/net/Kconfig +++ b/hw/net/Kconfig @@ -24,6 +24,11 @@ config PCNET_PCI config PCNET_COMMON bool +config TULIP +bool +default y if PCI_DEVICES +depends on PCI + config E1000_PCI bool default y if PCI_DEVICES diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index 9904273b06..7907d2c199 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -13,6 +13,7 @@ common-obj-$(CONFIG_E1000E_PCI_EXPRESS) += e1000e.o e1000e_core.o e1000x_common. common-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o common-obj-$(CONFIG_VMXNET3_PCI) += net_tx_pkt.o net_rx_pkt.o common-obj-$(CONFIG_VMXNET3_PCI) += vmxnet3.o +common-obj-$(CONFIG_TULIP) += tulip.o common-obj-$(CONFIG_SMC91C111) += smc91c111.o common-obj-$(CONFIG_LAN9118) += lan9118.o diff --git a/hw/net/trace-events b/hw/net/trace-events index 58665655cc..e70f12bee1 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -367,3 +367,17 @@ virtio_net_announce_notify(void) "" virtio_net_announce_timer(int round) "%d" virtio_net_handle_announce(int round) "%d" virtio_net_post_load_device(void) + +# tulip.c +tulip_reg_write(uint64_t addr, const char *name, int size, uint64_t val) "addr 0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64 +tulip_reg_read(uint64_t addr, const char *name, int size, uint64_t val) "addr 0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64 +tulip_receive(const uint8_t *buf, size_t len) "buf %p size %zu" +tulip_descriptor(const char *prefix, uint32_t addr, uint32_t status, uint32_t control, uint32_t len1, uint32_t len2, uint32_t buf1, uint32_t buf2) "%s 0x%08x: status 0x%08x control 0x%03x len1 %4d len2 %4d buf1 0x%08x buf2 0x%08x" +tulip_rx_state(const char *state) "RX %s" +tulip_tx_state(const char *state) "TX %s" +tulip_irq(uint32_t mask, uint32_t en, const char *state) "mask 0x%08x ie 0x%08x %s" +tulip_mii_write(int phy, int reg, uint16_t data) "phy 0x%x reg 0x%x data 0x%04x" +tulip_mii_read(int phy, int reg, uint16_t data) "phy 0x%x, reg 0x%x data 0x%04x" +tulip_reset(void) "" +tulip_setup_frame(void) "" +tulip_setup_filter(int n, uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f) "%d: %02x:%02x:%02x:%02x:%02x:%02x" diff --git a/hw/net/tulip.c b/hw/net/tulip.c new file mode 100644 index 00..f74b08b375 --- /dev/null +++ b/hw/net/tulip.c @@ -0,0 +1,1029 @@ +/* + * QEMU TULIP Emulation + * + * Copyright (c) 2019 Sven Schnelle + * + * This work is licensed under the GNU GPL license version 2 or later. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/irq.h" +#include "hw/pci/pci.h" +#include "hw/qdev-properties.h" +#include "hw/nvram/eeprom93xx.h" +#include "migration/vmstate.h" +#include "sysemu/sysemu.h" +#include "tulip.h" +#include "trace.h" +#include "net/eth.h" + +typedef struct TULIPState { +PCIDevice dev; +MemoryRegion io; +MemoryRegion memory; +NICConf c; +qemu_irq irq; +NICState *nic; +eeprom_t *eeprom; +uint32_t csr[16]; + +/* state for MII */ +uint32_
Re: [PATCH v6 00/12] target/mips: Misc cleanups for September/October 2019
Patchew URL: https://patchew.org/QEMU/1571685097-15175-1-git-send-email-aleksandar.marko...@rt-rk.com/ Hi, This series seems to have some coding style problems. See output below for more information: Subject: [PATCH v6 00/12] target/mips: Misc cleanups for September/October 2019 Type: series Message-id: 1571685097-15175-1-git-send-email-aleksandar.marko...@rt-rk.com === TEST SCRIPT BEGIN === #!/bin/bash git rev-parse base > /dev/null || exit 0 git config --local diff.renamelimit 0 git config --local diff.renames True git config --local diff.algorithm histogram ./scripts/checkpatch.pl --mailback base.. === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 From https://github.com/patchew-project/qemu - [tag update] patchew/20191018092136.26581-1-eric.au...@redhat.com -> patchew/20191018092136.26581-1-eric.au...@redhat.com * [new tag] patchew/20191023082431.30780-1-pbonz...@redhat.com -> patchew/20191023082431.30780-1-pbonz...@redhat.com - [tag update] patchew/cover.1570208781.git.maozhon...@cmss.chinamobile.com -> patchew/cover.1570208781.git.maozhon...@cmss.chinamobile.com Switched to a new branch 'test' d09fef5 target/mips: msa: Split helpers for ASUB_. 30a6202 target/mips: msa: Split helpers for HSUB_. 308fc7a target/mips: msa: Split helpers for PCK. 32248b0 target/mips: msa: Split helpers for S. dad828f target/mips: msa: Split helpers for HADD_. f1c8a56 target/mips: msa: Split helpers for ADD<_A|S_A|S_S|S_U|V>. f5f90bf target/mips: msa: Split helpers for ILV. ce348ae target/mips: msa: Split helpers for _. 704c174 target/mips: msa: Split helpers for _A. 4fcd018 MAINTAINERS: Update mail address of Aleksandar Rikalo 7311d0a target/mips: Clean up op_helper.c c464bc9 target/mips: Clean up helper.c === OUTPUT BEGIN === 1/12 Checking commit c464bc9194b7 (target/mips: Clean up helper.c) 2/12 Checking commit 7311d0a646ea (target/mips: Clean up op_helper.c) ERROR: spaces required around that '*' (ctx:WxV) #1059: FILE: target/mips/op_helper.c:3871: + float_status *status) \ ^ total: 1 errors, 0 warnings, 1681 lines checked Patch 2/12 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. 3/12 Checking commit 4fcd018cf015 (MAINTAINERS: Update mail address of Aleksandar Rikalo) 4/12 Checking commit 704c174cc449 (target/mips: msa: Split helpers for _A.) 5/12 Checking commit ce348ae7e85b (target/mips: msa: Split helpers for _.) 6/12 Checking commit f5f90bf94e05 (target/mips: msa: Split helpers for ILV.) 7/12 Checking commit f1c8a567a523 (target/mips: msa: Split helpers for ADD<_A|S_A|S_S|S_U|V>.) 8/12 Checking commit dad828f28cc7 (target/mips: msa: Split helpers for HADD_.) 9/12 Checking commit 32248b0e5194 (target/mips: msa: Split helpers for S.) 10/12 Checking commit 308fc7adf033 (target/mips: msa: Split helpers for PCK.) 11/12 Checking commit 30a62025b560 (target/mips: msa: Split helpers for HSUB_.) 12/12 Checking commit d09fef515e58 (target/mips: msa: Split helpers for ASUB_.) === OUTPUT END === Test command exited with code: 1 The full log is available at http://patchew.org/logs/1571685097-15175-1-git-send-email-aleksandar.marko...@rt-rk.com/testing.checkpatch/?type=message. --- Email generated automatically by Patchew [https://patchew.org/]. Please send your feedback to patchew-de...@redhat.com
[Bug 1192464] Re: udp checksum computed as 0 not converted to 0xffff, from guest os that share a common linux bridge among multiple guest os
Question is where is this zero checksum observed which is not clear from the report. If in the guest it is certainly correct. If in the host it is correct so long as the bridge appears to have checksum offloading as well. If whatever interface the guest packets appear to come from is not set up with checksum offloading this is a bug which should be fixed by setting the offload flags to match the guest. If outside the host this is a problem. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1192464 Title: udp checksum computed as 0 not converted to 0x, from guest os that share a common linux bridge among multiple guest os Status in QEMU: Incomplete Bug description: UDP checksum computed as '0' during transmission of packets that uses e1000 NIC in the Guest as well as emulated h/w in the qemu layer, That needs to be converted to 0x, This occurs only when Hardware checksum offload is been set in the guest OS NIC and made it as a transmitter. The guest O.S use the N/W interface that is been shared to the linux brige created in the host (used source=) in the xml tags of libvirt. As per RFC768(http://tools.ietf.org/html/rfc768 [^]), If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care). To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1192464/+subscriptions
Re: [PATCH] virtio: fix IO request length in virtio SCSI/block #PSBM-78839
On 21.10.2019 16:24, Stefan Hajnoczi wrote: > On Fri, Oct 18, 2019 at 02:55:47PM +0300, Denis Plotnikov wrote: >> From: "Denis V. Lunev" >> >> Linux guests submit IO requests no longer than PAGE_SIZE * max_seg >> field reported by SCSI controler. Thus typical sequential read with >> 1 MB size results in the following pattern of the IO from the guest: >>8,16 115754 2.766095122 2071 D R 2095104 + 1008 [dd] >>8,16 115755 2.766108785 2071 D R 2096112 + 1008 [dd] >>8,16 115756 2.766113486 2071 D R 2097120 + 32 [dd] >>8,16 115757 2.767668961 0 C R 2095104 + 1008 [0] >>8,16 115758 2.768534315 0 C R 2096112 + 1008 [0] >>8,16 115759 2.768539782 0 C R 2097120 + 32 [0] >> The IO was generated by >>dd if=/dev/sda of=/dev/null bs=1024 iflag=direct >> >> This effectively means that on rotational disks we will observe 3 IOPS >> for each 2 MBs processed. This definitely negatively affects both >> guest and host IO performance. >> >> The cure is relatively simple - we should report lengthy scatter-gather >> ability of the SCSI controller. Fortunately the situation here is very >> good. VirtIO transport layer can accomodate 1024 items in one request >> while we are using only 128. This situation is present since almost >> very beginning. 2 items are dedicated for request metadata thus we >> should publish VIRTQUEUE_MAX_SIZE - 2 as max_seg. >> >> The following pattern is observed after the patch: >>8,16 1 9921 2.662721340 2063 D R 2095104 + 1024 [dd] >>8,16 1 9922 2.662737585 2063 D R 2096128 + 1024 [dd] >>8,16 1 9923 2.665188167 0 C R 2095104 + 1024 [0] >>8,16 1 9924 2.665198777 0 C R 2096128 + 1024 [0] >> which is much better. >> >> The dark side of this patch is that we are tweaking guest visible >> parameter, though this should be relatively safe as above transport >> layer support is present in QEMU/host Linux for a very long time. >> The patch adds configurable property for VirtIO SCSI with a new default >> and hardcode option for VirtBlock which does not provide good >> configurable framework. >> >> Unfortunately the commit can not be applied as is. For the real cure we >> need guest to be fixed to accomodate that queue length, which is done >> only in the latest 4.14 kernel. Thus we are going to expose the property >> and tweak it on machine type level. >> >> The problem with the old kernels is that they have >> max_segments <= virtqueue_size restriction which cause the guest >> crashing in the case of violation. >> To fix the case described above in the old kernels we can increase >> virtqueue_size to 256 and max_segments to 254. The pitfall here is >> that seabios allows the virtqueue_size-s < 128, however, the seabios >> patch extending that value to 256 is pending. > If I understand correctly you are relying on Indirect Descriptor support > in the guest driver in order to exceed the Virtqueue Descriptor Table > size. > > Unfortunately the "max_segments <= virtqueue_size restriction" is > required by the VIRTIO 1.1 specification: > >2.6.5.3.1 Driver Requirements: Indirect Descriptors > >A driver MUST NOT create a descriptor chain longer than the Queue >Size of the device. > > So this idea seems to be in violation of the specification? > > There is a bug in hw/block/virtio-blk.c:virtio_blk_update_config() and > hw/scsi/virtio-scsi.c:virtio_scsi_get_config(): > >virtio_stl_p(vdev, &blkcfg.seg_max, 128 - 2); > > This number should be the minimum of blk_get_max_iov() and > virtio_queue_get_num(), minus 2 for the header and footer. Stefan, It seems VitrioSCSI don't have a direct link to blk, apart of VirtIOBlock->blk, and the link to a blk comes with each scsi request. I suspect that idea here is that a single virtioscsi can serve several blk-s. If my assumption is corect, then we can't get blk_get_max_iov() on virtioscsi configuration stage and we shouldn't take into account max_iov and limit max_segments with virtio_queue_get_num()-2 only. Is it so, or is there any other details to take into account? Thanks! Denis > > I looked at the Linux SCSI driver code and it seems each HBA has a > single max_segments number - it does not vary on a per-device basis. > This could be a problem if two host block device with different > max_segments are exposed to the guest through the same virtio-scsi > controller. Another bug? :( > > Anyway, if you want ~1024 descriptors you should set Queue Size to 1024. > I don't see a spec-compliant way of doing it otherwise. Hopefully I > have overlooked something and there is a nice way to solve this. > > Stefan
Re: [PATCH v4 1/3] tests/migration: mem leak fix
Le 04/10/2019 à 19:32, Mao Zhongyi a écrit : > ‘data’ has the possibility of memory leaks, so use the > glib macros g_autofree recommended by CODING_STYLE.rst > to automatically release the memory that returned from > g_malloc(). > > Signed-off-by: Mao Zhongyi > Reviewed-by: Alex Bennée > --- > tests/migration/stress.c | 21 ++--- > 1 file changed, 2 insertions(+), 19 deletions(-) > > diff --git a/tests/migration/stress.c b/tests/migration/stress.c > index d9aa4afe92..d8a6f64af0 100644 > --- a/tests/migration/stress.c > +++ b/tests/migration/stress.c > @@ -170,26 +170,14 @@ static unsigned long long now(void) > static int stressone(unsigned long long ramsizeMB) > { > size_t pagesPerMB = 1024 * 1024 / PAGE_SIZE; > -char *ram = malloc(ramsizeMB * 1024 * 1024); > +g_autofree char *ram = g_malloc(ramsizeMB * 1024 * 1024); > char *ramptr; > size_t i, j, k; > -char *data = malloc(PAGE_SIZE); > +g_autofree char *data = g_malloc(PAGE_SIZE); > char *dataptr; > size_t nMB = 0; > unsigned long long before, after; > > -if (!ram) { > -fprintf(stderr, "%s (%05d): ERROR: cannot allocate %llu MB of RAM: > %s\n", > -argv0, gettid(), ramsizeMB, strerror(errno)); > -return -1; > -} > -if (!data) { > -fprintf(stderr, "%s (%d): ERROR: cannot allocate %d bytes of RAM: > %s\n", > -argv0, gettid(), PAGE_SIZE, strerror(errno)); > -free(ram); > -return -1; > -} > - > /* We don't care about initial state, but we do want > * to fault it all into RAM, otherwise the first iter > * of the loop below will be quite slow. We cna't use > @@ -198,8 +186,6 @@ static int stressone(unsigned long long ramsizeMB) > memset(ram, 0xfe, ramsizeMB * 1024 * 1024); > > if (random_bytes(data, PAGE_SIZE) < 0) { > -free(ram); > -free(data); > return -1; > } > > @@ -227,9 +213,6 @@ static int stressone(unsigned long long ramsizeMB) > } > } > } > - > -free(data); > -free(ram); > } > > > Reviewed-by: Laurent Vivier
Re: [PATCH 2/2] virtiofsd: move to a new pid namespace
* Stefan Hajnoczi (stefa...@redhat.com) wrote: > virtiofsd needs access to /proc/self/fd. Let's move to a new pid > namespace so that a compromised process cannot see another other > processes running on the system. > > One wrinkle in this approach: unshare(CLONE_NEWPID) affects *child* > processes and not the current process. Therefore we need to fork the > pid 1 process that will actually run virtiofsd and leave a parent in > waitpid(2). This is not the same thing as daemonization and parent > processes should not notice a difference. > > Signed-off-by: Stefan Hajnoczi OK, I think that's OK (I don't know the mount semantics that well). Reviewed-by: Dr. David Alan Gilbert > --- > contrib/virtiofsd/passthrough_ll.c | 95 ++ > 1 file changed, 72 insertions(+), 23 deletions(-) > > diff --git a/contrib/virtiofsd/passthrough_ll.c > b/contrib/virtiofsd/passthrough_ll.c > index c27ff7d800..b6ee9b2e90 100644 > --- a/contrib/virtiofsd/passthrough_ll.c > +++ b/contrib/virtiofsd/passthrough_ll.c > @@ -56,9 +56,12 @@ > #include > #include > #include > +#include > #include > +#include > #include > > + > #include "ireg.h" > #include > #include > @@ -2749,6 +2752,72 @@ static void setup_net_namespace(void) > } > } > > +/* > + * Move to a new pid namespace to prevent access to other processes if this > + * process is compromised. > + */ > +static void setup_pid_namespace(void) > +{ > + pid_t child; > + > + /* > + * Create a new pid namespace for *child* processes. We'll have to > + * fork in order to enter the new pid namespace. A new mount namespace > + * is also needed so that we can remount /proc for the new pid > + * namespace. > + */ > + if (unshare(CLONE_NEWPID | CLONE_NEWNS) != 0) { > + fuse_log(FUSE_LOG_ERR, "unshare(CLONE_NEWPID | CLONE_NEWNS): > %m\n"); > + exit(1); > + } > + > + child = fork(); > + if (child < 0) { > + fuse_log(FUSE_LOG_ERR, "fork() failed: %m\n"); > + exit(1); > + } > + if (child > 0) { > + pid_t waited; > + int wstatus; > + > + /* The parent waits for the child */ > + do { > + waited = waitpid(child, &wstatus, 0); > + } while (waited < 0 && errno == EINTR); > + > + if (WIFEXITED(wstatus)) { > + exit(WEXITSTATUS(wstatus)); > + } > + > + exit(1); > + } > + > + /* > + * If the mounts have shared propagation then we want to opt out so our > + * mount changes don't affect the parent mount namespace. > + */ > + if (mount(NULL, "/", NULL, MS_REC|MS_SLAVE, NULL) < 0) { > + fuse_log(FUSE_LOG_ERR, "mount(/, MS_REC|MS_SLAVE): %m\n"); > + exit(1); > + } > + > + /* The child must remount /proc to use the new pid namespace */ > + if (mount("proc", "/proc", "proc", > + MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_RELATIME, NULL) < 0) { > + fuse_log(FUSE_LOG_ERR, "mount(/proc): %m\n"); > + exit(1); > + } > +} > + > +static void setup_proc_self_fd(struct lo_data *lo) > +{ > + lo->proc_self_fd = open("/proc/self/fd", O_PATH); > + if (lo->proc_self_fd == -1) { > + fuse_log(FUSE_LOG_ERR, "open(/proc/self/fd, O_PATH): %m\n"); > + exit(1); > + } > +} > + > /* This magic is based on lxc's lxc_pivot_root() */ > static void setup_pivot_root(const char *source) > { > @@ -2803,20 +2872,10 @@ static void setup_pivot_root(const char *source) > > /* > * Make the source directory our root so symlinks cannot escape and no other > - * files are accessible. > + * files are accessible. Assumes unshare(CLONE_NEWNS) was already called. > */ > static void setup_mount_namespace(const char *source) > { > - if (unshare(CLONE_NEWNS) != 0) { > - fuse_log(FUSE_LOG_ERR, "unshare(CLONE_NEWNS): %m\n"); > - exit(1); > - } > - > - if (mount(NULL, "/", NULL, MS_REC|MS_SLAVE, NULL) < 0) { > - fuse_log(FUSE_LOG_ERR, "mount(/, MS_REC|MS_PRIVATE): %m\n"); > - exit(1); > - } > - > if (mount(source, source, NULL, MS_BIND, NULL) < 0) { > fuse_log(FUSE_LOG_ERR, "mount(%s, %s, MS_BIND): %m\n", source, > source); > exit(1); > @@ -2831,6 +2890,8 @@ static void setup_mount_namespace(const char *source) > */ > static void setup_sandbox(struct lo_data *lo, bool enable_syslog) > { > + setup_pid_namespace(); > + setup_proc_self_fd(lo); > setup_net_namespace(); > setup_mount_namespace(lo->source); > setup_seccomp(enable_syslog); > @@ -2860,15 +2921,6 @@ static void setup_root(struct lo_data *lo, struct > lo_inode *root) > g_atomic_int_set(&root->refcount, 2); > } > > -static void setup_proc_self_fd(struct lo_data *lo) > -{ > - lo->proc_self_fd = open("/proc/self/fd"
[Bug 1847232] Re: qemu TCG in s390x mode issue with calculating HASH
Looks fixed to me ! The issue no longer shows even without specifying vx=off -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1847232 Title: qemu TCG in s390x mode issue with calculating HASH Status in QEMU: Fix Committed Bug description: When using go on s390x on Debian x64 (buster) (host) and debian s390x (sid) (guest) I run into the following problem : The following occurs while trying to build a custom project : go: github.com/FactomProject/basen@v0.0.0-20150613233007-fe3947df716e: Get https://proxy.golang.org/github.com/%21factom%21project/basen/@v/v0.0.0-20150613233007-fe3947df716e.mod: local error: tls: bad record MAC Doing a git bisect I find that this problem only occurs on and after commit 08ef92d556c584c7faf594ff3af46df456276e1b Before that commit, all works fine. Past this commit, build always fails. Without any proof, It looks like a hash calculation bug related to using z/Arch vector facilities... To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1847232/+subscriptions
[PATCH v4 04/16] virtio-scsi-test: add missing feature negotiation
VIRTIO Device Initialization requires feature negotiation. Currently virtio-scsi-test.c is non-compliant. libqos tests acknowledge all feature bits advertised by the device, except VIRTIO_F_BAD_FEATURE (which devices use to detect broken drivers!) and VIRTIO_RING_F_EVENT_IDX (which is not implemented in libqos and accepting it would break notifications). Signed-off-by: Stefan Hajnoczi --- tests/virtio-scsi-test.c | 8 1 file changed, 8 insertions(+) diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c index 7c8f9b27f8..0415e75876 100644 --- a/tests/virtio-scsi-test.c +++ b/tests/virtio-scsi-test.c @@ -123,10 +123,16 @@ static QVirtioSCSIQueues *qvirtio_scsi_init(QVirtioDevice *dev) QVirtioSCSIQueues *vs; const uint8_t test_unit_ready_cdb[VIRTIO_SCSI_CDB_SIZE] = {}; struct virtio_scsi_cmd_resp resp; +uint64_t features; int i; vs = g_new0(QVirtioSCSIQueues, 1); vs->dev = dev; + +features = qvirtio_get_features(dev); +features &= ~(QVIRTIO_F_BAD_FEATURE | (1ull << VIRTIO_RING_F_EVENT_IDX)); +qvirtio_set_features(dev, features); + vs->num_queues = qvirtio_config_readl(dev, 0); g_assert_cmpint(vs->num_queues, <, MAX_NUM_QUEUES); @@ -135,6 +141,8 @@ static QVirtioSCSIQueues *qvirtio_scsi_init(QVirtioDevice *dev) vs->vq[i] = qvirtqueue_setup(dev, alloc, i); } +qvirtio_set_driver_ok(dev); + /* Clear the POWER ON OCCURRED unit attention */ g_assert_cmpint(virtio_scsi_do_command(vs, test_unit_ready_cdb, NULL, 0, NULL, 0, &resp), -- 2.21.0
[PATCH v4 01/16] tests/virtio-blk-test: read config space after feature negotiation
The VIRTIO Configuration Space cannot be accessed before device feature bits have been read because a driver doesn't know the endianness until it has checked VIRTIO_F_VERSION_1. Fix this problem in preparation for VIRTIO 1.0 support. Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth --- tests/virtio-blk-test.c | 33 - 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index ed13167392..f6674fb233 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -125,10 +125,6 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc, char *data; QTestState *qts = global_qtest; -capacity = qvirtio_config_readq(dev, 0); - -g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); - features = qvirtio_get_features(dev); features = features & ~(QVIRTIO_F_BAD_FEATURE | (1u << VIRTIO_RING_F_INDIRECT_DESC) | @@ -136,6 +132,9 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc, (1u << VIRTIO_BLK_F_SCSI)); qvirtio_set_features(dev, features); +capacity = qvirtio_config_readq(dev, 0); +g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + qvirtio_set_driver_ok(dev); /* Write and read with 3 descriptor layout */ @@ -359,9 +358,6 @@ static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc) char *data; QTestState *qts = global_qtest; -capacity = qvirtio_config_readq(dev, 0); -g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); - features = qvirtio_get_features(dev); g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0); features = features & ~(QVIRTIO_F_BAD_FEATURE | @@ -369,6 +365,9 @@ static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc) (1u << VIRTIO_BLK_F_SCSI)); qvirtio_set_features(dev, features); +capacity = qvirtio_config_readq(dev, 0); +g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + vq = qvirtqueue_setup(dev, t_alloc, 0); qvirtio_set_driver_ok(dev); @@ -434,8 +433,16 @@ static void config(void *obj, void *data, QGuestAllocator *t_alloc) QVirtioBlk *blk_if = obj; QVirtioDevice *dev = blk_if->vdev; int n_size = TEST_IMAGE_SIZE / 2; +uint64_t features; uint64_t capacity; +features = qvirtio_get_features(dev); +features = features & ~(QVIRTIO_F_BAD_FEATURE | +(1u << VIRTIO_RING_F_INDIRECT_DESC) | +(1u << VIRTIO_RING_F_EVENT_IDX) | +(1u << VIRTIO_BLK_F_SCSI)); +qvirtio_set_features(dev, features); + capacity = qvirtio_config_readq(dev, 0); g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); @@ -475,9 +482,6 @@ static void msix(void *obj, void *u_data, QGuestAllocator *t_alloc) qpci_msix_enable(pdev->pdev); qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0); -capacity = qvirtio_config_readq(dev, 0); -g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); - features = qvirtio_get_features(dev); features = features & ~(QVIRTIO_F_BAD_FEATURE | (1u << VIRTIO_RING_F_INDIRECT_DESC) | @@ -485,6 +489,9 @@ static void msix(void *obj, void *u_data, QGuestAllocator *t_alloc) (1u << VIRTIO_BLK_F_SCSI)); qvirtio_set_features(dev, features); +capacity = qvirtio_config_readq(dev, 0); +g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + vq = qvirtqueue_setup(dev, t_alloc, 0); qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1); @@ -584,9 +591,6 @@ static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc) qpci_msix_enable(pdev->pdev); qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0); -capacity = qvirtio_config_readq(dev, 0); -g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); - features = qvirtio_get_features(dev); features = features & ~(QVIRTIO_F_BAD_FEATURE | (1u << VIRTIO_RING_F_INDIRECT_DESC) | @@ -594,6 +598,9 @@ static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc) (1u << VIRTIO_BLK_F_SCSI)); qvirtio_set_features(dev, features); +capacity = qvirtio_config_readq(dev, 0); +g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + vq = qvirtqueue_setup(dev, t_alloc, 0); qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1); -- 2.21.0
[PATCH v4 00/16] libqos: add VIRTIO PCI 1.0 support
v4: * Introduce bool d->features_negotiated so that tests can negotiate a 0 feature bit set in Legacy mode [Thomas] * Make the FEATURES_OK code change in qvirtio_set_driver_ok() clearer and mention it in the commit description [Thomas] * Fix indentation in qvring_init() [Thomas] v3: * Now implements VIRTIO 1.0 fully (vring, device initialization). This required several new patches to address the following issues: 1. Tests that do not negotiate features (non-compliant!) 2. Tests that access configuration space before feature negotiation (non-compliant!) 3. Tests that set up virtqueues before feature negotiation (non-compliant!) 4. vring accesses require byte-swapping when VIRTIO 1.0 is used with a big-endian guest because the qtest_readX/writeX() API automatically converts to guest-endian 5. VIRTIO 1.0 has an additional FEATURES_OK step during Device Initialization * Change uint8_t bar_idx to int [Thomas] * Document qpci_find_capability() [Thomas] * Every commit tested with arm, ppc64, and x86_64 targets using: git rebase -i origin/master -x 'make tests/qos-test && QTEST_QEMU_BINARY=ppc64-softmmu/qemu-system-ppc64 tests/qos-test && QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 tests/qos-test' QTEST_QEMU_BINARY=arm-softmmu/qemu-system-arm tests/qos-test' v2: * Fix checkpatch.pl issues, except MAINTAINERS file warning. libqos already has maintainers and the new virtio-pci-modern.[ch] files don't need extra entries since they are already covered by the existing libqos/ entry. New VIRTIO devices are Non-Transitional. This means they only expose the VIRTIO 1.0 interface, not the Legacy interface. The libqos only supports Legacy and Transitional devices (in Legacy mode). This patch series adds VIRTIO 1.0 support so that tests can run against Non-Transitional devices too. The virtio-fs device is Non-Transitional, so this is a prerequisite for virtio-fs qos tests. Stefan Hajnoczi (16): tests/virtio-blk-test: read config space after feature negotiation libqos: read QVIRTIO_MMIO_VERSION register libqos: extend feature bits to 64-bit virtio-scsi-test: add missing feature negotiation tests/virtio-blk-test: set up virtqueue after feature negotiation libqos: add missing virtio-9p feature negotiation libqos: enforce Device Initialization order libqos: implement VIRTIO 1.0 FEATURES_OK step libqos: access VIRTIO 1.0 vring in little-endian libqos: add iteration support to qpci_find_capability() libqos: pass full QVirtQueue to set_queue_address() libqos: add MSI-X callbacks to QVirtioPCIDevice libqos: expose common virtqueue setup/cleanup functions libqos: make the virtio-pci BAR index configurable libqos: extract Legacy virtio-pci.c code libqos: add VIRTIO PCI 1.0 support tests/Makefile.include | 1 + tests/libqos/pci.h | 2 +- tests/libqos/virtio-mmio.h | 1 + tests/libqos/virtio-pci-modern.h | 17 ++ tests/libqos/virtio-pci.h| 34 ++- tests/libqos/virtio.h| 19 +- tests/libqos/pci.c | 30 ++- tests/libqos/virtio-9p.c | 6 + tests/libqos/virtio-mmio.c | 38 ++- tests/libqos/virtio-net.c| 6 +- tests/libqos/virtio-pci-modern.c | 443 +++ tests/libqos/virtio-pci.c| 105 +--- tests/libqos/virtio.c| 160 --- tests/virtio-blk-test.c | 66 +++-- tests/virtio-scsi-test.c | 8 + 15 files changed, 802 insertions(+), 134 deletions(-) create mode 100644 tests/libqos/virtio-pci-modern.h create mode 100644 tests/libqos/virtio-pci-modern.c -- 2.21.0
[PATCH v4 02/16] libqos: read QVIRTIO_MMIO_VERSION register
There was no real virtio-mmio ABI change between Legacy and VIRTIO 1.0 except that the Version field was incremented from 1 to 2. However, QEMU does not allow Legacy drivers to perform VIRTIO 1.0 operations like accessing 64-bit feature bits. Since we will introduce 64-bit feature bit support we need a way to differentiate between virtio-mmio Version 1 and 2 to avoid upsetting QEMU when we operate in Legacy mode. Stash away the Version field so later patches can change behavior depending on the version. Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth --- tests/libqos/virtio-mmio.h | 1 + tests/libqos/virtio-mmio.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/tests/libqos/virtio-mmio.h b/tests/libqos/virtio-mmio.h index 17a17141c3..0e45778b07 100644 --- a/tests/libqos/virtio-mmio.h +++ b/tests/libqos/virtio-mmio.h @@ -40,6 +40,7 @@ typedef struct QVirtioMMIODevice { uint64_t addr; uint32_t page_size; uint32_t features; /* As it cannot be read later, save it */ +uint32_t version; } QVirtioMMIODevice; extern const QVirtioBus qvirtio_mmio; diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c index d0047876a8..7154b03c1d 100644 --- a/tests/libqos/virtio-mmio.c +++ b/tests/libqos/virtio-mmio.c @@ -223,6 +223,9 @@ void qvirtio_mmio_init_device(QVirtioMMIODevice *dev, QTestState *qts, magic = qtest_readl(qts, addr + QVIRTIO_MMIO_MAGIC_VALUE); g_assert(magic == ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)); +dev->version = qtest_readl(qts, addr + QVIRTIO_MMIO_VERSION); +g_assert(dev->version == 1 || dev->version == 2); + dev->qts = qts; dev->addr = addr; dev->page_size = page_size; -- 2.21.0
[PATCH v4 05/16] tests/virtio-blk-test: set up virtqueue after feature negotiation
VIRTIO Device Initialization requires that feature negotiation has completed before virtqueues are set up. This makes sense because the driver must know whether it is operating in Legacy or VIRTIO 1.0 mode before it can access vring fields with the correct endianness. Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth --- tests/virtio-blk-test.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 31680cc159..fe0dc4a896 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -113,8 +113,8 @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d, return addr; } -static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc, - QVirtQueue *vq) +/* Returns the request virtqueue so the caller can perform further tests */ +static QVirtQueue *test_basic(QVirtioDevice *dev, QGuestAllocator *alloc) { QVirtioBlkReq req; uint64_t req_addr; @@ -124,6 +124,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc, uint8_t status; char *data; QTestState *qts = global_qtest; +QVirtQueue *vq; features = qvirtio_get_features(dev); features = features & ~(QVIRTIO_F_BAD_FEATURE | @@ -135,6 +136,8 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc, capacity = qvirtio_config_readq(dev, 0); g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); +vq = qvirtqueue_setup(dev, alloc, 0); + qvirtio_set_driver_ok(dev); /* Write and read with 3 descriptor layout */ @@ -331,14 +334,16 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc, guest_free(alloc, req_addr); } + +return vq; } static void basic(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtioBlk *blk_if = obj; QVirtQueue *vq; -vq = qvirtqueue_setup(blk_if->vdev, t_alloc, 0); -test_basic(blk_if->vdev, t_alloc, vq); + +vq = test_basic(blk_if->vdev, t_alloc); qvirtqueue_cleanup(blk_if->vdev->bus, vq, t_alloc); } @@ -746,9 +751,7 @@ static void resize(void *obj, void *data, QGuestAllocator *t_alloc) QVirtQueue *vq; QTestState *qts = global_qtest; -vq = qvirtqueue_setup(dev, t_alloc, 0); - -test_basic(dev, t_alloc, vq); +vq = test_basic(dev, t_alloc); qmp_discard_response("{ 'execute': 'block_resize', " " 'arguments': { 'device': 'drive0', " -- 2.21.0
[PATCH v4 15/16] libqos: extract Legacy virtio-pci.c code
The current libqos virtio-pci.c code implements the VIRTIO Legacy interface. Extract existing code in preparation for VIRTIO 1.0 support. Signed-off-by: Stefan Hajnoczi Reviewed-by: Sergio Lopez Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé --- tests/libqos/virtio-pci.h | 2 -- tests/libqos/virtio-pci.c | 29 - 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h index 78a1c15c2a..6b3a385b06 100644 --- a/tests/libqos/virtio-pci.h +++ b/tests/libqos/virtio-pci.h @@ -45,8 +45,6 @@ typedef struct QVirtQueuePCI { uint32_t msix_data; } QVirtQueuePCI; -extern const QVirtioBus qvirtio_pci; - void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * addr); QVirtioPCIDevice *virtio_pci_new(QPCIBus *bus, QPCIAddress * addr); diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index e9595603f5..11866f7772 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -35,14 +35,6 @@ * original qvirtio_pci_destructor and qvirtio_pci_start_hw. */ -static inline bool qvirtio_pci_is_big_endian(QVirtioPCIDevice *dev) -{ -QPCIBus *bus = dev->pdev->bus; - -/* FIXME: virtio 1.0 is always little-endian */ -return qtest_big_endian(bus->qts); -} - #define CONFIG_BASE(dev) (VIRTIO_PCI_CONFIG_OFF((dev)->pdev->msix_enabled)) static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off) @@ -55,8 +47,7 @@ static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off) * but virtio ( < 1.0) is in guest order * so with a big-endian guest the order has been reversed, * reverse it again - * virtio-1.0 is always little-endian, like PCI, but this - * case will be managed inside qvirtio_pci_is_big_endian() + * virtio-1.0 is always little-endian, like PCI */ static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t off) @@ -262,7 +253,7 @@ static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq) qpci_io_writew(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NOTIFY, vq->index); } -const QVirtioBus qvirtio_pci = { +static const QVirtioBus qvirtio_pci_legacy = { .config_readb = qvirtio_pci_config_readb, .config_readw = qvirtio_pci_config_readw, .config_readl = qvirtio_pci_config_readl, @@ -396,17 +387,21 @@ void qvirtio_pci_start_hw(QOSGraphObject *obj) qvirtio_start_device(&dev->vdev); } +static void qvirtio_pci_init_legacy(QVirtioPCIDevice *dev) +{ +dev->vdev.device_type = qpci_config_readw(dev->pdev, PCI_SUBSYSTEM_ID); +dev->bar_idx = 0; +dev->vdev.bus = &qvirtio_pci_legacy; +dev->msix_ops = &qvirtio_pci_msix_ops_legacy; +dev->vdev.big_endian = qtest_big_endian(dev->pdev->bus->qts); +} + static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice *dev, QPCIDevice *pci_dev) { dev->pdev = pci_dev; -dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID); -dev->bar_idx = 0; - dev->config_msix_entry = -1; -dev->msix_ops = &qvirtio_pci_msix_ops_legacy; -dev->vdev.bus = &qvirtio_pci; -dev->vdev.big_endian = qvirtio_pci_is_big_endian(dev); +qvirtio_pci_init_legacy(dev); /* each virtio-xxx-pci device should override at least this function */ dev->obj.get_driver = NULL; -- 2.21.0
[PATCH v4 06/16] libqos: add missing virtio-9p feature negotiation
VIRTIO Device Initialization requires feature negotiation. The libqos virtio-9p driver lacks feature negotiation and is therefore non-compliant. libqos tests acknowledge all feature bits advertised by the device, except VIRTIO_F_BAD_FEATURE (which devices use to detect broken drivers!) and VIRTIO_RING_F_EVENT_IDX (which is not implemented in libqos and accepting it would break notifications). Signed-off-by: Stefan Hajnoczi --- tests/libqos/virtio-9p.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/tests/libqos/virtio-9p.c b/tests/libqos/virtio-9p.c index 8c9efce3e1..77dbfb62ad 100644 --- a/tests/libqos/virtio-9p.c +++ b/tests/libqos/virtio-9p.c @@ -32,6 +32,12 @@ static void virtio_9p_cleanup(QVirtio9P *interface) static void virtio_9p_setup(QVirtio9P *interface) { +uint64_t features; + +features = qvirtio_get_features(interface->vdev); +features &= ~(QVIRTIO_F_BAD_FEATURE | (1ull << VIRTIO_RING_F_EVENT_IDX)); +qvirtio_set_features(interface->vdev, features); + interface->vq = qvirtqueue_setup(interface->vdev, alloc, 0); qvirtio_set_driver_ok(interface->vdev); } -- 2.21.0
[PATCH v4 07/16] libqos: enforce Device Initialization order
According to VIRTIO 1.1 "3.1.1 Driver Requirements: Device Initialization", configuration space and virtqueues cannot be accessed before features have been negotiated. Enforce this requirement. Signed-off-by: Stefan Hajnoczi --- v4: * Introduce bool d->features_negotiated so that tests can negotiate a 0 feature bit set in Legacy mode [Thomas] --- tests/libqos/virtio.h | 1 + tests/libqos/virtio.c | 7 +++ 2 files changed, 8 insertions(+) diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h index a5c99fb3c9..0e8f823c7b 100644 --- a/tests/libqos/virtio.h +++ b/tests/libqos/virtio.h @@ -23,6 +23,7 @@ typedef struct QVirtioDevice { uint16_t device_type; uint64_t features; bool big_endian; +bool features_negotiated; } QVirtioDevice; typedef struct QVirtQueue { diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c index 4f7e6bb8a1..6049ff3b3e 100644 --- a/tests/libqos/virtio.c +++ b/tests/libqos/virtio.c @@ -15,21 +15,25 @@ uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr) { +g_assert_true(d->features_negotiated); return d->bus->config_readb(d, addr); } uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr) { +g_assert_true(d->features_negotiated); return d->bus->config_readw(d, addr); } uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr) { +g_assert_true(d->features_negotiated); return d->bus->config_readl(d, addr); } uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr) { +g_assert_true(d->features_negotiated); return d->bus->config_readq(d, addr); } @@ -42,11 +46,13 @@ void qvirtio_set_features(QVirtioDevice *d, uint64_t features) { d->features = features; d->bus->set_features(d, features); +d->features_negotiated = true; } QVirtQueue *qvirtqueue_setup(QVirtioDevice *d, QGuestAllocator *alloc, uint16_t index) { +g_assert_true(d->features_negotiated); return d->bus->virtqueue_setup(d, alloc, index); } @@ -60,6 +66,7 @@ void qvirtio_reset(QVirtioDevice *d) { d->bus->set_status(d, 0); g_assert_cmphex(d->bus->get_status(d), ==, 0); +d->features_negotiated = false; } void qvirtio_set_acknowledge(QVirtioDevice *d) -- 2.21.0
[PATCH v4 03/16] libqos: extend feature bits to 64-bit
In VIRTIO 1.0 feature bits changed from 32-bit to 64-bit. (In fact, the transports allow even more feature bits but nothing uses more than 64 bits today.) Add 64-bit feature bit support to virtio-mmio and virtio-pci. This will be necessary for VIRTIO 1.0 support. Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé --- tests/libqos/virtio.h | 12 ++-- tests/libqos/virtio-mmio.c | 28 ++-- tests/libqos/virtio-net.c | 6 +++--- tests/libqos/virtio-pci.c | 12 ++-- tests/libqos/virtio.c | 4 ++-- tests/virtio-blk-test.c| 8 6 files changed, 43 insertions(+), 27 deletions(-) diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h index 2cb2448f46..a5c99fb3c9 100644 --- a/tests/libqos/virtio.h +++ b/tests/libqos/virtio.h @@ -13,7 +13,7 @@ #include "libqos/malloc.h" #include "standard-headers/linux/virtio_ring.h" -#define QVIRTIO_F_BAD_FEATURE 0x4000 +#define QVIRTIO_F_BAD_FEATURE 0x4000ull typedef struct QVirtioBus QVirtioBus; @@ -52,13 +52,13 @@ struct QVirtioBus { uint64_t (*config_readq)(QVirtioDevice *d, uint64_t addr); /* Get features of the device */ -uint32_t (*get_features)(QVirtioDevice *d); +uint64_t (*get_features)(QVirtioDevice *d); /* Set features of the device */ -void (*set_features)(QVirtioDevice *d, uint32_t features); +void (*set_features)(QVirtioDevice *d, uint64_t features); /* Get features of the guest */ -uint32_t (*get_guest_features)(QVirtioDevice *d); +uint64_t (*get_guest_features)(QVirtioDevice *d); /* Get status of the device */ uint8_t (*get_status)(QVirtioDevice *d); @@ -103,8 +103,8 @@ uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr); uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr); uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr); uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr); -uint32_t qvirtio_get_features(QVirtioDevice *d); -void qvirtio_set_features(QVirtioDevice *d, uint32_t features); +uint64_t qvirtio_get_features(QVirtioDevice *d); +void qvirtio_set_features(QVirtioDevice *d, uint64_t features); bool qvirtio_is_big_endian(QVirtioDevice *d); void qvirtio_reset(QVirtioDevice *d); diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c index 7154b03c1d..78066e6e05 100644 --- a/tests/libqos/virtio-mmio.c +++ b/tests/libqos/virtio-mmio.c @@ -40,22 +40,38 @@ static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t off) return qtest_readq(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off); } -static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d) +static uint64_t qvirtio_mmio_get_features(QVirtioDevice *d) { QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); +uint64_t lo; +uint64_t hi = 0; + qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0); -return qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES); +lo = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES); + +if (dev->version >= 2) { +qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 1); +hi = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES); +} + +return (hi << 32) | lo; } -static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features) +static void qvirtio_mmio_set_features(QVirtioDevice *d, uint64_t features) { QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); dev->features = features; qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0); qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features); + +if (dev->version >= 2) { +qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 1); +qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, + features >> 32); +} } -static uint32_t qvirtio_mmio_get_guest_features(QVirtioDevice *d) +static uint64_t qvirtio_mmio_get_guest_features(QVirtioDevice *d) { QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return dev->features; @@ -149,8 +165,8 @@ static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d, vq->free_head = 0; vq->num_free = vq->size; vq->align = dev->page_size; -vq->indirect = (dev->features & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0; -vq->event = (dev->features & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0; +vq->indirect = dev->features & (1ull << VIRTIO_RING_F_INDIRECT_DESC); +vq->event = dev->features & (1ull << VIRTIO_RING_F_EVENT_IDX); qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size); diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c index 6567beb553..710d440c3d 100644 --- a/tests/libqos/virtio-net.c +++ b/tests/libqos/virtio-net.c @@ -44,11 +44
[PATCH v4 09/16] libqos: access VIRTIO 1.0 vring in little-endian
VIRTIO 1.0 uses little-endian for the vring. Legacy VIRTIO uses guest endianness. Adjust the code to handle both. Note that qvirtio_readq() is not defined because it has no users. All the other accessors are really needed. Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth --- v4: * Fixed indentation in qvring_init() [Thomas] --- tests/libqos/virtio.h | 4 +- tests/libqos/virtio-mmio.c | 1 + tests/libqos/virtio-pci.c | 1 + tests/libqos/virtio.c | 131 +++-- tests/virtio-blk-test.c| 8 +-- 5 files changed, 106 insertions(+), 39 deletions(-) diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h index 0e8f823c7b..ebbff5193b 100644 --- a/tests/libqos/virtio.h +++ b/tests/libqos/virtio.h @@ -27,6 +27,7 @@ typedef struct QVirtioDevice { } QVirtioDevice; typedef struct QVirtQueue { +QVirtioDevice *vdev; uint64_t desc; /* This points to an array of struct vring_desc */ uint64_t avail; /* This points to a struct vring_avail */ uint64_t used; /* This points to a struct vring_used */ @@ -135,7 +136,8 @@ void qvring_init(QTestState *qts, const QGuestAllocator *alloc, QVirtQueue *vq, QVRingIndirectDesc *qvring_indirect_desc_setup(QTestState *qs, QVirtioDevice *d, QGuestAllocator *alloc, uint16_t elem); -void qvring_indirect_desc_add(QTestState *qts, QVRingIndirectDesc *indirect, +void qvring_indirect_desc_add(QVirtioDevice *d, QTestState *qts, + QVRingIndirectDesc *indirect, uint64_t data, uint32_t len, bool write); uint32_t qvirtqueue_add(QTestState *qts, QVirtQueue *vq, uint64_t data, uint32_t len, bool write, bool next); diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c index 78066e6e05..4db1f1b8bc 100644 --- a/tests/libqos/virtio-mmio.c +++ b/tests/libqos/virtio-mmio.c @@ -157,6 +157,7 @@ static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d, uint64_t addr; vq = g_malloc0(sizeof(*vq)); +vq->vdev = d; qvirtio_mmio_queue_select(d, index); qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_ALIGN, dev->page_size); diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index 1b6b760fc6..7ecf5d0a52 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -217,6 +217,7 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, feat = qvirtio_pci_get_guest_features(d); qvirtio_pci_queue_select(d, index); +vqpci->vq.vdev = d; vqpci->vq.index = index; vqpci->vq.size = qvirtio_pci_get_queue_size(d); vqpci->vq.free_head = 0; diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c index fa597c2481..9aa360620c 100644 --- a/tests/libqos/virtio.c +++ b/tests/libqos/virtio.c @@ -8,11 +8,68 @@ */ #include "qemu/osdep.h" +#include "qemu/bswap.h" #include "libqtest.h" #include "libqos/virtio.h" #include "standard-headers/linux/virtio_config.h" #include "standard-headers/linux/virtio_ring.h" +/* + * qtest_readX/writeX() functions transfer host endian from/to guest endian. + * This works great for Legacy VIRTIO devices where we need guest endian + * accesses. For VIRTIO 1.0 the vring is little-endian so the automatic guest + * endianness conversion is not wanted. + * + * The following qvirtio_readX/writeX() functions handle Legacy and VIRTIO 1.0 + * accesses seamlessly. + */ +static uint16_t qvirtio_readw(QVirtioDevice *d, QTestState *qts, uint64_t addr) +{ +uint16_t val = qtest_readw(qts, addr); + +if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) { +val = bswap16(val); +} +return val; +} + +static uint32_t qvirtio_readl(QVirtioDevice *d, QTestState *qts, uint64_t addr) +{ +uint32_t val = qtest_readl(qts, addr); + +if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) { +val = bswap32(val); +} +return val; +} + +static void qvirtio_writew(QVirtioDevice *d, QTestState *qts, + uint64_t addr, uint16_t val) +{ +if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) { +val = bswap16(val); +} +qtest_writew(qts, addr, val); +} + +static void qvirtio_writel(QVirtioDevice *d, QTestState *qts, + uint64_t addr, uint32_t val) +{ +if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) { +val = bswap32(val); +} +qtest_writel(qts, addr, val); +} + +static void qvirtio_writeq(QVirtioDevice *d, QTestState *qts, + uint64_t addr, uint64_t val) +{ +if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) { +val = bswap64(val); +} +qtest_writeq(qts, addr, val); +} + uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr) { g_assert_true(d->feat
Re: [PATCH for 4.2 v1 00/19] testing/next before softfreeze
Thomas Huth writes: > - Original Message - >> From: "Alex Bennée" >> Sent: Tuesday, October 22, 2019 9:16:45 PM >> >> Hi, >> >> This is the current status of testing/next. I dropped the Travis arm64 >> build due to stability concerns. As far as I can tell Thomas' latest >> iotest updates are working fine. If there are any other patches worth >> considering before the softfreeze now is the time to shout. > > Feel free to include: > > https://lists.nongnu.org/archive/html/qemu-devel/2019-10/msg03912.html > ("gitlab-ci.yml: Use libvdeplug-dev to compile-test the VDE network > backend") done. -- Alex Bennée
[PATCH v4 08/16] libqos: implement VIRTIO 1.0 FEATURES_OK step
Device initialization has an extra step in VIRTIO 1.0. The FEATURES_OK status bit is set to indicate that feature negotiation has completed. The driver then reads the status register again to check that the device agrees with the final features. Implement this step as part of qvirtio_set_features() instead of introducing a separate function. This way all existing code works without modifications. The check in qvirtio_set_driver_ok() needs to be updated because FEATURES_OK will be set for VIRTIO 1.0 devices. Signed-off-by: Stefan Hajnoczi --- v4: * Make FEATURES_OK change in qvirtio_set_driver_ok() clearer and mention it in the commit description [Thomas] --- tests/libqos/virtio.c | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c index 6049ff3b3e..fa597c2481 100644 --- a/tests/libqos/virtio.c +++ b/tests/libqos/virtio.c @@ -46,6 +46,20 @@ void qvirtio_set_features(QVirtioDevice *d, uint64_t features) { d->features = features; d->bus->set_features(d, features); + +/* + * This could be a separate function for drivers that want to access + * configuration space before setting FEATURES_OK, but no existing users + * need that and it's less code for callers if this is done implicitly. +*/ +if (features & (1ull << VIRTIO_F_VERSION_1)) { +uint8_t status = d->bus->get_status(d) | + VIRTIO_CONFIG_S_FEATURES_OK; + +d->bus->set_status(d, status); +g_assert_cmphex(d->bus->get_status(d), ==, status); +} + d->features_negotiated = true; } @@ -86,7 +100,9 @@ void qvirtio_set_driver_ok(QVirtioDevice *d) { d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK); g_assert_cmphex(d->bus->get_status(d), ==, VIRTIO_CONFIG_S_DRIVER_OK | -VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE); +VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE | +(d->features & (1ull << VIRTIO_F_VERSION_1) ? + VIRTIO_CONFIG_S_FEATURES_OK : 0)); } void qvirtio_wait_queue_isr(QTestState *qts, QVirtioDevice *d, -- 2.21.0
[PATCH v4 10/16] libqos: add iteration support to qpci_find_capability()
VIRTIO 1.0 PCI devices have multiple PCI_CAP_ID_VNDR capabilities so we need a way to iterate over them. Extend qpci_find_capability() to take the last address. Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth -- v3: * Document qpci_find_capability() --- tests/libqos/pci.h | 2 +- tests/libqos/pci.c | 30 -- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h index a5389a5845..590c175190 100644 --- a/tests/libqos/pci.h +++ b/tests/libqos/pci.h @@ -86,7 +86,7 @@ bool qpci_has_buggy_msi(QPCIDevice *dev); bool qpci_check_buggy_msi(QPCIDevice *dev); void qpci_device_enable(QPCIDevice *dev); -uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id); +uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr); void qpci_msix_enable(QPCIDevice *dev); void qpci_msix_disable(QPCIDevice *dev); bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry); diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c index 662ee7a517..2309a724e4 100644 --- a/tests/libqos/pci.c +++ b/tests/libqos/pci.c @@ -115,10 +115,28 @@ void qpci_device_enable(QPCIDevice *dev) g_assert_cmphex(cmd & PCI_COMMAND_MASTER, ==, PCI_COMMAND_MASTER); } -uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id) +/** + * qpci_find_capability: + * @dev: the PCI device + * @id: the PCI Capability ID (PCI_CAP_ID_*) + * @start_addr: 0 to begin iteration or the last return value to continue + * iteration + * + * Iterate over the PCI Capabilities List. + * + * Returns: PCI Configuration Space offset of the capabililty structure or + * 0 if no further matching capability is found + */ +uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr) { uint8_t cap; -uint8_t addr = qpci_config_readb(dev, PCI_CAPABILITY_LIST); +uint8_t addr; + +if (start_addr) { +addr = qpci_config_readb(dev, start_addr + PCI_CAP_LIST_NEXT); +} else { +addr = qpci_config_readb(dev, PCI_CAPABILITY_LIST); +} do { cap = qpci_config_readb(dev, addr); @@ -138,7 +156,7 @@ void qpci_msix_enable(QPCIDevice *dev) uint8_t bir_table; uint8_t bir_pba; -addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX); +addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); g_assert_cmphex(addr, !=, 0); val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); @@ -167,7 +185,7 @@ void qpci_msix_disable(QPCIDevice *dev) uint16_t val; g_assert(dev->msix_enabled); -addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX); +addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); g_assert_cmphex(addr, !=, 0); val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); qpci_config_writew(dev, addr + PCI_MSIX_FLAGS, @@ -203,7 +221,7 @@ bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry) uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE; g_assert(dev->msix_enabled); -addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX); +addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); g_assert_cmphex(addr, !=, 0); val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); @@ -221,7 +239,7 @@ uint16_t qpci_msix_table_size(QPCIDevice *dev) uint8_t addr; uint16_t control; -addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX); +addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); g_assert_cmphex(addr, !=, 0); control = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); -- 2.21.0
[PATCH v4 12/16] libqos: add MSI-X callbacks to QVirtioPCIDevice
The MSI-X vectors are programmed differently in the VIRTIO 1.0 and Legacy interfaces. Introduce callbacks so different implementations can be used depending on the interface version. Signed-off-by: Stefan Hajnoczi Reviewed-by: Sergio Lopez Reviewed-by: Thomas Huth --- tests/libqos/virtio-pci.h | 12 tests/libqos/virtio-pci.c | 37 - 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h index 728b4715f1..4299efc023 100644 --- a/tests/libqos/virtio-pci.h +++ b/tests/libqos/virtio-pci.h @@ -14,16 +14,28 @@ #include "libqos/pci.h" #include "libqos/qgraph.h" +typedef struct QVirtioPCIMSIXOps QVirtioPCIMSIXOps; + typedef struct QVirtioPCIDevice { QOSGraphObject obj; QVirtioDevice vdev; QPCIDevice *pdev; QPCIBar bar; +const QVirtioPCIMSIXOps *msix_ops; uint16_t config_msix_entry; uint64_t config_msix_addr; uint32_t config_msix_data; } QVirtioPCIDevice; +struct QVirtioPCIMSIXOps { +/* Set the Configuration Vector for MSI-X */ +void (*set_config_vector)(QVirtioPCIDevice *d, uint16_t entry); + +/* Set the Queue Vector for MSI-X */ +void (*set_queue_vector)(QVirtioPCIDevice *d, uint16_t vq_idx, + uint16_t entry); +}; + typedef struct QVirtQueuePCI { QVirtQueue vq; uint16_t msix_entry; diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index e4fa318dcc..0725777a8d 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -281,6 +281,31 @@ const QVirtioBus qvirtio_pci = { .virtqueue_kick = qvirtio_pci_virtqueue_kick, }; +static void qvirtio_pci_set_config_vector(QVirtioPCIDevice *d, uint16_t entry) +{ +uint16_t vector; + +qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR, entry); +vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR); +g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR); +} + +static void qvirtio_pci_set_queue_vector(QVirtioPCIDevice *d, uint16_t vq_idx, + uint16_t entry) +{ +uint16_t vector; + +qvirtio_pci_queue_select(&d->vdev, vq_idx); +qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR, entry); +vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR); +g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR); +} + +static const QVirtioPCIMSIXOps qvirtio_pci_msix_ops_legacy = { +.set_config_vector = qvirtio_pci_set_config_vector, +.set_queue_vector = qvirtio_pci_set_queue_vector, +}; + void qvirtio_pci_device_enable(QVirtioPCIDevice *d) { qpci_device_enable(d->pdev); @@ -295,7 +320,6 @@ void qvirtio_pci_device_disable(QVirtioPCIDevice *d) void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci, QGuestAllocator *alloc, uint16_t entry) { -uint16_t vector; uint32_t control; uint64_t off; @@ -321,16 +345,12 @@ void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci, off + PCI_MSIX_ENTRY_VECTOR_CTRL, control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT); -qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index); -qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR, entry); -vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR); -g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR); +d->msix_ops->set_queue_vector(d, vqpci->vq.index, entry); } void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d, QGuestAllocator *alloc, uint16_t entry) { -uint16_t vector; uint32_t control; uint64_t off; @@ -358,9 +378,7 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d, off + PCI_MSIX_ENTRY_VECTOR_CTRL, control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT); -qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR, entry); -vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR); -g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR); +d->msix_ops->set_config_vector(d, entry); } void qvirtio_pci_destructor(QOSGraphObject *obj) @@ -383,6 +401,7 @@ static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice *dev, QPCIDevice *pci_ dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID); dev->config_msix_entry = -1; +dev->msix_ops = &qvirtio_pci_msix_ops_legacy; dev->vdev.bus = &qvirtio_pci; dev->vdev.big_endian = qvirtio_pci_is_big_endian(dev); -- 2.21.0
[PATCH v7 04/14] target/mips: msa: Split helpers for _A.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 11 +++- target/mips/msa_helper.c | 163 ++- target/mips/translate.c | 38 +-- 3 files changed, 187 insertions(+), 25 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index d615c83..cef4de6 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -877,6 +877,15 @@ DEF_HELPER_4(msa_div_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_div_u_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_div_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_mod_u_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_u_w, void, env, i32, i32, i32) @@ -940,8 +949,6 @@ DEF_HELPER_5(msa_max_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_max_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_min_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_min_u_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_max_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_min_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index a2052ba..3eb0ab1 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1736,7 +1736,152 @@ void helper_msa_div_u_d(CPUMIPSState *env, * +---+--+ */ -/* TODO: insert Int Max Min group helpers here */ +static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1; +uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2; +return abs_arg1 > abs_arg2 ? arg1 : arg2; +} + +void helper_msa_max_a_b(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->b[0] = msa_max_a_df(DF_BYTE, pws->b[0], pwt->b[0]); +pwd->b[1] = msa_max_a_df(DF_BYTE, pws->b[1], pwt->b[1]); +pwd->b[2] = msa_max_a_df(DF_BYTE, pws->b[2], pwt->b[2]); +pwd->b[3] = msa_max_a_df(DF_BYTE, pws->b[3], pwt->b[3]); +pwd->b[4] = msa_max_a_df(DF_BYTE, pws->b[4], pwt->b[4]); +pwd->b[5] = msa_max_a_df(DF_BYTE, pws->b[5], pwt->b[5]); +pwd->b[6] = msa_max_a_df(DF_BYTE, pws->b[6], pwt->b[6]); +pwd->b[7] = msa_max_a_df(DF_BYTE, pws->b[7], pwt->b[7]); +pwd->b[8] = msa_max_a_df(DF_BYTE, pws->b[8], pwt->b[8]); +pwd->b[9] = msa_max_a_df(DF_BYTE, pws->b[9], pwt->b[9]); +pwd->b[10] = msa_max_a_df(DF_BYTE, pws->b[10], pwt->b[10]); +pwd->b[11] = msa_max_a_df(DF_BYTE, pws->b[11], pwt->b[11]); +pwd->b[12] = msa_max_a_df(DF_BYTE, pws->b[12], pwt->b[12]); +pwd->b[13] = msa_max_a_df(DF_BYTE, pws->b[13], pwt->b[13]); +pwd->b[14] = msa_max_a_df(DF_BYTE, pws->b[14], pwt->b[14]); +pwd->b[15] = msa_max_a_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_max_a_h(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_max_a_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_max_a_df(DF_HALF, pws->h[1], pwt->h[1]); +pwd->h[2] = msa_max_a_df(DF_HALF, pws->h[2], pwt->h[2]); +pwd->h[3] = msa_max_a_df(DF_HALF, pws->h[3], pwt->h[3]); +pwd->h[4] = msa_max_a_df(DF_HALF, pws->h[4], pwt->h[4]); +pwd->h[5] = msa_max_a_df(DF_HALF, pws->h[5], pwt->h[5]); +pwd->h[6] = msa_max_a_df(DF_HALF, pws->h[6], pwt->h[6]); +pwd->h[7] = msa_max_a_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_max_a_w(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->w[0] = msa_max_a_df(DF_WORD, pws->w[0], pwt->w[0]); +pwd->w[1] = msa_max_a_df(DF_WORD, pws->w[1], pwt->w[1]); +pwd->w[2] = msa_max_a_df(DF_WORD, pws->w[2], pwt->w[2]); +pwd->w[3] = msa_max_a_df(DF_WORD, pws->w[3], pwt->
[PATCH v4 11/16] libqos: pass full QVirtQueue to set_queue_address()
Instead of just passing the vring page frame number, pass the full QVirtQueue. This will allow the VIRTIO 1.0 transport to program the fine-grained vring address registers in the future. Signed-off-by: Stefan Hajnoczi Reviewed-by: Sergio Lopez Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé --- tests/libqos/virtio.h | 2 +- tests/libqos/virtio-mmio.c | 6 -- tests/libqos/virtio-pci.c | 6 -- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h index ebbff5193b..529ef7555a 100644 --- a/tests/libqos/virtio.h +++ b/tests/libqos/virtio.h @@ -81,7 +81,7 @@ struct QVirtioBus { uint16_t (*get_queue_size)(QVirtioDevice *d); /* Set the address of the selected queue */ -void (*set_queue_address)(QVirtioDevice *d, uint32_t pfn); +void (*set_queue_address)(QVirtioDevice *d, QVirtQueue *vq); /* Setup the virtqueue specified by index */ QVirtQueue *(*virtqueue_setup)(QVirtioDevice *d, QGuestAllocator *alloc, diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c index 4db1f1b8bc..e0a2bd7bc6 100644 --- a/tests/libqos/virtio-mmio.c +++ b/tests/libqos/virtio-mmio.c @@ -143,9 +143,11 @@ static uint16_t qvirtio_mmio_get_queue_size(QVirtioDevice *d) return (uint16_t)qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NUM_MAX); } -static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, uint32_t pfn) +static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, QVirtQueue *vq) { QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); +uint64_t pfn = vq->desc / dev->page_size; + qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_PFN, pfn); } @@ -179,7 +181,7 @@ static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d, addr = guest_alloc(alloc, qvring_size(vq->size, dev->page_size)); qvring_init(dev->qts, alloc, vq, addr); -qvirtio_mmio_set_queue_address(d, vq->desc / dev->page_size); +qvirtio_mmio_set_queue_address(d, vq); return vq; } diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index 7ecf5d0a52..e4fa318dcc 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -199,9 +199,11 @@ static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d) return qpci_io_readw(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NUM); } -static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn) +static void qvirtio_pci_set_queue_address(QVirtioDevice *d, QVirtQueue *vq) { QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev); +uint64_t pfn = vq->desc / VIRTIO_PCI_VRING_ALIGN; + qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn); } @@ -239,7 +241,7 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, addr = guest_alloc(alloc, qvring_size(vqpci->vq.size, VIRTIO_PCI_VRING_ALIGN)); qvring_init(qvpcidev->pdev->bus->qts, alloc, &vqpci->vq, addr); -qvirtio_pci_set_queue_address(d, vqpci->vq.desc / VIRTIO_PCI_VRING_ALIGN); +qvirtio_pci_set_queue_address(d, &vqpci->vq); return &vqpci->vq; } -- 2.21.0
Re: [PATCH v1 07/19] cirrus.yml: reduce scope of MacOS build
Thomas Huth writes: > - Original Message - >> From: "Alex Bennée" >> Sent: Tuesday, October 22, 2019 9:16:52 PM >> >> The MacOS build can time out on Cirrus running to almost an hour. >> Reduce the scope to the historical MacOS architectures much the same >> way we do on Travis. > > Oh, really? For me, the builds on Cirrus-CI work reasonable fast and > almost always finish within 20 minutes, e.g.: It seems to be an intermittent thing: https://cirrus-ci.com/github/stsquad/qemu but looking again maybe it's only the xcode build that is reliably long... > > https://cirrus-ci.com/build/4976412120842240 > > Also the last macos_task from the official QEMU mirror on github finished > within 15 minutes: > > https://github.com/qemu/qemu/runs/269964092 > > ... so was your issue maybe just a temporary dropout? > > Thomas -- Alex Bennée
[PATCH v4 14/16] libqos: make the virtio-pci BAR index configurable
The Legacy virtio-pci interface always uses BAR 0. VIRTIO 1.0 may need to use a different BAR index, so make it configurable. Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé --- v3: * Change uint8_t bar_idx to int [Thomas] --- tests/libqos/virtio-pci.h | 2 ++ tests/libqos/virtio-pci.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h index 0e4a8b7b00..78a1c15c2a 100644 --- a/tests/libqos/virtio-pci.h +++ b/tests/libqos/virtio-pci.h @@ -25,6 +25,8 @@ typedef struct QVirtioPCIDevice { uint16_t config_msix_entry; uint64_t config_msix_addr; uint32_t config_msix_data; + +int bar_idx; } QVirtioPCIDevice; struct QVirtioPCIMSIXOps { diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index c900742f96..e9595603f5 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -310,7 +310,7 @@ static const QVirtioPCIMSIXOps qvirtio_pci_msix_ops_legacy = { void qvirtio_pci_device_enable(QVirtioPCIDevice *d) { qpci_device_enable(d->pdev); -d->bar = qpci_iomap(d->pdev, 0, NULL); +d->bar = qpci_iomap(d->pdev, d->bar_idx, NULL); } void qvirtio_pci_device_disable(QVirtioPCIDevice *d) @@ -400,6 +400,7 @@ static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice *dev, QPCIDevice *pci_ { dev->pdev = pci_dev; dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID); +dev->bar_idx = 0; dev->config_msix_entry = -1; dev->msix_ops = &qvirtio_pci_msix_ops_legacy; -- 2.21.0
[PATCH v7 00/14] target/mips: Misc cleanups for September/October 2019
From: Aleksandar Markovic Mostly cosmetic changes. v6->v7: - minor corrections in commit messages - added patches 13 and 14 v5->v6: - minor corrections (r-b, t-b marks) in commit messages - added patches 11 and 12 v4->v5: - minor correction in patch on helper.c - added patches 9 and 10 v3->v4: - added patches 7 and 8 v2->v3: - removed all patches that were already integrated - patches 1 and 2 are improved from v2 - added patches 3-6 v1->v2: - minor corrections to satisfy reviews - added several more patches Aleksandar Markovic (14): target/mips: Clean up helper.c target/mips: Clean up op_helper.c MAINTAINERS: Update mail address of Aleksandar Rikalo target/mips: msa: Split helpers for _A. target/mips: msa: Split helpers for _. target/mips: msa: Split helpers for ILV. target/mips: msa: Split helpers for ADD<_A|S_A|S_S|S_U|V>. target/mips: msa: Split helpers for HADD_. target/mips: msa: Split helpers for S. target/mips: msa: Split helpers for PCK. target/mips: msa: Split helpers for HSUB_. target/mips: msa: Split helpers for ASUB_. target/mips: Add support for emulation of CRC32 group of instructions target/mips: Demacro LMI decoder .mailmap |5 +- MAINTAINERS | 18 +- disas/mips.c |8 + target/mips/helper.c | 123 +- target/mips/helper.h | 157 +- target/mips/msa_helper.c | 4583 ++ target/mips/op_helper.c | 1032 +++ target/mips/translate.c | 800 ++-- 8 files changed, 4565 insertions(+), 2161 deletions(-) -- 2.7.4
[PATCH v4 13/16] libqos: expose common virtqueue setup/cleanup functions
The VIRTIO 1.0 code will need to perform additional steps but it will reuse the common virtqueue setup/cleanup code. Make these functions public. Make sure to invoke callbacks via QVirtioBus instead of directly calling the virtio-pci Legacy versions of these functions. Signed-off-by: Stefan Hajnoczi Reviewed-by: Sergio Lopez Reviewed-by: Thomas Huth --- tests/libqos/virtio-pci.h | 8 tests/libqos/virtio-pci.c | 19 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h index 4299efc023..0e4a8b7b00 100644 --- a/tests/libqos/virtio-pci.h +++ b/tests/libqos/virtio-pci.h @@ -65,4 +65,12 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d, QGuestAllocator *alloc, uint16_t entry); void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci, QGuestAllocator *alloc, uint16_t entry); + +/* Used by Legacy and Modern virtio-pci code */ +QVirtQueue *qvirtio_pci_virtqueue_setup_common(QVirtioDevice *d, + QGuestAllocator *alloc, + uint16_t index); +void qvirtio_pci_virtqueue_cleanup_common(QVirtQueue *vq, + QGuestAllocator *alloc); + #endif diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index 0725777a8d..c900742f96 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -207,8 +207,9 @@ static void qvirtio_pci_set_queue_address(QVirtioDevice *d, QVirtQueue *vq) qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn); } -static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, -QGuestAllocator *alloc, uint16_t index) +QVirtQueue *qvirtio_pci_virtqueue_setup_common(QVirtioDevice *d, + QGuestAllocator *alloc, + uint16_t index) { uint64_t feat; uint64_t addr; @@ -216,12 +217,12 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, QVirtioPCIDevice *qvpcidev = container_of(d, QVirtioPCIDevice, vdev); vqpci = g_malloc0(sizeof(*vqpci)); -feat = qvirtio_pci_get_guest_features(d); +feat = d->bus->get_guest_features(d); -qvirtio_pci_queue_select(d, index); +d->bus->queue_select(d, index); vqpci->vq.vdev = d; vqpci->vq.index = index; -vqpci->vq.size = qvirtio_pci_get_queue_size(d); +vqpci->vq.size = d->bus->get_queue_size(d); vqpci->vq.free_head = 0; vqpci->vq.num_free = vqpci->vq.size; vqpci->vq.align = VIRTIO_PCI_VRING_ALIGN; @@ -241,12 +242,12 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, addr = guest_alloc(alloc, qvring_size(vqpci->vq.size, VIRTIO_PCI_VRING_ALIGN)); qvring_init(qvpcidev->pdev->bus->qts, alloc, &vqpci->vq, addr); -qvirtio_pci_set_queue_address(d, &vqpci->vq); +d->bus->set_queue_address(d, &vqpci->vq); return &vqpci->vq; } -static void qvirtio_pci_virtqueue_cleanup(QVirtQueue *vq, +void qvirtio_pci_virtqueue_cleanup_common(QVirtQueue *vq, QGuestAllocator *alloc) { QVirtQueuePCI *vqpci = container_of(vq, QVirtQueuePCI, vq); @@ -276,8 +277,8 @@ const QVirtioBus qvirtio_pci = { .queue_select = qvirtio_pci_queue_select, .get_queue_size = qvirtio_pci_get_queue_size, .set_queue_address = qvirtio_pci_set_queue_address, -.virtqueue_setup = qvirtio_pci_virtqueue_setup, -.virtqueue_cleanup = qvirtio_pci_virtqueue_cleanup, +.virtqueue_setup = qvirtio_pci_virtqueue_setup_common, +.virtqueue_cleanup = qvirtio_pci_virtqueue_cleanup_common, .virtqueue_kick = qvirtio_pci_virtqueue_kick, }; -- 2.21.0
[PATCH v4 16/16] libqos: add VIRTIO PCI 1.0 support
Implement the VIRTIO 1.0 virtio-pci interface. The main change here is that the register layout is no longer a fixed layout in BAR 0. Instead we have to iterate of PCI Capabilities to find descriptions of where various registers are located. The vring registers are also more fine-grained, allowing for more flexible vring layouts, but we don't take advantage of that. Signed-off-by: Stefan Hajnoczi Reviewed-by: Sergio Lopez --- tests/Makefile.include | 1 + tests/libqos/virtio-pci-modern.h | 17 ++ tests/libqos/virtio-pci.h| 10 + tests/libqos/virtio-pci-modern.c | 443 +++ tests/libqos/virtio-pci.c| 6 +- 5 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 tests/libqos/virtio-pci-modern.h create mode 100644 tests/libqos/virtio-pci-modern.c diff --git a/tests/Makefile.include b/tests/Makefile.include index 3543451ed3..3f633c8313 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -715,6 +715,7 @@ qos-test-obj-y += tests/libqos/virtio-blk.o qos-test-obj-y += tests/libqos/virtio-mmio.o qos-test-obj-y += tests/libqos/virtio-net.o qos-test-obj-y += tests/libqos/virtio-pci.o +qos-test-obj-y += tests/libqos/virtio-pci-modern.o qos-test-obj-y += tests/libqos/virtio-rng.o qos-test-obj-y += tests/libqos/virtio-scsi.o qos-test-obj-y += tests/libqos/virtio-serial.o diff --git a/tests/libqos/virtio-pci-modern.h b/tests/libqos/virtio-pci-modern.h new file mode 100644 index 00..6bf2b207c3 --- /dev/null +++ b/tests/libqos/virtio-pci-modern.h @@ -0,0 +1,17 @@ +/* + * libqos virtio PCI VIRTIO 1.0 definitions + * + * Copyright (c) 2019 Red Hat, Inc + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef LIBQOS_VIRTIO_PCI_MODERN_H +#define LIBQOS_VIRTIO_PCI_MODERN_H + +#include "virtio-pci.h" + +bool qvirtio_pci_init_virtio_1(QVirtioPCIDevice *dev); + +#endif /* LIBQOS_VIRTIO_PCI_MODERN_H */ diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h index 6b3a385b06..294d5567ee 100644 --- a/tests/libqos/virtio-pci.h +++ b/tests/libqos/virtio-pci.h @@ -27,6 +27,13 @@ typedef struct QVirtioPCIDevice { uint32_t config_msix_data; int bar_idx; + +/* VIRTIO 1.0 */ +uint32_t common_cfg_offset; +uint32_t notify_cfg_offset; +uint32_t notify_off_multiplier; +uint32_t isr_cfg_offset; +uint32_t device_cfg_offset; } QVirtioPCIDevice; struct QVirtioPCIMSIXOps { @@ -43,6 +50,9 @@ typedef struct QVirtQueuePCI { uint16_t msix_entry; uint64_t msix_addr; uint32_t msix_data; + +/* VIRTIO 1.0 */ +uint64_t notify_offset; } QVirtQueuePCI; void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * addr); diff --git a/tests/libqos/virtio-pci-modern.c b/tests/libqos/virtio-pci-modern.c new file mode 100644 index 00..18d118866f --- /dev/null +++ b/tests/libqos/virtio-pci-modern.c @@ -0,0 +1,443 @@ +/* + * libqos VIRTIO 1.0 PCI driver + * + * Copyright (c) 2019 Red Hat, Inc + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "standard-headers/linux/pci_regs.h" +#include "standard-headers/linux/virtio_pci.h" +#include "standard-headers/linux/virtio_config.h" +#include "virtio-pci-modern.h" + +static uint8_t config_readb(QVirtioDevice *d, uint64_t addr) +{ +QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev); +return qpci_io_readb(dev->pdev, dev->bar, dev->device_cfg_offset + addr); +} + +static uint16_t config_readw(QVirtioDevice *d, uint64_t addr) +{ +QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev); +return qpci_io_readw(dev->pdev, dev->bar, dev->device_cfg_offset + addr); +} + +static uint32_t config_readl(QVirtioDevice *d, uint64_t addr) +{ +QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev); +return qpci_io_readl(dev->pdev, dev->bar, dev->device_cfg_offset + addr); +} + +static uint64_t config_readq(QVirtioDevice *d, uint64_t addr) +{ +QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev); +return qpci_io_readq(dev->pdev, dev->bar, dev->device_cfg_offset + addr); +} + +static uint64_t get_features(QVirtioDevice *d) +{ +QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev); +uint64_t lo, hi; + +qpci_io_writel(dev->pdev, dev->bar, dev->common_cfg_offset + + offsetof(struct virtio_pci_common_cfg, +device_feature_select), + 0); +lo = qpci_io_readl(dev->pdev, dev->bar, dev->common_cfg_offset + + offsetof(struct virtio_pci_common_cfg, device_feature)); + +qpci_io_writel(dev->pdev, dev->bar, dev->common_cfg_offset + + offsetof(struct virtio_pci_common_cfg, +device_feature_select), +
Re: [Bug 1847232] Re: qemu TCG in s390x mode issue with calculating HASH
On 23.10.19 11:37, Ivan Warren wrote: > Looks fixed to me ! The issue no longer shows even without specifying > vx=off > Nice, I suspect that there might be more issues when using golang (as it really makes excessive use of vector registers to my surprise). So in case you run into problems (and especially can't reproduce with vx=off), please inform me! Thanks! -- Thanks, David / dhildenb -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1847232 Title: qemu TCG in s390x mode issue with calculating HASH Status in QEMU: Fix Committed Bug description: When using go on s390x on Debian x64 (buster) (host) and debian s390x (sid) (guest) I run into the following problem : The following occurs while trying to build a custom project : go: github.com/FactomProject/basen@v0.0.0-20150613233007-fe3947df716e: Get https://proxy.golang.org/github.com/%21factom%21project/basen/@v/v0.0.0-20150613233007-fe3947df716e.mod: local error: tls: bad record MAC Doing a git bisect I find that this problem only occurs on and after commit 08ef92d556c584c7faf594ff3af46df456276e1b Before that commit, all works fine. Past this commit, build always fails. Without any proof, It looks like a hash calculation bug related to using z/Arch vector facilities... To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1847232/+subscriptions
[PATCH v7 05/14] target/mips: msa: Split helpers for _.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 20 ++- target/mips/msa_helper.c | 320 ++- target/mips/translate.c | 76 +-- 3 files changed, 372 insertions(+), 44 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index cef4de6..6419bb8 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -881,10 +881,26 @@ DEF_HELPER_4(msa_max_a_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_max_a_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_max_a_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_max_a_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_d, void, env, i32, i32, i32) DEF_HELPER_4(msa_min_a_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_min_a_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_min_a_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_min_a_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_d, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_u_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_u_h, void, env, i32, i32, i32) @@ -945,10 +961,6 @@ DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_addv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subv_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_max_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_max_u_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_min_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_min_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 3eb0ab1..65df15d 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1810,6 +1810,152 @@ void helper_msa_max_a_d(CPUMIPSState *env, } +static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +return arg1 > arg2 ? arg1 : arg2; +} + +void helper_msa_max_s_b(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->b[0] = msa_max_s_df(DF_BYTE, pws->b[0], pwt->b[0]); +pwd->b[1] = msa_max_s_df(DF_BYTE, pws->b[1], pwt->b[1]); +pwd->b[2] = msa_max_s_df(DF_BYTE, pws->b[2], pwt->b[2]); +pwd->b[3] = msa_max_s_df(DF_BYTE, pws->b[3], pwt->b[3]); +pwd->b[4] = msa_max_s_df(DF_BYTE, pws->b[4], pwt->b[4]); +pwd->b[5] = msa_max_s_df(DF_BYTE, pws->b[5], pwt->b[5]); +pwd->b[6] = msa_max_s_df(DF_BYTE, pws->b[6], pwt->b[6]); +pwd->b[7] = msa_max_s_df(DF_BYTE, pws->b[7], pwt->b[7]); +pwd->b[8] = msa_max_s_df(DF_BYTE, pws->b[8], pwt->b[8]); +pwd->b[9] = msa_max_s_df(DF_BYTE, pws->b[9], pwt->b[9]); +pwd->b[10] = msa_max_s_df(DF_BYTE, pws->b[10], pwt->b[10]); +pwd->b[11] = msa_max_s_df(DF_BYTE, pws->b[11], pwt->b[11]); +pwd->b[12] = msa_max_s_df(DF_BYTE, pws->b[12], pwt->b[12]); +pwd->b[13] = msa_max_s_df(DF_BYTE, pws->b[13], pwt->b[13]); +pwd->b[14] = msa_max_s_df(DF_BYTE, pws->b[14], pwt->b[14]); +pwd->b[15] = msa_max_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_max_s_h(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_max_s_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_max_s_df(DF_HALF, pws->h[1], pwt->h[1]); +pwd->h[2] = msa_max_s_df(DF_HALF, pws->h[2], pwt->h[2]); +pwd->h[3] = msa_max_s_df(DF_HALF, pws->h[3], pwt->h[3]); +pwd->h[4] = msa_max_s_df(DF_HALF, pws->h[4], pwt->h[4]); +pwd->h[5] = msa_max_s_df(DF_HALF, pws->h[5], pwt->h[5]); +pwd->h[6] = msa_max_s_df(DF_HALF, pws->h[6], pwt->h[6]); +pwd->h[7] = msa_max_s_df(DF_HALF, pws->h[7], pwt->h[7]); +}
Re: [PATCH v4 04/16] virtio-scsi-test: add missing feature negotiation
- Original Message - > From: "Stefan Hajnoczi" > Sent: Wednesday, October 23, 2019 12:04:13 PM > > VIRTIO Device Initialization requires feature negotiation. Currently > virtio-scsi-test.c is non-compliant. > > libqos tests acknowledge all feature bits advertised by the device, > except VIRTIO_F_BAD_FEATURE (which devices use to detect broken > drivers!) and VIRTIO_RING_F_EVENT_IDX (which is not implemented in > libqos and accepting it would break notifications). > > Signed-off-by: Stefan Hajnoczi > --- > tests/virtio-scsi-test.c | 8 > 1 file changed, 8 insertions(+) Reviewed-by: Thomas Huth"
[PATCH v7 10/14] target/mips: msa: Split helpers for PCK.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 11 +- target/mips/msa_helper.c | 386 +-- target/mips/translate.c | 38 - 3 files changed, 249 insertions(+), 186 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index f779404..7bb13d5 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -967,6 +967,15 @@ DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_sll_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_sll_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_sll_w, void, env, i32, i32, i32) @@ -1049,8 +1058,6 @@ DEF_HELPER_5(msa_dpsub_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_dpsub_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_pckev_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_pckod_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_hsub_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 38ff1da..2400632 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -3430,7 +3430,214 @@ void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws) * +---+--+ */ -/* TODO: insert Pack group helpers here */ + +void helper_msa_pckev_b(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +#if defined(HOST_WORDS_BIGENDIAN) +pwd->b[8] = pws->b[9]; +pwd->b[10] = pws->b[13]; +pwd->b[12] = pws->b[1]; +pwd->b[14] = pws->b[5]; +pwd->b[0] = pwt->b[9]; +pwd->b[2] = pwt->b[13]; +pwd->b[4] = pwt->b[1]; +pwd->b[6] = pwt->b[5]; +pwd->b[9] = pws->b[11]; +pwd->b[13] = pws->b[3]; +pwd->b[1] = pwt->b[11]; +pwd->b[5] = pwt->b[3]; +pwd->b[11] = pws->b[15]; +pwd->b[3] = pwt->b[15]; +pwd->b[15] = pws->b[7]; +pwd->b[7] = pwt->b[7]; +#else +pwd->b[15] = pws->b[14]; +pwd->b[13] = pws->b[10]; +pwd->b[11] = pws->b[6]; +pwd->b[9] = pws->b[2]; +pwd->b[7] = pwt->b[14]; +pwd->b[5] = pwt->b[10]; +pwd->b[3] = pwt->b[6]; +pwd->b[1] = pwt->b[2]; +pwd->b[14] = pws->b[12]; +pwd->b[10] = pws->b[4]; +pwd->b[6] = pwt->b[12]; +pwd->b[2] = pwt->b[4]; +pwd->b[12] = pws->b[8]; +pwd->b[4] = pwt->b[8]; +pwd->b[8] = pws->b[0]; +pwd->b[0] = pwt->b[0]; +#endif +} + +void helper_msa_pckev_h(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +#if defined(HOST_WORDS_BIGENDIAN) +pwd->h[4] = pws->h[5]; +pwd->h[6] = pws->h[1]; +pwd->h[0] = pwt->h[5]; +pwd->h[2] = pwt->h[1]; +pwd->h[5] = pws->h[7]; +pwd->h[1] = pwt->h[7]; +pwd->h[7] = pws->h[3]; +pwd->h[3] = pwt->h[3]; +#else +pwd->h[7] = pws->h[6]; +pwd->h[5] = pws->h[2]; +pwd->h[3] = pwt->h[6]; +pwd->h[1] = pwt->h[2]; +pwd->h[6] = pws->h[4]; +pwd->h[2] = pwt->h[4]; +pwd->h[4] = pws->h[0]; +pwd->h[0] = pwt->h[0]; +#endif +} + +void helper_msa_pckev_w(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +#if defined(HOST_WORDS_BIGENDIAN) +pwd->w[2] = pws->w[3]; +pwd->w[0] = pwt->w[3]; +pwd->w[3] = pws->w[1]; +pwd->w[1] = pwt->w[1]; +#else +pwd->w[3] = pws->w[2]; +pwd->w[1] = pwt->w[2]; +pwd->w[2] = pws->w[0]; +pwd->w[0] = pwt->w[0]; +#endif +} + +void helper_msa_pckev_d(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr)
[PATCH] buildfix: update texinfo menu
Build error message: qemu-doc.texi:34: node `Top' lacks menu item for `Recently removed features' despite being its Up target Fixes: 3264ffced3d0 ("dirty-bitmaps: remove deprecated autoload parameter") Signed-off-by: Gerd Hoffmann --- qemu-doc.texi | 1 + 1 file changed, 1 insertion(+) diff --git a/qemu-doc.texi b/qemu-doc.texi index 3c5022050f0f..3ddf5c0a6865 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -44,6 +44,7 @@ * Security:: * Implementation notes:: * Deprecated features:: +* Recently removed features:: * Supported build platforms:: * License:: * Index:: -- 2.18.1
[PATCH v7 07/14] target/mips: msa: Split helpers for ADD<_A|S_A|S_S|S_U|V>.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 30 +++- target/mips/msa_helper.c | 426 +-- target/mips/translate.c | 95 +-- 3 files changed, 482 insertions(+), 69 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index f3df187..ce01e97 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -822,6 +822,31 @@ DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_addv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32) @@ -976,12 +1001,7 @@ DEF_HELPER_5(msa_sra_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srl_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_addv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subv_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_adds_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subs_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subs_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subsus_u_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 499fcde..c31f46c 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -805,7 +805,383 @@ void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) * +---+--+ */ -/* TODO: insert Int Add group helpers here */ + +static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1; +uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2; +return abs_arg1 + abs_arg2; +} + +void helper_msa_add_a_b(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->b[0] = msa_add_a_df(DF_BYTE, pws->b[0], pwt->b[0]); +pwd->b[1] = msa_add_a_df(DF_BYTE, pws->b[1], pwt->b[1]); +pwd->b[2] = msa_add_a_df(DF_BYTE, pws->b[2], pwt->b[2]); +pwd->b[3] = msa_add_a_df(DF_BYTE, pws->b[3], pwt->b[3]); +pwd->b[4] = msa_add_a_df(DF_BYTE, pws->b[4], pwt->b[4]); +pwd->b[5] = msa_add_a_df(DF_BYTE, pws->b[5], pwt->b[5]); +pwd->b[6] = msa_add_a_df(DF_BYTE, pws->b[6], pwt->b[6]); +pwd->b[7] = msa_add_a_df(DF_BYTE, pws->b[7], pwt->b[7]); +pwd->b[8] = msa_add_a_df(DF_BYTE, pws->b[8], pwt->b[8]); +pwd->b[9] = msa_add_a_df(DF_BYTE, pws->b[9], pwt->b[9]); +pwd->b[10] = msa_add_a_df(DF_BYTE, pws->b[10], pwt->b[10]); +pwd->b[11] = msa_add_a_df(DF_BYTE, pws->b[11], pwt->b[11]); +pwd->b[12] = msa_add_a_df(DF_BYTE, pws->b[12], pwt->b[12]); +pwd->b[13] = msa_add_a_df(DF_BYTE, pws->b[13], pwt->b[13]); +pwd->b[14] = msa_add_a_df(DF_BYTE, pws->b[14], pwt->b[14]); +pwd->b[15] = msa_add_a_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_add_a_h(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_add_a_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_add_a_df(DF_HALF, pws->h[1],
Re: [PATCH] audio: fix missing break
On 10/23/19 10:24 AM, Paolo Bonzini wrote: Reported by Coverity (CID 1406449). Gerd sent the same patch earlier: https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg05923.html But your description is better. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Paolo Bonzini --- audio/paaudio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/audio/paaudio.c b/audio/paaudio.c index df541a72d3..55a91f8980 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -385,6 +385,7 @@ static pa_stream *qpa_simple_new ( map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT; map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT; map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT; +break; default: dolog("Internal error: unsupported channel count %d\n", ss->channels);
Re: [PATCH v4 06/16] libqos: add missing virtio-9p feature negotiation
- Original Message - > From: "Stefan Hajnoczi" > Sent: Wednesday, October 23, 2019 12:04:15 PM > > VIRTIO Device Initialization requires feature negotiation. The libqos > virtio-9p driver lacks feature negotiation and is therefore > non-compliant. > > libqos tests acknowledge all feature bits advertised by the device, > except VIRTIO_F_BAD_FEATURE (which devices use to detect broken > drivers!) and VIRTIO_RING_F_EVENT_IDX (which is not implemented in > libqos and accepting it would break notifications). > > Signed-off-by: Stefan Hajnoczi > --- > tests/libqos/virtio-9p.c | 6 ++ > 1 file changed, 6 insertions(+) Reviewed-by: Thomas Huth"
[PATCH v7 13/14] target/mips: Add support for emulation of CRC32 group of instructions
From: Aleksandar Markovic Add emulation of MIPS' CRC32 (Cyclic Redundancy Check) instructions. Reuse zlib crc32() and Linux crc32c(). Note that, at the time being, there is no MIPS CPU that supports CRC32 instructions (they are an optional part of MIPS64/32 R6 anf nanoMIPS ISAs). Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Markovic --- disas/mips.c| 8 target/mips/helper.h| 2 ++ target/mips/op_helper.c | 22 ++ target/mips/translate.c | 41 + 4 files changed, 73 insertions(+) diff --git a/disas/mips.c b/disas/mips.c index dfefe5e..75c48b3 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1409,6 +1409,14 @@ const struct mips_opcode mips_builtin_opcodes[] = {"dvp","t", 0x41600024, 0xffe0, TRAP|WR_t,0, I32R6}, {"evp","", 0x4164, 0x, TRAP, 0, I32R6}, {"evp","t", 0x4164, 0xffe0, TRAP|WR_t,0, I32R6}, +{"crc32b", "t,v,t", 0x7c0f, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I32R6}, +{"crc32h", "t,v,t", 0x7c4f, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I32R6}, +{"crc32w", "t,v,t", 0x7c8f, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I32R6}, +{"crc32d", "t,v,t", 0x7ccf, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I64R6}, +{"crc32cb","t,v,t", 0x7c00010f, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I32R6}, +{"crc32ch","t,v,t", 0x7c00014f, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I32R6}, +{"crc32cw","t,v,t", 0x7c00018f, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I32R6}, +{"crc32cd","t,v,t", 0x7c0001cf, 0xfc00ff3f, WR_d | RD_s | RD_t, 0, I64R6}, /* MSA */ {"sll.b", "+d,+e,+f", 0x780d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA}, diff --git a/target/mips/helper.h b/target/mips/helper.h index 7b8ad74..2095330 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -40,6 +40,8 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) #endif +DEF_HELPER_3(crc32, tl, tl, tl, i32) +DEF_HELPER_3(crc32c, tl, tl, tl, i32) DEF_HELPER_FLAGS_4(rotx, TCG_CALL_NO_RWG_SE, tl, tl, i32, i32, i32) #ifndef CONFIG_USER_ONLY diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 18fcee4..3298980 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -27,6 +27,8 @@ #include "exec/memop.h" #include "sysemu/kvm.h" #include "fpu/softfloat.h" +#include "qemu/crc32c.h" +#include /*/ /* Exceptions processing helpers */ @@ -350,6 +352,26 @@ target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx, return (int64_t)(int32_t)(uint32_t)tmp5; } +/* these crc32 functions are based on target/arm/helper-a64.c */ +target_ulong helper_crc32(target_ulong val, target_ulong m, uint32_t sz) +{ +uint8_t buf[8]; +target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); + +m &= mask; +stq_le_p(buf, m); +return (int32_t) (crc32(val ^ 0x, buf, sz) ^ 0x); +} + +target_ulong helper_crc32c(target_ulong val, target_ulong m, uint32_t sz) +{ +uint8_t buf[8]; +target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); +m &= mask; +stq_le_p(buf, m); +return (int32_t) (crc32c(val, buf, sz) ^ 0x); +} + #ifndef CONFIG_USER_ONLY static inline hwaddr do_translate_address(CPUMIPSState *env, diff --git a/target/mips/translate.c b/target/mips/translate.c index 20c69d2..b8e2707 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -451,6 +451,7 @@ enum { OPC_LWE= 0x2F | OPC_SPECIAL3, /* R6 */ +OPC_CRC32 = 0x0F | OPC_SPECIAL3, R6_OPC_PREF= 0x35 | OPC_SPECIAL3, R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, R6_OPC_LL = 0x36 | OPC_SPECIAL3, @@ -2547,6 +2548,7 @@ typedef struct DisasContext { bool nan2008; bool abs2008; bool saar; +bool crcp; } DisasContext; #define DISAS_STOP DISAS_TARGET_0 @@ -27017,6 +27019,33 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) } } +static void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz, + int crc32c) +{ +TCGv t0; +TCGv t1; +TCGv_i32 tsz = tcg_const_i32(1 << sz); +if (rd == 0) { +/* Treat as NOP. */ +return; +} +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +gen_load_gpr(t0, rt); +gen_load_gpr(t1, rs); + +if (crc32c) { +gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz); +} else { +gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz); +} + +tcg_temp_free(t0); +tcg_temp_free(t1); +tcg_temp_free_i32(tsz); +} + static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd, sa; @@ -27031,6 +27060,17 @@ s
[PATCH v7 14/14] target/mips: Demacro LMI decoder
From: Aleksandar Markovic This makes searches for instances of opcode usages easier. Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 247 +--- 1 file changed, 173 insertions(+), 74 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index b8e2707..36f57b1 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -5548,78 +5548,180 @@ static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) gen_load_fpr64(ctx, t0, rs); gen_load_fpr64(ctx, t1, rt); -#define LMI_HELPER(UP, LO) \ -case OPC_##UP: gen_helper_##LO(t0, t0, t1); break -#define LMI_HELPER_1(UP, LO) \ -case OPC_##UP: gen_helper_##LO(t0, t0); break -#define LMI_DIRECT(UP, LO, OP) \ -case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break - switch (opc) { -LMI_HELPER(PADDSH, paddsh); -LMI_HELPER(PADDUSH, paddush); -LMI_HELPER(PADDH, paddh); -LMI_HELPER(PADDW, paddw); -LMI_HELPER(PADDSB, paddsb); -LMI_HELPER(PADDUSB, paddusb); -LMI_HELPER(PADDB, paddb); - -LMI_HELPER(PSUBSH, psubsh); -LMI_HELPER(PSUBUSH, psubush); -LMI_HELPER(PSUBH, psubh); -LMI_HELPER(PSUBW, psubw); -LMI_HELPER(PSUBSB, psubsb); -LMI_HELPER(PSUBUSB, psubusb); -LMI_HELPER(PSUBB, psubb); - -LMI_HELPER(PSHUFH, pshufh); -LMI_HELPER(PACKSSWH, packsswh); -LMI_HELPER(PACKSSHB, packsshb); -LMI_HELPER(PACKUSHB, packushb); - -LMI_HELPER(PUNPCKLHW, punpcklhw); -LMI_HELPER(PUNPCKHHW, punpckhhw); -LMI_HELPER(PUNPCKLBH, punpcklbh); -LMI_HELPER(PUNPCKHBH, punpckhbh); -LMI_HELPER(PUNPCKLWD, punpcklwd); -LMI_HELPER(PUNPCKHWD, punpckhwd); - -LMI_HELPER(PAVGH, pavgh); -LMI_HELPER(PAVGB, pavgb); -LMI_HELPER(PMAXSH, pmaxsh); -LMI_HELPER(PMINSH, pminsh); -LMI_HELPER(PMAXUB, pmaxub); -LMI_HELPER(PMINUB, pminub); - -LMI_HELPER(PCMPEQW, pcmpeqw); -LMI_HELPER(PCMPGTW, pcmpgtw); -LMI_HELPER(PCMPEQH, pcmpeqh); -LMI_HELPER(PCMPGTH, pcmpgth); -LMI_HELPER(PCMPEQB, pcmpeqb); -LMI_HELPER(PCMPGTB, pcmpgtb); - -LMI_HELPER(PSLLW, psllw); -LMI_HELPER(PSLLH, psllh); -LMI_HELPER(PSRLW, psrlw); -LMI_HELPER(PSRLH, psrlh); -LMI_HELPER(PSRAW, psraw); -LMI_HELPER(PSRAH, psrah); - -LMI_HELPER(PMULLH, pmullh); -LMI_HELPER(PMULHH, pmulhh); -LMI_HELPER(PMULHUH, pmulhuh); -LMI_HELPER(PMADDHW, pmaddhw); - -LMI_HELPER(PASUBUB, pasubub); -LMI_HELPER_1(BIADD, biadd); -LMI_HELPER_1(PMOVMSKB, pmovmskb); - -LMI_DIRECT(PADDD, paddd, add); -LMI_DIRECT(PSUBD, psubd, sub); -LMI_DIRECT(XOR_CP2, xor, xor); -LMI_DIRECT(NOR_CP2, nor, nor); -LMI_DIRECT(AND_CP2, and, and); -LMI_DIRECT(OR_CP2, or, or); +case OPC_PADDSH: +gen_helper_paddsh(t0, t0, t1); +break; +case OPC_PADDUSH: +gen_helper_paddush(t0, t0, t1); +break; +case OPC_PADDH: +gen_helper_paddh(t0, t0, t1); +break; +case OPC_PADDW: +gen_helper_paddw(t0, t0, t1); +break; +case OPC_PADDSB: +gen_helper_paddsb(t0, t0, t1); +break; +case OPC_PADDUSB: +gen_helper_paddusb(t0, t0, t1); +break; +case OPC_PADDB: +gen_helper_paddb(t0, t0, t1); +break; + +case OPC_PSUBSH: gen_helper_psubsh(t0, t0, t1); +break; +case OPC_PSUBUSH: +gen_helper_psubush(t0, t0, t1); +break; +case OPC_PSUBH: +gen_helper_psubh(t0, t0, t1); +break; +case OPC_PSUBW: +gen_helper_psubw(t0, t0, t1); +break; +case OPC_PSUBSB: +gen_helper_psubsb(t0, t0, t1); +break; +case OPC_PSUBUSB: +gen_helper_psubusb(t0, t0, t1); +break; +case OPC_PSUBB: +gen_helper_psubb(t0, t0, t1); +break; + +case OPC_PSHUFH: +gen_helper_pshufh(t0, t0, t1); +break; +case OPC_PACKSSWH: +gen_helper_packsswh(t0, t0, t1); +break; +case OPC_PACKSSHB: +gen_helper_packsshb(t0, t0, t1); +break; +case OPC_PACKUSHB: +gen_helper_packushb(t0, t0, t1); +break; + +case OPC_PUNPCKLHW: +gen_helper_punpcklhw(t0, t0, t1); +break; +case OPC_PUNPCKHHW: +gen_helper_punpckhhw(t0, t0, t1); +break; +case OPC_PUNPCKLBH: +gen_helper_punpcklbh(t0, t0, t1); +break; +case OPC_PUNPCKHBH: +gen_helper_punpckhbh(t0, t0, t1); +break; +case OPC_PUNPCKLWD: +gen_helper_punpcklwd(t0, t0, t1); +break; +case OPC_PUNPCKHWD: +gen_helper_punpckhwd(t0, t0, t1); +break; + +case OPC_PAVGH: +gen_helper_pavgh(t0, t0, t1); +break; +case OPC_PAVGB: +gen_helper_pavgb(t0, t0, t1); +break; +case OPC_PMAXSH: +gen_helper_pmaxsh(t0, t0, t1); +break; +case OPC_PMINSH: +gen_helper_pminsh(t0, t0, t1); +break; +
[PATCH v7 03/14] MAINTAINERS: Update mail address of Aleksandar Rikalo
From: Aleksandar Markovic Aleksandar Rikalo wishes to change his primary mail address for QEMU. Some minor line order is corrected in .mailmap to be alphabetical, too. Reviewed-by: Aleksandar Rikalo Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Aleksandar Markovic --- .mailmap| 5 +++-- MAINTAINERS | 18 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.mailmap b/.mailmap index 0756a0b..3816e4e 100644 --- a/.mailmap +++ b/.mailmap @@ -39,10 +39,11 @@ Julia Suvorova Julia Suvorova via Qemu-devel Justin Terry (VM) via Qemu-devel # Next, replace old addresses by a more recent one. -Anthony Liguori Anthony Liguori -James Hogan Aleksandar Markovic Aleksandar Markovic +Aleksandar Rikalo +Anthony Liguori Anthony Liguori +James Hogan Paul Burton Paul Burton Paul Burton diff --git a/MAINTAINERS b/MAINTAINERS index 3ca8148..4964fbb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -208,7 +208,7 @@ F: disas/microblaze.c MIPS TCG CPUs M: Aurelien Jarno M: Aleksandar Markovic -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Maintained F: target/mips/ F: default-configs/*mips* @@ -363,7 +363,7 @@ F: target/arm/kvm.c MIPS KVM CPUs M: James Hogan -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Maintained F: target/mips/kvm.c @@ -934,7 +934,7 @@ MIPS Machines - Jazz M: Hervé Poussineau -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Maintained F: hw/mips/mips_jazz.c F: hw/display/jazz_led.c @@ -942,7 +942,7 @@ F: hw/dma/rc4030.c Malta M: Aurelien Jarno -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Maintained F: hw/mips/mips_malta.c F: hw/mips/gt64xxx_pci.c @@ -950,20 +950,20 @@ F: tests/acceptance/linux_ssh_mips_malta.py Mipssim M: Aleksandar Markovic -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Odd Fixes F: hw/mips/mips_mipssim.c F: hw/net/mipsnet.c R4000 M: Aurelien Jarno -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Maintained F: hw/mips/mips_r4k.c Fulong 2E M: Aleksandar Markovic -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Odd Fixes F: hw/mips/mips_fulong2e.c F: hw/isa/vt82c686.c @@ -972,7 +972,7 @@ F: include/hw/isa/vt82c686.h Boston M: Paul Burton -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Maintained F: hw/core/loader-fit.c F: hw/mips/boston.c @@ -2348,7 +2348,7 @@ F: disas/i386.c MIPS TCG target M: Aurelien Jarno -R: Aleksandar Rikalo +R: Aleksandar Rikalo S: Maintained F: tcg/mips/ -- 2.7.4
[PATCH v7 11/14] target/mips: msa: Split helpers for HSUB_.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 10 - target/mips/msa_helper.c | 108 +-- target/mips/translate.c | 32 +++--- 3 files changed, 129 insertions(+), 21 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 7bb13d5..d7c4bbf 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -945,6 +945,14 @@ DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hsub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_ilvev_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ilvev_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_ilvev_w, void, env, i32, i32, i32) @@ -1059,8 +1067,6 @@ DEF_HELPER_5(msa_dpsub_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_hsub_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 2400632..ae9e8e0 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -2888,7 +2888,101 @@ void helper_msa_mod_u_d(CPUMIPSState *env, * +---+--+ */ -/* TODO: insert Int Subtract group helpers here */ +/* TODO: insert the rest of Int Subtract group helpers here */ + + +static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df); +} + +void helper_msa_hsub_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_hsub_s_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_hsub_s_df(DF_HALF, pws->h[1], pwt->h[1]); +pwd->h[2] = msa_hsub_s_df(DF_HALF, pws->h[2], pwt->h[2]); +pwd->h[3] = msa_hsub_s_df(DF_HALF, pws->h[3], pwt->h[3]); +pwd->h[4] = msa_hsub_s_df(DF_HALF, pws->h[4], pwt->h[4]); +pwd->h[5] = msa_hsub_s_df(DF_HALF, pws->h[5], pwt->h[5]); +pwd->h[6] = msa_hsub_s_df(DF_HALF, pws->h[6], pwt->h[6]); +pwd->h[7] = msa_hsub_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_hsub_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->w[0] = msa_hsub_s_df(DF_WORD, pws->w[0], pwt->w[0]); +pwd->w[1] = msa_hsub_s_df(DF_WORD, pws->w[1], pwt->w[1]); +pwd->w[2] = msa_hsub_s_df(DF_WORD, pws->w[2], pwt->w[2]); +pwd->w[3] = msa_hsub_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_hsub_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->d[0] = msa_hsub_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); +pwd->d[1] = msa_hsub_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + + +static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df); +} + +void helper_msa_hsub_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_hsub_u_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_hsub_u_df(DF_HALF, pws->h[1], pwt->h[1]); +pwd->h[2] = msa_hsub_u_df(DF_HALF, pws->h[2], pwt->h[2]); +pwd->h[3] = msa_hsub_u_df(DF_HALF, pws->h[3], pwt->h[3]); +pwd->h[4] = msa_hsub_u_df(DF_HALF, pws->h[4], pwt->h[4]); +pwd->h[5] = msa_hsub_u_df(DF_HALF, pws->h[5], pwt->h[5]); +pwd->h[6] = msa_hsub_u_df(DF_HALF, pws->h[6], pwt->h[6]); +pwd->h[7] = msa_hsub_u_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_hsub_u_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(en
Re: [RFC PATCH 00/23] Add subcluster allocation to qcow2
Hi! This is very interesting! Could you please export a branch to look at, as patches can't be applied on master now :( 15.10.2019 18:23, Alberto Garcia wrote: > Hi, > > this series adds a new feature to the qcow2 on-disk format called > "Extended L2 Entries", which allows us to do subcluster allocation. > > This cover letter explains the reasons behind this proposal, the > changes to the on-disk format, test results and pending work. If you > are curious you can also have a look at previous discussions about > this feature: > > https://lists.gnu.org/archive/html/qemu-block/2017-04/msg00178.html > https://lists.gnu.org/archive/html/qemu-block/2019-06/msg01155.html > > This is the first proper version of the patches, and I believe that > the implementation is complete. However since I'm proposing a change > to the on-disk format I'm labeling this as RFC because I'm expecting > some debate. I'll remove the RFC tag and add more tests in future > revisions. > > === Problem === > > A qcow2 image is divided into units of constant size called clusters, > and among other things it contains metadata that maps guest addresses > to host addresses (the so-called L1 and L2 tables). > > There are two basic problems that result from this: > > 1) Reading from or writing to a qcow2 image involves reading the > corresponding entry on the L2 table that maps the guest address to > the host address. This is very slow because it involves two I/O > operations: one on the L2 table and the other one on the actual > data cluster. > > 2) A cluster is the smallest unit of allocation. Therefore writing a > mere 512 bytes to an empty disk requires allocating a complete > cluster and filling it with zeroes (or with data from the backing > image if there is one). This wastes more disk space and also has a > negative impact on I/O. > > Problem (1) can be solved by caching the L2 tables in memory. The > maximum amount of disk space used by L2 tables depends on the virtual > disk size and the cluster size: > > max_l2_size = virtual_disk_size * 8 / cluster_size > > Because of this, the only way to reduce the size of the L2 tables is > by increasing the cluster size (which can be any power of two between > 512 bytes and 2 MB). But then we hit problem (2): I/O is slower and > more disk space is wasted. > > === The proposal === > > The proposal is to extend the qcow2 format by allowing subcluster > allocation. The on-disk format remains essentially the same, except > that each data cluster is internally divided into 32 subclusters of > equal size. > > The way it works in practice is with a new optional feature called > "Extended L2 Entries", that needs to be enabled when an image is > created. With this, each entry on an L2 table is accompanied by a > bitmap indicating the allocation state of each one of the subclusters > for that cluster. The size of an L2 entry doubles from 64 to 128 bits. > > Other than L2 entries, all other data structures remain unchanged, but > for data clusters the smallest unit of allocation is now the > subcluster. Reference counting is still at the cluster level, because > there is no way to reference individual subclusters. Copy-on-write on > internal snapshots needs to copy complete clusters, so that scenario > would not benefit from this change. > > I see two main use cases for this feature: > > a) The qcow2 image is not too large / the L2 cache is not a problem, > but you want to increase the allocation performance. In this case > you can have a 128KB cluster with 4KB subclusters (with 4KB being a > common block size in ext4 and other filesystems) > > b) The qcow2 image is very large and you want to save metadata space > in order to have a smaller L2 cache. In this case you can go for > the maximum cluster size (2MB) but you want to have smaller > subclusters to increase the allocation performance and optimize the > disk usage. > > === Changes to the on-disk format === > > An L2 entry is 64 bits wide, with this format (for uncompressed > clusters): > > 6356 5548 4740 3932 3124 2316 15 8 7 0 > > **<> <--><--->* >Rsrved host cluster offset of data Reserved >(6 bits)(47 bits) (8 bits) > > bit 63: refcount == 1 (QCOW_OFLAG_COPIED) > bit 62: compressed = 1 (QCOW_OFLAG_COMPRESSED) > bit 0: all zeros (QCOW_OFLAG_ZERO) > > If Extended L2 Entries are enabled, bit 0 becomes reserved and must be > unset, and this 64-bit bitmap follows the entry: > > 6356 5548 4740 3932 3124 2316 15 8 7 0 > > <-> <-> >
[PATCH v7 01/14] target/mips: Clean up helper.c
From: Aleksandar Markovic Mostly fix errors and warnings reported by 'checkpatch.pl -f'. Cc: Markus Armbruster Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.c | 123 +++ 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/target/mips/helper.c b/target/mips/helper.c index a2b6459..781930a 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -39,8 +39,8 @@ enum { #if !defined(CONFIG_USER_ONLY) /* no MMU emulation */ -int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, -target_ulong address, int rw, int access_type) +int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, + target_ulong address, int rw, int access_type) { *physical = address; *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; @@ -48,26 +48,28 @@ int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, } /* fixed mapping MMU emulation */ -int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, - target_ulong address, int rw, int access_type) +int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, + target_ulong address, int rw, int access_type) { if (address <= (int32_t)0x7FFFUL) { -if (!(env->CP0_Status & (1 << CP0St_ERL))) +if (!(env->CP0_Status & (1 << CP0St_ERL))) { *physical = address + 0x4000UL; -else +} else { *physical = address; -} else if (address <= (int32_t)0xBFFFUL) +} +} else if (address <= (int32_t)0xBFFFUL) { *physical = address & 0x1FFF; -else +} else { *physical = address; +} *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; return TLBRET_MATCH; } /* MIPS32/MIPS64 R4000-style MMU emulation */ -int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, - target_ulong address, int rw, int access_type) +int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, +target_ulong address, int rw, int access_type) { uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; int i; @@ -99,8 +101,9 @@ int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, if (rw != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) { *physical = tlb->PFN[n] | (address & (mask >> 1)); *prot = PAGE_READ; -if (n ? tlb->D1 : tlb->D0) +if (n ? tlb->D1 : tlb->D0) { *prot |= PAGE_WRITE; +} if (!(n ? tlb->XI1 : tlb->XI0)) { *prot |= PAGE_EXEC; } @@ -130,7 +133,7 @@ static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx) int32_t adetlb_mask; switch (mmu_idx) { -case 3 /* ERL */: +case 3: /* ERL */ /* If EU is set, always unmapped */ if (eu) { return 0; @@ -204,7 +207,7 @@ static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical, pa & ~(hwaddr)segmask); } -static int get_physical_address (CPUMIPSState *env, hwaddr *physical, +static int get_physical_address(CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong real_address, int rw, int access_type, int mmu_idx) { @@ -252,14 +255,15 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical, } else { segctl = env->CP0_SegCtl2 >> 16; } -ret = get_segctl_physical_address(env, physical, prot, real_address, rw, - access_type, mmu_idx, segctl, - 0x3FFF); +ret = get_segctl_physical_address(env, physical, prot, + real_address, rw, access_type, + mmu_idx, segctl, 0x3FFF); #if defined(TARGET_MIPS64) } else if (address < 0x4000ULL) { /* xuseg */ if (UX && address <= (0x3FFFULL & env->SEGMask)) { -ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type); +ret = env->tlb->map_address(env, physical, prot, +real_address, rw, access_type); } else { ret = TLBRET_BADADDR; } @@ -267,7 +271,8 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical, /* xsseg */ if ((supervisor_mode || kernel_mode) && SX && address <= (0x7FFFULL & env->SEGMask)) { -ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type); +ret = env->tlb->map_address(env, physica
Re: [PATCH v2 0/4] apic: Fix migration breakage of >255 vcpus
On Sat, Oct 19, 2019 at 11:41:53AM +0800, Peter Xu wrote: > On Wed, Oct 16, 2019 at 11:40:01AM -0300, Eduardo Habkost wrote: > > On Wed, Oct 16, 2019 at 10:29:29AM +0800, Peter Xu wrote: > > > v2: > > > - use uint32_t rather than int64_t [Juan] > > > - one more patch (patch 4) to check dup SaveStateEntry [Dave] > > > - one more patch to define a macro (patch 1) to simplify patch 2 > > > > > > Please review, thanks. > > > > I wonder how hard it is to write a simple test case to reproduce > > the original bug. We can extend tests/migration-test.c or > > tests/acceptance/migration.py. If using -device with explicit > > apic-id, we probably don't even need to create >255 VCPUs. > > I can give it a shot next week. :) When I was playing with it, I noticed that it's not that easy at least for the migration-test. We need to do these: - add one specific CPU with apic-id>255, this is easy by using "-device qemu64-x86_64-cpu,..." - enable x2apic in the guest code, read apic-id on the special vcpu to make sure it's correct even after migration, but before that... - I failed to find a way to use apic-id>255 as the BSP of system but I can only create APs with apic-id>255, so we need to add initial MP support for the migration guest code, then run that apic-id check code on the new AP - I also probably found that q35 bug on bootstraping the 512B disk, so we probably need to workaround that too until fixed Unless someone has better idea on this, I'll simply stop here because I'm afraid it does not worth the effort so far... (or until we have some other requirement to enrich the migration qtest framework) -- Peter Xu
[PATCH v7 06/14] target/mips: msa: Split helpers for ILV.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 21 +- target/mips/msa_helper.c | 768 +-- target/mips/translate.c | 76 - 3 files changed, 496 insertions(+), 369 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 6419bb8..f3df187 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -912,6 +912,23 @@ DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) @@ -984,10 +1001,6 @@ DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_pckev_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_pckod_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ilvl_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ilvr_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ilvev_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ilvod_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srar_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srlr_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 65df15d..499fcde 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -2432,7 +2432,421 @@ void helper_msa_mod_u_d(CPUMIPSState *env, * +---+--+ */ -/* TODO: insert Interleave group helpers here */ + +void helper_msa_ilvev_b(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +#if defined(HOST_WORDS_BIGENDIAN) +pwd->b[8] = pws->b[9]; +pwd->b[9] = pwt->b[9]; +pwd->b[10] = pws->b[11]; +pwd->b[11] = pwt->b[11]; +pwd->b[12] = pws->b[13]; +pwd->b[13] = pwt->b[13]; +pwd->b[14] = pws->b[15]; +pwd->b[15] = pwt->b[15]; +pwd->b[0] = pws->b[1]; +pwd->b[1] = pwt->b[1]; +pwd->b[2] = pws->b[3]; +pwd->b[3] = pwt->b[3]; +pwd->b[4] = pws->b[5]; +pwd->b[5] = pwt->b[5]; +pwd->b[6] = pws->b[7]; +pwd->b[7] = pwt->b[7]; +#else +pwd->b[15] = pws->b[14]; +pwd->b[14] = pwt->b[14]; +pwd->b[13] = pws->b[12]; +pwd->b[12] = pwt->b[12]; +pwd->b[11] = pws->b[10]; +pwd->b[10] = pwt->b[10]; +pwd->b[9] = pws->b[8]; +pwd->b[8] = pwt->b[8]; +pwd->b[7] = pws->b[6]; +pwd->b[6] = pwt->b[6]; +pwd->b[5] = pws->b[4]; +pwd->b[4] = pwt->b[4]; +pwd->b[3] = pws->b[2]; +pwd->b[2] = pwt->b[2]; +pwd->b[1] = pws->b[0]; +pwd->b[0] = pwt->b[0]; +#endif +} + +void helper_msa_ilvev_h(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +#if defined(HOST_WORDS_BIGENDIAN) +pwd->h[4] = pws->h[5]; +pwd->h[5] = pwt->h[5]; +pwd->h[6] = pws->h[7]; +pwd->h[7] = pwt->h[7]; +pwd->h[0] = pws->h[1]; +pwd->h[1] = pwt->h[1]; +pwd->h[2] = pws->h[3]; +pwd->h[3] = pwt->h[3]; +#else +pwd->h[7] = pws->h[6]; +pwd->h[6] = pwt->h[6]; +pwd->h[5] = pws->h[4]; +pwd->h[4] = pwt->h[4]; +pwd->h[3] = pws->h[2]; +pwd->h[2] = pwt->h[2]; +pwd->h[1] = pws->h[0]; +pwd->h[0] = pwt->h[0]; +#endif +} + +void helper_msa_ilvev_w(CPUMIPSState *env, +uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +#if defined(HOST_WORDS
[PATCH v7 08/14] target/mips: msa: Split helpers for HADD_.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 10 +++- target/mips/msa_helper.c | 131 ++- target/mips/translate.c | 32 +--- 3 files changed, 141 insertions(+), 32 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index ce01e97..f25ba90 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -847,6 +847,14 @@ DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hadd_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32) @@ -1024,8 +1032,6 @@ DEF_HELPER_5(msa_pckod_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srar_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srlr_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_hadd_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_hadd_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_hsub_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index c31f46c..f5d3737 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1184,6 +1184,113 @@ void helper_msa_addv_d(CPUMIPSState *env, } +#define SIGNED_EVEN(a, df) \ +int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2)) + +#define UNSIGNED_EVEN(a, df) \ +uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2)) + +#define SIGNED_ODD(a, df) \ +int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2)) + +#define UNSIGNED_ODD(a, df) \ +uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2)) + + +static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df); +} + +void helper_msa_hadd_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_hadd_s_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_hadd_s_df(DF_HALF, pws->h[1], pwt->h[1]); +pwd->h[2] = msa_hadd_s_df(DF_HALF, pws->h[2], pwt->h[2]); +pwd->h[3] = msa_hadd_s_df(DF_HALF, pws->h[3], pwt->h[3]); +pwd->h[4] = msa_hadd_s_df(DF_HALF, pws->h[4], pwt->h[4]); +pwd->h[5] = msa_hadd_s_df(DF_HALF, pws->h[5], pwt->h[5]); +pwd->h[6] = msa_hadd_s_df(DF_HALF, pws->h[6], pwt->h[6]); +pwd->h[7] = msa_hadd_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_hadd_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->w[0] = msa_hadd_s_df(DF_WORD, pws->w[0], pwt->w[0]); +pwd->w[1] = msa_hadd_s_df(DF_WORD, pws->w[1], pwt->w[1]); +pwd->w[2] = msa_hadd_s_df(DF_WORD, pws->w[2], pwt->w[2]); +pwd->w[3] = msa_hadd_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_hadd_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->d[0] = msa_hadd_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); +pwd->d[1] = msa_hadd_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + + +static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df); +} + +void helper_msa_hadd_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_hadd_u_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_hadd_u_df(DF_HALF, pws->h[1], pwt->h[1]); +pwd->h[2] = msa_hadd_u_df(DF_HALF, pws->h[2], pwt->h[2]); +pwd->h[3] = msa_hadd_u_df(DF_HALF, pws->h[3], pwt->h[3]); +pwd->h[4] = msa_hadd_u_df(DF_HALF, pws->h[4], pwt->h[4]); +pwd->h[5] = msa_hadd_u_df(DF_HALF, pws->h[5], pwt->h[5]);
[PATCH v7 09/14] target/mips: msa: Split helpers for S.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 30 +++- target/mips/msa_helper.c | 424 +-- target/mips/translate.c | 91 -- 3 files changed, 479 insertions(+), 66 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index f25ba90..f779404 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -967,6 +967,31 @@ DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_sra_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srar_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srlr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_d, void, env, i32, i32, i32) + DEF_HELPER_3(msa_move_v, void, env, i32, i32) DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) @@ -1004,9 +1029,6 @@ DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srari_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_sll_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_sra_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srl_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subv_df, void, env, i32, i32, i32, i32) @@ -1030,8 +1052,6 @@ DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_pckev_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_pckod_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srar_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srlr_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_hsub_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index f5d3737..38ff1da 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -3461,7 +3461,382 @@ void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws) * +---+--+ */ -/* TODO: insert Shift group helpers here */ + +static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +int32_t b_arg2 = BIT_POSITION(arg2, df); +return arg1 << b_arg2; +} + +void helper_msa_sll_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->b[0] = msa_sll_df(DF_BYTE, pws->b[0], pwt->b[0]); +pwd->b[1] = msa_sll_df(DF_BYTE, pws->b[1], pwt->b[1]); +pwd->b[2] = msa_sll_df(DF_BYTE, pws->b[2], pwt->b[2]); +pwd->b[3] = msa_sll_df(DF_BYTE, pws->b[3], pwt->b[3]); +pwd->b[4] = msa_sll_df(DF_BYTE, pws->b[4], pwt->b[4]); +pwd->b[5] = msa_sll_df(DF_BYTE, pws->b[5], pwt->b[5]); +pwd->b[6] = msa_sll_df(DF_BYTE, pws->b[6], pwt->b[6]); +pwd->b[7] = msa_sll_df(DF_BYTE, pws->b[7], pwt->b[7]); +pwd->b[8] = msa_sll_df(DF_BYTE, pws->b[8], pwt->b[8]); +pwd->b[9] = msa_sll_df(DF_BYTE, pws->b[9], pwt->b[9]); +pwd->b[10] = msa_sll_df(DF_BYTE, pws->b[10], pwt->b[10]); +pwd->b[11] = msa_sll_df(DF_BYTE, pws->b[11], pwt->b[11]); +pwd->b[12] = msa_sll_df(DF_BYTE, pws->b[12], pwt->b[12]); +pwd->b[13] = msa_sll_df(DF_BYTE, pws->b[13], pwt->b[13]); +pwd->b[14] = msa_sll_df(DF_BYTE, pws->b[14], pwt->b[14]); +pwd->b[15] = msa_sll_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_sll_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_sll_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa
Re: [PATCH v4 16/16] libqos: add VIRTIO PCI 1.0 support
- Original Message - > From: "Stefan Hajnoczi" > Sent: Wednesday, October 23, 2019 12:04:25 PM > > Implement the VIRTIO 1.0 virtio-pci interface. The main change here is > that the register layout is no longer a fixed layout in BAR 0. Instead > we have to iterate of PCI Capabilities to find descriptions of where > various registers are located. The vring registers are also more > fine-grained, allowing for more flexible vring layouts, but we don't > take advantage of that. > > Signed-off-by: Stefan Hajnoczi > Reviewed-by: Sergio Lopez > --- > tests/Makefile.include | 1 + > tests/libqos/virtio-pci-modern.h | 17 ++ > tests/libqos/virtio-pci.h| 10 + > tests/libqos/virtio-pci-modern.c | 443 +++ > tests/libqos/virtio-pci.c| 6 +- > 5 files changed, 476 insertions(+), 1 deletion(-) > create mode 100644 tests/libqos/virtio-pci-modern.h > create mode 100644 tests/libqos/virtio-pci-modern.c Acked-by: Thomas Huth
[PATCH v7 12/14] target/mips: msa: Split helpers for ASUB_.
From: Aleksandar Markovic Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic --- target/mips/helper.h | 12 +++- target/mips/msa_helper.c | 169 ++- target/mips/translate.c | 38 +-- 3 files changed, 193 insertions(+), 26 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index d7c4bbf..7b8ad74 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -945,6 +945,16 @@ DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_asub_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_hsub_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_hsub_s_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_hsub_s_d, void, env, i32, i32, i32) @@ -1053,8 +1063,6 @@ DEF_HELPER_5(msa_subs_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subs_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subsus_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subsuu_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_asub_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_asub_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_mulv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_maddv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_msubv_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index ae9e8e0..0e39016 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -2888,6 +2888,157 @@ void helper_msa_mod_u_d(CPUMIPSState *env, * +---+--+ */ + +static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ +/* signed compare */ +return (arg1 < arg2) ? +(uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2); +} + +void helper_msa_asub_s_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->b[0] = msa_asub_s_df(DF_BYTE, pws->b[0], pwt->b[0]); +pwd->b[1] = msa_asub_s_df(DF_BYTE, pws->b[1], pwt->b[1]); +pwd->b[2] = msa_asub_s_df(DF_BYTE, pws->b[2], pwt->b[2]); +pwd->b[3] = msa_asub_s_df(DF_BYTE, pws->b[3], pwt->b[3]); +pwd->b[4] = msa_asub_s_df(DF_BYTE, pws->b[4], pwt->b[4]); +pwd->b[5] = msa_asub_s_df(DF_BYTE, pws->b[5], pwt->b[5]); +pwd->b[6] = msa_asub_s_df(DF_BYTE, pws->b[6], pwt->b[6]); +pwd->b[7] = msa_asub_s_df(DF_BYTE, pws->b[7], pwt->b[7]); +pwd->b[8] = msa_asub_s_df(DF_BYTE, pws->b[8], pwt->b[8]); +pwd->b[9] = msa_asub_s_df(DF_BYTE, pws->b[9], pwt->b[9]); +pwd->b[10] = msa_asub_s_df(DF_BYTE, pws->b[10], pwt->b[10]); +pwd->b[11] = msa_asub_s_df(DF_BYTE, pws->b[11], pwt->b[11]); +pwd->b[12] = msa_asub_s_df(DF_BYTE, pws->b[12], pwt->b[12]); +pwd->b[13] = msa_asub_s_df(DF_BYTE, pws->b[13], pwt->b[13]); +pwd->b[14] = msa_asub_s_df(DF_BYTE, pws->b[14], pwt->b[14]); +pwd->b[15] = msa_asub_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_asub_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->h[0] = msa_asub_s_df(DF_HALF, pws->h[0], pwt->h[0]); +pwd->h[1] = msa_asub_s_df(DF_HALF, pws->h[1], pwt->h[1]); +pwd->h[2] = msa_asub_s_df(DF_HALF, pws->h[2], pwt->h[2]); +pwd->h[3] = msa_asub_s_df(DF_HALF, pws->h[3], pwt->h[3]); +pwd->h[4] = msa_asub_s_df(DF_HALF, pws->h[4], pwt->h[4]); +pwd->h[5] = msa_asub_s_df(DF_HALF, pws->h[5], pwt->h[5]); +pwd->h[6] = msa_asub_s_df(DF_HALF, pws->h[6], pwt->h[6]); +pwd->h[7] = msa_asub_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_asub_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ +wr_t *pwd = &(env->active_fpu.fpr[wd].wr); +wr_t *pws = &(env->active_fpu.fpr[ws].wr); +wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + +pwd->w[0] = msa_asub_s_df(DF_WORD, pws->w[0], pwt->w[0]); +pwd->w[1] = msa_asub_s_df(DF_WORD, pws->w[1], pwt->w[1]); +pwd->w[2] = msa_asub_s_df(DF_WORD, pws->w[2], pwt->w[2]); +pwd->w[3] = msa_asub_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_asub_s_d(CPUMIPSState *env, +
Re: [RFC PATCH 1/4] net/awd.c: Introduce Advanced Watch Dog module framework
Hi Chen, On 10/16/19 1:22 PM, Zhang Chen wrote: From: Zhang Chen This patch introduce a new module named Advanced Watch Dog, and defined the input and output parameter. AWD use standard chardev as the way of communicationg with the outside world. Demo command: -object advanced-watchdog,id=heart1,server=on,awd_node=h1,notification_node=heartbeat0,opt_script=opt_script_path,iothread=iothread1,pulse_interval=1000,timeout=5000 Signed-off-by: Zhang Chen --- net/Makefile.objs | 1 + net/awd.c | 261 ++ qemu-options.hx | 6 ++ 3 files changed, 268 insertions(+) create mode 100644 net/awd.c diff --git a/net/Makefile.objs b/net/Makefile.objs index c5d076d19c..139b1394e9 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -19,6 +19,7 @@ common-obj-y += colo-compare.o common-obj-y += colo.o common-obj-y += filter-rewriter.o common-obj-y += filter-replay.o +common-obj-y += awd.o Can you add a net/Kconfig file introducing the ADVANCED_WATCHDOG selector? config COLO_ADVANCED_WATCHDOG bool default n Then use here: common-obj-$(COLO_ADVANCED_WATCHDOG) += awd.o Thanks, Phil. tap-obj-$(CONFIG_LINUX) = tap-linux.o tap-obj-$(CONFIG_BSD) = tap-bsd.o [...]
Re: [Qemu-devel] [PATCH] pci_bridge: fix a typo in comment
On 10/23/19 5:32 AM, maozy wrote: ping... I'm not sure qemu-trivial@ received this one because the email address looked odd (now fixed). On 11/8/18 9:12 PM, Philippe Mathieu-Daudé wrote: Cc'ing qemu-trivial@ On 8/11/18 13:21, Mao Zhongyi wrote: Signed-off-by: Mao Zhongyi Reviewed-by: Philippe Mathieu-Daudé --- 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..da8daa3ff2 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -310,7 +310,7 @@ void pci_bridge_reset(DeviceState *qdev) /* * the default values for base/limit registers aren't specified - * in the PCI-to-PCI-bridge spec. So we don't thouch them here. + * in the PCI-to-PCI-bridge spec. So we don't touch them here. * Each implementation can override it. * typical implementation does * zero base/limit registers or
Re: [PATCH v5 5/7] ppc: Reset the interrupt presenter from the CPU reset handler
On 10/22/19 6:38 PM, Cédric Le Goater wrote: On the sPAPR machine and PowerNV machine, the interrupt presenters are created by a machine handler at the core level and are reset independently. This is not consistent and it raises issues when it comes to handle hot-plugged CPUs. In that case, the presenters are not reset. This is less of an issue in XICS, although a zero MFFR could be a concern, but in XIVE, the OS CAM line is not set and this breaks the presenting algorithm. The current code has workarounds which need a global cleanup. Extend the sPAPR IRQ backend and the PowerNV Chip class with a new cpu_intc_reset() handler called by the CPU reset handler and remove the XiveTCTX reset handler which is now redundant. Signed-off-by: Cédric Le Goater --- include/hw/ppc/pnv.h | 1 + include/hw/ppc/spapr_irq.h | 2 ++ include/hw/ppc/xics.h | 1 + include/hw/ppc/xive.h | 1 + hw/intc/spapr_xive.c | 9 + hw/intc/xics.c | 8 ++-- hw/intc/xics_spapr.c | 7 +++ hw/intc/xive.c | 12 +--- hw/ppc/pnv.c | 18 ++ hw/ppc/pnv_core.c | 7 +-- hw/ppc/spapr_cpu_core.c| 5 - hw/ppc/spapr_irq.c | 14 ++ 12 files changed, 65 insertions(+), 20 deletions(-) diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 1cdbe55bf86c..2a780e633f23 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -111,6 +111,7 @@ typedef struct PnvChipClass { uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id); void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp); +void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu); ISABus *(*isa_create)(PnvChip *chip, Error **errp); void (*dt_populate)(PnvChip *chip, void *fdt); void (*pic_print_info)(PnvChip *chip, Monitor *mon); diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 5e150a667902..09232999b07e 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -52,6 +52,7 @@ typedef struct SpaprInterruptControllerClass { */ int (*cpu_intc_create)(SpaprInterruptController *intc, PowerPCCPU *cpu, Error **errp); +void (*cpu_intc_reset)(SpaprInterruptController *intc, PowerPCCPU *cpu); int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi, Error **errp); void (*free_irq)(SpaprInterruptController *intc, int irq); @@ -68,6 +69,7 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr); int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, PowerPCCPU *cpu, Error **errp); +void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu); void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon); void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle); diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 1e6a9300eb2b..602173c12250 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -161,6 +161,7 @@ void icp_set_mfrr(ICPState *icp, uint8_t mfrr); uint32_t icp_accept(ICPState *ss); uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr); void icp_eoi(ICPState *icp, uint32_t xirr); +void icp_reset(ICPState *icp); void ics_write_xive(ICSState *ics, int nr, int server, uint8_t priority, uint8_t saved_priority); diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index fd3319bd3202..99381639f50c 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -415,6 +415,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size); void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon); Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp); +void xive_tctx_reset(XiveTCTX *tctx); static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx) { diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index ba32d2cc5b0f..20a8d8285f64 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -553,6 +553,14 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc, return 0; } +static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc, + PowerPCCPU *cpu) Indent off :| +{ +XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx; + +xive_tctx_reset(tctx); +} + static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val) { SpaprXive *xive = SPAPR_XIVE(intc); @@ -697,6 +705,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) sicc->activate = spapr_xive_activate; sicc->deactivate = spapr_xive_deactivate; sicc->cpu_intc_create = spapr_xive_cpu_intc_create; +sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset; sicc->claim_irq = spapr_xive_claim_irq; sicc->f
[PATCH v7 02/14] target/mips: Clean up op_helper.c
From: Aleksandar Markovic Mostly fix errors and warnings reported by 'checkpatch.pl -f'. Reviewed-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic --- target/mips/op_helper.c | 1010 +++ 1 file changed, 663 insertions(+), 347 deletions(-) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 4de6465..18fcee4 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -64,8 +64,7 @@ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \ int mem_idx, uintptr_t retaddr)\ { \ -switch (mem_idx)\ -{ \ +switch (mem_idx) { \ case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr);\ default:\ @@ -92,12 +91,17 @@ static inline void do_##name(CPUMIPSState *env, target_ulong addr, \ static inline void do_##name(CPUMIPSState *env, target_ulong addr, \ type val, int mem_idx, uintptr_t retaddr) \ { \ -switch (mem_idx)\ -{ \ -case 0: cpu_##insn##_kernel_ra(env, addr, val, retaddr); break; \ -case 1: cpu_##insn##_super_ra(env, addr, val, retaddr); break; \ +switch (mem_idx) { \ +case 0: \ +cpu_##insn##_kernel_ra(env, addr, val, retaddr);\ +break; \ +case 1: \ +cpu_##insn##_super_ra(env, addr, val, retaddr); \ +break; \ default:\ -case 2: cpu_##insn##_user_ra(env, addr, val, retaddr); break; \ +case 2: \ +cpu_##insn##_user_ra(env, addr, val, retaddr); \ +break; \ case 3: \ cpu_##insn##_error_ra(env, addr, val, retaddr); \ break; \ @@ -114,7 +118,8 @@ HELPER_ST(sd, stq, uint64_t) /* 64 bits arithmetic for 32 bits hosts */ static inline uint64_t get_HILO(CPUMIPSState *env) { -return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0]; +return ((uint64_t)(env->active_tc.HI[0]) << 32) | + (uint32_t)env->active_tc.LO[0]; } static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO) @@ -435,9 +440,10 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, } #if defined(TARGET_MIPS64) -/* "half" load and stores. We must do the memory access inline, - or fault handling won't work. */ - +/* + * "half" load and stores. We must do the memory access inline, + * or fault handling won't work. + */ #ifdef TARGET_WORDS_BIGENDIAN #define GET_LMASK64(v) ((v) & 7) #else @@ -535,7 +541,7 @@ void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, target_ulong base_reglist = reglist & 0xf; target_ulong do_r31 = reglist & 0x10; -if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) { +if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { target_ulong i; for (i = 0; i < base_reglist; i++) { @@ -557,7 +563,7 @@ void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, target_ulong base_reglist = reglist & 0xf; target_ulong do_r31 = reglist & 0x10; -if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) { +if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { target_ulong i; for (i = 0; i < base_reglist; i++) { @@ -579,7 +585,7 @@ void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, target_ulong base_reglist = reglist & 0xf; target_ulong do_r31 = reglist & 0x10; -if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) { +if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { target_ulong i; for (i
Re: [PATCH v4 08/16] libqos: implement VIRTIO 1.0 FEATURES_OK step
- Original Message - > From: "Stefan Hajnoczi" > Sent: Wednesday, October 23, 2019 12:04:17 PM > > Device initialization has an extra step in VIRTIO 1.0. The FEATURES_OK > status bit is set to indicate that feature negotiation has completed. > The driver then reads the status register again to check that the device > agrees with the final features. > > Implement this step as part of qvirtio_set_features() instead of > introducing a separate function. This way all existing code works > without modifications. > > The check in qvirtio_set_driver_ok() needs to be updated because > FEATURES_OK will be set for VIRTIO 1.0 devices. > > Signed-off-by: Stefan Hajnoczi > --- > v4: > * Make FEATURES_OK change in qvirtio_set_driver_ok() clearer and >mention it in the commit description [Thomas] > --- > tests/libqos/virtio.c | 18 +- > 1 file changed, 17 insertions(+), 1 deletion(-) Reviewed-by: Thomas Huth"
Re: [PATCH v3 3/6] ps2: accept 'Set Key Make and Break' commands
Hi Sven, (Please Cc reviewers who previously commented your patch) On 10/22/19 10:59 PM, Sven Schnelle wrote: HP-UX sends both the 'Set key make and break (0xfc) and 'Set all key typematic make and break' (0xfa). QEMU response with 'Resend' as it doesn't handle these commands. HP-UX than reports an PS/2 max retransmission exceeded error. Add these commands and just reply with ACK. Signed-off-by: Sven Schnelle --- hw/input/ps2.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 67f92f6112..0b671b6339 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -49,6 +49,8 @@ #define KBD_CMD_RESET_DISABLE 0xF5/* reset and disable scanning */ #define KBD_CMD_RESET_ENABLE 0xF6/* reset and enable scanning */ #define KBD_CMD_RESET 0xFF/* Reset */ +#define KBD_CMD_SET_MAKE_BREAK 0xFC/* Set Make and Break mode */ +#define KBD_CMD_SET_TYPEMATIC 0xFA/* Set Typematic Make and Break mode */ /* Keyboard Replies */ #define KBD_REPLY_POR 0xAA/* Power on reset */ @@ -573,6 +575,7 @@ void ps2_write_keyboard(void *opaque, int val) case KBD_CMD_SCANCODE: case KBD_CMD_SET_LEDS: case KBD_CMD_SET_RATE: +case KBD_CMD_SET_MAKE_BREAK: OK s->common.write_cmd = val; ps2_queue(&s->common, KBD_REPLY_ACK); break; @@ -592,11 +595,18 @@ void ps2_write_keyboard(void *opaque, int val) KBD_REPLY_ACK, KBD_REPLY_POR); break; +case KBD_CMD_SET_TYPEMATIC: +ps2_queue(&s->common, KBD_REPLY_ACK); I'm not sure, can't this loop? Can you fold it with the '0x00' case? +break; default: ps2_queue(&s->common, KBD_REPLY_RESEND); break; } break; +case KBD_CMD_SET_MAKE_BREAK: We can reorder this one in the same case with: case KBD_CMD_SET_LEDS: case KBD_CMD_SET_RATE: +ps2_queue(&s->common, KBD_REPLY_ACK); +s->common.write_cmd = -1; +break; case KBD_CMD_SCANCODE: if (val == 0) { if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
Re: [PATCH v5 6/7] ppc/pnv: Fix naming of routines realizing the CPUs
On 10/22/19 6:38 PM, Cédric Le Goater wrote: The 'vcpu' suffix is inherited from the sPAPR machine. Use better names for PowerNV. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/pnv_core.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index be0310ac0340..e81cd3a3e047 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -162,7 +162,7 @@ static const MemoryRegionOps pnv_core_power9_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp) +static void pnv_core_cpu_realize(PowerPCCPU *cpu, PnvChip *chip, Error **errp) { CPUPPCState *env = &cpu->env; int core_pir; @@ -247,7 +247,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) } for (j = 0; j < cc->nr_threads; j++) { -pnv_realize_vcpu(pc->threads[j], pc->chip, &local_err); +pnv_core_cpu_realize(pc->threads[j], pc->chip, &local_err); if (local_err) { goto err; } @@ -269,7 +269,7 @@ err: error_propagate(errp, local_err); } -static void pnv_unrealize_vcpu(PowerPCCPU *cpu) +static void pnv_core_cpu_unrealize(PowerPCCPU *cpu) { PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); @@ -289,7 +289,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp) qemu_unregister_reset(pnv_core_reset, pc); for (i = 0; i < cc->nr_threads; i++) { -pnv_unrealize_vcpu(pc->threads[i]); +pnv_core_cpu_unrealize(pc->threads[i]); } g_free(pc->threads); } Reviewed-by: Philippe Mathieu-Daudé
Re: [PATCH] i386/kvm: add NoNonArchitecturalCoreSharing Hyper-V enlightenment
Eduardo Habkost writes: > On Mon, Oct 21, 2019 at 06:26:14PM +0200, Paolo Bonzini wrote: >> On 21/10/19 16:09, Vitaly Kuznetsov wrote: >> >>> +if (cpu->hyperv_no_nonarch_cs == ON_OFF_AUTO_ON) { >> >>> +env->features[FEAT_HV_RECOMM_EAX] |= HV_NO_NONARCH_CORESHARING; >> >>> +} else if (cpu->hyperv_no_nonarch_cs == ON_OFF_AUTO_AUTO) { >> >> Do you want to make auto the default if "-cpu host,migratable=off"? It >> >> can be done on top so I started queueing this patch. >> > Hm, one thing is that CPUID 0x4004 doesn't exist if no Hyper-V >> > enlightenments are passed so we'll probably have to modify your idea to >> > "-cpu host,migratable=off,+any-hyperv-enlightenment" but then the >> > question is how conservative are we, like if QEMU command line doesn't >> > change can new CPUID flags appear or not? And we'll probably need a way >> > to explicitly disable HV_NO_NONARCH_CORESHARING if needed. >> >> I would defer to Eduardo on whether "migratable=off" would allow adding >> new CPUID flags. The follow-up question however is whether we would >> benefit from a "+hyperv" option that enables all known Hyper-V >> enlightenment for a given machine type. > > I'm not sure what "adding new CPUID flags" means exactly, but on > both cases, the answer is yes: > > If you mean having new flags appear with the same QEMU command > line, this is 100% OK with "-cpu host". Doubly so with > "migratable=off". "-cpu host" doesn't guarantee a stable guest > ABI, and migratable=off doesn't guarantee the ability to live > migrate. > > If you just mean the ability to write "-cpu > host,migratable=off,+some-extra-flag", that's OK too. > > I would try to make "-cpu host,migratable=off" enable all > features out of the box (because users probably expect that). > But we you have a compelling reason to not enable the hyperv > flags by default (do we?), it's OK to require something like > "-cpu host,...,+hyperv". I'm not sure if the reason is compelling enough but I remember some Linux tools were only looking at the first hypervisor signature and reporting that we're now running on Hyper-V. Also, more features you enable larger the atack surface... Actually, we already '-cpu host,hv_passthrough' option which implies 'migratable=off', not sure if another one is needed. -- Vitaly
[Bug 1847232] Re: qemu TCG in s390x mode issue with calculating HASH
I will exercise this thoroughly ! The go application involved is itself a blockchain signing/verification application, so I suspect it will be a good exercise (codenotary.io) Thanks for looking into this and fixing this ! --Ivan -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1847232 Title: qemu TCG in s390x mode issue with calculating HASH Status in QEMU: Fix Committed Bug description: When using go on s390x on Debian x64 (buster) (host) and debian s390x (sid) (guest) I run into the following problem : The following occurs while trying to build a custom project : go: github.com/FactomProject/basen@v0.0.0-20150613233007-fe3947df716e: Get https://proxy.golang.org/github.com/%21factom%21project/basen/@v/v0.0.0-20150613233007-fe3947df716e.mod: local error: tls: bad record MAC Doing a git bisect I find that this problem only occurs on and after commit 08ef92d556c584c7faf594ff3af46df456276e1b Before that commit, all works fine. Past this commit, build always fails. Without any proof, It looks like a hash calculation bug related to using z/Arch vector facilities... To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1847232/+subscriptions
RE: [RFC PATCH 1/4] net/awd.c: Introduce Advanced Watch Dog module framework
> -Original Message- > From: Philippe Mathieu-Daudé > Sent: Wednesday, October 23, 2019 7:01 PM > To: Zhang, Chen ; Jason Wang > ; Paolo Bonzini ; qemu- > dev > Cc: Zhang Chen > Subject: Re: [RFC PATCH 1/4] net/awd.c: Introduce Advanced Watch Dog > module framework > > Hi Chen, > > On 10/16/19 1:22 PM, Zhang Chen wrote: > > From: Zhang Chen > > > > This patch introduce a new module named Advanced Watch Dog, and > > defined the input and output parameter. AWD use standard chardev as > > the way of communicationg with the outside world. > > Demo command: > > -object > > advanced- > watchdog,id=heart1,server=on,awd_node=h1,notification_node=he > > artbeat0,opt_script=opt_script_path,iothread=iothread1,pulse_interval= > > 1000,timeout=5000 > > > > Signed-off-by: Zhang Chen > > --- > > net/Makefile.objs | 1 + > > net/awd.c | 261 > ++ > > qemu-options.hx | 6 ++ > > 3 files changed, 268 insertions(+) > > create mode 100644 net/awd.c > > > > diff --git a/net/Makefile.objs b/net/Makefile.objs index > > c5d076d19c..139b1394e9 100644 > > --- a/net/Makefile.objs > > +++ b/net/Makefile.objs > > @@ -19,6 +19,7 @@ common-obj-y += colo-compare.o > > common-obj-y += colo.o > > common-obj-y += filter-rewriter.o > > common-obj-y += filter-replay.o > > +common-obj-y += awd.o > Can you add a net/Kconfig file introducing the ADVANCED_WATCHDOG > selector? > > config COLO_ADVANCED_WATCHDOG > bool > default n > > Then use here: > > common-obj-$(COLO_ADVANCED_WATCHDOG) += awd.o > Sure, but AWD is a universal module, COLO is just the first user. Maybe use "config ADVANCED_WATCHDOG" is better. Thanks Zhang Chen > Thanks, > > Phil. > > > > > tap-obj-$(CONFIG_LINUX) = tap-linux.o > > tap-obj-$(CONFIG_BSD) = tap-bsd.o > [...]
Re: [PATCH v5 4/7] ppc/pnv: Add a PnvChip pointer to PnvCore
On 10/22/19 6:38 PM, Cédric Le Goater wrote: We will use it to reset the interrupt presenter from the CPU reset handler. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz --- include/hw/ppc/pnv_core.h | 3 +++ hw/ppc/pnv_core.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h index bfbd2ec42aa6..55eee95104da 100644 --- a/include/hw/ppc/pnv_core.h +++ b/include/hw/ppc/pnv_core.h @@ -31,6 +31,8 @@ #define PNV_CORE_GET_CLASS(obj) \ OBJECT_GET_CLASS(PnvCoreClass, (obj), TYPE_PNV_CORE) +typedef struct PnvChip PnvChip; + typedef struct PnvCore { /*< private >*/ CPUCore parent_obj; @@ -38,6 +40,7 @@ typedef struct PnvCore { /*< public >*/ PowerPCCPU **threads; uint32_t pir; +PnvChip *chip; MemoryRegion xscom_regs; } PnvCore; diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 9f981a4940e6..cc17bbfed829 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -222,6 +222,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) "required link 'chip' not found: "); return; } +pc->chip = PNV_CHIP(chip); pc->threads = g_new(PowerPCCPU *, cc->nr_threads); for (i = 0; i < cc->nr_threads; i++) { @@ -243,7 +244,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) } for (j = 0; j < cc->nr_threads; j++) { -pnv_realize_vcpu(pc->threads[j], PNV_CHIP(chip), &local_err); +pnv_realize_vcpu(pc->threads[j], pc->chip, &local_err); if (local_err) { goto err; } Reviewed-by: Philippe Mathieu-Daudé
Re: [PATCH] buildfix: update texinfo menu
Cc'ed trivial@ On 10/23/19 12:19 PM, Gerd Hoffmann wrote: Build error message: qemu-doc.texi:34: node `Top' lacks menu item for `Recently removed features' despite being its Up target Fixes: 3264ffced3d0 ("dirty-bitmaps: remove deprecated autoload parameter") Signed-off-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daudé --- qemu-doc.texi | 1 + 1 file changed, 1 insertion(+) diff --git a/qemu-doc.texi b/qemu-doc.texi index 3c5022050f0f..3ddf5c0a6865 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -44,6 +44,7 @@ * Security:: * Implementation notes:: * Deprecated features:: +* Recently removed features:: * Supported build platforms:: * License:: * Index::
Re: [PATCH v4 07/16] libqos: enforce Device Initialization order
- Original Message - > From: "Stefan Hajnoczi" > Sent: Wednesday, October 23, 2019 12:04:16 PM > > According to VIRTIO 1.1 "3.1.1 Driver Requirements: Device > Initialization", configuration space and virtqueues cannot be accessed > before features have been negotiated. Enforce this requirement. > > Signed-off-by: Stefan Hajnoczi > --- > v4: > * Introduce bool d->features_negotiated so that tests can negotiate a >0 feature bit set in Legacy mode [Thomas] > --- > tests/libqos/virtio.h | 1 + > tests/libqos/virtio.c | 7 +++ > 2 files changed, 8 insertions(+) Reviewed-by: Thomas Huth
Re: [PATCH v10 3/3] iotests: test nbd reconnect
On 10/23/19 3:33 AM, Vladimir Sementsov-Ogievskiy wrote: 23.10.2019 4:31, Eric Blake wrote: On 10/9/19 3:41 AM, Vladimir Sementsov-Ogievskiy wrote: Add test, which starts backup to nbd target and restarts nbd server during backup. Signed-off-by: Vladimir Sementsov-Ogievskiy --- +vm.qmp_log('blockdev-backup', device='drive0', sync='full', target='backup0', + speed=(1 * 1024 * 1024)) This starts the job throttled, to give us time... + +# Wait for some progress +t = 0 +while t < wait_limit: + jobs = vm.qmp('query-block-jobs')['return'] + if jobs and jobs[0]['offset'] > 0: + break + time.sleep(wait_step) + t += wait_step + +if jobs and jobs[0]['offset'] > 0: + log('Backup job is started') + +log('Kill NBD server') +srv.kill() +srv.wait() + +jobs = vm.qmp('query-block-jobs')['return'] +if jobs and jobs[0]['offset'] < jobs[0]['len']: + log('Backup job is still in progress') + +vm.qmp_log('block-job-set-speed', device='drive0', speed=0) Ah, I overlooked this line in my late-night review. + +# Emulate server down time for 1 second +time.sleep(1) ...but once we restart,... + +log('Start NBD server') +srv = qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b) + +e = vm.event_wait('BLOCK_JOB_COMPLETED') ...should we unthrottle the job to allow the test to complete slightly faster after the reconnect? But that can be done as an improvement on top, if it helps. It is done above, before time.sleep(1) Yep, so I feel better now. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Re: [PATCH v1 05/19] travis.yml: Fix the ccache lines
On 10/22/19 9:16 PM, Alex Bennée wrote: From: Thomas Huth The "command -v ccache && ccache ..." likely were supposed to test the availability of ccache before running the program. But this shell construct causes Travis to abort if ccache is not available. Use an if-statement instead to fix this problem. Signed-off-by: Thomas Huth Message-Id: <20191009170701.14756-5-th...@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e65e53f3d7e..7e0d4ad2b31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -91,13 +91,13 @@ git: before_script: - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then export PATH="/usr/local/opt/ccache/libexec:$PATH" ; fi - - command -v ccache && ccache --zero-stats + - if command -v ccache ; then ccache --zero-stats ; fi - mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR} - ${SRC_DIR}/configure ${BASE_CONFIG} ${CONFIG} || { cat config.log && exit 1; } script: - make -j3 && travis_retry ${TEST_CMD} after_script: - - command -v ccache && ccache --show-stats + - if command -v ccache ; then ccache --show-stats ; fi matrix:
Re: [PATCH v5 3/7] ppc/pnv: Introduce a PnvCore reset handler
Hi Cédric, On 10/22/19 6:38 PM, Cédric Le Goater wrote: in which individual CPUs are reset. It will ease the introduction of future change reseting the interrupt presenter from the CPU reset handler. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/pnv_core.c | 19 +++ 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index b1a7489e7abf..9f981a4940e6 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -40,9 +40,8 @@ static const char *pnv_core_cpu_typename(PnvCore *pc) return cpu_type; } -static void pnv_cpu_reset(void *opaque) +static void pnv_core_cpu_reset(PowerPCCPU *cpu) { -PowerPCCPU *cpu = opaque; CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -192,8 +191,17 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp) /* Set time-base frequency to 512 MHz */ cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ); +} + +static void pnv_core_reset(void *dev) Here the opaque pointer is a 'PnvCore *pc'. If you don't want to call it 'opaque', maybe 'pc' is better. +{ +CPUCore *cc = CPU_CORE(dev); +PnvCore *pc = PNV_CORE(dev); This type conversion is not necessary. What about: static void pnv_core_reset(void *opaque) { PnvCore *pc = opaque; CPUCore *cc = CPU_CORE(pc); +int i; -qemu_register_reset(pnv_cpu_reset, cpu); +for (i = 0; i < cc->nr_threads; i++) { +pnv_core_cpu_reset(pc->threads[i]); +} } static void pnv_core_realize(DeviceState *dev, Error **errp) @@ -244,6 +252,8 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id); pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops, pc, name, PNV_XSCOM_EX_SIZE); + +qemu_register_reset(pnv_core_reset, pc); return; err: @@ -259,7 +269,6 @@ static void pnv_unrealize_vcpu(PowerPCCPU *cpu) { PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); -qemu_unregister_reset(pnv_cpu_reset, cpu); object_unparent(OBJECT(pnv_cpu_state(cpu)->intc)); cpu_remove_sync(CPU(cpu)); cpu->machine_data = NULL; @@ -273,6 +282,8 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp) CPUCore *cc = CPU_CORE(dev); int i; +qemu_unregister_reset(pnv_core_reset, pc); + for (i = 0; i < cc->nr_threads; i++) { pnv_unrealize_vcpu(pc->threads[i]); }
Re: [PATCH] i386/kvm: add NoNonArchitecturalCoreSharing Hyper-V enlightenment
On Wed, Oct 23, 2019 at 01:16:38PM +0200, Vitaly Kuznetsov wrote: > Eduardo Habkost writes: > > > On Mon, Oct 21, 2019 at 06:26:14PM +0200, Paolo Bonzini wrote: > >> On 21/10/19 16:09, Vitaly Kuznetsov wrote: > >> >>> +if (cpu->hyperv_no_nonarch_cs == ON_OFF_AUTO_ON) { > >> >>> +env->features[FEAT_HV_RECOMM_EAX] |= > >> >>> HV_NO_NONARCH_CORESHARING; > >> >>> +} else if (cpu->hyperv_no_nonarch_cs == ON_OFF_AUTO_AUTO) { > >> >> Do you want to make auto the default if "-cpu host,migratable=off"? It > >> >> can be done on top so I started queueing this patch. > >> > Hm, one thing is that CPUID 0x4004 doesn't exist if no Hyper-V > >> > enlightenments are passed so we'll probably have to modify your idea to > >> > "-cpu host,migratable=off,+any-hyperv-enlightenment" but then the > >> > question is how conservative are we, like if QEMU command line doesn't > >> > change can new CPUID flags appear or not? And we'll probably need a way > >> > to explicitly disable HV_NO_NONARCH_CORESHARING if needed. > >> > >> I would defer to Eduardo on whether "migratable=off" would allow adding > >> new CPUID flags. The follow-up question however is whether we would > >> benefit from a "+hyperv" option that enables all known Hyper-V > >> enlightenment for a given machine type. > > > > I'm not sure what "adding new CPUID flags" means exactly, but on > > both cases, the answer is yes: > > > > If you mean having new flags appear with the same QEMU command > > line, this is 100% OK with "-cpu host". Doubly so with > > "migratable=off". "-cpu host" doesn't guarantee a stable guest > > ABI, and migratable=off doesn't guarantee the ability to live > > migrate. > > > > If you just mean the ability to write "-cpu > > host,migratable=off,+some-extra-flag", that's OK too. > > > > I would try to make "-cpu host,migratable=off" enable all > > features out of the box (because users probably expect that). > > But we you have a compelling reason to not enable the hyperv > > flags by default (do we?), it's OK to require something like > > "-cpu host,...,+hyperv". > > I'm not sure if the reason is compelling enough but I remember some > Linux tools were only looking at the first hypervisor signature and > reporting that we're now running on Hyper-V. Also, more features you > enable larger the atack surface... > > Actually, we already '-cpu host,hv_passthrough' option which implies > 'migratable=off', not sure if another one is needed. So, if I understood correctly, Paolo's "+hyperv" suggestion above is already implemented by "hv_passthrough"? Sounds good enough to me. -- Eduardo
RE: [Virtio-fs] [PATCH 0/2] virtiofsd: Two fix for xattr operation
> -Original Message- > From: Stefan Hajnoczi [mailto:stefa...@redhat.com] > Sent: Monday, October 21, 2019 6:41 PM > To: Misono, Tomohiro/味曽野 智礼 > Cc: 'Miklos Szeredi' ; virtio...@redhat.com; > qemu-devel@nongnu.org > Subject: Re: [Virtio-fs] [PATCH 0/2] virtiofsd: Two fix for xattr operation > > On Fri, Oct 18, 2019 at 08:51:20AM +, misono.tomoh...@fujitsu.com wrote: > > > Doing unshare(CLONE_FS) after thread startup seems safe, though must > > > be careful to change the working directory to the root of the mount > > > *before* starting any threads. > > > > I think working directry is changed in setup_sandbox() -> > > setup_mount_namespace() -> setup_pivot_root(). > > So, can we just add unshare(CLONE_FS) in fv_queue_worker()? > > fv_queue_worker() is the thread pool worker function that is called for each > request. Calling unshare(CLONE_FS) for each request > is not necessary and will reduce performance. > > A thread-local variable can be used to avoid repeated calls to > unshare(CLONE_FS) from the same worker thread: > > static __thread bool clone_fs_called; > > static void fv_queue_worker(gpointer data, gpointer user_data) > { > ... > if (!clone_fs_called) { > int ret; > > ret = unshare(CLONE_FS); > assert(ret == 0); /* errors not expected according to man page */ > > clone_fs_called = true; > } > > Another issue is the seccomp policy. Since worker threads are spawned at > runtime it is necessary to add the unshare(2) syscall > to the seccomp whitelist in contrib/virtiofsd/seccomp.c. > Thanks for suggesting. I tried above code with fchdir() + ...xattr() + fchdir() in lo_...xattr and it solves all the problem about xattr I see. However, it seems the fix causes some performance issue in stress test as ACL check issues getxattr() and a lot of fchdir() happens. So, I may try to combine the old method for regular file and this method for special files. Thanks, Misono
[Bug 1192464] Re: udp checksum computed as 0 not converted to 0xffff, from guest os that share a common linux bridge among multiple guest os
Fixed: commit 0dacea92d26c31d453c58de2e99c178fee554166 Author: Ed Swierk Date: Thu Nov 16 06:06:06 2017 -0800 net: Transmit zero UDP checksum as 0x The checksum algorithm used by IPv4, TCP and UDP allows a zero value to be represented by either 0x and 0x. But per RFC 768, a zero UDP checksum must be transmitted as 0x because 0x is a special value meaning no checksum. Substitute 0x whenever a checksum is computed as zero when modifying a UDP datagram header. Doing this on IPv4 and TCP checksums is unnecessary but legal. Add a wrapper for net_checksum_finish() that makes the substitution. (We can't just change net_checksum_finish(), as that function is also used by receivers to verify checksums, and in that case the expected value is always 0x.) Signed-off-by: Ed Swierk Signed-off-by: Jason Wang ** Changed in: qemu Status: Incomplete => Fix Released -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1192464 Title: udp checksum computed as 0 not converted to 0x, from guest os that share a common linux bridge among multiple guest os Status in QEMU: Fix Released Bug description: UDP checksum computed as '0' during transmission of packets that uses e1000 NIC in the Guest as well as emulated h/w in the qemu layer, That needs to be converted to 0x, This occurs only when Hardware checksum offload is been set in the guest OS NIC and made it as a transmitter. The guest O.S use the N/W interface that is been shared to the linux brige created in the host (used source=) in the xml tags of libvirt. As per RFC768(http://tools.ietf.org/html/rfc768 [^]), If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care). To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1192464/+subscriptions