Re: [Qemu-devel] [PATCH v2 3/4] target/ppc: consolidate CPU device-tree id computation in helper
On Tue, 23 May 2017 12:35:54 +1000 David Gibson wrote: > On Mon, May 22, 2017 at 10:59:50AM +0200, Greg Kurz wrote: > > On Mon, 22 May 2017 12:04:13 +1000 > > David Gibson wrote: > > > > > On Fri, May 19, 2017 at 12:32:20PM +0200, Greg Kurz wrote: > > > > For historical reasons, we compute CPU device-tree ids with a > > > > non-trivial > > > > logic. This patch consolidate the logic in a single helper to be used > > > > in various places where it is currently open-coded. > > > > > > > > It is okay to get rid of DIV_ROUND_UP() because we're sure that the > > > > number > > > > of threads per core in the guest cannot exceed the number of threads per > > > > core in the host. > > > > > > However, your new logic still gives different answers in some cases. > > > In particular when max_cpus is not a multiple of smp_threads. Which > > > is generally a bad idea, but allowed for older machine types for > > > compatibility. e.g. smp_threads=4, max_cpus=6 smt=8 > > > > > > Old logic: > > >DIV_ROUND_UP(6 * 8, 4) > > > = ⌈48 / 4⌉ = 12 > > > > > > New logic gives: ⌊6 / 4⌋ * 8 + (6 % 4) > > >= 1 * 8 + 2 > > > = 10 > > > > > > > I now realize this two formulas are hardly reconcilable... this > > probably means that this patch shouldn't try to consolidate the > > logic in hw/ppc/spapr.c with the one in target/ppc/translate_init.c. > > Ok. > > > > In any case the DIV_ROUND_UP() isn't to handle the case where guest > > > threads-per-core is bigger than host threads-per-core, it's (IIRC) for > > > the case where guest threads-per-core is not a factor of host > > > threads-per-core. Again, a bad idea, but I think allowed in some old > > > cases. > > > > > > > FWIW, DIV_ROUND_UP() comes from this commit: > > > > f303f117fec3 spapr: ensure we have at least one XICS server > > Ah, yes, I see your point. Hrm. I thought even then that guest > threads > host threads was definitely incorrect; but I'm wondering if > the change was just because the check for guest threads > host threads > came later during init and we didn't want to crash before we got to > it. AFAICR, this was the only motivation... but I hadn't realized the trickiness of CPU id computations in ppc at the time. Otherwise I would have added another smp_threads > kvmppc_smt_threads() sanity check instead. :-\ > > > but I agree that this was a bad idea... > > But yeah, looks like we'll be taking a different approach so it's kind > of moot anyway. > > > > > > > > > > > Signed-off-by: Greg Kurz > > > > --- > > > > hw/ppc/spapr.c |6 ++ > > > > target/ppc/cpu.h| 17 + > > > > target/ppc/translate_init.c |3 +-- > > > > 3 files changed, 20 insertions(+), 6 deletions(-) > > > > > > > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > > > > index 75e298b4c6be..1bb05a9a6b07 100644 > > > > --- a/hw/ppc/spapr.c > > > > +++ b/hw/ppc/spapr.c > > > > @@ -981,7 +981,6 @@ static void *spapr_build_fdt(sPAPRMachineState > > > > *spapr, > > > > void *fdt; > > > > sPAPRPHBState *phb; > > > > char *buf; > > > > -int smt = kvmppc_smt_threads(); > > > > > > > > fdt = g_malloc0(FDT_MAX_SIZE); > > > > _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE))); > > > > @@ -1021,7 +1020,7 @@ static void *spapr_build_fdt(sPAPRMachineState > > > > *spapr, > > > > _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); > > > > > > > > /* /interrupt controller */ > > > > -spapr_dt_xics(DIV_ROUND_UP(max_cpus * smt, smp_threads), fdt, > > > > PHANDLE_XICP); > > > > +spapr_dt_xics(ppc_cpu_dt_id_from_index(max_cpus), fdt, > > > > PHANDLE_XICP); > > > > > > > > ret = spapr_populate_memory(spapr, fdt); > > > > if (ret < 0) { > > > > @@ -1977,7 +1976,6 @@ static void spapr_init_cpus(sPAPRMachineState > > > > *spapr) > > > > MachineState *machine = MACHINE(spapr); > > > > MachineClass *mc = MACHINE_GET_CLASS(machine); > > > > char *type = spapr_get_cpu_core_type(machine->cpu_model); > > > > -int smt = kvmppc_smt_threads(); > > > > const CPUArchIdList *possible_cpus; > > > > int boot_cores_nr = smp_cpus / smp_threads; > > > > int i; > > > > @@ -2014,7 +2012,7 @@ static void spapr_init_cpus(sPAPRMachineState > > > > *spapr) > > > > sPAPRDRConnector *drc = > > > > spapr_dr_connector_new(OBJECT(spapr), > > > > SPAPR_DR_CONNECTOR_TYPE_CPU, > > > > - (core_id / smp_threads) * smt); > > > > + > > > > ppc_cpu_dt_id_from_index(core_id)); > > > > > > > > qemu_register_reset(spapr_drc_reset, drc); > > > > } > > > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > > > > index 401e10e7dad8..47fe6c64698f 100644 > > > > --- a/target/ppc/cpu.h > > > > +++ b/target/ppc/cpu.h > > > > @@ -2529,4 +2529,21 @@ int ppc_get_
Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 3/4] target/ppc: consolidate CPU device-tree id computation in helper
On Mon, May 22, 2017 at 03:13:25PM +0200, Greg Kurz wrote: > On Mon, 22 May 2017 10:59:50 +0200 > Greg Kurz wrote: > > > On Mon, 22 May 2017 12:04:13 +1000 > > David Gibson wrote: > > > > > On Fri, May 19, 2017 at 12:32:20PM +0200, Greg Kurz wrote: > > > > For historical reasons, we compute CPU device-tree ids with a > > > > non-trivial > > > > logic. This patch consolidate the logic in a single helper to be used > > > > in various places where it is currently open-coded. > > > > > > > > It is okay to get rid of DIV_ROUND_UP() because we're sure that the > > > > number > > > > of threads per core in the guest cannot exceed the number of threads per > > > > core in the host. > > > > > > However, your new logic still gives different answers in some cases. > > > In particular when max_cpus is not a multiple of smp_threads. Which > > > is generally a bad idea, but allowed for older machine types for > > > compatibility. e.g. smp_threads=4, max_cpus=6 smt=8 > > > > > FWIW, this topology was never supported for pseries >= 2.7 since commit > 94a94e4c4919 ("spapr: convert boot CPUs into CPU core devices", QEMU 2.7): > > qemu-system-ppc64: max_cpus (6) must be multiple of threads (4) > > The same happens goes with smp_cpus. Yes, pre-2.7 is what I meant by older machine types. > If we care for compat with pre-2.7 machine types (ie, no support for CPU > hotplug), We do.. RHEL 7.3 is still 2.6 based, for one thing. > this topology isn't valid anymore since QEMU 2.9, with these > commits: > > 0c86d0fd92aa ("pseries: Always use core objects for CPU construction") which > causes the following error if we only set max_cpus: > > qemu-system-ppc64: This machine version does not support CPU hotplug That patch has explicit provision for allowing the last core to have a not-full complement of threads. > 8149e2992f78 ("pseries: Enforce homogeneous threads-per-core") which > causes the following error if we set smp_cpus (or smp_cpus == max_cpus): > > qemu-system-ppc64: invalid nr-threads 2, must be 4 This one does indeed do what you say - but that's a bug :(. It means migration from older versions may be broken. > So in the end, we already enforce max_cpus and smp_cpus to be multiple > of smp_threads for all machine types. In this case... > > > > Old logic: > > >DIV_ROUND_UP(6 * 8, 4) > > > = ⌈48 / 4⌉ = 12 > > > > > > New logic gives: ⌊6 / 4⌋ * 8 + (6 % 4) > > >= 1 * 8 + 2 > > > = 10 > > > > > > > I now realize this two formulas are hardly reconcilable... this > > probably means that this patch shouldn't try to consolidate the > > logic in hw/ppc/spapr.c with the one in target/ppc/translate_init.c. > > ... both formulas are equivalent, unless I'm missing something. Or > do we really want to re-allow the funky topologies for older > machines ? Want to? Not really. Have to for compatibility? Yes, absolutely. I've just sent a patch to address this. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
[Qemu-devel] [PATCH] pseries: Restore support for total vcpus not a multiple of threads-per-core for old machine types
As of pseries-2.7 and later, we require the total number of guest vcpus to be a multiple of the threads-per-core. pseries-2.6 and earlier machine types, however, are supposed to allow this for the sake of migration from old qemu versions which allowed this. Unfortunately, 8149e29 "pseries: Enforce homogeneous threads-per-core" broke this by not considering the old machine type case. This fixes it by only applying the check when the machine type supports hotpluggable cpus. By not-entirely-coincidence, that corresponds to the same time when we started enforcing total threads being a multiple of threads-per-core. Fixes: 8149e2992f7811355cc34721b79d69d1a3a667dd Signed-off-by: David Gibson --- hw/ppc/spapr.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c92d269..bcb0e18 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2863,7 +2863,13 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, goto out; } -if (cc->nr_threads != smp_threads) { +/* + * In general we should have homogeneous threads-per-core, but old + * (pre hotplug support) machine types allow the last core to have + * reduced threads as a compatibility hack for when we allowed + * total vcpus not a multiple of threads-per-core. + */ +if (mc->has_hotpluggable_cpus && (cc->nr_threads != smp_threads)) { error_setg(errp, "invalid nr-threads %d, must be %d", cc->nr_threads, smp_threads); return; -- 2.9.4
Re: [Qemu-devel] [virtio-dev] Re: [virtio-dev] Re: [PATCH v2 00/16] Vhost-pci for inter-VM communication
On 2017年05月23日 13:47, Wei Wang wrote: On 05/23/2017 10:08 AM, Jason Wang wrote: On 2017年05月22日 19:46, Wang, Wei W wrote: On Monday, May 22, 2017 10:28 AM, Jason Wang wrote: On 2017年05月19日 23:33, Stefan Hajnoczi wrote: On Fri, May 19, 2017 at 11:10:33AM +0800, Jason Wang wrote: On 2017年05月18日 11:03, Wei Wang wrote: On 05/17/2017 02:22 PM, Jason Wang wrote: On 2017年05月17日 14:16, Jason Wang wrote: On 2017年05月16日 15:12, Wei Wang wrote: Hi: Care to post the driver codes too? OK. It may take some time to clean up the driver code before post it out. You can first have a check of the draft at the repo here: https://github.com/wei-w-wang/vhost-pci-driver Best, Wei Interesting, looks like there's one copy on tx side. We used to have zerocopy support for tun for VM2VM traffic. Could you please try to compare it with your vhost-pci-net by: We can analyze from the whole data path - from VM1's network stack to send packets -> VM2's network stack to receive packets. The number of copies are actually the same for both. That's why I'm asking you to compare the performance. The only reason for vhost-pci is performance. You should prove it. There is another reason for vhost-pci besides maximum performance: vhost-pci makes it possible for end-users to run networking or storage appliances in compute clouds. Cloud providers do not allow end-users to run custom vhost-user processes on the host so you need vhost-pci. Stefan Then it has non NFV use cases and the question goes back to the performance comparing between vhost-pci and zerocopy vhost_net. If it does not perform better, it was less interesting at least in this case. Probably I can share what we got about vhost-pci and vhost-user: https://github.com/wei-w-wang/vhost-pci-discussion/blob/master/vhost_pci_vs_vhost_user.pdf Right now, I don’t have the environment to add the vhost_net test. Thanks, the number looks good. But I have some questions: - Is the number measured through your vhost-pci kernel driver code? Yes, the kernel driver code. Interesting, in the above link, "l2fwd" was used in vhost-pci testing. I want to know more about the test configuration: If l2fwd is the one that dpdk had, want to know how can you make it work for kernel driver. (Maybe packet socket I think?) If not, want to know how do you configure it (e.g through bridge or act_mirred or others). And in OVS dpdk, is dpdk l2fwd + pmd used in the testing? - Have you tested packet size other than 64B? Not yet. Better to test more since the time spent on 64B copy should be very fast. - Is zerocopy supported in OVS-dpdk? If yes, is it enabled in your test? zerocopy is not used in the test, but I don't think zerocopy can increase the throughput to 2x. I agree, but we need prove this with numbers. Thanks On the other side, we haven't put effort to optimize the draft kernel driver yet. Best, Wei
Re: [Qemu-devel] [virtio-dev] Re: [PATCH RFC] virtio-net: enable configurable tx queue size
On 2017年05月23日 13:15, Wei Wang wrote: On 05/23/2017 10:04 AM, Jason Wang wrote: On 2017年05月22日 19:52, Wei Wang wrote: On 05/20/2017 04:42 AM, Michael S. Tsirkin wrote: On Fri, May 19, 2017 at 10:32:19AM +0800, Wei Wang wrote: This patch enables the virtio-net tx queue size to be configurable between 256 (the default queue size) and 1024 by the user. The queue size specified by the user should be power of 2. Setting the tx queue size to be 1024 requires the guest driver to support the VIRTIO_NET_F_MAX_CHAIN_SIZE feature. This should be a generic ring feature, not one specific to virtio net. OK. How about making two more changes below: 1) make the default tx queue size = 1024 (instead of 256). As has been pointed out, you need compat the default value too in this case. The driver gets the size info from the device, then would it cause any compatibility issue if we change the default ring size to 1024 in the vhost case? In other words, is there any software (i.e. any virtio-net driver) functions based on the assumption of 256 queue size? I don't know. But is it safe e.g we migrate from 1024 to an older qemu with 256 as its queue size? For live migration, the queue size that is being used will also be transferred to the destination. We can reduce the size (to 256) if the MAX_CHAIN_SIZE feature is not supported by the guest. In this way, people who apply the QEMU patch can directly use the largest queue size(1024) without adding the booting command line. 2) The vhost backend does not use writev, so I think when the vhost backed is used, using 1024 queue size should not depend on the MAX_CHAIN_SIZE feature. But do we need to consider even larger queue size now? Need Michael's feedback on this. Meanwhile, I'll get the next version of code ready and check if larger queue size would cause any corner case. The problem is, do we really need a new config filed for this? Or just introduce a flag which means "I support up to 1024 sgs" is sufficient? Btw, I think it's better to draft a spec patch. I think it should be easier to draft the spec patch when the code is almost done. Maybe both. Thanks Best, Wei
Re: [Qemu-devel] [PATCH risu] ppc64: Fix patterns for rotate doubleword instructions
G 3 writes: > On May 22, 2017, at 4:32 AM, qemu-devel-requ...@nongnu.org wrote: > > Hello I have also done some work risu. My patches add ppc32 support. > Well my patches were made to work with Mac OS X but they are required > to work with Linux. Do you think you could help port these patches to > Linux? Ziviani did the ppc64 work, lets see if he can spare some time. The patches haven't come right on the mailing list, its tedious to pull them. Please resend them with git send-mail. > > ppc.risu: > https://patchwork.kernel.org/patch/9697489/ > > risu_ppc.c: > https://patchwork.kernel.org/patch/9697491/ > > risu_reginfo_ppc.c: > https://patchwork.kernel.org/patch/9697493/ > > risu_reginfo_ppc.h: > https://patchwork.kernel.org/patch/9697495/ > > risugen_ppc.pm: > https://patchwork.kernel.org/patch/9697497/ > > Add ppc support to configure: > https://patchwork.kernel.org/patch/9697499/ > > Add verbose option: > https://patchwork.kernel.org/patch/9697501/ > > Add end of test message: > https://patchwork.kernel.org/patch/9697503/ > > Add more descriptive comment for mismatch or end of test condition: > https://patchwork.kernel.org/patch/9697505/ Regards Nikunj
Re: [Qemu-devel] [virtio-dev] Re: [virtio-dev] Re: [PATCH v2 00/16] Vhost-pci for inter-VM communication
On 05/23/2017 10:08 AM, Jason Wang wrote: On 2017年05月22日 19:46, Wang, Wei W wrote: On Monday, May 22, 2017 10:28 AM, Jason Wang wrote: On 2017年05月19日 23:33, Stefan Hajnoczi wrote: On Fri, May 19, 2017 at 11:10:33AM +0800, Jason Wang wrote: On 2017年05月18日 11:03, Wei Wang wrote: On 05/17/2017 02:22 PM, Jason Wang wrote: On 2017年05月17日 14:16, Jason Wang wrote: On 2017年05月16日 15:12, Wei Wang wrote: Hi: Care to post the driver codes too? OK. It may take some time to clean up the driver code before post it out. You can first have a check of the draft at the repo here: https://github.com/wei-w-wang/vhost-pci-driver Best, Wei Interesting, looks like there's one copy on tx side. We used to have zerocopy support for tun for VM2VM traffic. Could you please try to compare it with your vhost-pci-net by: We can analyze from the whole data path - from VM1's network stack to send packets -> VM2's network stack to receive packets. The number of copies are actually the same for both. That's why I'm asking you to compare the performance. The only reason for vhost-pci is performance. You should prove it. There is another reason for vhost-pci besides maximum performance: vhost-pci makes it possible for end-users to run networking or storage appliances in compute clouds. Cloud providers do not allow end-users to run custom vhost-user processes on the host so you need vhost-pci. Stefan Then it has non NFV use cases and the question goes back to the performance comparing between vhost-pci and zerocopy vhost_net. If it does not perform better, it was less interesting at least in this case. Probably I can share what we got about vhost-pci and vhost-user: https://github.com/wei-w-wang/vhost-pci-discussion/blob/master/vhost_pci_vs_vhost_user.pdf Right now, I don’t have the environment to add the vhost_net test. Thanks, the number looks good. But I have some questions: - Is the number measured through your vhost-pci kernel driver code? Yes, the kernel driver code. - Have you tested packet size other than 64B? Not yet. - Is zerocopy supported in OVS-dpdk? If yes, is it enabled in your test? zerocopy is not used in the test, but I don't think zerocopy can increase the throughput to 2x. On the other side, we haven't put effort to optimize the draft kernel driver yet. Best, Wei
Re: [Qemu-devel] [PATCH] ivshmem-server: Detect and use if there is required -lrt linking
Kamil Rytarowski writes: > On 22.05.2017 08:28, Markus Armbruster wrote: >> Kamil Rytarowski writes: >> >>> Hello, >>> >>> Excuse me for delay, I missed this mail. >> >> No problem. >> >>> Please see in-line. >>> >>> On 17.05.2017 09:28, Markus Armbruster wrote: Kamil Rytarowski writes: > ivshmem-server makes use of the POSIX shared memory object interfaces. > This library is provided on NetBSD in -lrt (POSIX Real-time Library). > Add ./configure check if there is needed -lrt linking for shm_open() > and if so use it. Introduce new configure generated variable LIBS_SHMLIB. > > This fixes build issue on NetBSD. > > Signed-off-by: Kamil Rytarowski > --- > Makefile | 1 + > configure | 20 > 2 files changed, 21 insertions(+) > > diff --git a/Makefile b/Makefile > index 31d41a7eae..3248cb53d7 100644 > --- a/Makefile > +++ b/Makefile > @@ -473,6 +473,7 @@ ivshmem-client$(EXESUF): $(ivshmem-client-obj-y) > $(COMMON_LDADDS) > $(call LINK, $^) > ivshmem-server$(EXESUF): $(ivshmem-server-obj-y) $(COMMON_LDADDS) > $(call LINK, $^) > +ivshmem-server$(EXESUF): LIBS += $(LIBS_SHMLIB) > > module_block.h: $(SRC_PATH)/scripts/modules/module_block.py > config-host.mak > $(call quiet-command,$(PYTHON) $< $@ \ > diff --git a/configure b/configure > index 7c020c076b..50c3aee746 100755 > --- a/configure > +++ b/configure > @@ -179,6 +179,7 @@ audio_pt_int="" > audio_win_int="" > cc_i386=i386-pc-linux-gnu-gcc > libs_qga="" > +libs_shmlib="" > debug_info="yes" > stack_protector="" > > @@ -4133,6 +4134,24 @@ elif compile_prog "" "$pthread_lib -lrt" ; then >libs_qga="$libs_qga -lrt" > fi > > +## > +# Do we need librt for shm_open() > +cat > $TMPC < +#include > +#include > +#include > +#include > +int main(void) { > + return shm_open(NULL, O_RDWR, 0644); > +} > +EOF > + > +if compile_prog "" "" ; then > + : > +elif compile_prog "" "-lrt" ; then > + libs_shmlib="$libs_shmlib -lrt" > +fi > + > if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes > -a \ > "$aix" != "yes" -a "$haiku" != "yes" ; then > libs_softmmu="-lutil $libs_softmmu" > @@ -5949,6 +5968,7 @@ echo "EXESUF=$EXESUF" >> $config_host_mak > echo "DSOSUF=$DSOSUF" >> $config_host_mak > echo "LDFLAGS_SHARED=$LDFLAGS_SHARED" >> $config_host_mak > echo "LIBS_QGA+=$libs_qga" >> $config_host_mak > +echo "LIBS_SHMLIB+=$libs_shmlib" >> $config_host_mak > echo "TASN1_LIBS=$tasn1_libs" >> $config_host_mak > echo "TASN1_CFLAGS=$tasn1_cflags" >> $config_host_mak > echo "POD2MAN=$POD2MAN" >> $config_host_mak We already have a test for -lrt. >>> >>> Correct. >>> It looks for timer_create() and clock_gettime(). >>> >>> >>> timer_create(2) and clock_settime(2) are in libc on NetBSD. >>> If we need -lrt, >>> >>> We need it just for shm_open(3). >>> we add it to LIBS and to LIBS_QGA. The latter because we don't use LIBS for qemu-ga: qemu-ga$(EXESUF): LIBS = $(LIBS_QGA) This patch adds a second test for -lrt, to look for shm_open(). It adds -lrt to new variable LIBS_SHMLIB, which gets used only for ivshmem-server: ivshmem-server$(EXESUF): LIBS += $(LIBS_SHMLIB) Note that ivshmem-server already uses LIBS. Shouldn't we instead widen the existing test for -lrt to cover shm_open()? >>> >>> I will prepare patch in the requested way. I don't have preference. >>> Can you confirm that the existing test does not add -lrt to LIBS on NetBSD? >>> >>> config-host.mak:LIBS+=-lm -L/usr/pkg/lib -lgthread-2.0 -pthread >>> -Wl,-R/usr/pkg/lib -lglib-2.0 -lintl -lz >>> config-host.mak:LIBS_QGA+=-lm -L/usr/pkg/lib -lgthread-2.0 -pthread >>> -Wl,-R/usr/pkg/lib -lglib-2.0 -lintl >>> tests/ivshmem-test.c also calls shm_open(). Does it work on NetBSD? >>> >>> Currently it's disabled, as it requires eventfd() (Linux API). >> >> You're right. >> >> So is the ivshmem device. Hmm. Why would anyone want ivshmem-server on >> NetBSD? Its purpose is connecting ivshmem-doorbell devices. Could we >> simply add the obvious CONFIG_IVSHMEM dependence to >> contrib/ivshmem-*/Makefile.objs? >> > > In general I would like to get feature parity on NetBSD, there is no > reason to blacklist this feature for !Linux hosts. However short term Feature parity is a worthy goal, but compiling ivshmem-server without ivshmem-doorbell doesn't gets you a feature, it gets you a binary you can't use for its intended purpose :) > there are higher priorities, to fix build of pristine sources > (ivshmem-server is blocking here, not that I'm right now working on i
Re: [Qemu-devel] [virtio-dev] Re: [PATCH RFC] virtio-net: enable configurable tx queue size
On 05/23/2017 10:04 AM, Jason Wang wrote: On 2017年05月22日 19:52, Wei Wang wrote: On 05/20/2017 04:42 AM, Michael S. Tsirkin wrote: On Fri, May 19, 2017 at 10:32:19AM +0800, Wei Wang wrote: This patch enables the virtio-net tx queue size to be configurable between 256 (the default queue size) and 1024 by the user. The queue size specified by the user should be power of 2. Setting the tx queue size to be 1024 requires the guest driver to support the VIRTIO_NET_F_MAX_CHAIN_SIZE feature. This should be a generic ring feature, not one specific to virtio net. OK. How about making two more changes below: 1) make the default tx queue size = 1024 (instead of 256). As has been pointed out, you need compat the default value too in this case. The driver gets the size info from the device, then would it cause any compatibility issue if we change the default ring size to 1024 in the vhost case? In other words, is there any software (i.e. any virtio-net driver) functions based on the assumption of 256 queue size? For live migration, the queue size that is being used will also be transferred to the destination. We can reduce the size (to 256) if the MAX_CHAIN_SIZE feature is not supported by the guest. In this way, people who apply the QEMU patch can directly use the largest queue size(1024) without adding the booting command line. 2) The vhost backend does not use writev, so I think when the vhost backed is used, using 1024 queue size should not depend on the MAX_CHAIN_SIZE feature. But do we need to consider even larger queue size now? Need Michael's feedback on this. Meanwhile, I'll get the next version of code ready and check if larger queue size would cause any corner case. Btw, I think it's better to draft a spec patch. I think it should be easier to draft the spec patch when the code is almost done. Best, Wei
Re: [Qemu-devel] [Qemu-ppc] [RFC PATCH v2 4/4] spapr: Fix migration of Radix guests
On Mon, May 22, 2017 at 04:30:50PM +1000, Suraj Jitindar Singh wrote: > On Fri, 2017-05-19 at 11:10 +0530, Bharata B Rao wrote: > > Fix migration of radix guests by ensuring that we issue > > KVM_PPC_CONFIGURE_V3_MMU for radix case post migration. > > > > Reported-by: Nageswara R Sastry > > Signed-off-by: Bharata B Rao > > --- > > hw/ppc/spapr.c | 12 > > 1 file changed, 12 insertions(+) > > > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > > index daf335c..8f20f14 100644 > > --- a/hw/ppc/spapr.c > > +++ b/hw/ppc/spapr.c > > @@ -1400,6 +1400,18 @@ static int spapr_post_load(void *opaque, int > > version_id) > > err = spapr_rtc_import_offset(&spapr->rtc, spapr- > > >rtc_offset); > > } > > This will break migration for tcg radix guests. > > Given that there is essentially nothing special we need to do on > incoming tcg migration, I suggest we make it: > > if (spapr->patb_entry && kvm_enabled()) { > [snip] > } > > > > > +if (spapr->patb_entry) { > > +PowerPCCPU *cpu = POWERPC_CPU(first_cpu); > > +if (kvmppc_has_cap_mmu_radix() && kvm_enabled()) { > > Why not make this a bit more generic? Something like: > > err = kvmppc_configure_v3_mmu(cpu, !!(spapr->patb_entry & PATBE1_GR), > !!(cpu->env.spr[SPR_LPCR] & LPCR_GTSE), spapr->patb_entry); > if (err) { > error_report("Process table config unsupported by the host"); > return -EINVAL; > } > > return err; > > While I don't think it's possible currently, there is nothing > inherently incorrect about having a non-zero process table entry for a > hash guest. And this saves a future update. How about having this logic in spapr_post_load() ? if (spapr->patb_entry) { /* Can be Hash(in future?) or Radix guest (current) */ PowerPCCPU *cpu = POWERPC_CPU(first_cpu); bool radix = !!(spapr->patb_entry & PATBE1_GR); bool gtse = !!(cpu->env.spr[SPR_LPCR] & LPCR_GTSE); if (radix) { /* Radix guest, configure MMU */ /* kvmppc_configure_v3_mmu() is NOP for TCG */ err = kvmppc_configure_v3_mmu(cpu, radix, gtse, spapr->patb_entry); if (err) { error_report("Process table config unsupported by the host"); return -EINVAL; } } else { /* Can be Hash guest (in future ?), nothing to do */ } } else { /* Hash guest (current), nothing to do */ } Regards, Bharata.
Re: [Qemu-devel] [PATCH] migration: keep bytes_xfer_prev init'd to zero
On Fri, May 19, 2017 at 10:59:02PM +0100, Felipe Franciosi wrote: > The first time migration_bitmap_sync() is called, bytes_xfer_prev is set > to ram_state.bytes_transferred which is, at this point, zero. The next > time migration_bitmap_sync() is called, an iteration has happened and > bytes_xfer_prev is set to 'x' bytes. Most likely, more than one second > has passed, so the auto converge logic will be triggered and > bytes_xfer_now will also be set to 'x' bytes. > > This condition is currently masked by dirty_rate_high_cnt, which will > wait for a few iterations before throttling. It would otherwise always > assume zero bytes have been copied and therefore throttle the guest > (possibly) prematurely. > > Given bytes_xfer_prev is only used by the auto convergence logic, it > makes sense to only set its value after a check has been made against > bytes_xfer_now. > > Signed-off-by: Felipe Franciosi > ~ > --- > migration/ram.c | 4 > 1 file changed, 4 deletions(-) > > diff --git a/migration/ram.c b/migration/ram.c > index f59fdd4..793af39 100644 > --- a/migration/ram.c > +++ b/migration/ram.c > @@ -670,10 +670,6 @@ static void migration_bitmap_sync(RAMState *rs) > > rs->bitmap_sync_count++; > > -if (!rs->bytes_xfer_prev) { > -rs->bytes_xfer_prev = ram_bytes_transferred(); > -} > - > if (!rs->time_last_bitmap_sync) { > rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); > } > -- > 1.9.5 > > I feel like this patch wants to correctly initialize bytes_xfer_prev, however I still see problem. E.g., when user specify auto-convergence during migration, and in the first iteration we'll always have a very small bytes_xfer_prev (with this patch, it'll be zero) with a very big bytes_xfer_now (which is the ram_bytes_transferred() value). If so, do you think squash below change together with current one would be more accurate? diff --git a/migration/ram.c b/migration/ram.c index f59fdd4..e01a218 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -703,7 +703,8 @@ static void migration_bitmap_sync(RAMState *rs) throttling */ bytes_xfer_now = ram_bytes_transferred(); -if (rs->dirty_pages_rate && +/* Skip first iteration when bytes_xfer_prev not inited */ +if (rs->bytes_xfer_prev && rs->dirty_pages_rate && (rs->num_dirty_pages_period * TARGET_PAGE_SIZE > (bytes_xfer_now - rs->bytes_xfer_prev) / 2) && (rs->dirty_rate_high_cnt++ >= 2)) { Even I am not sure whether we can move bytes_xfer_prev out of RAMState since it's only used by migration_bitmap_sync(). Thanks, -- Peter Xu
Re: [Qemu-devel] [PATCH v13] migration: spapr: migrate pending_events of spapr state
On Mon, May 22, 2017 at 03:40:39PM -0300, Daniel Henrique Barboza wrote: > From: Jianjun Duan > > In racing situations between hotplug events and migration operation, > a rtas hotplug event could have not yet be delivered to the source > guest when migration is started. In this case the pending_events of > spapr state need be transmitted to the target so that the hotplug > event can be finished on the target. > > All the different fields of the events are encoded as defined by > PAPR. We can migrate them as a binary stream inside VBUFFER without > any concerns about data padding or endianess. > > pending_events is put in a subsection in the spapr state VMSD to make > sure migration across different versions is not broken. > > Signed-off-by: Jianjun Duan > Signed-off-by: Daniel Henrique Barboza > --- > hw/ppc/spapr.c | 32 > hw/ppc/spapr_events.c | 19 +++ > include/hw/ppc/spapr.h | 3 ++- > 3 files changed, 53 insertions(+), 1 deletion(-) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 75e298b..558f951 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -1453,6 +1453,37 @@ static bool version_before_3(void *opaque, int > version_id) > return version_id < 3; > } > > +static bool spapr_pending_events_needed(void *opaque) > +{ > +sPAPRMachineState *spapr = (sPAPRMachineState *)opaque; > +return !QTAILQ_EMPTY(&spapr->pending_events); > +} > + > +static const VMStateDescription vmstate_spapr_event_entry = { > +.name = "spapr_event_log_entry", > +.version_id = 1, > +.minimum_version_id = 1, > +.fields = (VMStateField[]) { > +VMSTATE_INT32(log_type, sPAPREventLogEntry), > +VMSTATE_UINT32(data_size, sPAPREventLogEntry), > +VMSTATE_VBUFFER_ALLOC_UINT32(data, sPAPREventLogEntry, 0, > + NULL, data_size), > +VMSTATE_END_OF_LIST() > +}, > +}; > + > +static const VMStateDescription vmstate_spapr_pending_events = { > +.name = "spapr_pending_events", > +.version_id = 1, > +.minimum_version_id = 1, > +.needed = spapr_pending_events_needed, > +.fields = (VMStateField[]) { > +VMSTATE_QTAILQ_V(pending_events, sPAPRMachineState, 1, > + vmstate_spapr_event_entry, sPAPREventLogEntry, > next), > +VMSTATE_END_OF_LIST() > +}, > +}; > + > static bool spapr_ov5_cas_needed(void *opaque) > { > sPAPRMachineState *spapr = opaque; > @@ -1551,6 +1582,7 @@ static const VMStateDescription vmstate_spapr = { > .subsections = (const VMStateDescription*[]) { > &vmstate_spapr_ov5_cas, > &vmstate_spapr_patb_entry, > +&vmstate_spapr_pending_events, > NULL > } > }; > diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c > index 73e2a18..6c42041 100644 > --- a/hw/ppc/spapr_events.c > +++ b/hw/ppc/spapr_events.c > @@ -346,10 +346,29 @@ static void rtas_event_log_queue(int log_type, void > *data) > { > sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); > sPAPREventLogEntry *entry = g_new(sPAPREventLogEntry, 1); > +struct epow_log_full *new_epow = NULL; > +struct hp_log_full *new_hp = NULL; > +uint32_t ext_length = 0; > > g_assert(data); > entry->log_type = log_type; > entry->data = data; > + > +switch (log_type) { > +case RTAS_LOG_TYPE_EPOW: > +new_epow = (struct epow_log_full *)data; > +ext_length = be32_to_cpu(new_epow->hdr.extended_length); > +entry->data_size = ext_length + sizeof(new_epow->hdr); > +break; > +case RTAS_LOG_TYPE_HOTPLUG: > +new_hp = (struct hp_log_full *)data; > +ext_length = be32_to_cpu(new_hp->hdr.extended_length); > +entry->data_size = ext_length + sizeof(new_hp->hdr); > +break; > +default: > +g_assert(false); > +} > + You're still overcomplicating this. Both epow_log_full and hp_log_full start with an rtas_error_log header, which is what contains the extended_length field. You can just case data directly to struct rtas_error_log *, and derive the data size from there. And.. come to think of it, you don't need the log_type in the vmsd either, since it can be derived from the summary field in the same header. And.. going even further, we could alter the existing code so that instead of embedding the rtas_error_log header in the allocated buffer, we could inline it into the sPAPREventLogEntry structure, with just the extended data in the variable sized buffer. Then we wouldn't need a new data_size field, the extended_size field from the rtas_error_log substructure would already be exactly what we need to size the buffer. > QTAILQ_INSERT_TAIL(&spapr->pending_events, entry, next); > } > > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index be2b3b8..b2fcd62 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -598,8 +598,9 @@ struct sP
Re: [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1'
Hi Hervé, On 05/22/2017 06:12 PM, Hervé Poussineau wrote: According to specification: "'MSWIN4.1' is the recommanded setting, because it is the setting least likely to cause compatibility problems. If you want to put something else in here, that is your option, but the result may be that some FAT drivers might not recognize the volume." It also says "Typically this is some indication of what system formatted the volume." From https://technet.microsoft.com/en-us/library/cc976796.aspx: "Following the jump instruction is the 8-byte OEM ID, a string of characters that identifies the name and version number of the operating system that formatted the volume. To preserve compatibility with MS-DOS, Windows 2000 records "MSDOS5.0" in this field on FAT16 and FAT32 disks. On NTFS disks, Windows 2000 records "NTFS." You may also see the OEM ID "MSWIN4.0" on disks formatted by Windows 95 and "MSWIN4.1" on disks formatted by Windows 95 OSR2 and Windows 98. Windows 2000 does not use the OEM ID field in the boot sector except for verifying NTFS volumes." I'm curious which one is the most up-to-date, the specification v1.03 or a Windows 2000. Do you have an idea if there is more MSDOS/W2K vs W95/98 users? Hopefully W95 is a Long time no see to me. You think having "QEMU" OEM does more harm than good? Specification: "FAT: General overview of on-disk format" v1.03, page 9 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/vvfat.c b/block/vvfat.c index 53e8faa54c..1f7f46ecea 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1024,7 +1024,7 @@ static int init_directories(BDRVVVFATState* s, bootsector->jump[0]=0xeb; bootsector->jump[1]=0x3e; bootsector->jump[2]=0x90; -memcpy(bootsector->name,"QEMU",8); +memcpy(bootsector->name, "MSWIN4.1", 8); bootsector->sector_size=cpu_to_le16(0x200); bootsector->sectors_per_cluster=s->sectors_per_cluster; bootsector->reserved_sectors=cpu_to_le16(1); Regards, Phil.
[Qemu-devel] [PATCH v5 1/4] net/rocker: Remove the dead error handling
Memory allocation functions like world_alloc, desc_ring_alloc etc, they are all wrappers around g_malloc, g_new etc. But g_malloc and similar functions doesn't return null. Because they ignore the fact that g_malloc() of 0 bytes returns null. So error checks for these allocation failure are superfluous. Now, remove them entirely. Signed-off-by: Mao Zhongyi --- hw/net/rocker/rocker.c| 46 --- hw/net/rocker/rocker_desc.c | 10 -- hw/net/rocker/rocker_fp.c | 4 hw/net/rocker/rocker_of_dpa.c | 20 --- hw/net/rocker/rocker_world.c | 12 +-- 5 files changed, 5 insertions(+), 87 deletions(-) diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index 6e70fdd..d01ba9d 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -239,10 +239,6 @@ static int tx_consume(Rocker *r, DescInfo *info) } iov[iovcnt].iov_len = frag_len; iov[iovcnt].iov_base = g_malloc(frag_len); -if (!iov[iovcnt].iov_base) { -err = -ROCKER_ENOMEM; -goto err_no_mem; -} if (pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base, iov[iovcnt].iov_len)) { @@ -262,7 +258,6 @@ static int tx_consume(Rocker *r, DescInfo *info) err_too_many_frags: err_bad_io: -err_no_mem: err_bad_attr: for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) { g_free(iov[i].iov_base); @@ -674,10 +669,6 @@ int rx_produce(World *world, uint32_t pport, */ data = g_malloc(data_size); -if (!data) { -err = -ROCKER_ENOMEM; -goto out; -} iov_to_buf(iov, iovcnt, 0, data, data_size); pci_dma_write(dev, frag_addr, data, data_size); g_free(data); @@ -722,11 +713,6 @@ static void rocker_test_dma_ctrl(Rocker *r, uint32_t val) buf = g_malloc(r->test_dma_size); -if (!buf) { -DPRINTF("test dma buffer alloc failed"); -return; -} - switch (val) { case ROCKER_TEST_DMA_CTRL_CLEAR: memset(buf, 0, r->test_dma_size); @@ -1313,13 +1299,6 @@ static int pci_rocker_init(PCIDevice *dev) r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r); -for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) { -if (!r->worlds[i]) { -err = -ENOMEM; -goto err_world_alloc; -} -} - if (!r->world_name) { r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA])); } @@ -1396,9 +1375,6 @@ static int pci_rocker_init(PCIDevice *dev) } r->rings = g_new(DescRing *, rocker_pci_ring_count(r)); -if (!r->rings) { -goto err_rings_alloc; -} /* Rings are ordered like this: * - command ring @@ -1410,14 +1386,9 @@ static int pci_rocker_init(PCIDevice *dev) * . */ -err = -ENOMEM; for (i = 0; i < rocker_pci_ring_count(r); i++) { DescRing *ring = desc_ring_alloc(r, i); -if (!ring) { -goto err_ring_alloc; -} - if (i == ROCKER_RING_CMD) { desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD); } else if (i == ROCKER_RING_EVENT) { @@ -1437,10 +1408,6 @@ static int pci_rocker_init(PCIDevice *dev) fp_port_alloc(r, r->name, &r->fp_start_macaddr, i, &r->fp_ports_peers[i]); -if (!port) { -goto err_port_alloc; -} - r->fp_port[i] = port; fp_port_set_world(port, r->world_dflt); } @@ -1449,25 +1416,12 @@ static int pci_rocker_init(PCIDevice *dev) return 0; -err_port_alloc: -for (--i; i >= 0; i--) { -FpPort *port = r->fp_port[i]; -fp_port_free(port); -} -i = rocker_pci_ring_count(r); -err_ring_alloc: -for (--i; i >= 0; i--) { -desc_ring_free(r->rings[i]); -} -g_free(r->rings); -err_rings_alloc: err_duplicate: rocker_msix_uninit(r); err_msix_init: object_unparent(OBJECT(&r->msix_bar)); object_unparent(OBJECT(&r->mmio)); err_world_type_by_name: -err_world_alloc: for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) { if (r->worlds[i]) { world_free(r->worlds[i]); diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c index ac02797..d0df89a 100644 --- a/hw/net/rocker/rocker_desc.c +++ b/hw/net/rocker/rocker_desc.c @@ -65,10 +65,6 @@ char *desc_get_buf(DescInfo *info, bool read_only) info->buf_size = size; } -if (!info->buf) { -return NULL; -} - if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size)) { return NULL; } @@ -144,9 +140,6 @@ bool desc_ring_set_size(DescRing *ring, uint32_t size) ring->head = ring->tail = 0; ring->info = g_renew(DescInfo, ring->info, size); -if (!ring->info) { -return false; -} memset(ring->info, 0, size * sizeof(DescInfo)); @@ -347,9 +340,6 @@ DescRing *desc_ring_alloc(Rocker *r, i
[Qemu-devel] [PATCH v5 4/4] net/rocker: Fix the unusual macro name
Suggested-by: Markus Armbruster Signed-off-by: Mao Zhongyi --- hw/net/rocker/rocker.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index 2764529..f8a32f7 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -69,10 +69,10 @@ struct rocker { QLIST_ENTRY(rocker) next; }; -#define ROCKER "rocker" +#define TYPE_ROCKER "rocker" -#define to_rocker(obj) \ -OBJECT_CHECK(Rocker, (obj), ROCKER) +#define ROCKER(obj) \ +OBJECT_CHECK(Rocker, (obj), TYPE_ROCKER) static QLIST_HEAD(, rocker) rockers; @@ -1287,7 +1287,7 @@ static World *rocker_world_type_by_name(Rocker *r, const char *name) static void pci_rocker_realize(PCIDevice *dev, Error **errp) { -Rocker *r = to_rocker(dev); +Rocker *r = ROCKER(dev); const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } }; const MACAddr dflt = { .a = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x01 } }; static int sw_index; @@ -1333,7 +1333,7 @@ static void pci_rocker_realize(PCIDevice *dev, Error **errp) /* validate switch properties */ if (!r->name) { -r->name = g_strdup(ROCKER); +r->name = g_strdup(TYPE_ROCKER); } if (rocker_find(r->name)) { @@ -1429,7 +1429,7 @@ err_world_type_by_name: static void pci_rocker_uninit(PCIDevice *dev) { -Rocker *r = to_rocker(dev); +Rocker *r = ROCKER(dev); int i; QLIST_REMOVE(r, next); @@ -1462,7 +1462,7 @@ static void pci_rocker_uninit(PCIDevice *dev) static void rocker_reset(DeviceState *dev) { -Rocker *r = to_rocker(dev); +Rocker *r = ROCKER(dev); int i; for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) { @@ -1500,7 +1500,7 @@ static Property rocker_properties[] = { }; static const VMStateDescription rocker_vmsd = { -.name = ROCKER, +.name = TYPE_ROCKER, .unmigratable = 1, }; @@ -1523,7 +1523,7 @@ static void rocker_class_init(ObjectClass *klass, void *data) } static const TypeInfo rocker_info = { -.name = ROCKER, +.name = TYPE_ROCKER, .parent= TYPE_PCI_DEVICE, .instance_size = sizeof(Rocker), .class_init= rocker_class_init, -- 2.9.3
[Qemu-devel] [PATCH v5 2/4] net/rocker: Plug memory leak in pci_rocker_init()
pci_rocker_init() leaks a World when the name more than 9 chars, then return a negative value directly, doesn't make a correct cleanup. So add a new goto label to fix it. Signed-off-by: Mao Zhongyi Reviewed-by: Markus Armbruster --- hw/net/rocker/rocker.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index d01ba9d..6d44f37 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -1357,7 +1357,8 @@ static int pci_rocker_init(PCIDevice *dev) fprintf(stderr, "rocker: name too long; please shorten to at most %d chars\n", MAX_ROCKER_NAME_LEN); -return -EINVAL; +err = -EINVAL; +goto err_name_too_long; } if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) { @@ -1416,6 +1417,7 @@ static int pci_rocker_init(PCIDevice *dev) return 0; +err_name_too_long: err_duplicate: rocker_msix_uninit(r); err_msix_init: -- 2.9.3
[Qemu-devel] [PATCH v5 3/4] net/rocker: Convert to realize()
The rocker device still implements the old PCIDeviceClass .init() instead of the new .realize(). All devices need to be converted to .realize(). .init() reports errors with fprintf() and return 0 on success, negative number on failure. Meanwhile, when -device rocker fails, it first report a specific error, then a generic one, like this: $ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker rocker: name too long; please shorten to at most 9 chars qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed Now, convert it to .realize() that passes errors to its callers via its errp argument. Also avoid the superfluous second error message. After the patch, effect like this: $ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker qemu-system-x86_64: -device rocker,name=qemu-rocker: name too long; please shorten to at most 9 chars Signed-off-by: Mao Zhongyi Reviewed-by: Markus Armbruster --- hw/net/rocker/rocker.c | 27 +++ 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index 6d44f37..2764529 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -1238,20 +1238,18 @@ rollback: return err; } -static int rocker_msix_init(Rocker *r) +static int rocker_msix_init(Rocker *r, Error **errp) { PCIDevice *dev = PCI_DEVICE(r); int err; -Error *local_err = NULL; err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports), &r->msix_bar, ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET, &r->msix_bar, ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET, -0, &local_err); +0, errp); if (err) { -error_report_err(local_err); return err; } @@ -1287,7 +1285,7 @@ static World *rocker_world_type_by_name(Rocker *r, const char *name) return NULL; } -static int pci_rocker_init(PCIDevice *dev) +static void pci_rocker_realize(PCIDevice *dev, Error **errp) { Rocker *r = to_rocker(dev); const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } }; @@ -1305,10 +1303,9 @@ static int pci_rocker_init(PCIDevice *dev) r->world_dflt = rocker_world_type_by_name(r, r->world_name); if (!r->world_dflt) { -fprintf(stderr, -"rocker: requested world \"%s\" does not exist\n", +error_setg(errp, +"invalid argument requested world %s does not exist", r->world_name); -err = -EINVAL; goto err_world_type_by_name; } @@ -1328,7 +1325,7 @@ static int pci_rocker_init(PCIDevice *dev) /* MSI-X init */ -err = rocker_msix_init(r); +err = rocker_msix_init(r, errp); if (err) { goto err_msix_init; } @@ -1340,7 +1337,7 @@ static int pci_rocker_init(PCIDevice *dev) } if (rocker_find(r->name)) { -err = -EEXIST; +error_setg(errp, "%s already exists", r->name); goto err_duplicate; } @@ -1354,10 +1351,9 @@ static int pci_rocker_init(PCIDevice *dev) #define ROCKER_IFNAMSIZ 16 #define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3) if (strlen(r->name) > MAX_ROCKER_NAME_LEN) { -fprintf(stderr, -"rocker: name too long; please shorten to at most %d chars\n", +error_setg(errp, +"name too long; please shorten to at most %d chars", MAX_ROCKER_NAME_LEN); -err = -EINVAL; goto err_name_too_long; } @@ -1415,7 +1411,7 @@ static int pci_rocker_init(PCIDevice *dev) QLIST_INSERT_HEAD(&rockers, r, next); -return 0; +return; err_name_too_long: err_duplicate: @@ -1429,7 +1425,6 @@ err_world_type_by_name: world_free(r->worlds[i]); } } -return err; } static void pci_rocker_uninit(PCIDevice *dev) @@ -1514,7 +1509,7 @@ static void rocker_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); -k->init = pci_rocker_init; +k->realize = pci_rocker_realize; k->exit = pci_rocker_uninit; k->vendor_id = PCI_VENDOR_ID_REDHAT; k->device_id = PCI_DEVICE_ID_REDHAT_ROCKER; -- 2.9.3
[Qemu-devel] [PATCH v5 0/4] Convert to realize and fix error handling
v5: * Patch 1 removed the dead error handling that was previously missing. * Patch 2 and 3 has not changed. * Patch 4 is a new patch to fix the unusual macro name. v4: * Patch 1 is following Markus's suggestion that remove the dead error handling. * Patch 2 is separate from patch 1 to plug the memory leak in the v3. * Patch 3 is based on the patch 1 in the v3. Meanwhile, dorp the superfluous prefix "rocker:" and adjust the commit message. v3: * Following Jason's suggstion that add suitable error message to each error site. * Modified the commit message to make it easier to read. v2: * Following Philippe's suggestion that shorten the patch subject "hw/net/rocker/rocker" to "net/rocker". * Use a consistent log format to report error message. * Add a specific goto label "err_name_too_long" to make a correct cleanup. Mao Zhongyi (4): net/rocker: Remove the dead error handling net/rocker: Plug memory leak in pci_rocker_init() net/rocker: Convert to realize() net/rocker: Fix the unusual macro name hw/net/rocker/rocker.c| 93 ++- hw/net/rocker/rocker_desc.c | 10 - hw/net/rocker/rocker_fp.c | 4 -- hw/net/rocker/rocker_of_dpa.c | 20 -- hw/net/rocker/rocker_world.c | 12 +++--- 5 files changed, 27 insertions(+), 112 deletions(-) -- 2.9.3
[Qemu-devel] [PATCH 27/31] target/s390x: Use unwind data for helper_tprot
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 1 - target/s390x/translate.c | 1 - 2 files changed, 2 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index a874f8a..7f22bf0 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -943,7 +943,6 @@ uint32_t HELPER(testblock)(CPUS390XState *env, uint64_t real_addr) uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2) { /* XXX implement */ - return 0; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 694e099..282fa27 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4054,7 +4054,6 @@ static ExitStatus op_testblock(DisasContext *s, DisasOps *o) static ExitStatus op_tprot(DisasContext *s, DisasOps *o) { -potential_page_fault(s); gen_helper_tprot(cc_op, o->addr1, o->in2); set_cc_static(s); return NO_EXIT; -- 2.9.4
[Qemu-devel] [PATCH 23/31] target/s390x: Use unwind data for helper_lctlg
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 8 target/s390x/translate.c | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 902290c..26960e4 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -821,20 +821,20 @@ void HELPER(cdsg)(CPUS390XState *env, uint64_t addr, #if !defined(CONFIG_USER_ONLY) void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { +uintptr_t ra = GETPC(); S390CPU *cpu = s390_env_get_cpu(env); bool PERchanged = false; -int i; uint64_t src = a2; -uint64_t val; +uint32_t i; for (i = r1;; i = (i + 1) % 16) { -val = cpu_ldq_data(env, src); +uint64_t val = cpu_ldq_data_ra(env, src, ra); if (env->cregs[i] != val && i >= 9 && i <= 11) { PERchanged = true; } env->cregs[i] = val; HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n", - i, src, env->cregs[i]); + i, src, val); src += sizeof(uint64_t); if (i == r3) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 531b5f1..886991e 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2557,7 +2557,6 @@ static ExitStatus op_lctlg(DisasContext *s, DisasOps *o) TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); check_privileged(s); -potential_page_fault(s); gen_helper_lctlg(cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); -- 2.9.4
[Qemu-devel] [PATCH 21/31] target/s390x: Use unwind data for helper_tre
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 15 --- target/s390x/translate.c | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 748a6e8..4c6c6ee 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -720,8 +720,10 @@ void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array, uint64_t HELPER(tre)(CPUS390XState *env, uint64_t array, uint64_t len, uint64_t trans) { +uintptr_t ra = GETPC(); uint8_t end = env->regs[0] & 0xff; uint64_t l = len; +uint32_t cc = 0; uint64_t i; if (!(env->psw.mask & PSW_MASK_64)) { @@ -733,25 +735,24 @@ uint64_t HELPER(tre)(CPUS390XState *env, uint64_t array, amount of work we're willing to do. For now, let's cap at 8k. */ if (l > 0x2000) { l = 0x2000; -env->cc_op = 3; -} else { -env->cc_op = 0; +cc = 3; } for (i = 0; i < l; i++) { uint8_t byte, new_byte; -byte = cpu_ldub_data(env, array + i); +byte = cpu_ldub_data_ra(env, array + i, ra); if (byte == end) { -env->cc_op = 1; +cc = 1; break; } -new_byte = cpu_ldub_data(env, trans + byte); -cpu_stb_data(env, array + i, new_byte); +new_byte = cpu_ldub_data_ra(env, trans + byte, ra); +cpu_stb_data_ra(env, array + i, new_byte, ra); } +env->cc_op = cc; env->retxl = len - i; return array + i; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index b506cee..ecef71c 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4078,7 +4078,6 @@ static ExitStatus op_tr(DisasContext *s, DisasOps *o) static ExitStatus op_tre(DisasContext *s, DisasOps *o) { -potential_page_fault(s); gen_helper_tre(o->out, cpu_env, o->out, o->out2, o->in2); return_low128(o->out2); set_cc_static(s); -- 2.9.4
[Qemu-devel] [PATCH 31/31] target/s390x: Use unwind data for helper_mvcs/mvcp
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 8 ++-- target/s390x/translate.c | 2 -- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 4becc80..d8d29bd 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -1031,6 +1031,7 @@ uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2) uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) { +uintptr_t ra = GETPC(); int cc = 0, i; HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n", @@ -1044,7 +1045,8 @@ uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) /* XXX replace w/ memcpy */ for (i = 0; i < l; i++) { -cpu_stb_secondary(env, a1 + i, cpu_ldub_primary(env, a2 + i)); +uint8_t x = cpu_ldub_primary_ra(env, a2 + i, ra); +cpu_stb_secondary_ra(env, a1 + i, x, ra); } return cc; @@ -1052,6 +1054,7 @@ uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) { +uintptr_t ra = GETPC(); int cc = 0, i; HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n", @@ -1065,7 +1068,8 @@ uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) /* XXX replace w/ memcpy */ for (i = 0; i < l; i++) { -cpu_stb_primary(env, a1 + i, cpu_ldub_secondary(env, a2 + i)); +uint8_t x = cpu_ldub_secondary_ra(env, a2 + i, ra); +cpu_stb_primary_ra(env, a1 + i, x, ra); } return cc; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index ca5be7b..67c85f0 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2928,7 +2928,6 @@ static ExitStatus op_mvcp(DisasContext *s, DisasOps *o) { int r1 = get_field(s->fields, l1); check_privileged(s); -potential_page_fault(s); gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2); set_cc_static(s); return NO_EXIT; @@ -2938,7 +2937,6 @@ static ExitStatus op_mvcs(DisasContext *s, DisasOps *o) { int r1 = get_field(s->fields, l1); check_privileged(s); -potential_page_fault(s); gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2); set_cc_static(s); return NO_EXIT; -- 2.9.4
[Qemu-devel] [PATCH 22/31] target/s390x: Use unwind data for helper_trt
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 9 + target/s390x/translate.c | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 4c6c6ee..902290c 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -760,16 +760,17 @@ uint64_t HELPER(tre)(CPUS390XState *env, uint64_t array, uint32_t HELPER(trt)(CPUS390XState *env, uint32_t len, uint64_t array, uint64_t trans) { +uintptr_t ra = GETPC(); uint32_t cc = 0; -int i; +uint32_t i; for (i = 0; i <= len; i++) { -uint8_t byte = cpu_ldub_data(env, array + i); -uint8_t sbyte = cpu_ldub_data(env, trans + byte); +uint8_t byte = cpu_ldub_data_ra(env, array + i, ra); +uint8_t sbyte = cpu_ldub_data_ra(env, trans + byte, ra); if (sbyte != 0) { env->regs[1] = array + i; -env->regs[2] = (env->regs[2] & ~0xff) | sbyte; +env->regs[2] = deposit64(env->regs[2], 0, 8, sbyte); cc = (i == len) ? 2 : 1; break; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index ecef71c..531b5f1 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4087,7 +4087,6 @@ static ExitStatus op_tre(DisasContext *s, DisasOps *o) static ExitStatus op_trt(DisasContext *s, DisasOps *o) { TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1)); -potential_page_fault(s); gen_helper_trt(cc_op, cpu_env, l, o->addr1, o->in2); tcg_temp_free_i32(l); set_cc_static(s); -- 2.9.4
[Qemu-devel] [PATCH 28/31] target/s390x: Use unwind data for helper_lra
Note that exception_index is not live during a TB, so there is no point saving it around mmu_translate. Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 4 +--- target/s390x/translate.c | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 7f22bf0..81b27c0 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -1181,17 +1181,16 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr) { CPUState *cs = CPU(s390_env_get_cpu(env)); uint32_t cc = 0; -int old_exc = cs->exception_index; uint64_t asc = env->psw.mask & PSW_MASK_ASC; uint64_t ret; int flags; /* XXX incomplete - has more corner cases */ if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) { +cpu_restore_state(cs, GETPC()); program_interrupt(env, PGM_SPECIAL_OP, 2); } -cs->exception_index = old_exc; if (mmu_translate(env, addr, 0, asc, &ret, &flags, true)) { cc = 3; } @@ -1200,7 +1199,6 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr) } else { ret |= addr & ~TARGET_PAGE_MASK; } -cs->exception_index = old_exc; env->cc_op = cc; return ret; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 282fa27..3e4b397 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2565,7 +2565,6 @@ static ExitStatus op_lctlg(DisasContext *s, DisasOps *o) static ExitStatus op_lra(DisasContext *s, DisasOps *o) { check_privileged(s); -potential_page_fault(s); gen_helper_lra(o->out, cpu_env, o->in2); set_cc_static(s); return NO_EXIT; -- 2.9.4
[Qemu-devel] [PATCH 19/31] target/s390x: Use unwind data for helper_unpk
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 9 + target/s390x/translate.c | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index da81b38..d37e691 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -660,6 +660,7 @@ uint64_t HELPER(cksm)(CPUS390XState *env, uint64_t r1, void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, uint64_t src) { +uintptr_t ra = GETPC(); int len_dest = len >> 4; int len_src = len & 0xf; uint8_t b; @@ -669,8 +670,8 @@ void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, src += len_src; /* last byte is special, it only flips the nibbles */ -b = cpu_ldub_data(env, src); -cpu_stb_data(env, dest, (b << 4) | (b >> 4)); +b = cpu_ldub_data_ra(env, src, ra); +cpu_stb_data_ra(env, dest, (b << 4) | (b >> 4), ra); src--; len_src--; @@ -680,7 +681,7 @@ void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, uint8_t cur_byte = 0; if (len_src > 0) { -cur_byte = cpu_ldub_data(env, src); +cur_byte = cpu_ldub_data_ra(env, src, ra); } len_dest--; @@ -699,7 +700,7 @@ void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, /* zone bits */ cur_byte |= 0xf0; -cpu_stb_data(env, dest, cur_byte); +cpu_stb_data_ra(env, dest, cur_byte, ra); } } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 21c21a6..e8eefec 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4099,7 +4099,6 @@ static ExitStatus op_trt(DisasContext *s, DisasOps *o) static ExitStatus op_unpk(DisasContext *s, DisasOps *o) { TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1)); -potential_page_fault(s); gen_helper_unpk(cpu_env, l, o->addr1, o->in2); tcg_temp_free_i32(l); return NO_EXIT; -- 2.9.4
[Qemu-devel] [PATCH 20/31] target/s390x: Use unwind data for helper_tr
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 10 +- target/s390x/translate.c | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index d37e691..748a6e8 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -707,13 +707,13 @@ void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array, uint64_t trans) { -int i; +uintptr_t ra = GETPC(); +uint32_t i; for (i = 0; i <= len; i++) { -uint8_t byte = cpu_ldub_data(env, array + i); -uint8_t new_byte = cpu_ldub_data(env, trans + byte); - -cpu_stb_data(env, array + i, new_byte); +uint8_t byte = cpu_ldub_data_ra(env, array + i, ra); +uint8_t new_byte = cpu_ldub_data_ra(env, trans + byte, ra); +cpu_stb_data_ra(env, array + i, new_byte, ra); } } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index e8eefec..b506cee 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4070,7 +4070,6 @@ static ExitStatus op_tprot(DisasContext *s, DisasOps *o) static ExitStatus op_tr(DisasContext *s, DisasOps *o) { TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1)); -potential_page_fault(s); gen_helper_tr(cpu_env, l, o->addr1, o->in2); tcg_temp_free_i32(l); set_cc_static(s); -- 2.9.4
[Qemu-devel] [PATCH 29/31] target/s390x: Use atomic operations for COMPARE SWAP PURGE
Signed-off-by: Richard Henderson --- target/s390x/helper.h | 2 +- target/s390x/insn-data.def | 2 +- target/s390x/mem_helper.c | 32 target/s390x/translate.c | 42 ++ 4 files changed, 48 insertions(+), 30 deletions(-) diff --git a/target/s390x/helper.h b/target/s390x/helper.h index 2b4e7be..a2e0bf2 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -107,13 +107,13 @@ DEF_HELPER_FLAGS_2(tprot, TCG_CALL_NO_RWG, i32, i64, i64) DEF_HELPER_FLAGS_2(iske, TCG_CALL_NO_RWG_SE, i64, env, i64) DEF_HELPER_FLAGS_3(sske, TCG_CALL_NO_RWG, void, env, i64, i64) DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_NO_RWG, i32, env, i64) -DEF_HELPER_3(csp, i32, env, i32, i64) DEF_HELPER_4(mvcs, i32, env, i64, i64, i64) DEF_HELPER_4(mvcp, i32, env, i64, i64, i64) DEF_HELPER_4(sigp, i32, env, i64, i32, i64) DEF_HELPER_FLAGS_2(sacf, TCG_CALL_NO_WG, void, env, i64) DEF_HELPER_FLAGS_3(ipte, TCG_CALL_NO_RWG, void, env, i64, i64) DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_NO_RWG, void, env) +DEF_HELPER_FLAGS_1(purge, TCG_CALL_NO_RWG, void, env) DEF_HELPER_2(lra, i64, env, i64) DEF_HELPER_FLAGS_2(lura, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_2(lurag, TCG_CALL_NO_WG, i64, env, i64) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 3c3541c..4c91f30 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -837,7 +837,7 @@ #ifndef CONFIG_USER_ONLY /* COMPARE AND SWAP AND PURGE */ -C(0xb250, CSP, RRE, Z, 0, ra2, 0, 0, csp, 0) +D(0xb250, CSP, RRE, Z, r1_32u, ra2, r1_P, 0, csp, 0, MO_TEUL) /* DIAGNOSE (KVM hypercall) */ C(0x8300, DIAG,RSI, Z, 0, 0, 0, 0, diag, 0) /* INSERT STORAGE KEY EXTENDED */ diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 81b27c0..4becc80 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -1029,30 +1029,6 @@ uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2) return re >> 1; } -/* compare and swap and purge */ -uint32_t HELPER(csp)(CPUS390XState *env, uint32_t r1, uint64_t r2) -{ -S390CPU *cpu = s390_env_get_cpu(env); -uint32_t cc; -uint32_t o1 = env->regs[r1]; -uint64_t a2 = r2 & ~3ULL; -uint32_t o2 = cpu_ldl_data(env, a2); - -if (o1 == o2) { -cpu_stl_data(env, a2, env->regs[(r1 + 1) & 15]); -if (r2 & 0x3) { -/* flush TLB / ALB */ -tlb_flush(CPU(cpu)); -} -cc = 0; -} else { -env->regs[r1] = (env->regs[r1] & 0xULL) | o2; -cc = 1; -} - -return cc; -} - uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) { int cc = 0, i; @@ -1130,6 +1106,14 @@ void HELPER(ptlb)(CPUS390XState *env) tlb_flush(CPU(cpu)); } +/* flush global tlb */ +void HELPER(purge)(CPUS390XState *env) +{ +S390CPU *cpu = s390_env_get_cpu(env); + +tlb_flush_all_cpus(CPU(cpu)); +} + /* load using real address */ uint64_t HELPER(lura)(CPUS390XState *env, uint64_t addr) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 3e4b397..ca5be7b 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2003,11 +2003,45 @@ static ExitStatus op_cdsg(DisasContext *s, DisasOps *o) #ifndef CONFIG_USER_ONLY static ExitStatus op_csp(DisasContext *s, DisasOps *o) { -TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); +TCGMemOp mop = s->insn->data; +TCGv_i64 addr, old, cc; +TCGLabel *lab = gen_new_label(); + +/* Note that in1 = R1 (zero-extended expected value), + out = R1 (original reg), out2 = R1+1 (new value). */ + check_privileged(s); -gen_helper_csp(cc_op, cpu_env, r1, o->in2); -tcg_temp_free_i32(r1); -set_cc_static(s); +addr = tcg_temp_new_i64(); +old = tcg_temp_new_i64(); +tcg_gen_andi_i64(addr, o->in2, -1ULL << (mop & MO_SIZE)); +tcg_gen_atomic_cmpxchg_i64(old, addr, o->in1, o->out2, + get_mem_index(s), mop | MO_ALIGN); +tcg_temp_free_i64(addr); + +/* Are the memory and expected values (un)equal? */ +cc = tcg_temp_new_i64(); +tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in1, old); +tcg_gen_extrl_i64_i32(cc_op, cc); + +/* Write back the output now, so that it happens before the + following branch, so that we don't need local temps. */ +if ((mop & MO_SIZE) == MO_32) { +tcg_gen_deposit_i64(o->out, o->out, old, 0, 32); +} else { +tcg_gen_mov_i64(o->out, old); +} +tcg_temp_free_i64(old); + +/* If the comparison was equal, and the LSB of R2 was set, + then we need to flush the TLB (for all cpus). */ +tcg_gen_xori_i64(cc, cc, 1); +tcg_gen_and_i64(cc, cc, o->in2); +tcg_gen_brcondi_i64(TCG_COND_EQ, cc, 0, lab); +tcg_temp_free_i64(cc); + +gen_helper_purge(cpu_env); +gen_set_label(lab); + return NO_EXIT; } #endif -- 2.9.4
[Qemu-devel] [PATCH 17/31] target/s390x: Use unwind data for helper_clcle
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 6 +++--- target/s390x/translate.c | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 7a59be0..6e85406 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -576,12 +576,12 @@ uint32_t HELPER(mvcle)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { +uintptr_t ra = GETPC(); uint64_t destlen = env->regs[r1 + 1]; uint64_t dest = get_address_31fix(env, r1); uint64_t srclen = env->regs[r3 + 1]; uint64_t src = get_address_31fix(env, r3); uint8_t pad = a2 & 0xff; -uint8_t v1 = 0, v2 = 0; uint32_t cc = 0; if (!(destlen || srclen)) { @@ -593,8 +593,8 @@ uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2, } for (; destlen || srclen; src++, dest++, destlen--, srclen--) { -v1 = srclen ? cpu_ldub_data(env, src) : pad; -v2 = destlen ? cpu_ldub_data(env, dest) : pad; +uint8_t v1 = srclen ? cpu_ldub_data_ra(env, src, ra) : pad; +uint8_t v2 = destlen ? cpu_ldub_data_ra(env, dest, ra) : pad; if (v1 != v2) { cc = (v1 < v2) ? 1 : 2; break; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index c00c15e..ad85a75 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -1917,7 +1917,6 @@ static ExitStatus op_clcle(DisasContext *s, DisasOps *o) { TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); -potential_page_fault(s); gen_helper_clcle(cc_op, cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); -- 2.9.4
[Qemu-devel] [PATCH 26/31] target/s390x: Use unwind data for helper_testblock
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 3 +++ target/s390x/translate.c | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 1e31bd3..a874f8a 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -912,6 +912,7 @@ void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) uint32_t HELPER(testblock)(CPUS390XState *env, uint64_t real_addr) { +uintptr_t ra = GETPC(); CPUState *cs = CPU(s390_env_get_cpu(env)); uint64_t abs_addr; int i; @@ -920,12 +921,14 @@ uint32_t HELPER(testblock)(CPUS390XState *env, uint64_t real_addr) abs_addr = mmu_real2abs(env, real_addr) & TARGET_PAGE_MASK; if (!address_space_access_valid(&address_space_memory, abs_addr, TARGET_PAGE_SIZE, true)) { +cpu_restore_state(cs, ra); program_interrupt(env, PGM_ADDRESSING, 4); return 1; } /* Check low-address protection */ if ((env->cregs[0] & CR0_LOWPROT) && real_addr < 0x2000) { +cpu_restore_state(cs, ra); program_interrupt(env, PGM_PROTECTION, 4); return 1; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 3a2151f..694e099 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4047,7 +4047,6 @@ static ExitStatus op_tcxb(DisasContext *s, DisasOps *o) static ExitStatus op_testblock(DisasContext *s, DisasOps *o) { check_privileged(s); -potential_page_fault(s); gen_helper_testblock(cc_op, cpu_env, o->in2); set_cc_static(s); return NO_EXIT; -- 2.9.4
[Qemu-devel] [PATCH 16/31] target/s390x: Use unwind data for helper_mvcle
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 7 --- target/s390x/translate.c | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index b764c48..7a59be0 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -525,6 +525,7 @@ uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2) uint32_t HELPER(mvcle)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { +uintptr_t ra = GETPC(); uint64_t destlen = env->regs[r1 + 1]; uint64_t dest = env->regs[r1]; uint64_t srclen = env->regs[r3 + 1]; @@ -553,12 +554,12 @@ uint32_t HELPER(mvcle)(CPUS390XState *env, uint32_t r1, uint64_t a2, } for (; destlen && srclen; src++, dest++, destlen--, srclen--) { -v = cpu_ldub_data(env, src); -cpu_stb_data(env, dest, v); +v = cpu_ldub_data_ra(env, src, ra); +cpu_stb_data_ra(env, dest, v, ra); } for (; destlen; dest++, destlen--) { -cpu_stb_data(env, dest, pad); +cpu_stb_data_ra(env, dest, pad, ra); } env->regs[r1 + 1] = destlen; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index ad2e632..c00c15e 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2887,7 +2887,6 @@ static ExitStatus op_mvcle(DisasContext *s, DisasOps *o) { TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); -potential_page_fault(s); gen_helper_mvcle(cc_op, cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); -- 2.9.4
[Qemu-devel] [PATCH 30/31] target/s390x: Implement CSPG
Signed-off-by: Richard Henderson --- target/s390x/insn-data.def | 1 + 1 file changed, 1 insertion(+) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 4c91f30..8604847 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -838,6 +838,7 @@ #ifndef CONFIG_USER_ONLY /* COMPARE AND SWAP AND PURGE */ D(0xb250, CSP, RRE, Z, r1_32u, ra2, r1_P, 0, csp, 0, MO_TEUL) +D(0xb98a, CSPG,RRE, Z, r1_o, ra2, r1_P, 0, csp, 0, MO_TEQ) /* DIAGNOSE (KVM hypercall) */ C(0x8300, DIAG,RSI, Z, 0, 0, 0, 0, diag, 0) /* INSERT STORAGE KEY EXTENDED */ -- 2.9.4
[Qemu-devel] [PATCH 25/31] target/s390x: Use unwind data for helper_stctl
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 10 ++ target/s390x/translate.c | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index b169e0e..1e31bd3 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -880,11 +880,12 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { -int i; +uintptr_t ra = GETPC(); uint64_t dest = a2; +uint32_t i; for (i = r1;; i = (i + 1) % 16) { -cpu_stq_data(env, dest, env->cregs[i]); +cpu_stq_data_ra(env, dest, env->cregs[i], ra); dest += sizeof(uint64_t); if (i == r3) { @@ -895,11 +896,12 @@ void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { -int i; +uintptr_t ra = GETPC(); uint64_t dest = a2; +uint32_t i; for (i = r1;; i = (i + 1) % 16) { -cpu_stl_data(env, dest, env->cregs[i]); +cpu_stl_data_ra(env, dest, env->cregs[i], ra); dest += sizeof(uint32_t); if (i == r3) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 4d964a8..3a2151f 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3617,7 +3617,6 @@ static ExitStatus op_stctg(DisasContext *s, DisasOps *o) TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); check_privileged(s); -potential_page_fault(s); gen_helper_stctg(cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); @@ -3629,7 +3628,6 @@ static ExitStatus op_stctl(DisasContext *s, DisasOps *o) TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); check_privileged(s); -potential_page_fault(s); gen_helper_stctl(cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); -- 2.9.4
[Qemu-devel] [PATCH 13/31] target/s390x: Use unwind data for helper_lam
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 3 ++- target/s390x/translate.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index d1a7bcd..4ecec74 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -450,10 +450,11 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t v1, uint64_t addr) /* load access registers r1 to r3 from memory at a2 */ void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { +uintptr_t ra = GETPC(); int i; for (i = r1;; i = (i + 1) % 16) { -env->aregs[i] = cpu_ldl_data(env, a2); +env->aregs[i] = cpu_ldl_data_ra(env, a2, ra); a2 += 4; if (i == r3) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index f9d05b6..1fc58a1 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2626,7 +2626,6 @@ static ExitStatus op_lam(DisasContext *s, DisasOps *o) { TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); -potential_page_fault(s); gen_helper_lam(cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); -- 2.9.4
[Qemu-devel] [PATCH 14/31] target/s390x: Use unwind data for helper_stam
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 3 ++- target/s390x/translate.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 4ecec74..d6d5047 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -466,10 +466,11 @@ void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) /* store access registers r1 to r3 in memory at a2 */ void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { +uintptr_t ra = GETPC(); int i; for (i = r1;; i = (i + 1) % 16) { -cpu_stl_data(env, a2, env->aregs[i]); +cpu_stl_data_ra(env, a2, env->aregs[i], ra); a2 += 4; if (i == r3) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 1fc58a1..da7b5a6 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3867,7 +3867,6 @@ static ExitStatus op_stam(DisasContext *s, DisasOps *o) { TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); -potential_page_fault(s); gen_helper_stam(cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); -- 2.9.4
[Qemu-devel] [PATCH 24/31] target/s390x: Use unwind data for helper_lctl
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 9 + target/s390x/translate.c | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 26960e4..b169e0e 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -851,18 +851,19 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { +uintptr_t ra = GETPC(); S390CPU *cpu = s390_env_get_cpu(env); bool PERchanged = false; -int i; uint64_t src = a2; -uint32_t val; +uint32_t i; for (i = r1;; i = (i + 1) % 16) { -val = cpu_ldl_data(env, src); +uint32_t val = cpu_ldl_data_ra(env, src, ra); if ((uint32_t)env->cregs[i] != val && i >= 9 && i <= 11) { PERchanged = true; } -env->cregs[i] = (env->cregs[i] & 0xULL) | val; +env->cregs[i] = deposit64(env->cregs[i], 0, 32, val); +HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%x\n", i, src, val); src += sizeof(uint32_t); if (i == r3) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 886991e..4d964a8 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2545,7 +2545,6 @@ static ExitStatus op_lctl(DisasContext *s, DisasOps *o) TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3)); check_privileged(s); -potential_page_fault(s); gen_helper_lctl(cpu_env, r1, o->in2, r3); tcg_temp_free_i32(r1); tcg_temp_free_i32(r3); -- 2.9.4
[Qemu-devel] [PATCH 10/31] target/s390x: Use unwind data for helper_clst
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 5 +++-- target/s390x/translate.c | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 3c28f3a..7c9e7c7 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -337,6 +337,7 @@ uint64_t HELPER(srst)(CPUS390XState *env, uint64_t r0, uint64_t end, /* unsigned string compare (c is string terminator) */ uint64_t HELPER(clst)(CPUS390XState *env, uint64_t c, uint64_t s1, uint64_t s2) { +uintptr_t ra = GETPC(); uint32_t len; c = c & 0xff; @@ -346,8 +347,8 @@ uint64_t HELPER(clst)(CPUS390XState *env, uint64_t c, uint64_t s1, uint64_t s2) /* Lest we fail to service interrupts in a timely manner, limit the amount of work we're willing to do. For now, let's cap at 8k. */ for (len = 0; len < 0x2000; ++len) { -uint8_t v1 = cpu_ldub_data(env, s1 + len); -uint8_t v2 = cpu_ldub_data(env, s2 + len); +uint8_t v1 = cpu_ldub_data_ra(env, s1 + len, ra); +uint8_t v2 = cpu_ldub_data_ra(env, s2 + len, ra); if (v1 == v2) { if (v1 == c) { /* Equal. CC=0, and don't advance the registers. */ diff --git a/target/s390x/translate.c b/target/s390x/translate.c index ba7d0f9..735aa82 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -1939,7 +1939,6 @@ static ExitStatus op_clm(DisasContext *s, DisasOps *o) static ExitStatus op_clst(DisasContext *s, DisasOps *o) { -potential_page_fault(s); gen_helper_clst(o->in1, cpu_env, regs[0], o->in1, o->in2); set_cc_static(s); return_low128(o->in2); -- 2.9.4
[Qemu-devel] [PATCH 18/31] target/s390x: Use unwind data for helper_cksm
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 11 ++- target/s390x/translate.c | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 6e85406..da81b38 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -614,6 +614,7 @@ uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint64_t HELPER(cksm)(CPUS390XState *env, uint64_t r1, uint64_t src, uint64_t src_len) { +uintptr_t ra = GETPC(); uint64_t max_len, len; uint64_t cksm = (uint32_t)r1; @@ -623,21 +624,21 @@ uint64_t HELPER(cksm)(CPUS390XState *env, uint64_t r1, /* Process full words as available. */ for (len = 0; len + 4 <= max_len; len += 4, src += 4) { -cksm += (uint32_t)cpu_ldl_data(env, src); +cksm += (uint32_t)cpu_ldl_data_ra(env, src, ra); } switch (max_len - len) { case 1: -cksm += cpu_ldub_data(env, src) << 24; +cksm += cpu_ldub_data_ra(env, src, ra) << 24; len += 1; break; case 2: -cksm += cpu_lduw_data(env, src) << 16; +cksm += cpu_lduw_data_ra(env, src, ra) << 16; len += 2; break; case 3: -cksm += cpu_lduw_data(env, src) << 16; -cksm += cpu_ldub_data(env, src + 2) << 8; +cksm += cpu_lduw_data_ra(env, src, ra) << 16; +cksm += cpu_ldub_data_ra(env, src + 2, ra) << 8; len += 3; break; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index ad85a75..21c21a6 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -1868,7 +1868,6 @@ static ExitStatus op_cksm(DisasContext *s, DisasOps *o) int r2 = get_field(s->fields, r2); TCGv_i64 len = tcg_temp_new_i64(); -potential_page_fault(s); gen_helper_cksm(len, cpu_env, o->in1, o->in2, regs[r2 + 1]); set_cc_static(s); return_low128(o->out); -- 2.9.4
[Qemu-devel] [PATCH 11/31] target/s390x: Use unwind data for helper_mvpg
Signed-off-by: Richard Henderson --- target/s390x/helper.h | 2 +- target/s390x/mem_helper.c | 9 + target/s390x/translate.c | 3 +-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/target/s390x/helper.h b/target/s390x/helper.h index d6cc513..2b4e7be 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -12,7 +12,7 @@ DEF_HELPER_FLAGS_3(divs64, TCG_CALL_NO_WG, s64, env, s64, s64) DEF_HELPER_FLAGS_4(divu64, TCG_CALL_NO_WG, i64, env, i64, i64, i64) DEF_HELPER_4(srst, i64, env, i64, i64, i64) DEF_HELPER_4(clst, i64, env, i64, i64, i64) -DEF_HELPER_4(mvpg, void, env, i64, i64, i64) +DEF_HELPER_FLAGS_4(mvpg, TCG_CALL_NO_WG, i32, env, i64, i64, i64) DEF_HELPER_4(mvst, i64, env, i64, i64, i64) DEF_HELPER_FLAGS_4(ex, TCG_CALL_NO_WG, void, env, i32, i64, i64) DEF_HELPER_FLAGS_4(stam, TCG_CALL_NO_WG, void, env, i32, i64, i32) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 7c9e7c7..9ef9f4a 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -373,11 +373,12 @@ uint64_t HELPER(clst)(CPUS390XState *env, uint64_t c, uint64_t s1, uint64_t s2) } /* move page */ -void HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2) +uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2) { -/* XXX missing r0 handling */ -env->cc_op = 0; -fast_memmove(env, r1, r2, TARGET_PAGE_SIZE, 0); +/* ??? missing r0 handling, which includes access keys, but more + importantly optional suppression of the exception! */ +fast_memmove(env, r1, r2, TARGET_PAGE_SIZE, GETPC()); +return 0; /* data moved */ } /* string copy (c is string terminator) */ diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 735aa82..a1edc79 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2921,8 +2921,7 @@ static ExitStatus op_mvcs(DisasContext *s, DisasOps *o) static ExitStatus op_mvpg(DisasContext *s, DisasOps *o) { -potential_page_fault(s); -gen_helper_mvpg(cpu_env, regs[0], o->in1, o->in2); +gen_helper_mvpg(cc_op, cpu_env, regs[0], o->in1, o->in2); set_cc_static(s); return NO_EXIT; } -- 2.9.4
[Qemu-devel] [PATCH 15/31] target/s390x: Use unwind data for helper_mvcl
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 7 --- target/s390x/translate.c | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index d6d5047..b764c48 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -482,6 +482,7 @@ void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) /* move long */ uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2) { +uintptr_t ra = GETPC(); uint64_t destlen = env->regs[r1 + 1] & 0xff; uint64_t dest = get_address_31fix(env, r1); uint64_t srclen = env->regs[r2 + 1] & 0xff; @@ -503,12 +504,12 @@ uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2) } for (; destlen && srclen; src++, dest++, destlen--, srclen--) { -v = cpu_ldub_data(env, src); -cpu_stb_data(env, dest, v); +v = cpu_ldub_data_ra(env, src, ra); +cpu_stb_data_ra(env, dest, v, ra); } for (; destlen; dest++, destlen--) { -cpu_stb_data(env, dest, pad); +cpu_stb_data_ra(env, dest, pad, ra); } env->regs[r1 + 1] = destlen; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index da7b5a6..ad2e632 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2876,7 +2876,6 @@ static ExitStatus op_mvcl(DisasContext *s, DisasOps *o) { TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2)); -potential_page_fault(s); gen_helper_mvcl(cc_op, cpu_env, r1, r2); tcg_temp_free_i32(r1); tcg_temp_free_i32(r2); -- 2.9.4
[Qemu-devel] [PATCH 12/31] target/s390x: Use unwind data for helper_mvst
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 5 +++-- target/s390x/translate.c | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 9ef9f4a..d1a7bcd 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -384,6 +384,7 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2) /* string copy (c is string terminator) */ uint64_t HELPER(mvst)(CPUS390XState *env, uint64_t c, uint64_t d, uint64_t s) { +uintptr_t ra = GETPC(); uint32_t len; c = c & 0xff; @@ -393,8 +394,8 @@ uint64_t HELPER(mvst)(CPUS390XState *env, uint64_t c, uint64_t d, uint64_t s) /* Lest we fail to service interrupts in a timely manner, limit the amount of work we're willing to do. For now, let's cap at 8k. */ for (len = 0; len < 0x2000; ++len) { -uint8_t v = cpu_ldub_data(env, s + len); -cpu_stb_data(env, d + len, v); +uint8_t v = cpu_ldub_data_ra(env, s + len, ra); +cpu_stb_data_ra(env, d + len, v, ra); if (v == c) { /* Complete. Set CC=1 and advance R1. */ env->cc_op = 1; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index a1edc79..f9d05b6 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2928,7 +2928,6 @@ static ExitStatus op_mvpg(DisasContext *s, DisasOps *o) static ExitStatus op_mvst(DisasContext *s, DisasOps *o) { -potential_page_fault(s); gen_helper_mvst(o->in1, cpu_env, regs[0], o->in1, o->in2); set_cc_static(s); return_low128(o->in2); -- 2.9.4
[Qemu-devel] [PATCH 06/31] target/s390x: Use unwind data for helper_mvc
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 19 ++- target/s390x/translate.c | 1 - 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index e75c2de0..0295485 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -91,7 +91,7 @@ static void fast_memset(CPUS390XState *env, uint64_t dest, uint8_t byte, } static void fast_memmove(CPUS390XState *env, uint64_t dest, uint64_t src, - uint32_t l) + uint32_t l, uintptr_t ra) { int mmu_idx = cpu_mmu_index(env, false); @@ -110,7 +110,7 @@ static void fast_memmove(CPUS390XState *env, uint64_t dest, uint64_t src, /* We failed to get access to one or both whole pages. The next read or write access will likely fill the QEMU TLB for the next iteration. */ -cpu_stb_data(env, dest, cpu_ldub_data(env, src)); +cpu_stb_data_ra(env, dest, cpu_ldub_data_ra(env, src, ra), ra); src++; dest++; l--; @@ -187,27 +187,28 @@ uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest, /* memmove */ void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) { -int i = 0; +uintptr_t ra = GETPC(); +uint32_t i; HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", __func__, l, dest, src); /* mvc with source pointing to the byte after the destination is the same as memset with the first source byte */ -if (dest == (src + 1)) { -fast_memset(env, dest, cpu_ldub_data(env, src), l + 1, 0); +if (dest == src + 1) { +fast_memset(env, dest, cpu_ldub_data_ra(env, src, ra), l + 1, ra); return; } /* mvc and memmove do not behave the same when areas overlap! */ -if ((dest < src) || (src + l < dest)) { -fast_memmove(env, dest, src, l + 1); +if (dest < src || src + l < dest) { +fast_memmove(env, dest, src, l + 1, ra); return; } /* slow version with byte accesses which always work */ for (i = 0; i <= l; i++) { -cpu_stb_data(env, dest + i, cpu_ldub_data(env, src + i)); +cpu_stb_data_ra(env, dest + i, cpu_ldub_data_ra(env, src + i, ra), ra); } } @@ -373,7 +374,7 @@ void HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2) { /* XXX missing r0 handling */ env->cc_op = 0; -fast_memmove(env, r1, r2, TARGET_PAGE_SIZE); +fast_memmove(env, r1, r2, TARGET_PAGE_SIZE, 0); } /* string copy (c is string terminator) */ diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 6a51d56..66f3cd6 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -2871,7 +2871,6 @@ static ExitStatus op_movx(DisasContext *s, DisasOps *o) static ExitStatus op_mvc(DisasContext *s, DisasOps *o) { TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1)); -potential_page_fault(s); gen_helper_mvc(cpu_env, l, o->addr1, o->in2); tcg_temp_free_i32(l); return NO_EXIT; -- 2.9.4
[Qemu-devel] [PATCH 08/31] target/s390x: Use unwind data for helper_clm
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 11 ++- target/s390x/translate.c | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index d04850b..5f38ac3 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -243,16 +243,16 @@ uint32_t HELPER(clc)(CPUS390XState *env, uint32_t l, uint64_t s1, uint64_t s2) uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask, uint64_t addr) { -uint8_t r, d; -uint32_t cc; +uintptr_t ra = GETPC(); +uint32_t cc = 0; HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1, mask, addr); -cc = 0; + while (mask) { if (mask & 8) { -d = cpu_ldub_data(env, addr); -r = (r1 & 0xff00UL) >> 24; +uint8_t d = cpu_ldub_data_ra(env, addr, ra); +uint8_t r = extract32(r1, 24, 8); HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d, addr); if (r < d) { @@ -267,6 +267,7 @@ uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask, mask = (mask << 1) & 0xf; r1 <<= 8; } + HELPER_LOG("\n"); return cc; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index aefbc90..84f09b1 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -1930,7 +1930,6 @@ static ExitStatus op_clm(DisasContext *s, DisasOps *o) TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3)); TCGv_i32 t1 = tcg_temp_new_i32(); tcg_gen_extrl_i64_i32(t1, o->in1); -potential_page_fault(s); gen_helper_clm(cc_op, cpu_env, t1, m3, o->in2); set_cc_static(s); tcg_temp_free_i32(t1); -- 2.9.4
[Qemu-devel] [PATCH 07/31] target/s390x: Use unwind data for helper_clc
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 18 +- target/s390x/translate.c | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 0295485..d04850b 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -215,26 +215,26 @@ void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) /* compare unsigned byte arrays */ uint32_t HELPER(clc)(CPUS390XState *env, uint32_t l, uint64_t s1, uint64_t s2) { -int i; -unsigned char x, y; -uint32_t cc; +uintptr_t ra = GETPC(); +uint32_t cc = 0; +uint32_t i; HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n", __func__, l, s1, s2); + for (i = 0; i <= l; i++) { -x = cpu_ldub_data(env, s1 + i); -y = cpu_ldub_data(env, s2 + i); +uint8_t x = cpu_ldub_data_ra(env, s1 + i, ra); +uint8_t y = cpu_ldub_data_ra(env, s2 + i, ra); HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y); if (x < y) { cc = 1; -goto done; +break; } else if (x > y) { cc = 2; -goto done; +break; } } -cc = 0; - done: + HELPER_LOG("\n"); return cc; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 66f3cd6..aefbc90 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -1903,7 +1903,6 @@ static ExitStatus op_clc(DisasContext *s, DisasOps *o) tcg_gen_qemu_ld64(cc_dst, o->in2, get_mem_index(s)); break; default: -potential_page_fault(s); vl = tcg_const_i32(l); gen_helper_clc(cc_op, cpu_env, vl, o->addr1, o->in2); tcg_temp_free_i32(vl); -- 2.9.4
[Qemu-devel] [PATCH 09/31] target/s390x: Use unwind data for helper_srst
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 3 ++- target/s390x/translate.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 5f38ac3..3c28f3a 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -302,6 +302,7 @@ static inline uint64_t get_address_31fix(CPUS390XState *env, int reg) uint64_t HELPER(srst)(CPUS390XState *env, uint64_t r0, uint64_t end, uint64_t str) { +uintptr_t ra = GETPC(); uint32_t len; uint8_t v, c = r0; @@ -319,7 +320,7 @@ uint64_t HELPER(srst)(CPUS390XState *env, uint64_t r0, uint64_t end, env->cc_op = 2; return end; } -v = cpu_ldub_data(env, str + len); +v = cpu_ldub_data_ra(env, str + len, ra); if (v == c) { /* Character found. Set R1 to the location; R2 is unmodified. */ env->cc_op = 1; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 84f09b1..ba7d0f9 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3977,7 +3977,6 @@ static ExitStatus op_stmh(DisasContext *s, DisasOps *o) static ExitStatus op_srst(DisasContext *s, DisasOps *o) { -potential_page_fault(s); gen_helper_srst(o->in1, cpu_env, regs[0], o->in1, o->in2); set_cc_static(s); return_low128(o->in2); -- 2.9.4
[Qemu-devel] [PATCH 04/31] target/s390x: Use unwind data for helper_xc
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 25 - target/s390x/translate.c | 1 - 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 1018fe0..e0a6fad 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -68,7 +68,7 @@ static inline uint64_t adj_len_to_page(uint64_t len, uint64_t addr) } static void fast_memset(CPUS390XState *env, uint64_t dest, uint8_t byte, -uint32_t l) +uint32_t l, uintptr_t ra) { int mmu_idx = cpu_mmu_index(env, false); @@ -83,7 +83,7 @@ static void fast_memset(CPUS390XState *env, uint64_t dest, uint8_t byte, } else { /* We failed to get access to the whole page. The next write access will likely fill the QEMU TLB for the next iteration. */ -cpu_stb_data(env, dest, byte); +cpu_stb_data_ra(env, dest, byte, ra); dest++; l--; } @@ -142,27 +142,26 @@ uint32_t HELPER(nc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) { -int i; -unsigned char x; -uint32_t cc = 0; +uintptr_t ra = GETPC(); +uint8_t cc = 0; +uint32_t i; HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", __func__, l, dest, src); /* xor with itself is the same as memset(0) */ if (src == dest) { -fast_memset(env, dest, 0, l + 1); +fast_memset(env, dest, 0, l + 1, ra); return 0; } for (i = 0; i <= l; i++) { -x = cpu_ldub_data(env, dest + i) ^ cpu_ldub_data(env, src + i); -if (x) { -cc = 1; -} -cpu_stb_data(env, dest + i, x); +uint8_t x = cpu_ldub_data_ra(env, dest + i, ra); +x ^= cpu_ldub_data_ra(env, src + i, ra); +cc |= x; +cpu_stb_data_ra(env, dest + i, x, ra); } -return cc; +return cc != 0; } /* or on array */ @@ -196,7 +195,7 @@ void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) /* mvc with source pointing to the byte after the destination is the same as memset with the first source byte */ if (dest == (src + 1)) { -fast_memset(env, dest, cpu_ldub_data(env, src), l + 1); +fast_memset(env, dest, cpu_ldub_data(env, src), l + 1, 0); return; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 6aa9c90..a770407 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4166,7 +4166,6 @@ static ExitStatus op_xc(DisasContext *s, DisasOps *o) /* But in general we'll defer to a helper. */ o->in2 = get_address(s, 0, b2, d2); t32 = tcg_const_i32(l); -potential_page_fault(s); gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2); tcg_temp_free_i32(t32); set_cc_static(s); -- 2.9.4
[Qemu-devel] [PATCH 05/31] target/s390x: Use unwind data for helper_oc
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 18 +- target/s390x/translate.c | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index e0a6fad..e75c2de0 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -168,20 +168,20 @@ uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) { -int i; -unsigned char x; -uint32_t cc = 0; +uintptr_t ra = GETPC(); +uint8_t cc = 0; +uint32_t i; HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", __func__, l, dest, src); + for (i = 0; i <= l; i++) { -x = cpu_ldub_data(env, dest + i) | cpu_ldub_data(env, src + i); -if (x) { -cc = 1; -} -cpu_stb_data(env, dest + i, x); +uint8_t x = cpu_ldub_data_ra(env, dest + i, ra); +x |= cpu_ldub_data_ra(env, src + i, ra); +cc |= x; +cpu_stb_data_ra(env, dest + i, x, ra); } -return cc; +return cc != 0; } /* memmove */ diff --git a/target/s390x/translate.c b/target/s390x/translate.c index a770407..6a51d56 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3082,7 +3082,6 @@ static ExitStatus op_negf128(DisasContext *s, DisasOps *o) static ExitStatus op_oc(DisasContext *s, DisasOps *o) { TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1)); -potential_page_fault(s); gen_helper_oc(cc_op, cpu_env, l, o->addr1, o->in2); tcg_temp_free_i32(l); set_cc_static(s); -- 2.9.4
[Qemu-devel] [PATCH 03/31] target/s390x: Use unwind data for helper_nc
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 18 +- target/s390x/translate.c | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index db80d53..1018fe0 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -122,20 +122,20 @@ static void fast_memmove(CPUS390XState *env, uint64_t dest, uint64_t src, uint32_t HELPER(nc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) { -int i; -unsigned char x; -uint32_t cc = 0; +uintptr_t ra = GETPC(); +uint8_t cc = 0; +uint32_t i; HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", __func__, l, dest, src); + for (i = 0; i <= l; i++) { -x = cpu_ldub_data(env, dest + i) & cpu_ldub_data(env, src + i); -if (x) { -cc = 1; -} -cpu_stb_data(env, dest + i, x); +uint8_t x = cpu_ldub_data_ra(env, dest + i, ra); +x &= cpu_ldub_data_ra(env, src + i, ra); +cc |= x; +cpu_stb_data_ra(env, dest + i, x, ra); } -return cc; +return cc != 0; } /* xor on array */ diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 3a72c38..6aa9c90 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3048,7 +3048,6 @@ static ExitStatus op_nabsf128(DisasContext *s, DisasOps *o) static ExitStatus op_nc(DisasContext *s, DisasOps *o) { TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1)); -potential_page_fault(s); gen_helper_nc(cc_op, cpu_env, l, o->addr1, o->in2); tcg_temp_free_i32(l); set_cc_static(s); -- 2.9.4
[Qemu-devel] [PATCH 02/31] target/s390x: Implement EXECUTE via new TranslationBlock
Previously, helper_ex would construct the insn and then implement the insn via direct calls other helpers. This was sufficient to boot Linux but that is all. It is easy enough to go the whole nine yards by stashing state for EXECUTE within the cpu, and then relying on a new TB to be created that properly and completely interprets the insn. Signed-off-by: Richard Henderson --- target/s390x/cpu.h | 4 +- target/s390x/helper.h | 2 +- target/s390x/insn-data.def | 4 +- target/s390x/machine.c | 19 +++ target/s390x/mem_helper.c | 136 +++-- target/s390x/translate.c | 124 + 6 files changed, 133 insertions(+), 156 deletions(-) diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index 4f38ba0..79235cf 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -103,6 +103,8 @@ typedef struct CPUS390XState { uint64_t cc_dst; uint64_t cc_vr; +uint64_t ex_value; + uint64_t __excp_addr; uint64_t psa; @@ -391,7 +393,7 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc, target_ulong *cs_base, uint32_t *flags) { *pc = env->psw.addr; -*cs_base = 0; +*cs_base = env->ex_value; *flags = ((env->psw.mask >> 32) & ~FLAG_MASK_CC) | ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0); } diff --git a/target/s390x/helper.h b/target/s390x/helper.h index 1fae191..d6cc513 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -14,7 +14,7 @@ DEF_HELPER_4(srst, i64, env, i64, i64, i64) DEF_HELPER_4(clst, i64, env, i64, i64, i64) DEF_HELPER_4(mvpg, void, env, i64, i64, i64) DEF_HELPER_4(mvst, i64, env, i64, i64, i64) -DEF_HELPER_5(ex, i32, env, i32, i64, i64, i64) +DEF_HELPER_FLAGS_4(ex, TCG_CALL_NO_WG, void, env, i32, i64, i64) DEF_HELPER_FLAGS_4(stam, TCG_CALL_NO_WG, void, env, i32, i64, i32) DEF_HELPER_FLAGS_4(lam, TCG_CALL_NO_WG, void, env, i32, i64, i32) DEF_HELPER_4(mvcle, i32, env, i32, i64, i32) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index cac0f51..3c3541c 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -327,9 +327,9 @@ C(0xeb57, XIY, SIY, LD, m1_8u, i2_8u, new, m1_8, xor, nz64) /* EXECUTE */ -C(0x4400, EX, RX_a, Z, r1_o, a2, 0, 0, ex, 0) +C(0x4400, EX, RX_a, Z, 0, a2, 0, 0, ex, 0) /* EXECUTE RELATIVE LONG */ -C(0xc600, EXRL,RIL_b, EE, r1_o, ri2, 0, 0, ex, 0) +C(0xc600, EXRL,RIL_b, EE, 0, ri2, 0, 0, ex, 0) /* EXTRACT ACCESS */ C(0xb24f, EAR, RRE, Z, 0, 0, new, r1_32, ear, 0) diff --git a/target/s390x/machine.c b/target/s390x/machine.c index 8503fa1..8f908bb 100644 --- a/target/s390x/machine.c +++ b/target/s390x/machine.c @@ -34,6 +34,7 @@ static int cpu_post_load(void *opaque, int version_id) return 0; } + static void cpu_pre_save(void *opaque) { S390CPU *cpu = opaque; @@ -156,6 +157,23 @@ const VMStateDescription vmstate_riccb = { } }; +static bool exval_needed(void *opaque) +{ +S390CPU *cpu = opaque; +return cpu->env.ex_value != 0; +} + +const VMStateDescription vmstate_exval = { +.name = "cpu/exval", +.version_id = 1, +.minimum_version_id = 1, +.needed = exval_needed, +.fields = (VMStateField[]) { +VMSTATE_UINT64(env.ex_value, S390CPU), +VMSTATE_END_OF_LIST() +} +}; + const VMStateDescription vmstate_s390_cpu = { .name = "cpu", .post_load = cpu_post_load, @@ -188,6 +206,7 @@ const VMStateDescription vmstate_s390_cpu = { &vmstate_fpu, &vmstate_vregs, &vmstate_riccb, +&vmstate_exval, NULL }, }; diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index e3325a4..db80d53 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -405,115 +405,41 @@ uint64_t HELPER(mvst)(CPUS390XState *env, uint64_t c, uint64_t d, uint64_t s) return d + len; } -static uint32_t helper_icm(CPUS390XState *env, uint32_t r1, uint64_t address, - uint32_t mask) -{ -int pos = 24; /* top of the lower half of r1 */ -uint64_t rmask = 0xff00ULL; -uint8_t val = 0; -int ccd = 0; -uint32_t cc = 0; +/* Execute instruction. This instruction executes an insn modified with + the contents of r1. It does not change the executed instruction in memory; + it does not change the program counter. -while (mask) { -if (mask & 8) { -env->regs[r1] &= ~rmask; -val = cpu_ldub_data(env, address); -if ((val & 0x80) && !ccd) { -cc = 1; -} -ccd = 1; -if (val && cc == 0) { -cc = 2; -} -env->regs[r1] |= (uint64_t)val << pos; -address++; -} -mask = (mask << 1) & 0xf; -pos -= 8; -rmask >>=
[Qemu-devel] [PATCH 01/31] target/s390: Use cpu_loop_exit_restore for tlb_fill
Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 0c6a0d9..e3325a4 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -41,15 +41,9 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) { -int ret; - -ret = s390_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx); +int ret = s390_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx); if (unlikely(ret != 0)) { -if (likely(retaddr)) { -/* now we have a real cpu fault */ -cpu_restore_state(cs, retaddr); -} -cpu_loop_exit(cs); +cpu_loop_exit_restore(cs, retaddr); } } -- 2.9.4
[Qemu-devel] [PATCH 00/31] target/s390x unwind patches
We can use cpu_restore_state (and via *_ra memory helpers) to avoid storing cpu state in expectation of the unlikely case of page fault or specification error. There are more that can be fixed, but this is all of mem_helper.c, and this patch set is large enough. r~ Richard Henderson (31): target/s390: Use cpu_loop_exit_restore for tlb_fill target/s390x: Implement EXECUTE via new TranslationBlock target/s390x: Use unwind data for helper_nc target/s390x: Use unwind data for helper_xc target/s390x: Use unwind data for helper_oc target/s390x: Use unwind data for helper_mvc target/s390x: Use unwind data for helper_clc target/s390x: Use unwind data for helper_clm target/s390x: Use unwind data for helper_srst target/s390x: Use unwind data for helper_clst target/s390x: Use unwind data for helper_mvpg target/s390x: Use unwind data for helper_mvst target/s390x: Use unwind data for helper_lam target/s390x: Use unwind data for helper_stam target/s390x: Use unwind data for helper_mvcl target/s390x: Use unwind data for helper_mvcle target/s390x: Use unwind data for helper_clcle target/s390x: Use unwind data for helper_cksm target/s390x: Use unwind data for helper_unpk target/s390x: Use unwind data for helper_tr target/s390x: Use unwind data for helper_tre target/s390x: Use unwind data for helper_trt target/s390x: Use unwind data for helper_lctlg target/s390x: Use unwind data for helper_lctl target/s390x: Use unwind data for helper_stctl target/s390x: Use unwind data for helper_testblock target/s390x: Use unwind data for helper_tprot target/s390x: Use unwind data for helper_lra target/s390x: Use atomic operations for COMPARE SWAP PURGE target/s390x: Implement CSPG target/s390x: Use unwind data for helper_mvcs/mvcp target/s390x/cpu.h | 4 +- target/s390x/helper.h | 6 +- target/s390x/insn-data.def | 7 +- target/s390x/machine.c | 19 ++ target/s390x/mem_helper.c | 428 +++-- target/s390x/translate.c | 197 - 6 files changed, 321 insertions(+), 340 deletions(-) -- 2.9.4
Re: [Qemu-devel] [PATCH v2 3/4] target/ppc: consolidate CPU device-tree id computation in helper
On Mon, May 22, 2017 at 10:59:50AM +0200, Greg Kurz wrote: > On Mon, 22 May 2017 12:04:13 +1000 > David Gibson wrote: > > > On Fri, May 19, 2017 at 12:32:20PM +0200, Greg Kurz wrote: > > > For historical reasons, we compute CPU device-tree ids with a non-trivial > > > logic. This patch consolidate the logic in a single helper to be used > > > in various places where it is currently open-coded. > > > > > > It is okay to get rid of DIV_ROUND_UP() because we're sure that the number > > > of threads per core in the guest cannot exceed the number of threads per > > > core in the host. > > > > However, your new logic still gives different answers in some cases. > > In particular when max_cpus is not a multiple of smp_threads. Which > > is generally a bad idea, but allowed for older machine types for > > compatibility. e.g. smp_threads=4, max_cpus=6 smt=8 > > > > Old logic: > > DIV_ROUND_UP(6 * 8, 4) > >= ⌈48 / 4⌉ = 12 > > > > New logic gives: ⌊6 / 4⌋ * 8 + (6 % 4) > >= 1 * 8 + 2 > >= 10 > > > > I now realize this two formulas are hardly reconcilable... this > probably means that this patch shouldn't try to consolidate the > logic in hw/ppc/spapr.c with the one in target/ppc/translate_init.c. Ok. > > In any case the DIV_ROUND_UP() isn't to handle the case where guest > > threads-per-core is bigger than host threads-per-core, it's (IIRC) for > > the case where guest threads-per-core is not a factor of host > > threads-per-core. Again, a bad idea, but I think allowed in some old > > cases. > > > > FWIW, DIV_ROUND_UP() comes from this commit: > > f303f117fec3 spapr: ensure we have at least one XICS server Ah, yes, I see your point. Hrm. I thought even then that guest threads > host threads was definitely incorrect; but I'm wondering if the change was just because the check for guest threads > host threads came later during init and we didn't want to crash before we got to it. > but I agree that this was a bad idea... But yeah, looks like we'll be taking a different approach so it's kind of moot anyway. > > > > > > > Signed-off-by: Greg Kurz > > > --- > > > hw/ppc/spapr.c |6 ++ > > > target/ppc/cpu.h| 17 + > > > target/ppc/translate_init.c |3 +-- > > > 3 files changed, 20 insertions(+), 6 deletions(-) > > > > > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > > > index 75e298b4c6be..1bb05a9a6b07 100644 > > > --- a/hw/ppc/spapr.c > > > +++ b/hw/ppc/spapr.c > > > @@ -981,7 +981,6 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, > > > void *fdt; > > > sPAPRPHBState *phb; > > > char *buf; > > > -int smt = kvmppc_smt_threads(); > > > > > > fdt = g_malloc0(FDT_MAX_SIZE); > > > _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE))); > > > @@ -1021,7 +1020,7 @@ static void *spapr_build_fdt(sPAPRMachineState > > > *spapr, > > > _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); > > > > > > /* /interrupt controller */ > > > -spapr_dt_xics(DIV_ROUND_UP(max_cpus * smt, smp_threads), fdt, > > > PHANDLE_XICP); > > > +spapr_dt_xics(ppc_cpu_dt_id_from_index(max_cpus), fdt, PHANDLE_XICP); > > > > > > ret = spapr_populate_memory(spapr, fdt); > > > if (ret < 0) { > > > @@ -1977,7 +1976,6 @@ static void spapr_init_cpus(sPAPRMachineState > > > *spapr) > > > MachineState *machine = MACHINE(spapr); > > > MachineClass *mc = MACHINE_GET_CLASS(machine); > > > char *type = spapr_get_cpu_core_type(machine->cpu_model); > > > -int smt = kvmppc_smt_threads(); > > > const CPUArchIdList *possible_cpus; > > > int boot_cores_nr = smp_cpus / smp_threads; > > > int i; > > > @@ -2014,7 +2012,7 @@ static void spapr_init_cpus(sPAPRMachineState > > > *spapr) > > > sPAPRDRConnector *drc = > > > spapr_dr_connector_new(OBJECT(spapr), > > > SPAPR_DR_CONNECTOR_TYPE_CPU, > > > - (core_id / smp_threads) * smt); > > > + > > > ppc_cpu_dt_id_from_index(core_id)); > > > > > > qemu_register_reset(spapr_drc_reset, drc); > > > } > > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > > > index 401e10e7dad8..47fe6c64698f 100644 > > > --- a/target/ppc/cpu.h > > > +++ b/target/ppc/cpu.h > > > @@ -2529,4 +2529,21 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); > > > PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); > > > > > > void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int > > > len); > > > + > > > +#if !defined(CONFIG_USER_ONLY) > > > +#include "sysemu/cpus.h" > > > +#include "target/ppc/kvm_ppc.h" > > > + > > > +static inline int ppc_cpu_dt_id_from_index(int cpu_index) > > > +{ > > > +/* POWER HV support has an historical limitation that different > > > threads > > > + * on a single core cannot be in different guests at the same tim
Re: [Qemu-devel] [PATCH v2 3/4] target/ppc: consolidate CPU device-tree id computation in helper
On Mon, May 22, 2017 at 04:33:36PM +0200, Greg Kurz wrote: > On Mon, 22 May 2017 12:12:46 +1000 > David Gibson wrote: > > > On Mon, May 22, 2017 at 12:04:13PM +1000, David Gibson wrote: > > > On Fri, May 19, 2017 at 12:32:20PM +0200, Greg Kurz wrote: > > > > For historical reasons, we compute CPU device-tree ids with a > > > > non-trivial > > > > logic. This patch consolidate the logic in a single helper to be used > > > > in various places where it is currently open-coded. > > > > > > > > It is okay to get rid of DIV_ROUND_UP() because we're sure that the > > > > number > > > > of threads per core in the guest cannot exceed the number of threads per > > > > core in the host. > > > > > > However, your new logic still gives different answers in some cases. > > > In particular when max_cpus is not a multiple of smp_threads. Which > > > is generally a bad idea, but allowed for older machine types for > > > compatibility. e.g. smp_threads=4, max_cpus=6 smt=8 > > > > > > Old logic: > > >DIV_ROUND_UP(6 * 8, 4) > > > = ⌈48 / 4⌉ = 12 > > > > > > New logic gives: ⌊6 / 4⌋ * 8 + (6 % 4) > > >= 1 * 8 + 2 > > > = 10 > > > > > > In any case the DIV_ROUND_UP() isn't to handle the case where guest > > > threads-per-core is bigger than host threads-per-core, it's (IIRC) for > > > the case where guest threads-per-core is not a factor of host > > > threads-per-core. Again, a bad idea, but I think allowed in some old > > > cases. > > > > Oh, so, the other more general point here is that I actually want to > > get rid of dt_id from the cpu structure. It's basically an abuse of > > the cpu stuff to include what's really an spapr concept - dt IDs for > > powernv are based on the PIR and not allocate the same way. > > > > Yeah, I agree. I guess this calls for the introduction of a sPAPRCPUThread > object type derived from PowerPCCPU. It probably deserves to be addressed > in a separate patchset. I don't think that will be necessary. It would also be mucky, since we'd need a whole slew of them for each CPU type. I think just converting between spapr dt id and cpu index at runtime should be sufficient. > > That said, I'm still ok with a fixed version of this patch as an > > interim step. > > > > Given that the logic change doesn't break anything in the end (see my other > mail), then we're good ? > > > > > Signed-off-by: Greg Kurz > > > > --- > > > > hw/ppc/spapr.c |6 ++ > > > > target/ppc/cpu.h| 17 + > > > > target/ppc/translate_init.c |3 +-- > > > > 3 files changed, 20 insertions(+), 6 deletions(-) > > > > > > > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > > > > index 75e298b4c6be..1bb05a9a6b07 100644 > > > > --- a/hw/ppc/spapr.c > > > > +++ b/hw/ppc/spapr.c > > > > @@ -981,7 +981,6 @@ static void *spapr_build_fdt(sPAPRMachineState > > > > *spapr, > > > > void *fdt; > > > > sPAPRPHBState *phb; > > > > char *buf; > > > > -int smt = kvmppc_smt_threads(); > > > > > > > > fdt = g_malloc0(FDT_MAX_SIZE); > > > > _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE))); > > > > @@ -1021,7 +1020,7 @@ static void *spapr_build_fdt(sPAPRMachineState > > > > *spapr, > > > > _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); > > > > > > > > /* /interrupt controller */ > > > > -spapr_dt_xics(DIV_ROUND_UP(max_cpus * smt, smp_threads), fdt, > > > > PHANDLE_XICP); > > > > +spapr_dt_xics(ppc_cpu_dt_id_from_index(max_cpus), fdt, > > > > PHANDLE_XICP); > > > > > > > > ret = spapr_populate_memory(spapr, fdt); > > > > if (ret < 0) { > > > > @@ -1977,7 +1976,6 @@ static void spapr_init_cpus(sPAPRMachineState > > > > *spapr) > > > > MachineState *machine = MACHINE(spapr); > > > > MachineClass *mc = MACHINE_GET_CLASS(machine); > > > > char *type = spapr_get_cpu_core_type(machine->cpu_model); > > > > -int smt = kvmppc_smt_threads(); > > > > const CPUArchIdList *possible_cpus; > > > > int boot_cores_nr = smp_cpus / smp_threads; > > > > int i; > > > > @@ -2014,7 +2012,7 @@ static void spapr_init_cpus(sPAPRMachineState > > > > *spapr) > > > > sPAPRDRConnector *drc = > > > > spapr_dr_connector_new(OBJECT(spapr), > > > > SPAPR_DR_CONNECTOR_TYPE_CPU, > > > > - (core_id / smp_threads) * smt); > > > > + > > > > ppc_cpu_dt_id_from_index(core_id)); > > > > > > > > qemu_register_reset(spapr_drc_reset, drc); > > > > } > > > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > > > > index 401e10e7dad8..47fe6c64698f 100644 > > > > --- a/target/ppc/cpu.h > > > > +++ b/target/ppc/cpu.h > > > > @@ -2529,4 +2529,21 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); > > > > PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); > > > > > > > > void ppc_maybe_bswap_register(CPUPPCStat
[Qemu-devel] [PULL 9/9] e1000e: Fix ICR "Other" causes clear logic
From: Sameeh Jubran This commit fixes a bug which causes the guest to hang. The bug was observed upon a "receive overrun" (bit #6 of the ICR register) interrupt which could be triggered post migration in a heavy traffic environment. Even though the "receive overrun" bit (#6) is masked out by the IMS register (refer to the log below) the driver still receives an interrupt as the "receive overrun" bit (#6) causes the "Other" - bit #24 of the ICR register - bit to be set as documented below. The driver handles the interrupt and clears the "Other" bit (#24) but doesn't clear the "receive overrun" bit (#6) which leads to an infinite loop. Apparently the Windows driver expects that the "receive overrun" bit and other ones - documented below - to be cleared when the "Other" bit (#24) is cleared. So to sum that up: 1. Bit #6 of the ICR register is set by heavy traffic 2. As a results of setting bit #6, bit #24 is set 3. The driver receives an interrupt for bit 24 (it doesn't receieve an interrupt for bit #6 as it is masked out by IMS) 4. The driver handles and clears the interrupt of bit #24 5. Bit #6 is still set. 6. 2 happens all over again The Interrupt Cause Read - ICR register: The ICR has the "Other" bit - bit #24 - that is set when one or more of the following ICR register's bits are set: LSC - bit #2, RXO - bit #6, MDAC - bit #9, SRPD - bit #16, ACK - bit #17, MNG - bit #18 This bug can occur with any of these bits depending on the driver's behaviour and the way it configures the device. However, trying to reproduce it with any bit other than RX0 is challenging and came to failure as the drivers don't implement most of these bits, trying to reproduce it with LSC (Link Status Change - bit #2) bit didn't succeed too as it seems that Windows handles this bit differently. Log sample of the storm: 27563@1494850819.411877:e1000e_irq_pending_interrupts ICR PENDING: 0x100 (ICR: 0x815000c2, IMS: 0x1a4) 27563@1494850819.411900:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.411915:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412380:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412395:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412436:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412441:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412998:e1000e_irq_pending_interrupts ICR PENDING: 0x100 (ICR: 0x815000c2, IMS: 0x1a4) * This bug behaviour wasn't observed with the Linux driver. This commit solves: https://bugzilla.redhat.com/show_bug.cgi?id=1447935 https://bugzilla.redhat.com/show_bug.cgi?id=1449490 Cc: qemu-sta...@nongnu.org Signed-off-by: Sameeh Jubran Signed-off-by: Jason Wang --- hw/net/e1000e_core.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 28c5be1..8140564 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -2454,14 +2454,20 @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val) static void e1000e_set_icr(E1000ECore *core, int index, uint32_t val) { +uint32_t icr = 0; if ((core->mac[ICR] & E1000_ICR_ASSERTED) && (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { trace_e1000e_irq_icr_process_iame(); e1000e_clear_ims_bits(core, core->mac[IAM]); } -trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val); -core->mac[ICR] &= ~val; +icr = core->mac[ICR] & ~val; +/* Windows driver expects that the "receive overrun" bit and other + * ones to be cleared when the "Other" bit (#24) is cleared. + */ +icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr; +trace_e1000e_irq_icr_write(val, core->mac[ICR], icr); +core->mac[ICR] = icr; e1000e_update_interrupt_state(core); } -- 2.7.4
[Qemu-devel] [PULL 7/9] net/filter-mirror.c: Rename filter_mirror_send() and fix codestyle
From: Zhang Chen Because filter_mirror_receive_iov() and filter_redirector_receive_iov() both use the filter_mirror_send() to send packet, so I change filter_mirror_send() to filter_send() that looks more common. And fix some codestyle. Signed-off-by: Zhang Chen Signed-off-by: Jason Wang --- net/filter-mirror.c | 29 - 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/net/filter-mirror.c b/net/filter-mirror.c index fd0322f..8b1b069 100644 --- a/net/filter-mirror.c +++ b/net/filter-mirror.c @@ -43,9 +43,9 @@ typedef struct MirrorState { SocketReadState rs; } MirrorState; -static int filter_mirror_send(CharBackend *chr_out, - const struct iovec *iov, - int iovcnt) +static int filter_send(CharBackend *chr_out, + const struct iovec *iov, + int iovcnt) { int ret = 0; ssize_t size = 0; @@ -141,9 +141,9 @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf, MirrorState *s = FILTER_MIRROR(nf); int ret; -ret = filter_mirror_send(&s->chr_out, iov, iovcnt); +ret = filter_send(&s->chr_out, iov, iovcnt); if (ret) { -error_report("filter_mirror_send failed(%s)", strerror(-ret)); +error_report("filter mirror send failed(%s)", strerror(-ret)); } /* @@ -164,9 +164,9 @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf, int ret; if (qemu_chr_fe_get_driver(&s->chr_out)) { -ret = filter_mirror_send(&s->chr_out, iov, iovcnt); +ret = filter_send(&s->chr_out, iov, iovcnt); if (ret) { -error_report("filter_mirror_send failed(%s)", strerror(-ret)); +error_report("filter redirector send failed(%s)", strerror(-ret)); } return iov_size(iov, iovcnt); } else { @@ -286,8 +286,9 @@ static char *filter_redirector_get_indev(Object *obj, Error **errp) return g_strdup(s->indev); } -static void -filter_redirector_set_indev(Object *obj, const char *value, Error **errp) +static void filter_redirector_set_indev(Object *obj, +const char *value, +Error **errp) { MirrorState *s = FILTER_REDIRECTOR(obj); @@ -302,8 +303,9 @@ static char *filter_mirror_get_outdev(Object *obj, Error **errp) return g_strdup(s->outdev); } -static void -filter_mirror_set_outdev(Object *obj, const char *value, Error **errp) +static void filter_mirror_set_outdev(Object *obj, + const char *value, + Error **errp) { MirrorState *s = FILTER_MIRROR(obj); @@ -323,8 +325,9 @@ static char *filter_redirector_get_outdev(Object *obj, Error **errp) return g_strdup(s->outdev); } -static void -filter_redirector_set_outdev(Object *obj, const char *value, Error **errp) +static void filter_redirector_set_outdev(Object *obj, + const char *value, + Error **errp) { MirrorState *s = FILTER_REDIRECTOR(obj); -- 2.7.4
[Qemu-devel] [PULL 8/9] net/filter-rewriter: Remove unused option in filter-rewriter
From: Zhang Chen Signed-off-by: Zhang Chen Signed-off-by: Jason Wang --- qemu-options.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index f07a310..f63f7dc 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4072,7 +4072,7 @@ Create a filter-redirector we need to differ outdev id from indev id, id can not be the same. we can just use indev or outdev, but at least one of indev or outdev need to be specified. -@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},rewriter-mode=@var{mode}[,queue=@var{all|rx|tx}] +@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid}[,queue=@var{all|rx|tx}] Filter-rewriter is a part of COLO project.It will rewrite tcp packet to secondary from primary to keep secondary tcp connection,and rewrite -- 2.7.4
[Qemu-devel] [PULL 3/9] virtio-net: fix wild pointer when remove virtio-net queues
From: Yunjian Wang The tx_bh or tx_timer will free in virtio_net_del_queue() function, when removing virtio-net queues if the guest doesn't support multiqueue. But it might be still referenced by virtio_net_set_status(), which needs to be set NULL. And also the tx_waiting needs to be set zero to prevent virtio_net_set_status() accessing tx_bh or tx_timer. Cc: qemu-sta...@nongnu.org Signed-off-by: Yunjian Wang Signed-off-by: Jason Wang --- hw/net/virtio-net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 7d091c9..98bd683 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1522,9 +1522,12 @@ static void virtio_net_del_queue(VirtIONet *n, int index) if (q->tx_timer) { timer_del(q->tx_timer); timer_free(q->tx_timer); +q->tx_timer = NULL; } else { qemu_bh_delete(q->tx_bh); +q->tx_bh = NULL; } +q->tx_waiting = 0; virtio_del_queue(vdev, index * 2 + 1); } -- 2.7.4
[Qemu-devel] [PULL 6/9] net/filter-mirror.c: Remove duplicate check code.
From: Zhang Chen The s->outdev have checked in filter_mirror_set_outdev(). Signed-off-by: Zhang Chen Signed-off-by: Jason Wang --- net/filter-mirror.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/net/filter-mirror.c b/net/filter-mirror.c index 72fa7c2..fd0322f 100644 --- a/net/filter-mirror.c +++ b/net/filter-mirror.c @@ -194,12 +194,6 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp) MirrorState *s = FILTER_MIRROR(nf); Chardev *chr; -if (!s->outdev) { -error_setg(errp, "filter mirror needs 'outdev' " - "property set"); -return; -} - chr = qemu_chr_find(s->outdev); if (chr == NULL) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, -- 2.7.4
[Qemu-devel] [PULL 2/9] net/dump: Issue a warning for the deprecated "-net dump"
From: Thomas Huth Network dumping should be done with "-object filter-dump" nowadays. Using "-net dump" via the VLAN mechanism is considered as deprecated and might be removed in a future release. So warn the users now to inform them to user the filter-dump method instead. Signed-off-by: Thomas Huth Signed-off-by: Jason Wang --- net/dump.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/dump.c b/net/dump.c index 89a149b..442eb53 100644 --- a/net/dump.c +++ b/net/dump.c @@ -194,6 +194,9 @@ int net_init_dump(const Netdev *netdev, const char *name, assert(peer); +error_report("'-net dump' is deprecated. " + "Please use '-object filter-dump' instead."); + if (dump->has_file) { file = dump->file; } else { -- 2.7.4
[Qemu-devel] [PULL 5/9] hmp / net: Mark host_net_add/remove as deprecated
From: Thomas Huth The netdev_add and netdev_del commands should be used nowadays instead. Signed-off-by: Thomas Huth Signed-off-by: Jason Wang --- hmp-commands.hx | 8 net/net.c | 13 + 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 0aca984..baeac47 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1296,7 +1296,7 @@ ETEXI .name = "host_net_add", .args_type = "device:s,opts:s?", .params = "tap|user|socket|vde|netmap|bridge|vhost-user|dump [options]", -.help = "add host VLAN client", +.help = "add host VLAN client (deprecated, use netdev_add instead)", .cmd= hmp_host_net_add, .command_completion = host_net_add_completion, }, @@ -1304,14 +1304,14 @@ ETEXI STEXI @item host_net_add @findex host_net_add -Add host VLAN client. +Add host VLAN client. Deprecated, please use @code{netdev_add} instead. ETEXI { .name = "host_net_remove", .args_type = "vlan_id:i,device:s", .params = "vlan_id name", -.help = "remove host VLAN client", +.help = "remove host VLAN client (deprecated, use netdev_del instead)", .cmd= hmp_host_net_remove, .command_completion = host_net_remove_completion, }, @@ -1319,7 +1319,7 @@ ETEXI STEXI @item host_net_remove @findex host_net_remove -Remove host VLAN client. +Remove host VLAN client. Deprecated, please use @code{netdev_del} instead. ETEXI { diff --git a/net/net.c b/net/net.c index 0ac3b9e..6235aab 100644 --- a/net/net.c +++ b/net/net.c @@ -45,6 +45,7 @@ #include "qapi-visit.h" #include "qapi/opts-visitor.h" #include "sysemu/sysemu.h" +#include "sysemu/qtest.h" #include "net/filter.h" #include "qapi/string-output-visitor.h" @@ -1149,6 +1150,12 @@ void hmp_host_net_add(Monitor *mon, const QDict *qdict) const char *opts_str = qdict_get_try_str(qdict, "opts"); Error *local_err = NULL; QemuOpts *opts; +static bool warned; + +if (!warned && !qtest_enabled()) { +error_report("host_net_add is deprecated, use netdev_add instead"); +warned = true; +} if (!net_host_check_device(device)) { monitor_printf(mon, "invalid host network device %s\n", device); @@ -1175,6 +1182,12 @@ void hmp_host_net_remove(Monitor *mon, const QDict *qdict) NetClientState *nc; int vlan_id = qdict_get_int(qdict, "vlan_id"); const char *device = qdict_get_str(qdict, "device"); +static bool warned; + +if (!warned && !qtest_enabled()) { +error_report("host_net_remove is deprecated, use netdev_del instead"); +warned = true; +} nc = net_hub_find_client_by_name(vlan_id, device); if (!nc) { -- 2.7.4
[Qemu-devel] [PULL 4/9] COLO-compare: Improve tcp compare trace event readability
From: Zhang Chen Because of previous patch's trace arguments over the limit of UST backend, so I rewrite the patch. Signed-off-by: Zhang Chen Signed-off-by: Jason Wang --- net/colo-compare.c | 33 ++--- net/trace-events | 3 +-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/net/colo-compare.c b/net/colo-compare.c index 4ab80b1..2639c7f 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -265,17 +265,28 @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt) } if (res != 0 && trace_event_get_state(TRACE_COLO_COMPARE_MISCOMPARE)) { -trace_colo_compare_pkt_info_src(inet_ntoa(ppkt->ip->ip_src), -ntohl(stcp->th_seq), -ntohl(stcp->th_ack), -res, stcp->th_flags, -spkt->size); - -trace_colo_compare_pkt_info_dst(inet_ntoa(ppkt->ip->ip_dst), -ntohl(ptcp->th_seq), -ntohl(ptcp->th_ack), -res, ptcp->th_flags, -ppkt->size); +char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20]; + +strcpy(pri_ip_src, inet_ntoa(ppkt->ip->ip_src)); +strcpy(pri_ip_dst, inet_ntoa(ppkt->ip->ip_dst)); +strcpy(sec_ip_src, inet_ntoa(spkt->ip->ip_src)); +strcpy(sec_ip_dst, inet_ntoa(spkt->ip->ip_dst)); + +trace_colo_compare_ip_info(ppkt->size, pri_ip_src, + pri_ip_dst, spkt->size, + sec_ip_src, sec_ip_dst); + +trace_colo_compare_tcp_info("pri tcp packet", +ntohl(ptcp->th_seq), +ntohl(ptcp->th_ack), +res, ptcp->th_flags, +ppkt->size); + +trace_colo_compare_tcp_info("sec tcp packet", +ntohl(stcp->th_seq), +ntohl(stcp->th_ack), +res, stcp->th_flags, +spkt->size); qemu_hexdump((char *)ppkt->data, stderr, "colo-compare ppkt", ppkt->size); diff --git a/net/trace-events b/net/trace-events index 35198bc..247e5c0 100644 --- a/net/trace-events +++ b/net/trace-events @@ -13,8 +13,7 @@ colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d" colo_compare_ip_info(int psize, const char *sta, const char *stb, int ssize, const char *stc, const char *std) "ppkt size = %d, ip_src = %s, ip_dst = %s, spkt size = %d, ip_src = %s, ip_dst = %s" colo_old_packet_check_found(int64_t old_time) "%" PRId64 colo_compare_miscompare(void) "" -colo_compare_pkt_info_src(const char *src, uint32_t sseq, uint32_t sack, int res, uint32_t sflag, int ssize) "src/dst: %s s: seq/ack=%u/%u res=%d flags=%x spkt_size: %d\n" -colo_compare_pkt_info_dst(const char *dst, uint32_t dseq, uint32_t dack, int res, uint32_t dflag, int dsize) "src/dst: %s d: seq/ack=%u/%u res=%d flags=%x dpkt_size: %d\n" +colo_compare_tcp_info(const char *pkt, uint32_t seq, uint32_t ack, int res, uint32_t flag, int size) "side: %s seq/ack= %u/%u res= %d flags= %x pkt_size: %d\n" # net/filter-rewriter.c colo_filter_rewriter_debug(void) "" -- 2.7.4
[Qemu-devel] [PULL 1/9] net/tap: Replace tap-haiku.c and tap-aix.c by a generic tap-stub.c
From: Thomas Huth The files tap-haiku.c and tap-aix.c are identical (except one line of error message). We should avoid such code duplication, so replace these by a generic tap-stub.c file instead. Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Jason Wang --- net/Makefile.objs | 15 +- net/tap-aix.c | 88 --- net/tap-haiku.c | 87 -- net/tap-stub.c| 87 ++ 4 files changed, 95 insertions(+), 182 deletions(-) delete mode 100644 net/tap-aix.c delete mode 100644 net/tap-haiku.c create mode 100644 net/tap-stub.c diff --git a/net/Makefile.objs b/net/Makefile.objs index 2e2fd43..67ba5e2 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -3,13 +3,7 @@ common-obj-y += socket.o common-obj-y += dump.o common-obj-y += eth.o common-obj-$(CONFIG_L2TPV3) += l2tpv3.o -common-obj-$(CONFIG_POSIX) += tap.o vhost-user.o -common-obj-$(CONFIG_LINUX) += tap-linux.o -common-obj-$(CONFIG_WIN32) += tap-win32.o -common-obj-$(CONFIG_BSD) += tap-bsd.o -common-obj-$(CONFIG_SOLARIS) += tap-solaris.o -common-obj-$(CONFIG_AIX) += tap-aix.o -common-obj-$(CONFIG_HAIKU) += tap-haiku.o +common-obj-$(CONFIG_POSIX) += vhost-user.o common-obj-$(CONFIG_SLIRP) += slirp.o common-obj-$(CONFIG_VDE) += vde.o common-obj-$(CONFIG_NETMAP) += netmap.o @@ -20,3 +14,10 @@ common-obj-y += colo-compare.o common-obj-y += colo.o common-obj-y += filter-rewriter.o common-obj-y += filter-replay.o + +tap-obj-$(CONFIG_LINUX) = tap-linux.o +tap-obj-$(CONFIG_BSD) = tap-bsd.o +tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o +tap-obj-y ?= tap-stub.o +common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y) +common-obj-$(CONFIG_WIN32) += tap-win32.o diff --git a/net/tap-aix.c b/net/tap-aix.c deleted file mode 100644 index 0e6da63..000 --- a/net/tap-aix.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "tap_int.h" - -int tap_open(char *ifname, int ifname_size, int *vnet_hdr, - int vnet_hdr_required, int mq_required, Error **errp) -{ -error_setg(errp, "no tap on AIX"); -return -1; -} - -void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp) -{ -} - -int tap_probe_vnet_hdr(int fd) -{ -return 0; -} - -int tap_probe_has_ufo(int fd) -{ -return 0; -} - -int tap_probe_vnet_hdr_len(int fd, int len) -{ -return 0; -} - -void tap_fd_set_vnet_hdr_len(int fd, int len) -{ -} - -int tap_fd_set_vnet_le(int fd, int is_le) -{ -return -EINVAL; -} - -int tap_fd_set_vnet_be(int fd, int is_be) -{ -return -EINVAL; -} - -void tap_fd_set_offload(int fd, int csum, int tso4, -int tso6, int ecn, int ufo) -{ -} - -int tap_fd_enable(int fd) -{ -return -1; -} - -int tap_fd_disable(int fd) -{ -return -1; -} - -int tap_fd_get_ifname(int fd, char *ifname) -{ -return -1; -} - diff --git a/net/tap-haiku.c b/net/tap-haiku.c deleted file mode 100644 index b27e57e..000 --- a/net/tap-haiku.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SO
[Qemu-devel] [PULL 0/9] Net patches
The following changes since commit 56821559f0ba682fe6b367815572e6f974d329ab: Merge remote-tracking branch 'dgilbert/tags/pull-hmp-20170517' into staging (2017-05-18 13:36:15 +0100) are available in the git repository at: https://github.com/jasowang/qemu.git tags/net-pull-request for you to fetch changes up to 82342e91b60a4a078811df4e1a545e57abffa11d: e1000e: Fix ICR "Other" causes clear logic (2017-05-23 10:10:38 +0800) Sameeh Jubran (1): e1000e: Fix ICR "Other" causes clear logic Thomas Huth (3): net/tap: Replace tap-haiku.c and tap-aix.c by a generic tap-stub.c net/dump: Issue a warning for the deprecated "-net dump" hmp / net: Mark host_net_add/remove as deprecated Yunjian Wang (1): virtio-net: fix wild pointer when remove virtio-net queues Zhang Chen (4): COLO-compare: Improve tcp compare trace event readability net/filter-mirror.c: Remove duplicate check code. net/filter-mirror.c: Rename filter_mirror_send() and fix codestyle net/filter-rewriter: Remove unused option in filter-rewriter hmp-commands.hx | 8 ++-- hw/net/e1000e_core.c | 10 - hw/net/virtio-net.c | 3 ++ net/Makefile.objs | 15 net/colo-compare.c| 33 ++-- net/dump.c| 3 ++ net/filter-mirror.c | 35 - net/net.c | 13 +++ net/tap-haiku.c | 87 --- net/{tap-aix.c => tap-stub.c} | 3 +- net/trace-events | 3 +- qemu-options.hx | 2 +- 12 files changed, 80 insertions(+), 135 deletions(-) delete mode 100644 net/tap-haiku.c rename net/{tap-aix.c => tap-stub.c} (97%)
Re: [Qemu-devel] [PATCH 0/7] KVM: MMU: fast write protect
Ping... Sorry to disturb, just make this patchset not be missed. :) On 05/04/2017 03:06 PM, Paolo Bonzini wrote: On 04/05/2017 05:36, Xiao Guangrong wrote: Great. As there is no conflict between these two patchsets except dirty ring pages takes benefit from write-protect-all, i think they can be developed and iterated independently, right? I can certainly start reviewing this one. Paolo Or you prefer to merge dirty ring pages first then review the new version of this patchset later?
Re: [Qemu-devel] A problem of IRQchip in QEMU and KVM for ARM
Any idea? Thanks. On Fri, May 19, 2017 at 1:46 PM, Li Zhang wrote: > > Hi, > > I am looking into QEMU code in ARM recently and trying to add add_hot_cpu in > QEMU for ARM, > but it doesn't work when enabling KVM. It reports error: > > "kvm_init_vcpu failed: Device or resourc busy." > > By debugging QEMU with gdb, it failed on ioctl. In kernel soruce code > arch/arm/kvm/arm.c, > vcpu is created by this following function, it will report -EBUSY if > irqchip_in_kernel. > > struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) > { > int err; > struct kvm_vcpu *vcpu; > > if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) { > err = -EBUSY; > goto out; > } > > > } > > I set virt machine with kernel_irqchip = off, it can execute cpu-add > interface correctly with qmp-shell > commands. But VMs still can't work well with kernel_irqchip=off when > executing "info cpus" in qemu monitor. > > My question is that: > 1) Can we change this error status in kvm_arch_vcpu_create? > 2) Is it that irqchip_kernel=off isn't supported with KVM enabled on ARM? > > -- > > Best Regards > -Li -- Best Regards -Li
Re: [Qemu-devel] [virtio-dev] Re: [virtio-dev] Re: [PATCH v2 00/16] Vhost-pci for inter-VM communication
On 2017年05月22日 19:46, Wang, Wei W wrote: On Monday, May 22, 2017 10:28 AM, Jason Wang wrote: On 2017年05月19日 23:33, Stefan Hajnoczi wrote: On Fri, May 19, 2017 at 11:10:33AM +0800, Jason Wang wrote: On 2017年05月18日 11:03, Wei Wang wrote: On 05/17/2017 02:22 PM, Jason Wang wrote: On 2017年05月17日 14:16, Jason Wang wrote: On 2017年05月16日 15:12, Wei Wang wrote: Hi: Care to post the driver codes too? OK. It may take some time to clean up the driver code before post it out. You can first have a check of the draft at the repo here: https://github.com/wei-w-wang/vhost-pci-driver Best, Wei Interesting, looks like there's one copy on tx side. We used to have zerocopy support for tun for VM2VM traffic. Could you please try to compare it with your vhost-pci-net by: We can analyze from the whole data path - from VM1's network stack to send packets -> VM2's network stack to receive packets. The number of copies are actually the same for both. That's why I'm asking you to compare the performance. The only reason for vhost-pci is performance. You should prove it. There is another reason for vhost-pci besides maximum performance: vhost-pci makes it possible for end-users to run networking or storage appliances in compute clouds. Cloud providers do not allow end-users to run custom vhost-user processes on the host so you need vhost-pci. Stefan Then it has non NFV use cases and the question goes back to the performance comparing between vhost-pci and zerocopy vhost_net. If it does not perform better, it was less interesting at least in this case. Probably I can share what we got about vhost-pci and vhost-user: https://github.com/wei-w-wang/vhost-pci-discussion/blob/master/vhost_pci_vs_vhost_user.pdf Right now, I don’t have the environment to add the vhost_net test. Thanks, the number looks good. But I have some questions: - Is the number measured through your vhost-pci kernel driver code? - Have you tested packet size other than 64B? - Is zerocopy supported in OVS-dpdk? If yes, is it enabled in your test? Btw, do you have data about vhost_net v.s. vhost_user? I haven't. Thanks Best, Wei
Re: [Qemu-devel] [virtio-dev] Re: [PATCH RFC] virtio-net: enable configurable tx queue size
On 2017年05月22日 19:52, Wei Wang wrote: On 05/20/2017 04:42 AM, Michael S. Tsirkin wrote: On Fri, May 19, 2017 at 10:32:19AM +0800, Wei Wang wrote: This patch enables the virtio-net tx queue size to be configurable between 256 (the default queue size) and 1024 by the user. The queue size specified by the user should be power of 2. Setting the tx queue size to be 1024 requires the guest driver to support the VIRTIO_NET_F_MAX_CHAIN_SIZE feature. This should be a generic ring feature, not one specific to virtio net. OK. How about making two more changes below: 1) make the default tx queue size = 1024 (instead of 256). As has been pointed out, you need compat the default value too in this case. We can reduce the size (to 256) if the MAX_CHAIN_SIZE feature is not supported by the guest. In this way, people who apply the QEMU patch can directly use the largest queue size(1024) without adding the booting command line. 2) The vhost backend does not use writev, so I think when the vhost backed is used, using 1024 queue size should not depend on the MAX_CHAIN_SIZE feature. But do we need to consider even larger queue size now? Btw, I think it's better to draft a spec patch. Thanks Best, Wei
Re: [Qemu-devel] [PATCH v2 00/11] Preparation for block job mutex
On Mon, May 08, 2017 at 04:12:59PM +0200, Paolo Bonzini wrote: > These are a bunch of cleanups and patches extracted from the AioContext > lock removal series. As a general theme, the patches reorganize > blockjob.c to follow the blockjob.h/blockjob_int.h separation more > closely. For this reason, a lot of the patches are just moving functions > around. > > The blockjob.h/blockjob_int.h split later will correspond to different > locking rules, but the patches are independent from this change, and > can be applied/reviewed separately. > > There is no code change from v1, but all patches now have Reviewed-by > from at least one of John and Stefan. > > Thanks, > > Paolo > > > Paolo Bonzini (11): > blockjob: remove unnecessary check > blockjob: remove iostatus_reset callback > blockjob: introduce block_job_early_fail > blockjob: introduce block_job_pause/resume_all > blockjob: separate monitor and blockjob APIs > blockjob: move iostatus reset inside block_job_user_resume > blockjob: introduce block_job_cancel_async, check iostatus invariants > blockjob: group BlockJob transaction functions together > blockjob: strengthen a bit test-blockjob-txn > blockjob: reorganize block_job_completed_txn_abort > blockjob: use deferred_to_main_loop to indicate the coroutine has > ended > > block/backup.c | 2 +- > block/commit.c | 2 +- > block/io.c | 19 +- > block/mirror.c | 2 +- > blockdev.c | 1 - > blockjob.c | 900 > +++ > include/block/blockjob.h | 16 - > include/block/blockjob_int.h | 27 +- > tests/test-blockjob-txn.c| 7 +- > tests/test-blockjob.c| 10 +- > 10 files changed, 522 insertions(+), 464 deletions(-) > > -- > 2.12.2 > Thanks, Applied to my block branch: git://github.com/codyprime/qemu-kvm-jtc block -Jeff
[Qemu-devel] [PATCH V2] Add code to connect to external panel, for ARM
>From 5f5c186162ef5f56872095318106e9fe360ae310 Mon Sep 17 00:00:00 2001 From: John Bradley Date: Tue, 23 May 2017 01:43:32 +0100 Subject: [PATCH] Add code to connect to external panel, for ARM Has no effect if panel not found. GDummyPanel Fix formating issues. Add inital discussion of protocol version. Add code to connect with https://github.com/flypie/GDummyPanel The code uses GNU Sockets & Windows sockets as on MINGW GNU no available. This is inteded as a Demo for RFC. Signed-off-by: John Bradley --- hw/gpio/bcm2835_gpio.c | 136 +++-- include/hw/gpio/bcm2835_gpio.h | 4 + include/qemu/PanelEmu.h| 53 +++ util/Makefile.objs | 1 + util/PanelEmu.c| 326 + 5 files changed, 479 insertions(+), 41 deletions(-) create mode 100644 include/qemu/PanelEmu.h create mode 100644 util/PanelEmu.c diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c index acc2e3cf9e..5df3f4cddf 100644 --- a/hw/gpio/bcm2835_gpio.c +++ b/hw/gpio/bcm2835_gpio.c @@ -19,6 +19,8 @@ #include "hw/sd/sd.h" #include "hw/gpio/bcm2835_gpio.h" + + #define GPFSEL0 0x00 #define GPFSEL1 0x04 #define GPFSEL2 0x08 @@ -75,24 +77,24 @@ static void gpfsel_set(BCM2835GpioState *s, uint8_t reg, uint32_t value) /* SD controller selection (48-53) */ if (s->sd_fsel != 0 -&& (s->fsel[48] == 0) /* SD_CLK_R */ -&& (s->fsel[49] == 0) /* SD_CMD_R */ -&& (s->fsel[50] == 0) /* SD_DATA0_R */ -&& (s->fsel[51] == 0) /* SD_DATA1_R */ -&& (s->fsel[52] == 0) /* SD_DATA2_R */ -&& (s->fsel[53] == 0) /* SD_DATA3_R */ -) { +&& (s->fsel[48] == 0) /* SD_CLK_R */ +&& (s->fsel[49] == 0) /* SD_CMD_R */ +&& (s->fsel[50] == 0) /* SD_DATA0_R */ +&& (s->fsel[51] == 0) /* SD_DATA1_R */ +&& (s->fsel[52] == 0) /* SD_DATA2_R */ +&& (s->fsel[53] == 0) /* SD_DATA3_R */ +) { /* SDHCI controller selected */ sdbus_reparent_card(s->sdbus_sdhost, s->sdbus_sdhci); s->sd_fsel = 0; } else if (s->sd_fsel != 4 -&& (s->fsel[48] == 4) /* SD_CLK_R */ -&& (s->fsel[49] == 4) /* SD_CMD_R */ -&& (s->fsel[50] == 4) /* SD_DATA0_R */ -&& (s->fsel[51] == 4) /* SD_DATA1_R */ -&& (s->fsel[52] == 4) /* SD_DATA2_R */ -&& (s->fsel[53] == 4) /* SD_DATA3_R */ -) { + && (s->fsel[48] == 4) /* SD_CLK_R */ + && (s->fsel[49] == 4) /* SD_CMD_R */ + && (s->fsel[50] == 4) /* SD_DATA0_R */ + && (s->fsel[51] == 4) /* SD_DATA1_R */ + && (s->fsel[52] == 4) /* SD_DATA2_R */ + && (s->fsel[53] == 4) /* SD_DATA3_R */ + ) { /* SDHost controller selected */ sdbus_reparent_card(s->sdbus_sdhci, s->sdbus_sdhost); s->sd_fsel = 4; @@ -108,7 +110,7 @@ static int gpfsel_is_out(BCM2835GpioState *s, int index) } static void gpset(BCM2835GpioState *s, -uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) + uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) { uint32_t changes = val & ~*lev; uint32_t cur = 1; @@ -125,7 +127,7 @@ static void gpset(BCM2835GpioState *s, } static void gpclr(BCM2835GpioState *s, -uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) + uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) { uint32_t changes = val & *lev; uint32_t cur = 1; @@ -141,11 +143,12 @@ static void gpclr(BCM2835GpioState *s, *lev &= ~val; } -static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset, -unsigned size) +static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset, unsigned size) { BCM2835GpioState *s = (BCM2835GpioState *)opaque; +uint64_t Data; + switch (offset) { case GPFSEL0: case GPFSEL1: @@ -163,8 +166,20 @@ static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset, /* Write Only */ return 0; case GPLEV0: +if (s->panel.socket != -1) { +if (panel_read(&s->panel, &Data)) { +s->lev0 = (uint32_t)Data; +s->lev1 = (uint32_t)(Data >> 32); +} +} return s->lev0; case GPLEV1: +if (s->panel.socket != -1) { +if (panel_read(&s->panel, &Data)) { +s->lev0 = (uint32_t)Data; +s->lev1 = (uint32_t)(Data >> 32); +} +} return s->lev1; case GPEDS0: case GPEDS1: @@ -187,7 +202,7 @@ static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset, return 0; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", -__func__, offset); + __func__, offset); break; } @@ -195,9 +210,11 @@ static ui
Re: [Qemu-devel] [PATCH v2] e1000e: Fix ICR "Other" causes clear logic
On 2017年05月22日 19:26, Sameeh Jubran wrote: This commit fixes a bug which causes the guest to hang. The bug was observed upon a "receive overrun" (bit #6 of the ICR register) interrupt which could be triggered post migration in a heavy traffic environment. Even though the "receive overrun" bit (#6) is masked out by the IMS register (refer to the log below) the driver still receives an interrupt as the "receive overrun" bit (#6) causes the "Other" - bit #24 of the ICR register - bit to be set as documented below. The driver handles the interrupt and clears the "Other" bit (#24) but doesn't clear the "receive overrun" bit (#6) which leads to an infinite loop. Apparently the Windows driver expects that the "receive overrun" bit and other ones - documented below - to be cleared when the "Other" bit (#24) is cleared. So to sum that up: 1. Bit #6 of the ICR register is set by heavy traffic 2. As a results of setting bit #6, bit #24 is set 3. The driver receives an interrupt for bit 24 (it doesn't receieve an interrupt for bit #6 as it is masked out by IMS) 4. The driver handles and clears the interrupt of bit #24 5. Bit #6 is still set. 6. 2 happens all over again The Interrupt Cause Read - ICR register: The ICR has the "Other" bit - bit #24 - that is set when one or more of the following ICR register's bits are set: LSC - bit #2, RXO - bit #6, MDAC - bit #9, SRPD - bit #16, ACK - bit #17, MNG - bit #18 This bug can occur with any of these bits depending on the driver's behaviour and the way it configures the device. However, trying to reproduce it with any bit other than RX0 is challenging and came to failure as the drivers don't implement most of these bits, trying to reproduce it with LSC (Link Status Change - bit #2) bit didn't succeed too as it seems that Windows handles this bit differently. Log sample of the storm: 27563@1494850819.411877:e1000e_irq_pending_interrupts ICR PENDING: 0x100 (ICR: 0x815000c2, IMS: 0x1a4) 27563@1494850819.411900:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.411915:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412380:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412395:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412436:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412441:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa4) 27563@1494850819.412998:e1000e_irq_pending_interrupts ICR PENDING: 0x100 (ICR: 0x815000c2, IMS: 0x1a4) * This bug behaviour wasn't observed with the Linux driver. This commit solves: https://bugzilla.redhat.com/show_bug.cgi?id=1447935 https://bugzilla.redhat.com/show_bug.cgi?id=1449490 Signed-off-by: Sameeh Jubran --- hw/net/e1000e_core.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 28c5be1..8174b53 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -2454,14 +2454,17 @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val) static void e1000e_set_icr(E1000ECore *core, int index, uint32_t val) { +uint32_t icr = 0; if ((core->mac[ICR] & E1000_ICR_ASSERTED) && (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { trace_e1000e_irq_icr_process_iame(); e1000e_clear_ims_bits(core, core->mac[IAM]); } -trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val); -core->mac[ICR] &= ~val; +icr = core->mac[ICR] & ~val; +icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr; +trace_e1000e_irq_icr_write(val, core->mac[ICR], icr); +core->mac[ICR] = icr; e1000e_update_interrupt_state(core); } Applied and add a comment in the code to explain. Thanks
Re: [Qemu-devel] [PATCH 4/4] target/mips: optimize WSBH, DSBH and DSHD
On 05/16/2017 04:01 PM, Aurelien Jarno wrote: Use the same mask to avoid having to load two different constants, as suggested by Richard Henderson. Signed-off-by: Aurelien Jarno --- target/mips/translate.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH] Add code to connect to external panel, for ARM
Hi, This series seems to have some coding style problems. See output below for more information: Type: series Subject: [Qemu-devel] [PATCH] Add code to connect to external panel, for ARM Message-id: 1da30c06-46bd-47fa-b0ef-886ea9ab84e5@ONE.local === TEST SCRIPT BEGIN === #!/bin/bash BASE=base n=1 total=$(git log --oneline $BASE.. | wc -l) failed=0 git config --local diff.renamelimit 0 git config --local diff.renames True commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..." if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then failed=1 echo fi n=$((n+1)) done exit $failed === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 Switched to a new branch 'test' d9e7e6b Add code to connect to external panel, for ARM === OUTPUT BEGIN === Checking PATCH 1/1: Add code to connect to external panel, for ARM... WARNING: line over 80 characters #169: FILE: hw/arm/bcm2835_peripherals.c:307: +memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_POWER << MBOX_AS_CHAN_SHIFT, ERROR: spaces required around that '=' (ctx:VxV) #182: FILE: hw/arm/bcm2835_peripherals.c:444: +dc->user_creatable=false; ^ WARNING: line over 80 characters #450: FILE: hw/gpio/bcm2835_gpio.c:397: + .instance_size = sizeof(BCM2835GpioState), WARNING: line over 80 characters #452: FILE: hw/gpio/bcm2835_gpio.c:399: + .class_init = bcm2835_gpio_class_init, WARNING: architecture specific defines should be avoided #500: FILE: include/qemu/PanelEmu.h:17: +#ifdef __cplusplus ERROR: code indent should never use tabs #517: FILE: include/qemu/PanelEmu.h:34: +^I unless something changed */$ WARNING: architecture specific defines should be avoided #531: FILE: include/qemu/PanelEmu.h:48: +#ifdef __cplusplus WARNING: architecture specific defines should be avoided #555: FILE: util/PanelEmu.c:13: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #686: FILE: util/PanelEmu.c:144: +#ifdef __MINGW32__ ERROR: space required after that ',' (ctx:VxV) #710: FILE: util/PanelEmu.c:168: +int i,j; ^ WARNING: architecture specific defines should be avoided #780: FILE: util/PanelEmu.c:238: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #800: FILE: util/PanelEmu.c:258: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #808: FILE: util/PanelEmu.c:266: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #817: FILE: util/PanelEmu.c:275: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #825: FILE: util/PanelEmu.c:283: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #839: FILE: util/PanelEmu.c:297: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #856: FILE: util/PanelEmu.c:314: +#ifdef __MINGW32__ WARNING: architecture specific defines should be avoided #864: FILE: util/PanelEmu.c:322: +#ifdef __MINGW32__ total: 3 errors, 15 warnings, 794 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. === OUTPUT END === Test command exited with code: 1 --- Email generated automatically by Patchew [http://patchew.org/]. Please send your feedback to patchew-de...@freelists.org
Re: [Qemu-devel] [PATCH] Add code to connect to external panel, for ARM
Hi, This series failed automatic build test. Please find the testing commands and their output below. If you have docker installed, you can probably reproduce it locally. Type: series Subject: [Qemu-devel] [PATCH] Add code to connect to external panel, for ARM Message-id: 1da30c06-46bd-47fa-b0ef-886ea9ab84e5@ONE.local === TEST SCRIPT BEGIN === #!/bin/bash set -e git submodule update --init dtc # Let docker tests dump environment info export SHOW_ENV=1 export J=8 time make docker-test-quick@centos6 time make docker-test-mingw@fedora time make docker-test-build@min-glib === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 From https://github.com/patchew-project/qemu * [new tag] patchew/1da30c06-46bd-47fa-b0ef-886ea9ab84e5@ONE.local -> patchew/1da30c06-46bd-47fa-b0ef-886ea9ab84e5@ONE.local - [tag update] patchew/20170516230159.4195-1-aurel...@aurel32.net -> patchew/20170516230159.4195-1-aurel...@aurel32.net Switched to a new branch 'test' d9e7e6b Add code to connect to external panel, for ARM === OUTPUT BEGIN === Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc' Cloning into '/var/tmp/patchew-tester-tmp-w8i_o01_/src/dtc'... Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d' BUILD centos6 make[1]: Entering directory '/var/tmp/patchew-tester-tmp-w8i_o01_/src' ARCHIVE qemu.tgz ARCHIVE dtc.tgz COPYRUNNER RUN test-quick in qemu:centos6 Packages installed: SDL-devel-1.2.14-7.el6_7.1.x86_64 ccache-3.1.6-2.el6.x86_64 epel-release-6-8.noarch gcc-4.4.7-17.el6.x86_64 git-1.7.1-4.el6_7.1.x86_64 glib2-devel-2.28.8-5.el6.x86_64 libfdt-devel-1.4.0-1.el6.x86_64 make-3.81-23.el6.x86_64 package g++ is not installed pixman-devel-0.32.8-1.el6.x86_64 tar-1.23-15.el6_8.x86_64 zlib-devel-1.2.3-29.el6.x86_64 Environment variables: PACKAGES=libfdt-devel ccache tar git make gcc g++ zlib-devel glib2-devel SDL-devel pixman-devel epel-release HOSTNAME=5ac9900aaa1d TERM=xterm MAKEFLAGS= -j8 HISTSIZE=1000 J=8 USER=root CCACHE_DIR=/var/tmp/ccache EXTRA_CONFIGURE_OPTS= V= SHOW_ENV=1 MAIL=/var/spool/mail/root PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/ LANG=en_US.UTF-8 TARGET_LIST= HISTCONTROL=ignoredups SHLVL=1 HOME=/root TEST_DIR=/tmp/qemu-test LOGNAME=root LESSOPEN=||/usr/bin/lesspipe.sh %s FEATURES= dtc DEBUG= G_BROKEN_FILENAMES=1 CCACHE_HASHDIR= _=/usr/bin/env Configure options: --enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install No C++ compiler available; disabling C++ specific optional code Install prefix/var/tmp/qemu-build/install BIOS directory/var/tmp/qemu-build/install/share/qemu binary directory /var/tmp/qemu-build/install/bin library directory /var/tmp/qemu-build/install/lib module directory /var/tmp/qemu-build/install/lib/qemu libexec directory /var/tmp/qemu-build/install/libexec include directory /var/tmp/qemu-build/install/include config directory /var/tmp/qemu-build/install/etc local state directory /var/tmp/qemu-build/install/var Manual directory /var/tmp/qemu-build/install/share/man ELF interp prefix /usr/gnemul/qemu-%M Source path /tmp/qemu-test/src C compilercc Host C compiler cc C++ compiler Objective-C compiler cc ARFLAGS rv CFLAGS-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g QEMU_CFLAGS -I/usr/include/pixman-1 -I$(SRC_PATH)/dtc/libfdt -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wendif-labels -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all LDFLAGS -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g make make install install pythonpython -B smbd /usr/sbin/smbd module supportno host CPU x86_64 host big endian no target list x86_64-softmmu aarch64-softmmu tcg debug enabled no gprof enabled no sparse enabledno strip binariesyes profiler no static build no pixmansystem SDL support yes (1.2.14) GTK support no GTK GL supportno VTE support no TLS priority NORMAL GNUTLS supportno GNUTLS rndno libgcrypt no libgcrypt kdf no nettleno nettle kdfno libtasn1 no curses supportno virgl support no curl support no mingw32 support no Audio drivers oss Block whitelist (rw) Block whitelist (ro) VirtFS supportno VNC support yes VNC SASL support no VNC JPEG support no VNC PNG support no xen support no brlapi suppo
[Qemu-devel] [PATCH] Add code to connect to external panel, for ARM
>From 9256c1450557ed67b4328761ab80b4e80be26e3e Mon Sep 17 00:00:00 2001 From: John Bradley Date: Tue, 23 May 2017 01:43:32 +0100 Subject: [PATCH] Add code to connect to external panel, for ARM Has no effect if panel not found. GDummyPanel Fix formating issues. Add inital discussion of protocol version. Add code to connect with https://github.com/flypie/GDummyPanel The code uses GNU Sockets & Windows sockets as on MINGW GNU no available. This is inteded as a Demo for RFC. Signed-off-by: John Bradley --- hw/arm/Makefile.objs | 2 +- hw/arm/bcm2835_peripherals.c | 104 + hw/gpio/bcm2835_gpio.c | 136 +++-- include/hw/gpio/bcm2835_gpio.h | 4 + include/qemu/PanelEmu.h| 53 +++ util/PanelEmu.c| 326 + 6 files changed, 583 insertions(+), 42 deletions(-) create mode 100644 include/qemu/PanelEmu.h create mode 100644 util/PanelEmu.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 4c5c4ee76c..35b2da24f5 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -11,7 +11,7 @@ obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) += digic.o obj-y += omap1.o omap2.o strongarm.o obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o -obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o +obj-$(CONFIG_RASPI) += bcm2835.o bcm2835_peripherals.o bcm2836.o raspi.o obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 369ef1e3bd..0ca05ca685 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -56,6 +56,29 @@ static void bcm2835_peripherals_init(Object *obj) object_property_add_child(obj, "aux", OBJECT(&s->aux), NULL); qdev_set_parent_bus(DEVICE(&s->aux), sysbus_get_default()); +/* System timer */ +object_initialize(&s->st, sizeof(s->st), TYPE_BCM2835_ST); +object_property_add_child(obj, "systimer", OBJECT(&s->st), NULL); +qdev_set_parent_bus(DEVICE(&s->st), sysbus_get_default()); + +/* ARM timer */ +object_initialize(&s->timer, sizeof(s->timer), TYPE_BCM2835_TIMER); +object_property_add_child(obj, "armtimer", OBJECT(&s->timer), NULL); +qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default()); + +/* USB controller */ +object_initialize(&s->usb, sizeof(s->usb), TYPE_BCM2835_USB); +object_property_add_child(obj, "usb", OBJECT(&s->usb), NULL); +qdev_set_parent_bus(DEVICE(&s->usb), sysbus_get_default()); + +object_property_add_const_link(OBJECT(&s->usb), "dma_mr", + OBJECT(&s->gpu_bus_mr), &error_abort); + +/* MPHI - Message-based Parallel Host Interface */ +object_initialize(&s->mphi, sizeof(s->mphi), TYPE_BCM2835_MPHI); +object_property_add_child(obj, "mphi", OBJECT(&s->mphi), NULL); +qdev_set_parent_bus(DEVICE(&s->mphi), sysbus_get_default()); + /* Mailboxes */ object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX); object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL); @@ -64,6 +87,11 @@ static void bcm2835_peripherals_init(Object *obj) object_property_add_const_link(OBJECT(&s->mboxes), "mbox-mr", OBJECT(&s->mbox_mr), &error_abort); +/* Power management */ +object_initialize(&s->power, sizeof(s->power), TYPE_BCM2835_POWER); +object_property_add_child(obj, "power", OBJECT(&s->power), NULL); +qdev_set_parent_bus(DEVICE(&s->power), sysbus_get_default()); + /* Framebuffer */ object_initialize(&s->fb, sizeof(s->fb), TYPE_BCM2835_FB); object_property_add_child(obj, "fb", OBJECT(&s->fb), NULL); @@ -179,6 +207,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(s->uart0, 0, qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_UART)); + /* AUX / UART1 */ qdev_prop_set_chr(DEVICE(&s->aux), "chardev", serial_hds[1]); @@ -194,6 +223,67 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_AUX)); +/* System timer */ +object_property_set_bool(OBJECT(&s->st), true, "realized", &err); +if (err) { +error_propagate(errp, err); +return; +} + +memory_region_add_subregion(&s->peri_mr, ST_OFFSET, +sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->st), 0)); +sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 0, +qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_TIMER0)); +sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 1, +qdev_get_gpio_in_named(DEVICE(&s->ic), BCM283
Re: [Qemu-devel] [PATCH 3/4] target/cris: optimize swap
On 05/16/2017 04:01 PM, Aurelien Jarno wrote: Use the same mask to avoid having to load two different constants, as suggest by Richard Henderson. Also use one less temp. Signed-off-by: Aurelien Jarno --- target/cris/translate.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 2/4] target/arm: simplify and optimize aarch64 rev16
On 05/16/2017 04:01 PM, Aurelien Jarno wrote: Instead of byteswapping individual 16-bit words one by one, work on the whole register at the same time using shifts and mask. This is the same strategy than the aarch32 version of rev16 and is much more efficient in the case sf=1. Signed-off-by: Aurelien Jarno --- target/arm/translate-a64.c | 24 ++-- 1 file changed, 6 insertions(+), 18 deletions(-) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 1/4] target/arm: optimize aarch32 rev16
On 05/16/2017 04:01 PM, Aurelien Jarno wrote: Use the same mask to avoid having to load two different constants, as suggested by Richard Henderson. Signed-off-by: Aurelien Jarno --- target/arm/translate.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH] [PATCH V2] GDummyPanel Fix formatingissues.
Hi, This series seems to have some coding style problems. See output below for more information: Message-id: 56fa8a79-fa90-4adc-aa0e-0527c9d96698@ONE.local Subject: [Qemu-devel] [PATCH] [PATCH V2] GDummyPanel Fix formatingissues. Type: series === TEST SCRIPT BEGIN === #!/bin/bash BASE=base n=1 total=$(git log --oneline $BASE.. | wc -l) failed=0 git config --local diff.renamelimit 0 git config --local diff.renames True commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..." if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then failed=1 echo fi n=$((n+1)) done exit $failed === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 Switched to a new branch 'test' c33a1f7 GDummyPanel Fix formatingissues. === OUTPUT BEGIN === Checking PATCH 1/1: GDummyPanel Fix formatingissues ERROR: space prohibited between function name and open parenthesis '(' #37: FILE: hw/gpio/bcm2835_gpio.c:60: +if (index < sizeof (s->fsel)) { ERROR: space prohibited between function name and open parenthesis '(' #46: FILE: hw/gpio/bcm2835_gpio.c:72: +if (index < sizeof (s->fsel)) { ERROR: space prohibited after that '~' (ctx:WxW) #97: FILE: hw/gpio/bcm2835_gpio.c:115: +uint32_t changes = val & ~ *lev; ^ ERROR: switch and case should be at the same indent #122: FILE: hw/gpio/bcm2835_gpio.c:152: switch (offset) { +case GPFSEL0: +case GPFSEL1: +case GPFSEL2: +case GPFSEL3: +case GPFSEL4: +case GPFSEL5: [...] +case GPSET0: +case GPSET1: [...] +case GPCLR0: +case GPCLR1: [...] +case GPLEV0: [...] +case GPLEV1: [...] +case GPEDS0: +case GPEDS1: +case GPREN0: +case GPREN1: +case GPFEN0: +case GPFEN1: +case GPHEN0: +case GPHEN1: +case GPLEN0: +case GPLEN1: +case GPAREN0: +case GPAREN1: +case GPAFEN0: +case GPAFEN1: +case GPPUD: +case GPPUDCLK0: +case GPPUDCLK1: [...] +default: ERROR: switch and case should be at the same indent #232: FILE: hw/gpio/bcm2835_gpio.c:219: switch (offset) { +case GPFSEL0: +case GPFSEL1: +case GPFSEL2: +case GPFSEL3: +case GPFSEL4: +case GPFSEL5: [...] +case GPSET0: [...] +case GPSET1: [...] +case GPCLR0: [...] +case GPCLR1: [...] +case GPLEV0: +case GPLEV1: [...] +case GPEDS0: +case GPEDS1: +case GPREN0: +case GPREN1: +case GPFEN0: +case GPFEN1: +case GPHEN0: +case GPHEN1: +case GPLEN0: +case GPLEN1: +case GPAREN0: +case GPAREN1: +case GPAFEN0: +case GPAFEN1: +case GPPUD: +case GPPUDCLK0: +case GPPUDCLK1: [...] +default: WARNING: line over 80 characters #364: FILE: hw/gpio/bcm2835_gpio.c:316: + .endianness = DEVICE_NATIVE_ENDIAN, WARNING: line over 80 characters #380: FILE: hw/gpio/bcm2835_gpio.c:323: +.fields = (VMStateField[]) ERROR: space prohibited between function name and open parenthesis '(' #395: FILE: hw/gpio/bcm2835_gpio.c:339: +qbus_create_inplace(&s->sdbus, sizeof (s->sdbus), WARNING: line over 80 characters #449: FILE: hw/gpio/bcm2835_gpio.c:397: + .instance_size = sizeof (BCM2835GpioState), ERROR: space prohibited between function name and open parenthesis '(' #449: FILE: hw/gpio/bcm2835_gpio.c:397: + .instance_size = sizeof (BCM2835GpioState), WARNING: line over 80 characters #451: FILE: hw/gpio/bcm2835_gpio.c:399: + .class_init = bcm2835_gpio_class_init, WARNING: architecture specific defines should be avoided #499: FILE: include/qemu/PanelEmu.h:17: +#ifdef __cplusplus ERROR: code indent should never use tabs #516: FILE: include/qemu/PanelEmu.h:34: +^I unless something changed */$ WARNING: architecture specific defines should be avoided #530: FILE: include/qemu/PanelEmu.h:48: +#ifdef __cplusplus WARNING: architecture specific defines should be avoided #564: FILE: util/PanelEmu.c:13: +#ifdef __MINGW32__ ERROR: open brace '{' following enum go on the same line #575: FILE: util/PanelEmu.c:24: +typedef enum +{ ERROR: open brace '{' following struct go on the same line #596: FILE: util/PanelEmu.c:45: +typedef struct +{ WARNING: architecture specific defines should be avoided #697: FILE: util/PanelEmu.c:146: +#ifdef __MINGW32__ ERROR: spaces required around that '&&' (ctx:VxO) #730: FILE: util/PanelEmu.c:179: +while (NoError&&! NoDat
Re: [Qemu-devel] [PATCH] [PATCH V2] GDummyPanel Fix formatingissues.
Hi, This series failed automatic build test. Please find the testing commands and their output below. If you have docker installed, you can probably reproduce it locally. Message-id: 56fa8a79-fa90-4adc-aa0e-0527c9d96698@ONE.local Subject: [Qemu-devel] [PATCH] [PATCH V2] GDummyPanel Fix formatingissues. Type: series === TEST SCRIPT BEGIN === #!/bin/bash set -e git submodule update --init dtc # Let docker tests dump environment info export SHOW_ENV=1 export J=8 time make docker-test-quick@centos6 time make docker-test-mingw@fedora time make docker-test-build@min-glib === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 From https://github.com/patchew-project/qemu - [tag update] patchew/20170520002653.20213-1-and...@aj.id.au -> patchew/20170520002653.20213-1-and...@aj.id.au * [new tag] patchew/56fa8a79-fa90-4adc-aa0e-0527c9d96698@ONE.local -> patchew/56fa8a79-fa90-4adc-aa0e-0527c9d96698@ONE.local Switched to a new branch 'test' c33a1f7 GDummyPanel Fix formatingissues. === OUTPUT BEGIN === Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc' Cloning into '/var/tmp/patchew-tester-tmp-p472ny77/src/dtc'... Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d' BUILD centos6 make[1]: Entering directory '/var/tmp/patchew-tester-tmp-p472ny77/src' ARCHIVE qemu.tgz ARCHIVE dtc.tgz COPYRUNNER RUN test-quick in qemu:centos6 Packages installed: SDL-devel-1.2.14-7.el6_7.1.x86_64 ccache-3.1.6-2.el6.x86_64 epel-release-6-8.noarch gcc-4.4.7-17.el6.x86_64 git-1.7.1-4.el6_7.1.x86_64 glib2-devel-2.28.8-5.el6.x86_64 libfdt-devel-1.4.0-1.el6.x86_64 make-3.81-23.el6.x86_64 package g++ is not installed pixman-devel-0.32.8-1.el6.x86_64 tar-1.23-15.el6_8.x86_64 zlib-devel-1.2.3-29.el6.x86_64 Environment variables: PACKAGES=libfdt-devel ccache tar git make gcc g++ zlib-devel glib2-devel SDL-devel pixman-devel epel-release HOSTNAME=b25fe748bc53 TERM=xterm MAKEFLAGS= -j8 HISTSIZE=1000 J=8 USER=root CCACHE_DIR=/var/tmp/ccache EXTRA_CONFIGURE_OPTS= V= SHOW_ENV=1 MAIL=/var/spool/mail/root PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/ LANG=en_US.UTF-8 TARGET_LIST= HISTCONTROL=ignoredups SHLVL=1 HOME=/root TEST_DIR=/tmp/qemu-test LOGNAME=root LESSOPEN=||/usr/bin/lesspipe.sh %s FEATURES= dtc DEBUG= G_BROKEN_FILENAMES=1 CCACHE_HASHDIR= _=/usr/bin/env Configure options: --enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install No C++ compiler available; disabling C++ specific optional code Install prefix/var/tmp/qemu-build/install BIOS directory/var/tmp/qemu-build/install/share/qemu binary directory /var/tmp/qemu-build/install/bin library directory /var/tmp/qemu-build/install/lib module directory /var/tmp/qemu-build/install/lib/qemu libexec directory /var/tmp/qemu-build/install/libexec include directory /var/tmp/qemu-build/install/include config directory /var/tmp/qemu-build/install/etc local state directory /var/tmp/qemu-build/install/var Manual directory /var/tmp/qemu-build/install/share/man ELF interp prefix /usr/gnemul/qemu-%M Source path /tmp/qemu-test/src C compilercc Host C compiler cc C++ compiler Objective-C compiler cc ARFLAGS rv CFLAGS-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g QEMU_CFLAGS -I/usr/include/pixman-1 -I$(SRC_PATH)/dtc/libfdt -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wendif-labels -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all LDFLAGS -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g make make install install pythonpython -B smbd /usr/sbin/smbd module supportno host CPU x86_64 host big endian no target list x86_64-softmmu aarch64-softmmu tcg debug enabled no gprof enabled no sparse enabledno strip binariesyes profiler no static build no pixmansystem SDL support yes (1.2.14) GTK support no GTK GL supportno VTE support no TLS priority NORMAL GNUTLS supportno GNUTLS rndno libgcrypt no libgcrypt kdf no nettleno nettle kdfno libtasn1 no curses supportno virgl support no curl support no mingw32 support no Audio drivers oss Block whitelist (rw) Block whitelist (ro) VirtFS supportno VNC support yes VNC SASL support no VNC JPEG support no VNC PNG support no xen support no brlapi supportno bluez support
[Qemu-devel] [PATCH] [PATCH V2] GDummyPanel Fix formatingissues.
>From 468b7c74d36b1e9d56ca014531301f0485254866 Mon Sep 17 00:00:00 2001 From: John Bradley Date: Fri, 19 May 2017 00:01:07 +0100 Subject: [PATCH] [PATCH V2] GDummyPanel Fix formatingissues. Add inital discussion of protocol version. Add code to connect with https://github.com/flypie/GDummyPanel The code uses GNU Sockets & Windows sockets as on MINGW GNU no available. This is inteded as a Demo for RFC. Signed-off-by: John Bradley --- hw/gpio/bcm2835_gpio.c | 316 ++- include/hw/gpio/bcm2835_gpio.h | 4 + include/qemu/PanelEmu.h| 53 +++ util/Makefile.objs | 1 + util/PanelEmu.c| 327 + 5 files changed, 570 insertions(+), 131 deletions(-) create mode 100644 include/qemu/PanelEmu.h create mode 100644 util/PanelEmu.c diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c index acc2e3cf9e..2c9026c597 100644 --- a/hw/gpio/bcm2835_gpio.c +++ b/hw/gpio/bcm2835_gpio.c @@ -19,6 +19,8 @@ #include "hw/sd/sd.h" #include "hw/gpio/bcm2835_gpio.h" + + #define GPFSEL0 0x00 #define GPFSEL1 0x04 #define GPFSEL2 0x08 @@ -55,7 +57,7 @@ static uint32_t gpfsel_get(BCM2835GpioState *s, uint8_t reg) uint32_t value = 0; for (i = 0; i < 10; i++) { uint32_t index = 10 * reg + i; -if (index < sizeof(s->fsel)) { +if (index < sizeof (s->fsel)) { value |= (s->fsel[index] & 0x7) << (3 * i); } } @@ -67,7 +69,7 @@ static void gpfsel_set(BCM2835GpioState *s, uint8_t reg, uint32_t value) int i; for (i = 0; i < 10; i++) { uint32_t index = 10 * reg + i; -if (index < sizeof(s->fsel)) { +if (index < sizeof (s->fsel)) { int fsel = (value >> (3 * i)) & 0x7; s->fsel[index] = fsel; } @@ -75,24 +77,24 @@ static void gpfsel_set(BCM2835GpioState *s, uint8_t reg, uint32_t value) /* SD controller selection (48-53) */ if (s->sd_fsel != 0 -&& (s->fsel[48] == 0) /* SD_CLK_R */ -&& (s->fsel[49] == 0) /* SD_CMD_R */ -&& (s->fsel[50] == 0) /* SD_DATA0_R */ -&& (s->fsel[51] == 0) /* SD_DATA1_R */ -&& (s->fsel[52] == 0) /* SD_DATA2_R */ -&& (s->fsel[53] == 0) /* SD_DATA3_R */ -) { +&& (s->fsel[48] == 0) /* SD_CLK_R */ +&& (s->fsel[49] == 0) /* SD_CMD_R */ +&& (s->fsel[50] == 0) /* SD_DATA0_R */ +&& (s->fsel[51] == 0) /* SD_DATA1_R */ +&& (s->fsel[52] == 0) /* SD_DATA2_R */ +&& (s->fsel[53] == 0) /* SD_DATA3_R */ +) { /* SDHCI controller selected */ sdbus_reparent_card(s->sdbus_sdhost, s->sdbus_sdhci); s->sd_fsel = 0; } else if (s->sd_fsel != 4 -&& (s->fsel[48] == 4) /* SD_CLK_R */ -&& (s->fsel[49] == 4) /* SD_CMD_R */ -&& (s->fsel[50] == 4) /* SD_DATA0_R */ -&& (s->fsel[51] == 4) /* SD_DATA1_R */ -&& (s->fsel[52] == 4) /* SD_DATA2_R */ -&& (s->fsel[53] == 4) /* SD_DATA3_R */ -) { + && (s->fsel[48] == 4) /* SD_CLK_R */ + && (s->fsel[49] == 4) /* SD_CMD_R */ + && (s->fsel[50] == 4) /* SD_DATA0_R */ + && (s->fsel[51] == 4) /* SD_DATA1_R */ + && (s->fsel[52] == 4) /* SD_DATA2_R */ + && (s->fsel[53] == 4) /* SD_DATA3_R */ + ) { /* SDHost controller selected */ sdbus_reparent_card(s->sdbus_sdhci, s->sdbus_sdhost); s->sd_fsel = 4; @@ -108,9 +110,9 @@ static int gpfsel_is_out(BCM2835GpioState *s, int index) } static void gpset(BCM2835GpioState *s, -uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) + uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) { -uint32_t changes = val & ~*lev; +uint32_t changes = val & ~ *lev; uint32_t cur = 1; int i; @@ -125,7 +127,7 @@ static void gpset(BCM2835GpioState *s, } static void gpclr(BCM2835GpioState *s, -uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) + uint32_t val, uint8_t start, uint8_t count, uint32_t *lev) { uint32_t changes = val & *lev; uint32_t cur = 1; @@ -141,116 +143,153 @@ static void gpclr(BCM2835GpioState *s, *lev &= ~val; } -static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset, -unsigned size) +static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset, unsigned size) { BCM2835GpioState *s = (BCM2835GpioState *)opaque; +uint64_t Data; + switch (offset) { -case GPFSEL0: -case GPFSEL1: -case GPFSEL2: -case GPFSEL3: -case GPFSEL4: -case GPFSEL5: -return gpfsel_get(s, offset / 4); -case GPSET0: -case GPSET1: -/* Write Only */ -return 0; -case GPCLR0: -case GPCLR1: -/* Write Only */ -return 0; -case GPLEV0: -
Re: [Qemu-devel] [PATCH 2/2] hw/arm: Integrate ADC model into Aspeed SoC
On Fri, May 19, 2017 at 5:26 PM, Andrew Jeffery wrote: > Signed-off-by: Andrew Jeffery The connections look good to me. I'll have a look at V2 of your first patch. Reviewed-by: Alistair Francis Thanks, Alistair > --- > hw/arm/aspeed_soc.c | 15 +++ > include/hw/arm/aspeed_soc.h | 2 ++ > 2 files changed, 17 insertions(+) > > diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c > index 5c667d2c35b6..11f9588720d2 100644 > --- a/hw/arm/aspeed_soc.c > +++ b/hw/arm/aspeed_soc.c > @@ -31,6 +31,7 @@ > #define ASPEED_SOC_VIC_BASE 0x1E6C > #define ASPEED_SOC_SDMC_BASE0x1E6E > #define ASPEED_SOC_SCU_BASE 0x1E6E2000 > +#define ASPEED_SOC_ADC_BASE 0x1E6E9000 > #define ASPEED_SOC_SRAM_BASE0x1E72 > #define ASPEED_SOC_TIMER_BASE 0x1E782000 > #define ASPEED_SOC_WDT_BASE 0x1E785000 > @@ -157,6 +158,10 @@ static void aspeed_soc_init(Object *obj) > object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), >"hw-strap2", &error_abort); > > +object_initialize(&s->adc, sizeof(s->adc), TYPE_ASPEED_ADC); > +object_property_add_child(obj, "adc", OBJECT(&s->adc), NULL); > +qdev_set_parent_bus(DEVICE(&s->adc), sysbus_get_default()); > + > object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename); > object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL); > qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default()); > @@ -256,6 +261,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error > **errp) > } > sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE); > > +/* ADC */ > +object_property_set_bool(OBJECT(&s->adc), true, "realized", &err); > +if (err) { > +error_propagate(errp, err); > +return; > +} > +sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, ASPEED_SOC_ADC_BASE); > +sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0, > +qdev_get_gpio_in(DEVICE(&s->vic), 31)); > + > /* UART - attach an 8250 to the IO space as our UART5 */ > if (serial_hds[0]) { > qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]); > diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h > index d16205c66b5f..3b4d66d30f08 100644 > --- a/include/hw/arm/aspeed_soc.h > +++ b/include/hw/arm/aspeed_soc.h > @@ -15,6 +15,7 @@ > #include "hw/arm/arm.h" > #include "hw/intc/aspeed_vic.h" > #include "hw/misc/aspeed_scu.h" > +#include "hw/adc/aspeed_adc.h" > #include "hw/misc/aspeed_sdmc.h" > #include "hw/timer/aspeed_timer.h" > #include "hw/i2c/aspeed_i2c.h" > @@ -37,6 +38,7 @@ typedef struct AspeedSoCState { > AspeedTimerCtrlState timerctrl; > AspeedI2CState i2c; > AspeedSCUState scu; > +AspeedADCState adc; > AspeedSMCState fmc; > AspeedSMCState spi[ASPEED_SPIS_NUM]; > AspeedSDMCState sdmc; > -- > 2.9.3 > >
Re: [Qemu-devel] [PATCH V2] migration: expose qemu_announce_self() via qmp
Ohh, sorry. I don't know how or why, but I missed all your replies (this was archived in gmail) Below is qmp-net-test.c, It's just a copy and paste of what Markus suggested. I could try doing it with a socket (virtio-net-test.c) as Jason suggested but I'm afraid I won't have time this week as support is quite busy. Thanks Vlad for actively working on this. /* > * Test cases for network-related QMP commands > * > * Copyright (c) 2017 Red Hat Inc. > * > * Authors: > * Markus Armbruster , > * > * 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 "libqtest.h" > #include "qapi/error.h" > > const char common_args[] = "-nodefaults -machine none"; > > static void test_qmp_announce_self(void) > { > QDict *resp, *ret; > > qtest_start(common_args); > > resp = qmp("{ 'execute': 'announce-self' }"); > ret = qdict_get_qdict(resp, "return"); > g_assert(ret && !qdict_size(ret)); > QDECREF(resp); > > qtest_end(); > } > > int main(int argc, char *argv[]) > { > g_test_init(&argc, &argv, NULL); > > qtest_add_func("qmp/net/announce_self", test_qmp_announce_self); > > return g_test_run(); > } > On Sat, May 13, 2017 at 7:16 AM, Vlad Yasevich wrote: > On 05/12/2017 03:24 PM, Dr. David Alan Gilbert wrote: > > * Vlad Yasevich (vyase...@redhat.com) wrote: > >> On 02/20/2017 07:16 PM, Germano Veit Michel wrote: > >>> qemu_announce_self() is triggered by qemu at the end of migrations > >>> to update the network regarding the path to the guest l2addr. > >>> > >>> however it is also useful when there is a network change such as > >>> an active bond slave swap. Essentially, it's the same as a migration > >>> from a network perspective - the guest moves to a different point > >>> in the network topology. > >>> > >>> this exposes the function via qmp. > >>> > >>> Signed-off-by: Germano Veit Michel > >>> --- > >>> include/migration/vmstate.h | 5 + > >>> migration/savevm.c | 30 +++--- > >>> qapi-schema.json| 18 ++ > >>> 3 files changed, 42 insertions(+), 11 deletions(-) > >>> > >>> diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h > >>> index 63e7b02..a08715c 100644 > >>> --- a/include/migration/vmstate.h > >>> +++ b/include/migration/vmstate.h > >>> @@ -1042,6 +1042,11 @@ int64_t self_announce_delay(int round) > >>> return 50 + (SELF_ANNOUNCE_ROUNDS - round - 1) * 100; > >>> } > >>> > >>> +struct AnnounceRound { > >>> +QEMUTimer *timer; > >>> +int count; > >>> +}; > >>> + > >>> void dump_vmstate_json_to_file(FILE *out_fp); > >>> > >>> #endif > >>> diff --git a/migration/savevm.c b/migration/savevm.c > >>> index 5ecd264..44e196b 100644 > >>> --- a/migration/savevm.c > >>> +++ b/migration/savevm.c > >>> @@ -118,29 +118,37 @@ static void qemu_announce_self_iter(NICState > >>> *nic, void *opaque) > >>> qemu_send_packet_raw(qemu_get_queue(nic), buf, len); > >>> } > >>> > >>> - > >>> static void qemu_announce_self_once(void *opaque) > >>> { > >>> -static int count = SELF_ANNOUNCE_ROUNDS; > >>> -QEMUTimer *timer = *(QEMUTimer **)opaque; > >>> +struct AnnounceRound *round = opaque; > >>> > >>> qemu_foreach_nic(qemu_announce_self_iter, NULL); > >>> > >>> -if (--count) { > >>> +round->count--; > >>> +if (round->count) { > >>> /* delay 50ms, 150ms, 250ms, ... */ > >>> -timer_mod(timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + > >>> - self_announce_delay(count)); > >>> +timer_mod(round->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) > + > >>> + self_announce_delay(round->count)); > >>> } else { > >>> -timer_del(timer); > >>> -timer_free(timer); > >>> +timer_del(round->timer); > >>> +timer_free(round->timer); > >>> +g_free(round); > >>> } > >>> } > >>> > >>> void qemu_announce_self(void) > >>> { > >>> -static QEMUTimer *timer; > >>> -timer = timer_new_ms(QEMU_CLOCK_REALTIME, > qemu_announce_self_once, &timer); > >>> -qemu_announce_self_once(&timer); > >>> +struct AnnounceRound *round = g_malloc(sizeof(struct > AnnounceRound)); > >>> +if (!round) > >>> +return; > >>> +round->count = SELF_ANNOUNCE_ROUNDS; > >>> +round->timer = timer_new_ms(QEMU_CLOCK_REALTIME, > >>> qemu_announce_self_once, round); > >>> +qemu_announce_self_once(round); > >>> +} > >> > >> So, I've been looking and this code and have been playing with it and > with David's > >> patches and my patches to include virtio self announcements as well. > What I've discovered > >> is what I think is a possible packet amplification issue here. > >> > >> This creates a new timer every time we do do a announce_self. With > just migration, > >> this is not an issue since you only migrate once at a time, so there
Re: [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode
Hi, This series seems to have some coding style problems. See output below for more information: Message-id: 20170522211205.14265-1-hpous...@reactos.org Subject: [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Type: series === TEST SCRIPT BEGIN === #!/bin/bash BASE=base n=1 total=$(git log --oneline $BASE.. | wc -l) failed=0 git config --local diff.renamelimit 0 git config --local diff.renames True commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..." if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then failed=1 echo fi n=$((n+1)) done exit $failed === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 Switched to a new branch 'test' a44e0b9 vvfat: change OEM name to 'MSWIN4.1' ff2c35b vvfat: handle KANJI lead byte 0xe5 6e11c6c vvfat: limit number of entries in root directory in FAT12/FAT16 e5687f8 vvfat: correctly generate numeric-tail of short file names 20780e0 vvfat: correctly create base short names for non-ASCII filenames 2d4bf63 vvfat: correctly create long names for non-ASCII filenames 48accbf vvfat: always create . and .. entries at first and in that order 3105081 vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors 6f108da vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir a4cbca8 vvfat: rename useless enumeration values 663af27 vvfat: fix typos 76286f8 vvfat: replace tabs by 8 spaces e4e4ff3 vvfat: fix qemu-img map and qemu-img convert === OUTPUT BEGIN === Checking PATCH 1/13: vvfat: fix qemu-img map and qemu-img convert... Checking PATCH 2/13: vvfat: replace tabs by 8 spaces... ERROR: braces {} are necessary for all arms of this statement #33: FILE: block/vvfat.c:106: +if (!array->pointer) [...] ERROR: spaces required around that '=' (ctx:VxV) #56: FILE: block/vvfat.c:127: +int increment=count*array->item_size; ^ ERROR: spaces required around that '*' (ctx:VxV) #56: FILE: block/vvfat.c:127: +int increment=count*array->item_size; ^ ERROR: spaces required around that '=' (ctx:VxV) #57: FILE: block/vvfat.c:128: +array->pointer=g_realloc(array->pointer,array->size+increment); ^ ERROR: space required after that ',' (ctx:VxV) #57: FILE: block/vvfat.c:128: +array->pointer=g_realloc(array->pointer,array->size+increment); ^ ERROR: spaces required around that '+' (ctx:VxV) #57: FILE: block/vvfat.c:128: +array->pointer=g_realloc(array->pointer,array->size+increment); ^ ERROR: space required before the open parenthesis '(' #58: FILE: block/vvfat.c:129: +if(!array->pointer) ERROR: braces {} are necessary for all arms of this statement #58: FILE: block/vvfat.c:129: +if(!array->pointer) [...] ERROR: spaces required around that '+=' (ctx:VxV) #61: FILE: block/vvfat.c:131: +array->size+=increment; ^ ERROR: spaces required around that '+' (ctx:VxV) #66: FILE: block/vvfat.c:134: +array->pointer+index*array->item_size, ^ ERROR: spaces required around that '*' (ctx:VxV) #66: FILE: block/vvfat.c:134: +array->pointer+index*array->item_size, ^ ERROR: spaces required around that '-' (ctx:VxV) #67: FILE: block/vvfat.c:135: +(array->next-index)*array->item_size); ^ ERROR: spaces required around that '*' (ctx:VxV) #67: FILE: block/vvfat.c:135: +(array->next-index)*array->item_size); ^ ERROR: spaces required around that '<' (ctx:VxV) #78: FILE: block/vvfat.c:150: +index_to<0 || index_to>=array->next || ^ ERROR: spaces required around that '>=' (ctx:VxV) #78: FILE: block/vvfat.c:150: +index_to<0 || index_to>=array->next || ^ ERROR: spaces required around that '<' (ctx:VxV) #79: FILE: block/vvfat.c:151: +index_from<0 || index_from>=array->next) ^ ERROR: spaces required around that '>=' (ctx:VxV) #79: FILE: block/vvfat.c:151: +index_from<0 || index_from>=array->next) ^ ERROR: spaces required around that '+' (ctx:VxV) #93: FILE: block/vvfat.c:164: +memmove(to+is*count,to,from-to); ^ ERROR: spaces required around that '*' (ctx:VxV) #93: FILE: block/vvfat.c:164: +memmove(to+is*count,to,from-to); ^ ERROR: space required after that ',' (ctx:VxV) #93: FILE: block/vvfat.c:164: +memmove(to+is*count,to,from-to); ^ ERROR: space required after that ',' (ctx:VxV) #93: FILE: block/vvfa
[Qemu-devel] [PATCH] qapi: Fix some blockdev-add documentation regressions
In the process of getting rid of docs/qmp-commands.txt, we managed to regress on any text that changed after the point where the move was first branched and when the move actually occurred. For example, commit 3282eca for blockdev-snapshot re-added the extra "options" layer which had been cleaned up in commit 0153d2f. While I didn't audit for all such regressions, I did scrub for all bogus uses of nested "options". Signed-off-by: Eric Blake --- qapi/block-core.json | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 6b974b9..3bd7fa2 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1206,11 +1206,11 @@ # Example: # # -> { "execute": "blockdev-add", -# "arguments": { "options": { "driver": "qcow2", -# "node-name": "node1534", -# "file": { "driver": "file", -#"filename": "hd1.qcow2" }, -# "backing": "" } } } +# "arguments": { "driver": "qcow2", +# "node-name": "node1534", +# "file": { "driver": "file", +# "filename": "hd1.qcow2" }, +# "backing": "" } } # # <- { "return": {} } # @@ -3237,10 +3237,10 @@ # # -> { "execute": "blockdev-add", # "arguments": { -# "options": { "node-name": "node0", -# "driver": "raw", -# "file": { "driver": "file", -# "filename": "fedora.iso" } } } } +# "node-name": "node0", +# "driver": "raw", +# "file": { "driver": "file", +#"filename": "fedora.iso" } } } # <- { "return": {} } # # -> { "execute": "x-blockdev-insert-medium", @@ -3693,10 +3693,10 @@ # 1. Add a new node to a quorum # -> { "execute": "blockdev-add", # "arguments": { -# "options": { "driver": "raw", -# "node-name": "new_node", -#"file": { "driver": "file", -# "filename": "test.raw" } } } } +# "driver": "raw", +# "node-name": "new_node", +# "file": { "driver": "file", +#"filename": "test.raw" } } } # <- { "return": {} } # -> { "execute": "x-blockdev-change", # "arguments": { "parent": "disk1", -- 2.9.4
Re: [Qemu-devel] [PATCH v8 14/21] (SQUASHED) move doc to schema
On 01/13/2017 08:41 AM, Marc-André Lureau wrote: > qmp-commands: move 'add_client' doc to schema > Sadly, the squashed version introduced some documentation regressions. For example, the documentation for blockdev-snapshot (got merged as commit 3282eca4): > @@ -983,9 +1193,31 @@ > # > # Generates a snapshot of a block device. > # > +# Create a snapshot, by installing 'node' as the backing image of > +# 'overlay'. Additionally, if 'node' is associated with a block > +# device, the block device changes to using 'overlay' as its new active > +# image. > +# > # For the arguments, see the documentation of BlockdevSnapshot. > # > # Since: 2.5 > +# > +# Example: > +# > +# -> { "execute": "blockdev-add", > +# "arguments": { "options": { "driver": "qcow2", > +# "node-name": "node1534", > +# "file": { "driver": "file", > +#"filename": "hd1.qcow2" }, > +# "backing": "" } } } > +# > +# <- { "return": {} } > +# > +# -> { "execute": "blockdev-snapshot", > +# "arguments": { "node": "ide-hd0", > +# "overlay": "node1534" } } > +# <- { "return": {} } > +# reintroduced the bogus 'options' layer, which was not present in the pre-move text: > -blockdev-snapshot > -- > -Since 2.5 > - > -Create a snapshot, by installing 'node' as the backing image of > -'overlay'. Additionally, if 'node' is associated with a block > -device, the block device changes to using 'overlay' as its new active > -image. > - > -Arguments: > - > -- "node": device that will have a snapshot created (json-string) > -- "overlay": device that will have 'node' as its backing image (json-string) > - > -Example: > - > --> { "execute": "blockdev-add", > -"arguments": { "driver": "qcow2", > - "node-name": "node1534", > - "file": { "driver": "file", > - "filename": "hd1.qcow2" }, > - "backing": "" } } > - > -<- { "return": {} } > - > --> { "execute": "blockdev-snapshot", "arguments": { "node": "ide-hd0", > -"overlay": "node1534" } } > -<- { "return": {} } > - where 'options' had been cleaned up in commit 0153d2f. I really don't feel like auditing what other doc changes were inadvertently regressed (probably anything that changed between when Marc-André first branched his work, and when Markus finally merged it - which could be several months of commits to double-check); it might be sufficient to just review commits 65ce54f..c08d644 to look for any differences? Is that something we can automate by script? -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH v2 02/13] vvfat: replace tabs by 8 spaces
This was a complete mess. On 2299 indented lines: - 1329 were with spaces only - 617 with tabulations only - 353 with spaces and tabulations Signed-off-by: Hervé Poussineau --- block/vvfat.c | 2054 - 1 file changed, 1027 insertions(+), 1027 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index df24091bf6..d3afb731b6 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -101,12 +101,12 @@ static inline void* array_get(array_t* array,unsigned int index) { static inline int array_ensure_allocated(array_t* array, int index) { if((index + 1) * array->item_size > array->size) { - int new_size = (index + 32) * array->item_size; - array->pointer = g_realloc(array->pointer, new_size); - if (!array->pointer) - return -1; - array->size = new_size; - array->next = index + 1; +int new_size = (index + 32) * array->item_size; +array->pointer = g_realloc(array->pointer, new_size); +if (!array->pointer) +return -1; +array->size = new_size; +array->next = index + 1; } return 0; @@ -116,7 +116,7 @@ static inline void* array_get_next(array_t* array) { unsigned int next = array->next; if (array_ensure_allocated(array, next) < 0) - return NULL; +return NULL; array->next = next + 1; return array_get(array, next); @@ -124,15 +124,15 @@ static inline void* array_get_next(array_t* array) { static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) { if((array->next+count)*array->item_size>array->size) { - int increment=count*array->item_size; - array->pointer=g_realloc(array->pointer,array->size+increment); - if(!array->pointer) +int increment=count*array->item_size; +array->pointer=g_realloc(array->pointer,array->size+increment); +if(!array->pointer) return NULL; - array->size+=increment; +array->size+=increment; } memmove(array->pointer+(index+count)*array->item_size, - array->pointer+index*array->item_size, - (array->next-index)*array->item_size); +array->pointer+index*array->item_size, +(array->next-index)*array->item_size); array->next+=count; return array->pointer+index*array->item_size; } @@ -147,12 +147,12 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun int is; if(!array || - index_to<0 || index_to>=array->next || - index_from<0 || index_from>=array->next) - return -1; +index_to<0 || index_to>=array->next || +index_from<0 || index_from>=array->next) +return -1; if(index_to==index_from) - return 0; +return 0; is=array->item_size; from=array->pointer+index_from*is; @@ -161,9 +161,9 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun memcpy(buf,from,is*count); if(index_to 0); assert(index + count <= array->next); if(array_roll(array,array->next-1,index,count)) - return -1; +return -1; array->next -= count; return 0; } @@ -217,21 +217,21 @@ typedef struct bootsector_t { uint32_t total_sectors; union { struct { - uint8_t drive_number; - uint8_t current_head; - uint8_t signature; - uint32_t id; - uint8_t volume_label[11]; - } QEMU_PACKED fat16; - struct { - uint32_t sectors_per_fat; - uint16_t flags; - uint8_t major,minor; - uint32_t first_cluster_of_root_directory; - uint16_t info_sector; - uint16_t backup_boot_sector; - uint16_t ignored; - } QEMU_PACKED fat32; +uint8_t drive_number; +uint8_t current_head; +uint8_t signature; +uint32_t id; +uint8_t volume_label[11]; +} QEMU_PACKED fat16; +struct { +uint32_t sectors_per_fat; +uint16_t flags; +uint8_t major,minor; +uint32_t first_cluster_of_root_directory; +uint16_t info_sector; +uint16_t backup_boot_sector; +uint16_t ignored; +} QEMU_PACKED fat32; } u; uint8_t fat_type[8]; uint8_t ignored[0x1c0]; @@ -285,25 +285,25 @@ typedef struct mapping_t { /* the clusters of a file may be in any order; this points to the first */ int first_mapping_index; union { - /* offset is -* - the offset in the file (in clusters) for a file, or -* - the next cluster of the directory for a directory, and -* - the address of the buffer for a faked entry -*/ - struct { - uint32_t offset; - } file; - struct { - int parent_mapping_index; - int first_dir_index; -
[Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short names for non-ASCII filenames
More specifically, create short name from filename and change blacklist of invalid chars to whitelist of valid chars. Windows 9x also now correctly see long file names of filenames containing a space, but Scandisk still complains about mismatch between SFN and LFN. Specification: "FAT: General overview of on-disk format" v1.03, pages 30-31 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 105 ++ 1 file changed, 77 insertions(+), 28 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index d34241da17..3cb65493cd 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -516,6 +516,81 @@ static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin) direntry->begin_hi = cpu_to_le16((begin >> 16) & 0x); } +static uint8_t to_valid_short_char(gunichar c) +{ +c = g_unichar_toupper(c); +if ((c >= '0' && c <= '9') || +(c >= 'A' && c <= 'Z') || +strchr("$%'-_@~`!(){}^#&", c) != 0) { +return c; +} else { +return 0; +} +} + +static direntry_t *create_short_filename(BDRVVVFATState *s, + const char *filename) +{ +int i, j = 0; +direntry_t *entry = array_get_next(&(s->directory)); +const gchar *p, *last_dot = NULL; +gunichar c; +bool lossy_conversion = false; +char tail[11]; + +if (!entry) { +return NULL; +} +memset(entry->name, 0x20, sizeof(entry->name)); + +/* copy filename and search last dot */ +for (p = filename; ; p = g_utf8_next_char(p)) { +c = g_utf8_get_char(p); +if (c == '\0') { +break; +} else if (c == '.') { +if (j == 0) { +/* '.' at start of filename */ +lossy_conversion = true; +} else { +if (last_dot) { +lossy_conversion = true; +} +last_dot = p; +} +} else if (!last_dot) { +/* first part of the name; copy it */ +uint8_t v = to_valid_short_char(c); +if (j < 8 && v) { +entry->name[j++] = v; +} else { +lossy_conversion = true; +} +} +} + +/* copy extension (if any) */ +if (last_dot) { +j = 0; +for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) { +c = g_utf8_get_char(p); +if (c == '\0') { +break; +} else { +/* extension; copy it */ +uint8_t v = to_valid_short_char(c); +if (j < 3 && v) { +entry->name[8 + (j++)] = v; +} else { +lossy_conversion = true; +} +} +} +} +(void)lossy_conversion; +return entry; +} + /* fat functions */ static inline uint8_t fat_chksum(const direntry_t* entry) @@ -614,7 +689,7 @@ static inline void init_fat(BDRVVVFATState* s) static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, unsigned int directory_start, const char* filename, int is_dot) { -int i,j,long_index=s->directory.next; +int long_index = s->directory.next; direntry_t* entry = NULL; direntry_t* entry_long = NULL; @@ -626,33 +701,7 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, } entry_long=create_long_filename(s,filename); - -i = strlen(filename); -for(j = i - 1; j>0 && filename[j]!='.';j--); -if (j > 0) -i = (j > 8 ? 8 : j); -else if (i > 8) -i = 8; - -entry=array_get_next(&(s->directory)); -memset(entry->name, 0x20, sizeof(entry->name)); -memcpy(entry->name, filename, i); - -if (j > 0) { -for (i = 0; i < 3 && filename[j + 1 + i]; i++) { -entry->name[8 + i] = filename[j + 1 + i]; -} -} - -/* upcase & remove unwanted characters */ -for(i=10;i>=0;i--) { -if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--); -if(entry->name[i]<=' ' || entry->name[i]>0x7f -|| strchr(".*?<>|\":/\\[];,+='",entry->name[i])) -entry->name[i]='_'; -else if(entry->name[i]>='a' && entry->name[i]<='z') -entry->name[i]+='A'-'a'; -} +entry = create_short_filename(s, filename); /* mangle duplicates */ while(1) { -- 2.11.0
[Qemu-devel] [PATCH v2 04/13] vvfat: rename useless enumeration values
MODE_FAKED and MODE_RENAMED are not and were never used. Signed-off-by: Hervé Poussineau --- block/vvfat.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 8b5f53ad26..6a36d4f7fa 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -287,8 +287,7 @@ typedef struct mapping_t { union { /* offset is * - the offset in the file (in clusters) for a file, or - * - the next cluster of the directory for a directory, and - * - the address of the buffer for a faked entry + * - the next cluster of the directory for a directory */ struct { uint32_t offset; @@ -301,9 +300,13 @@ typedef struct mapping_t { /* path contains the full path, i.e. it always starts with s->path */ char* path; -enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2, -MODE_DIRECTORY = 4, MODE_FAKED = 8, -MODE_DELETED = 16, MODE_RENAMED = 32 } mode; +enum { +MODE_UNDEFINED = 0, +MODE_NORMAL = 1, +MODE_MODIFIED = 2, +MODE_DIRECTORY = 4, +MODE_DELETED = 8, +} mode; int read_only; } mapping_t; -- 2.11.0
Re: [Qemu-devel] [Qemu-block] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert
On 05/22/2017 04:11 PM, Hervé Poussineau wrote: > - bs->total_sectors is the number of sectors of the whole disk > - s->sector_count is the number of sectors of the FAT partition > > This fixes the following assert in qemu-img map: > qemu-img.c:2641: get_block_status: Assertion `nb_sectors' failed. > > This also fixes an infinite loop in qemu-img convert. > > Fixes: 4480e0f924a42e1db8b8cfcac4d0634dd1bb27a0 > Fixes: https://bugs.launchpad.net/qemu/+bug/1599539 > Signed-off-by: Hervé Poussineau > --- > block/vvfat.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) I gave Reviewed-by: on version 1, and suggested that this be cc'd to qemu-stable: https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg03622.html It helps to add that into the commit message for v2, to make it clear that you haven't changed anything in this commit since that review. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names
More specifically: - try without numeric-tail only if LFN didn't have invalid short chars - start at ~1 (instead of ~0) - handle case if numeric tail is more than one char (ie > 10) Windows 9x Scandisk doesn't see anymore mismatches between short file names and long file names for non-ASCII filenames. Specification: "FAT: General overview of on-disk format" v1.03, page 31 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 62 --- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 3cb65493cd..414bca6dee 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -529,7 +529,8 @@ static uint8_t to_valid_short_char(gunichar c) } static direntry_t *create_short_filename(BDRVVVFATState *s, - const char *filename) + const char *filename, + unsigned int directory_start) { int i, j = 0; direntry_t *entry = array_get_next(&(s->directory)); @@ -587,8 +588,32 @@ static direntry_t *create_short_filename(BDRVVVFATState *s, } } } -(void)lossy_conversion; -return entry; + +/* numeric-tail generation */ +for (j = 0; j < 8; j++) { +if (entry->name[j] == ' ') { +break; +} +} +for (i = lossy_conversion ? 1 : 0; i < 99; i++) { +direntry_t *entry1; +if (i > 0) { +int len = sprintf(tail, "~%d", i); +memcpy(entry->name + MIN(j, 8 - len), tail, len); +} +for (entry1 = array_get(&(s->directory), directory_start); + entry1 < entry; entry1++) { +if (!is_long_name(entry1) && +!memcmp(entry1->name, entry->name, 11)) { +break; /* found dupe */ +} +} +if (entry1 == entry) { +/* no dupe found */ +return entry; +} +} +return NULL; } /* fat functions */ @@ -701,36 +726,7 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, } entry_long=create_long_filename(s,filename); -entry = create_short_filename(s, filename); - -/* mangle duplicates */ -while(1) { -direntry_t* entry1=array_get(&(s->directory),directory_start); -int j; - -for(;entry1name,entry->name,11)) -break; /* found dupe */ -if(entry1==entry) /* no dupe found */ -break; - -/* use all 8 characters of name */ -if(entry->name[7]==' ') { -int j; -for(j=6;j>0 && entry->name[j]==' ';j--) -entry->name[j]='~'; -} - -/* increment number */ -for(j=7;j>0 && entry->name[j]=='9';j--) -entry->name[j]='0'; -if(j>0) { -if(entry->name[j]<'0' || entry->name[j]>'9') -entry->name[j]='0'; -else -entry->name[j]++; -} -} +entry = create_short_filename(s, filename, directory_start); /* calculate checksum; propagate to long name */ if(entry_long) { -- 2.11.0
[Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir
- offset_to_bootsector is the number of sectors up to FAT bootsector - offset_to_fat is the number of sectors up to first File Allocation Table - offset_to_root_dir is the number of sectors up to root directory sector Replace first_sectors_number - 1 by offset_to_bootsector. Replace first_sectors_number by offset_to_fat. Replace faked_sectors by offset_to_rootdir. Signed-off-by: Hervé Poussineau --- block/vvfat.c | 70 --- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 6a36d4f7fa..e694d82df4 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -320,22 +320,24 @@ static void print_mapping(const struct mapping_t* mapping); typedef struct BDRVVVFATState { CoMutex lock; BlockDriverState* bs; /* pointer to parent */ -unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */ unsigned char first_sectors[0x40*0x200]; int fat_type; /* 16 or 32 */ array_t fat,directory,mapping; char volume_label[11]; +uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */ + unsigned int cluster_size; unsigned int sectors_per_cluster; unsigned int sectors_per_fat; unsigned int sectors_of_root_directory; uint32_t last_cluster_of_root_directory; -unsigned int faked_sectors; /* how many sectors are faked before file data */ uint32_t sector_count; /* total number of sectors of the partition */ uint32_t cluster_count; /* total number of clusters of this partition */ uint32_t max_fat_value; +uint32_t offset_to_fat; +uint32_t offset_to_root_dir; int current_fd; mapping_t* current_mapping; @@ -394,15 +396,15 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs) partition->attributes=0x80; /* bootable */ /* LBA is used when partition is outside the CHS geometry */ -lba = sector2CHS(&partition->start_CHS, s->first_sectors_number - 1, +lba = sector2CHS(&partition->start_CHS, s->offset_to_bootsector, cyls, heads, secs); lba |= sector2CHS(&partition->end_CHS, s->bs->total_sectors - 1, cyls, heads, secs); /*LBA partitions are identified only by start/length_sector_long not by CHS*/ -partition->start_sector_long = cpu_to_le32(s->first_sectors_number - 1); +partition->start_sector_long = cpu_to_le32(s->offset_to_bootsector); partition->length_sector_long = cpu_to_le32(s->bs->total_sectors -- s->first_sectors_number + 1); +- s->offset_to_bootsector); /* FAT12/FAT16/FAT32 */ /* DOS uses different types when partition is LBA, @@ -823,12 +825,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num) { -return (sector_num-s->faked_sectors)/s->sectors_per_cluster; +return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster; } static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num) { -return s->faked_sectors + s->sectors_per_cluster * cluster_num; +return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num; } static int init_directories(BDRVVVFATState* s, @@ -855,6 +857,9 @@ static int init_directories(BDRVVVFATState* s, i = 1+s->sectors_per_cluster*0x200*8/s->fat_type; s->sectors_per_fat=(s->sector_count+i)/i; /* round up */ +s->offset_to_fat = s->offset_to_bootsector + 1; +s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2; + array_init(&(s->mapping),sizeof(mapping_t)); array_init(&(s->directory),sizeof(direntry_t)); @@ -868,7 +873,6 @@ static int init_directories(BDRVVVFATState* s, /* Now build FAT, and write back information into directory */ init_fat(s); -s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2; s->cluster_count=sector2cluster(s, s->sector_count); mapping = array_get_next(&(s->mapping)); @@ -946,7 +950,8 @@ static int init_directories(BDRVVVFATState* s, s->current_mapping = NULL; - bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200); +bootsector = (bootsector_t *)(s->first_sectors + + s->offset_to_bootsector * 0x200); bootsector->jump[0]=0xeb; bootsector->jump[1]=0x3e; bootsector->jump[2]=0x90; @@ -957,16 +962,18 @@ static int init_directories(BDRVVVFATState* s, bootsector->number_of_fats=0x2; /* number of FATs */ bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10); bootsector->total_sectors16=s->sector_count>0x?0:cpu_to_le16(s->sector_count); -bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/ +/* media descriptor: hard di
[Qemu-devel] [PATCH v2 06/13] vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors
Specification: "FAT: General overview of on-disk format" v1.03, pages 11-13 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index e694d82df4..c1034cdd1f 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -218,23 +218,30 @@ typedef struct bootsector_t { union { struct { uint8_t drive_number; -uint8_t current_head; +uint8_t reserved1; uint8_t signature; uint32_t id; uint8_t volume_label[11]; +uint8_t fat_type[8]; +uint8_t ignored[0x1c0]; } QEMU_PACKED fat16; struct { uint32_t sectors_per_fat; uint16_t flags; uint8_t major,minor; -uint32_t first_cluster_of_root_directory; +uint32_t first_cluster_of_root_dir; uint16_t info_sector; uint16_t backup_boot_sector; -uint16_t ignored; +uint8_t reserved[12]; +uint8_t drive_number; +uint8_t reserved1; +uint8_t signature; +uint32_t id; +uint8_t volume_label[11]; +uint8_t fat_type[8]; +uint8_t ignored[0x1a4]; } QEMU_PACKED fat32; } u; -uint8_t fat_type[8]; -uint8_t ignored[0x1c0]; uint8_t magic[2]; } QEMU_PACKED bootsector_t; @@ -974,13 +981,13 @@ static int init_directories(BDRVVVFATState* s, /* LATER TODO: if FAT32, this is wrong */ /* drive_number: fda=0, hda=0x80 */ bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80; -bootsector->u.fat16.current_head=0; bootsector->u.fat16.signature=0x29; bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd); memcpy(bootsector->u.fat16.volume_label, s->volume_label, sizeof(bootsector->u.fat16.volume_label)); -memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12 ":s->fat_type==16?"FAT16 ":"FAT32 "),8); +memcpy(bootsector->u.fat16.fat_type, + s->fat_type == 12 ? "FAT12 " : "FAT16 ", 8); bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa; return 0; -- 2.11.0
[Qemu-devel] [PATCH v2 07/13] vvfat: always create . and .. entries at first and in that order
readdir() doesn't always return . and .. entries at first and in that order. This leads to not creating them at first in the directory, which raises some errors on file system checking utilities like MS-DOS Scandisk. Specification: "FAT: General overview of on-disk format" v1.03, page 25 Fixes: https://bugs.launchpad.net/qemu/+bug/1599539 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index c1034cdd1f..d4664c531b 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -728,6 +728,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) i = mapping->info.dir.first_dir_index = first_cluster == 0 ? 0 : s->directory.next; +if (first_cluster != 0) { +/* create the top entries of a subdirectory */ +(void)create_short_and_long_name(s, i, ".", 1); +(void)create_short_and_long_name(s, i, "..", 1); +} + /* actually read the directory, and allocate the mappings */ while((entry=readdir(dir))) { unsigned int length=strlen(dirname)+2+strlen(entry->d_name); @@ -749,8 +755,11 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) } /* create directory entry for this file */ -direntry=create_short_and_long_name(s, i, entry->d_name, -is_dot || is_dotdot); +if (!is_dot && !is_dotdot) { +direntry = create_short_and_long_name(s, i, entry->d_name, 0); +} else { +direntry = array_get(&(s->directory), is_dot ? i : i + 1); +} direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20); direntry->reserved[0]=direntry->reserved[1]=0; direntry->ctime=fat_datetime(st.st_ctime,1); -- 2.11.0
[Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert
- bs->total_sectors is the number of sectors of the whole disk - s->sector_count is the number of sectors of the FAT partition This fixes the following assert in qemu-img map: qemu-img.c:2641: get_block_status: Assertion `nb_sectors' failed. This also fixes an infinite loop in qemu-img convert. Fixes: 4480e0f924a42e1db8b8cfcac4d0634dd1bb27a0 Fixes: https://bugs.launchpad.net/qemu/+bug/1599539 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 9c82371360..df24091bf6 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2969,8 +2969,7 @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file) { -BDRVVVFATState* s = bs->opaque; -*n = s->sector_count - sector_num; +*n = bs->total_sectors - sector_num; if (*n > nb_sectors) { *n = nb_sectors; } else if (*n < 0) { -- 2.11.0
[Qemu-devel] [PATCH v2 11/13] vvfat: limit number of entries in root directory in FAT12/FAT16
FAT12/FAT16 root directory is two sectors in size, which allows only 512 directory entries. Prevent QEMU startup if too much files exist, instead of overflowing root directory. Also introduce variable root_entries, which will be required for FAT32. Fixes: https://bugs.launchpad.net/qemu/+bug/1599539/comments/4 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 26 +- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 414bca6dee..5376659010 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -338,8 +338,9 @@ typedef struct BDRVVVFATState { unsigned int cluster_size; unsigned int sectors_per_cluster; unsigned int sectors_per_fat; -unsigned int sectors_of_root_directory; uint32_t last_cluster_of_root_directory; +/* how many entries are available in root directory (0 for FAT32) */ +uint16_t root_entries; uint32_t sector_count; /* total number of sectors of the partition */ uint32_t cluster_count; /* total number of clusters of this partition */ uint32_t max_fat_value; @@ -786,6 +787,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) int is_dot=!strcmp(entry->d_name,"."); int is_dotdot=!strcmp(entry->d_name,".."); +if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) { +fprintf(stderr, "Too many entries in root directory\n"); +closedir(dir); +return -2; +} + if(first_cluster == 0 && (is_dotdot || is_dot)) continue; @@ -859,15 +866,15 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) memset(direntry,0,sizeof(direntry_t)); } -/* TODO: if there are more entries, bootsector has to be adjusted! */ -#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster) -if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) { +if (s->fat_type != 32 && +mapping_index == 0 && +s->directory.next < s->root_entries) { /* root directory */ int cur = s->directory.next; -array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1); -s->directory.next = ROOT_ENTRIES; +array_ensure_allocated(&(s->directory), s->root_entries - 1); +s->directory.next = s->root_entries; memset(array_get(&(s->directory), cur), 0, -(ROOT_ENTRIES - cur) * sizeof(direntry_t)); +(s->root_entries - cur) * sizeof(direntry_t)); } /* re-get the mapping, since s->mapping was possibly realloc()ed */ @@ -932,6 +939,8 @@ static int init_directories(BDRVVVFATState* s, /* Now build FAT, and write back information into directory */ init_fat(s); +/* TODO: if there are more entries, bootsector has to be adjusted! */ +s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster; s->cluster_count=sector2cluster(s, s->sector_count); mapping = array_get_next(&(s->mapping)); @@ -1000,7 +1009,6 @@ static int init_directories(BDRVVVFATState* s, } mapping = array_get(&(s->mapping), 0); -s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster; s->last_cluster_of_root_directory = mapping->end; /* the FAT signature */ @@ -1019,7 +1027,7 @@ static int init_directories(BDRVVVFATState* s, bootsector->sectors_per_cluster=s->sectors_per_cluster; bootsector->reserved_sectors=cpu_to_le16(1); bootsector->number_of_fats=0x2; /* number of FATs */ -bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10); +bootsector->root_entries = cpu_to_le16(s->root_entries); bootsector->total_sectors16=s->sector_count>0x?0:cpu_to_le16(s->sector_count); /* media descriptor: hard disk=0xf8, floppy=0xf0 */ bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0); -- 2.11.0
[Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1'
According to specification: "'MSWIN4.1' is the recommanded setting, because it is the setting least likely to cause compatibility problems. If you want to put something else in here, that is your option, but the result may be that some FAT drivers might not recognize the volume." Specification: "FAT: General overview of on-disk format" v1.03, page 9 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/vvfat.c b/block/vvfat.c index 53e8faa54c..1f7f46ecea 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1024,7 +1024,7 @@ static int init_directories(BDRVVVFATState* s, bootsector->jump[0]=0xeb; bootsector->jump[1]=0x3e; bootsector->jump[2]=0x90; -memcpy(bootsector->name,"QEMU",8); +memcpy(bootsector->name, "MSWIN4.1", 8); bootsector->sector_size=cpu_to_le16(0x200); bootsector->sectors_per_cluster=s->sectors_per_cluster; bootsector->reserved_sectors=cpu_to_le16(1); -- 2.11.0
[Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non-ASCII filenames
Assume that input filename is encoded as UTF-8, so correctly create UTF-16 encoding. Signed-off-by: Hervé Poussineau --- block/vvfat.c | 38 ++ 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index d4664c531b..d34241da17 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -425,28 +425,19 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs) /* direntry functions */ -/* dest is assumed to hold 258 bytes, and pads with 0x up to next multiple of 26 */ -static inline int short2long_name(char* dest,const char* src) +static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename) { -int i; -int len; -for(i=0;i<129 && src[i];i++) { -dest[2*i]=src[i]; -dest[2*i+1]=0; +int number_of_entries, i; +glong length; +direntry_t *entry; + +gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL); +if (!longname) { +fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename); +return NULL; } -len=2*i; -dest[2*i]=dest[2*i+1]=0; -for(i=2*i+2;(i%26);i++) -dest[i]=0xff; -return len; -} -static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename) -{ -char buffer[258]; -int length=short2long_name(buffer,filename), -number_of_entries=(length+25)/26,i; -direntry_t* entry; +number_of_entries = (length * 2 + 25) / 26; for(i=0;idirectory)); @@ -461,8 +452,15 @@ static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* fil else if(offset<22) offset=14+offset-10; else offset=28+offset-22; entry=array_get(&(s->directory),s->directory.next-1-(i/26)); -entry->name[offset]=buffer[i]; +if (i >= 2 * length + 2) { +entry->name[offset] = 0xff; +} else if (i % 2 == 0) { +entry->name[offset] = longname[i / 2] & 0xff; +} else { +entry->name[offset] = longname[i / 2] >> 8; +} } +g_free(longname); return array_get(&(s->directory),s->directory.next-number_of_entries); } -- 2.11.0
[Qemu-devel] [PATCH v2 03/13] vvfat: fix typos
Signed-off-by: Hervé Poussineau --- block/vvfat.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index d3afb731b6..8b5f53ad26 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -404,9 +404,9 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs) /* FAT12/FAT16/FAT32 */ /* DOS uses different types when partition is LBA, probably to prevent older versions from using CHS on them */ -partition->fs_type= s->fat_type==12 ? 0x1: -s->fat_type==16 ? (lba?0xe:0x06): - /*fat_tyoe==32*/ (lba?0xc:0x0b); +partition->fs_type = s->fat_type == 12 ? 0x1 : + s->fat_type == 16 ? (lba ? 0xe : 0x06) : + /*s->fat_type == 32*/ (lba ? 0xc : 0x0b); real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa; } @@ -806,7 +806,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) (ROOT_ENTRIES - cur) * sizeof(direntry_t)); } - /* reget the mapping, since s->mapping was possibly realloc()ed */ +/* re-get the mapping, since s->mapping was possibly realloc()ed */ mapping = array_get(&(s->mapping), mapping_index); first_cluster += (s->directory.next - mapping->info.dir.first_dir_index) * 0x20 / s->cluster_size; -- 2.11.0
[Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode
Hi, This patchset fixes some of issues I encountered when trying to use vvfat, and fixes bug #1599539: https://bugs.launchpad.net/qemu/+bug/1599539 Patch 1 fixes a crash when using 'qemu-img convert'. Patches 2 to 6 are code cleanup. No functionnal changes. Patches 7 to 13 fix problems detected by disk checking utilities in read-only mode. With these patches, vvfat creates valid FAT volumes and can be used with QEMU disk utilities. Read-write mode is still buggy after this patchset, but at least, I was not able to crash QEMU anymore. Note that patch 2 doesn't pass checkpatch.pl, as it changes indentation only. Hervé Changes v1->v2: - small changes following Kevin remarks (patches 3, 5, 6) - use g_utf8_* functions instead of ad-hock code (patches 8 and 9) - fix a bug with filenames starting with a dot (patch 9) Hervé Poussineau (13): vvfat: fix qemu-img map and qemu-img convert vvfat: replace tabs by 8 spaces vvfat: fix typos vvfat: rename useless enumeration values vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors vvfat: always create . and .. entries at first and in that order vvfat: correctly create long names for non-ASCII filenames vvfat: correctly create base short names for non-ASCII filenames vvfat: correctly generate numeric-tail of short file names vvfat: limit number of entries in root directory in FAT12/FAT16 vvfat: handle KANJI lead byte 0xe5 vvfat: change OEM name to 'MSWIN4.1' block/vvfat.c | 2306 ++--- 1 file changed, 1198 insertions(+), 1108 deletions(-) -- 2.11.0
[Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5
Specification: "FAT: General overview of on-disk format" v1.03, page 23 Signed-off-by: Hervé Poussineau --- block/vvfat.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 5376659010..53e8faa54c 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -590,6 +590,10 @@ static direntry_t *create_short_filename(BDRVVVFATState *s, } } +if (entry->name[0] == 0xe5) { +entry->name[0] = 0x05; +} + /* numeric-tail generation */ for (j = 0; j < 8; j++) { if (entry->name[j] == ' ') { @@ -710,8 +714,6 @@ static inline void init_fat(BDRVVVFATState* s) } -/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */ -/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, unsigned int directory_start, const char* filename, int is_dot) { @@ -1744,6 +1746,9 @@ static int parse_short_name(BDRVVVFATState* s, } else lfn->name[i + j + 1] = '\0'; +if (lfn->name[0] == 0x05) { +lfn->name[0] = 0xe5; +} lfn->len = strlen((char*)lfn->name); return 0; -- 2.11.0
[Qemu-devel] [PATCH] qemu-doc: Move the qemu-ga description into a separate chapter
The qemu-ga description is currently a subsection of the Disk Images chapter - which does not make much sense since the qemu-ga is not directly related to disk images. So let's move this information into a separate chapter instead. Signed-off-by: Thomas Huth --- qemu-doc.texi | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index b0bfd84..965ba59 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -34,6 +34,7 @@ * Introduction:: * QEMU PC System emulator:: * QEMU System emulator for non PC targets:: +* QEMU Guest Agent:: * QEMU User space emulator:: * Implementation notes:: * License:: @@ -396,7 +397,6 @@ snapshots. * vm_snapshots:: VM snapshots * qemu_img_invocation:: qemu-img Invocation * qemu_nbd_invocation:: qemu-nbd Invocation -* qemu_ga_invocation::qemu-ga Invocation * disk_images_formats:: Disk image file formats * host_drives:: Using host drives * disk_images_fat_images::Virtual FAT disk images @@ -490,11 +490,6 @@ state is not saved or restored properly (in particular USB). @include qemu-nbd.texi -@node qemu_ga_invocation -@subsection @code{qemu-ga} Invocation - -@include qemu-ga.texi - @node disk_images_formats @subsection Disk image file formats @@ -2685,6 +2680,12 @@ Note that this allows guest direct access to the host filesystem, so should only be used with trusted guest OS. @end table + +@node QEMU Guest Agent +@chapter QEMU Guest Agent invocation + +@include qemu-ga.texi + @node QEMU User space emulator @chapter QEMU User space emulator -- 1.8.3.1