[Qemu-devel] [PATCH v2 1/2] hw/arm: check fw_cfg return value before using it
The fw_cfg value returned from fw_cfg_find() may be NULL, so check it before using. Signed-off-by: Hongbo Zhang --- hw/arm/boot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index e09201c..43b217f 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -930,6 +930,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) hwaddr entry; static const ARMInsnFixup *primary_loader; AddressSpace *as = arm_boot_address_space(cpu, info); +FWCfgState *fw_cfg; /* CPU objects (unlike devices) are not automatically reset on system * reset, so we must always register a handler to do so. If we're @@ -960,11 +961,10 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) info->dtb_start = info->loader_start; } -if (info->kernel_filename) { -FWCfgState *fw_cfg; +fw_cfg = fw_cfg_find(); +if (info->kernel_filename && fw_cfg) { bool try_decompressing_kernel; -fw_cfg = fw_cfg_find(); try_decompressing_kernel = arm_feature(>env, ARM_FEATURE_AARCH64); -- 2.7.4
[Qemu-devel] [PATCH v2 2/2] hw/arm: Add Arm Enterprise machine type
For the Aarch64, there is one machine 'virt', it is primarily meant to run on KVM and execute virtualization workloads, but we need an environment as faithful as possible to physical hardware, for supporting firmware and OS development for pysical Aarch64 machines. This patch introduces new machine type 'Enterprise' with main features: - Based on 'virt' machine type. - Re-designed memory map. - EL2 and EL3 are enabled by default. - GIC version 3 by default. - AHCI controller attached to system bus, and then CDROM and hard disc can be added to it. - EHCI controller attached to system bus, with USB mouse and key board installed by default. - E1000E ethernet card on PCIE bus. - VGA display adaptor on PCIE bus. - Default CPU type cortex-a57, 4 cores, and 1G bytes memory. - No virtio functions enabled, since this is to emulate real hardware. - No paravirtualized fw_cfg device either. Arm Trusted Firmware and UEFI porting to this are done accordingly. Signed-off-by: Hongbo Zhang --- Changes since v1: - rebase on v3.0.0-rc0 - introduce another auxillary patch as 1/2, so this is 2/2 - rename 'sbsa' to 'enterprise' - remove paravirualized fw_cfg - set gic_vertion to 3 instead of 2 - edit commit message to describe purpose of this platform hw/arm/virt-acpi-build.c | 59 +- hw/arm/virt.c| 199 ++- include/hw/arm/virt.h| 3 + 3 files changed, 255 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 6ea47e2..212832e 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -84,6 +84,52 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, aml_append(scope, dev); } +static void acpi_dsdt_add_ahci(Aml *scope, const MemMapEntry *ahci_memmap, + uint32_t ahci_irq) +{ +Aml *dev = aml_device("AHC0"); +aml_append(dev, aml_name_decl("_HID", aml_string("LNRO001E"))); +aml_append(dev, aml_name_decl("_UID", aml_int(0))); +aml_append(dev, aml_name_decl("_CCA", aml_int(1))); + +Aml *crs = aml_resource_template(); +aml_append(crs, aml_memory32_fixed(ahci_memmap->base, + ahci_memmap->size, AML_READ_WRITE)); +aml_append(crs, + aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, _irq, 1)); +aml_append(dev, aml_name_decl("_CRS", crs)); + +Aml *pkg = aml_package(3); +aml_append(pkg, aml_int(0x1)); +aml_append(pkg, aml_int(0x6)); +aml_append(pkg, aml_int(0x1)); + +/* append the SATA class id */ +aml_append(dev, aml_name_decl("_CLS", pkg)); + +aml_append(scope, dev); +} + +static void acpi_dsdt_add_ehci(Aml *scope, const MemMapEntry *ehci_memmap, + uint32_t ehci_irq) +{ +Aml *dev = aml_device("EHC0"); +aml_append(dev, aml_name_decl("_HID", aml_string("PNP0D20"))); +aml_append(dev, aml_name_decl("_UID", aml_int(0))); +aml_append(dev, aml_name_decl("_CCA", aml_int(1))); + +Aml *crs = aml_resource_template(); +aml_append(crs, aml_memory32_fixed(ehci_memmap->base, + ehci_memmap->size, AML_READ_WRITE)); +aml_append(crs, + aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, _irq, 1)); +aml_append(dev, aml_name_decl("_CRS", crs)); + +aml_append(scope, dev); +} + static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap) { Aml *dev = aml_device("FWCF"); @@ -768,14 +814,23 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) (irqmap[VIRT_UART] + ARM_SPI_BASE)); acpi_dsdt_add_flash(scope, [VIRT_FLASH]); acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]); -acpi_dsdt_add_virtio(scope, [VIRT_MMIO], -(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS); +if (!vms->enterprise) { +acpi_dsdt_add_virtio(scope, [VIRT_MMIO], + (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS); +} acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE), vms->highmem, vms->highmem_ecam); acpi_dsdt_add_gpio(scope, [VIRT_GPIO], (irqmap[VIRT_GPIO] + ARM_SPI_BASE)); acpi_dsdt_add_power_button(scope); +if (vms->enterprise) { +acpi_dsdt_add_ahci(scope, [VIRT_AHCI], + (irqmap[VIRT_AHCI] + ARM_SPI_BASE)); +acpi_dsdt_add_ehci(scope, [VIRT_EHCI], + (irqmap[VIRT_EHCI] + ARM_SPI_BASE)); +} + aml_append(dsdt, scope); /* copy AML table into ACPI tables blob and patch header there */ diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 281ddcd..498b526 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -59,6 +59,10 @@
Re: [Qemu-devel] [RFC v3] qemu: Add virtio pmem device
Hi Eric, > > On 07/13/2018 02:52 AM, Pankaj Gupta wrote: > > This patch adds virtio-pmem Qemu device. > > > > This device presents memory address range information to guest > > which is backed by file backend type. It acts like persistent > > memory device for KVM guest. Guest can perform read and persistent > > write operations on this memory range with the help of DAX capable > > filesystem. > > > > Persistent guest writes are assured with the help of virtio based > > flushing interface. When guest userspace space performs fsync on > > file fd on pmem device, a flush command is send to Qemu over VIRTIO > > and host side flush/sync is done on backing image file. > > > > Changes from RFC v2: > > This patch has no n/M in the subject line; but is included in a thread > that also has a 0/2 cover letter, as well as 1/2 and 2/2 patches in > separate mails. Is that intentional? Yes, kernel series has 0-2 patches and Qemu has this one. I thought its good to keep separate numbering for both the sets. > > When sending revision notes on a specific patch, it's best to place them... Sure. > > > - Use aio_worker() to avoid Qemu from hanging with blocking fsync > >call - Stefan > > - Use virtio_st*_p() for endianess - Stefan > > - Correct indentation in qapi/misc.json - Eric > > > > Signed-off-by: Pankaj Gupta > > --- > > ...here, after the --- separator. They are useful to reviewers on the > list, but are stripped by 'git am' as they don't need to be part of the > git history (a year from now, we won't care how many iterations the > patch went through during review, only what actually landed). > > > > +++ b/qapi/misc.json > > @@ -2907,6 +2907,29 @@ > > } > > } > > > > +## > > +# @VirtioPMemDeviceInfo: > > +# > > +# VirtioPMem state information > > +# > > +# @id: device's ID > > +# > > +# @start: physical address, where device is mapped > > +# > > +# @size: size of memory that the device provides > > +# > > +# @memdev: memory backend linked with device > > +# > > +# Since: 2.13 > > There is no 2.13 release, and you've missed the 3.0 window. Please > update this and any other version reference to 3.1. okay. Thanks, Pankaj
[Qemu-devel] RDMA wrongly detected as being supported on FreeBSD
In commit 18a398f6a39df4b08ff86ac0d38384193ca5f4cc, ./configure on FreeBSD incorrectly detects RDMA support, with the build subsequently failing with: /home/bcran/workspace/qemu/hw/rdma/vmw/pvrdma_cmd.c:19:10: fatal error: 'linux/types.h' file not found #include ^~~ 1 error generated. gmake[1]: *** [/home/bcran/workspace/qemu/rules.mak:69: hw/rdma/vmw/pvrdma_cmd.o] Error 1 gmake[1]: *** Waiting for unfinished jobs gmake: *** [Makefile:481: subdir-x86_64-softmmu] Error 2 -- Rebecca Cran
Re: [Qemu-devel] [PATCH V10 10/20] qmp event: Add COLO_EXIT event to notify users while exited COLO
On Tue, Jul 24, 2018 at 10:54 PM, Dr. David Alan Gilbert < dgilb...@redhat.com> wrote: > * Zhang Chen (zhangc...@gmail.com) wrote: > > On Tue, Jul 24, 2018 at 2:41 AM, Eric Blake wrote: > > > > > On 07/22/2018 02:33 PM, Zhang Chen wrote: > > > > > >> From: zhanghailiang > > >> > > >> If some errors happen during VM's COLO FT stage, it's important to > > >> notify the users of this event. Together with 'x-colo-lost-heartbeat', > > >> Users can intervene in COLO's failover work immediately. > > >> If users don't want to get involved in COLO's failover verdict, > > >> it is still necessary to notify users that we exited COLO mode. > > >> > > >> Signed-off-by: zhanghailiang > > >> Signed-off-by: Li Zhijian > > >> Signed-off-by: Zhang Chen > > >> Reviewed-by: Eric Blake > > >> Reviewed-by: Markus Armbruster > > >> --- > > >> migration/colo.c| 31 +++ > > >> qapi/migration.json | 38 ++ > > >> 2 files changed, 69 insertions(+) > > >> > > > > > > At this point in the release cycle, this series feels like enough of a > new > > > feature (rather than a bug fix) that it is probably not appropriate for > > > 3.0, which means... > > > > > > > > > +++ b/qapi/migration.json > > >> @@ -900,6 +900,44 @@ > > >> { 'enum': 'FailoverStatus', > > >> 'data': [ 'none', 'require', 'active', 'completed', 'relaunch' ] } > > >> +## > > >> +# @COLO_EXIT: > > >> +# > > >> +# Emitted when VM finishes COLO mode due to some errors happening or > > >> +# at the request of users. > > >> +# > > >> +# @mode: report COLO mode when COLO exited. > > >> +# > > >> +# @reason: describes the reason for the COLO exit. > > >> +# > > >> +# Since: 3.0 > > >> > > > > > > ...this and other references should be updated to 3.1. > > > > > > OK, I will fix it and resend this series. > > No need to resend now; resend after the review of the other bits in the > series; I'm sure there will be other minor things; anyway we can always > fix up version nunmbers in merge. > OK, I got it. Thanks Zhang Chen > > Dave > > > Thanks > > Zhang Chen > > > > > > > > > > > > > -- > > > Eric Blake, Principal Software Engineer > > > Red Hat, Inc. +1-919-301-3266 > > > Virtualization: qemu.org | libvirt.org > > > > -- > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK >
[Qemu-devel] When is PCIUnregisterFunc called?
Hi QEMU developers, I'm trying to inject some operations during the emulated device teardown phase. For an emulated PCIe device, such as NVMe or IVSHMEM, I notice that QEMU registers PCIDeviceClass pc->init and pc->exit functions for that device. ->init() (e.g. nvme_init(), or ivshmem_init()) are marked as constructors and called before QEMU main() runs. However, I failed to find when the ->exit() function is called. When I add some printf() into the ->exit() func, it's not even printed. Could anyone give any pointers on this? Thanks. Best, Huaicheng
[Qemu-devel] [Bug 1783422] Re: qemu_clock_get_ns does not take into account icount_time_shift
Actually implementing this fix causes a linux boot to crash. So there may be something more to this. I will investigate more. [ 892.294463] BUG: soft lockup - CPU#0 stuck for 347s! [swapper/0:1] [ 892.490416] Modules linked in: [ 892.635725] [ 892.790816] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.16.0-6-armmp-lpae #1 Debian 3.16.56-1+deb8u1 [ 893.098786] task: ee059640 ti: ee05a000 task.ti: ee05a000 [ 893.322395] PC is at vprintk_emit+0x2c8/0x650 [ 893.525852] LR is at console_unlock+0x234/0x4dc [ 893.749395] pc : []lr : []psr: 6153 [ 893.749395] sp : ee05bdc8 ip : ee05bd70 fp : ee05be2c [ 894.117789] r10: 0001 r9 : r8 : 0006 [ 894.329454] r7 : r6 : 0028 r5 : c0a3dd98 r4 : c0a3dd98 [ 894.571266] r3 : c09b44cc r2 : 6153 r1 : 6153 r0 : c0a3dd98 [ 894.807621] Flags: nZCv IRQs on FIQs off Mode SVC_32 ISA ARM Segment kernel [ 895.089213] Control: 30c7387d Table: 40003000 DAC: fffd [ 895.329468] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.16.0-6-armmp-lpae #1 Debian 3.16.56-1+deb8u1 [ 895.720505] [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [ 896.065798] [] (show_stack) from [] (dump_stack+0x9c/0xb0) [ 896.393691] [] (dump_stack) from [] (show_regs+0x30/0x34) [ 896.713637] [] (show_regs) from [] (watchdog_timer_fn+0x18c/0x1e4) [ 897.062977] [] (watchdog_timer_fn) from [] (__run_hrtimer+0x88/0x2a8) [ 897.412317] [] (__run_hrtimer) from [] (hrtimer_run_queues+0xc0/0x1a4) [ 897.785790] [] (hrtimer_run_queues) from [] (update_process_times+0x3c/0x70) [ 898.169815] [] (update_process_times) from [] (tick_periodic+0x4c/0xcc) [ 898.532622] [] (tick_periodic) from [] (tick_handle_periodic+0x94/0x98) [ 898.895806] [] (tick_handle_periodic) from [] (arch_timer_handler_virt+0x38/0x40) [ 899.292479] [] (arch_timer_handler_virt) from [] (handle_percpu_devid_irq+0x80/0x194) [ 899.702210] [] (handle_percpu_devid_irq) from [] (generic_handle_irq+0x3c/0x4c) [ 900.082647] [] (generic_handle_irq) from [] (handle_IRQ+0x50/0xa0) [ 900.427431] [] (handle_IRQ) from [] (gic_handle_irq+0x3c/0x70) [ 900.767678] [] (gic_handle_irq) from [] (__irq_svc+0x40/0x54) [ 901.037948] Exception stack(0xee05bd80 to 0xee05bdc8) [ 901.317607] bd80: c0a3dd98 6153 6153 c09b44cc c0a3dd98 c0a3dd98 0028 [ 901.677252] bda0: 0006 0001 ee05be2c ee05bd70 ee05bdc8 c00bd7a8 c00bdd18 [ 901.970690] bdc0: 6153 [ 902.218760] [] (__irq_svc) from [] (vprintk_emit+0x2c8/0x650) [ 902.571360] [] (vprintk_emit) from [] (printk+0x44/0x4c) [ 902.916079] [] (printk) from [] (__clocksource_select+0x12c/0x170) [ 903.290503] [] (__clocksource_select) from [] (clocksource_done_booting+0x38/0x4c) [ 903.671545] [] (clocksource_done_booting) from [] (do_one_initcall+0xf0/0x234) [ 904.050606] [] (do_one_initcall) from [] (kernel_init_freeable+0x1c8/0x268) [ 904.433926] [] (kernel_init_freeable) from [] (kernel_init+0x1c/0x100) [ 904.797782] [] (kernel_init) from [] (ret_from_fork+0x14/0x20) ** Changed in: ubuntu Status: New => Incomplete -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1783422 Title: qemu_clock_get_ns does not take into account icount_time_shift Status in QEMU: Incomplete Bug description: Hello, If you check the qemu/util/qemu-timer.c you will find the following function: 597: int64_t qemu_clock_get_ns(QEMUClockType type) 598: { 602:switch (type) { 606:case QEMU_CLOCK_VIRTUAL: 607:if (use_icount) { 608:return cpu_get_icount(); Now on line 606, in case we requested QEMU_CLOCK_VIRTUAL, and we are using icount, the value of cpu_get_icount(); will be returned. However if I understand correctly, in order to convert icount to ns, you must use take into account the icount shift -- as defined in the documentation: "The virtual cpu will execute one instruction every 2^N ns of virtual time.". Therefor, the correct value to return would be cpu_icount_to_ns(cpu_get_icount()), where cpu_icount_to_ns is defined in cpus.c: 296: int64_t cpu_icount_to_ns(int64_t icount) 297: { 298:return icount << icount_time_shift; 299: } Best Regards, Humberto "SilverOne" Carvalho To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1783422/+subscriptions
[Qemu-devel] [Bug 1783422] [NEW] qemu_clock_get_ns does not take into account icount_time_shift
Public bug reported: Hello, If you check the qemu/util/qemu-timer.c you will find the following function: 597: int64_t qemu_clock_get_ns(QEMUClockType type) 598: { 602:switch (type) { 606:case QEMU_CLOCK_VIRTUAL: 607:if (use_icount) { 608:return cpu_get_icount(); Now on line 606, in case we requested QEMU_CLOCK_VIRTUAL, and we are using icount, the value of cpu_get_icount(); will be returned. However if I understand correctly, in order to convert icount to ns, you must use take into account the icount shift -- as defined in the documentation: "The virtual cpu will execute one instruction every 2^N ns of virtual time.". Therefor, the correct value to return would be cpu_icount_to_ns(cpu_get_icount()), where cpu_icount_to_ns is defined in cpus.c: 296: int64_t cpu_icount_to_ns(int64_t icount) 297: { 298:return icount << icount_time_shift; 299: } Best Regards, Humberto "SilverOne" Carvalho ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1783422 Title: qemu_clock_get_ns does not take into account icount_time_shift Status in QEMU: New Bug description: Hello, If you check the qemu/util/qemu-timer.c you will find the following function: 597: int64_t qemu_clock_get_ns(QEMUClockType type) 598: { 602:switch (type) { 606:case QEMU_CLOCK_VIRTUAL: 607:if (use_icount) { 608:return cpu_get_icount(); Now on line 606, in case we requested QEMU_CLOCK_VIRTUAL, and we are using icount, the value of cpu_get_icount(); will be returned. However if I understand correctly, in order to convert icount to ns, you must use take into account the icount shift -- as defined in the documentation: "The virtual cpu will execute one instruction every 2^N ns of virtual time.". Therefor, the correct value to return would be cpu_icount_to_ns(cpu_get_icount()), where cpu_icount_to_ns is defined in cpus.c: 296: int64_t cpu_icount_to_ns(int64_t icount) 297: { 298:return icount << icount_time_shift; 299: } Best Regards, Humberto "SilverOne" Carvalho To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1783422/+subscriptions
[Qemu-devel] [Bug 1783437] [NEW] read-modify-write page faults error code has write bit unset
Public bug reported: Consider the attached C file, which does a read-modify-write of the form `add [mem], reg`, where `mem` points to a non-present page. In the resulting page fault, the W/R bit is not set, while real hardware does set this bit. % gcc -m32 qemu-bug1.c&& ./a.out && qemu-i386 ./a.out page fault: addr=0x7000 err=0x6 page fault: addr=0x7000 err=0x4 Tested on the qemu-3.0.0-rc1 release. ** Affects: qemu Importance: Undecided Status: New ** Attachment added: "qemu-bug1.c" https://bugs.launchpad.net/bugs/1783437/+attachment/5167345/+files/qemu-bug1.c -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1783437 Title: read-modify-write page faults error code has write bit unset Status in QEMU: New Bug description: Consider the attached C file, which does a read-modify-write of the form `add [mem], reg`, where `mem` points to a non-present page. In the resulting page fault, the W/R bit is not set, while real hardware does set this bit. % gcc -m32 qemu-bug1.c&& ./a.out && qemu-i386 ./a.out page fault: addr=0x7000 err=0x6 page fault: addr=0x7000 err=0x4 Tested on the qemu-3.0.0-rc1 release. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1783437/+subscriptions
[Qemu-devel] [Bug 1783422] [NEW] qemu_clock_get_ns does not take into account icount_time_shift
You have been subscribed to a public bug: Hello, If you check the qemu/util/qemu-timer.c you will find the following function: 597: int64_t qemu_clock_get_ns(QEMUClockType type) 598: { 602:switch (type) { 606:case QEMU_CLOCK_VIRTUAL: 607:if (use_icount) { 608:return cpu_get_icount(); Now on line 606, in case we requested QEMU_CLOCK_VIRTUAL, and we are using icount, the value of cpu_get_icount(); will be returned. However if I understand correctly, in order to convert icount to ns, you must use take into account the icount shift -- as defined in the documentation: "The virtual cpu will execute one instruction every 2^N ns of virtual time.". Therefor, the correct value to return would be cpu_icount_to_ns(cpu_get_icount()), where cpu_icount_to_ns is defined in cpus.c: 296: int64_t cpu_icount_to_ns(int64_t icount) 297: { 298:return icount << icount_time_shift; 299: } Best Regards, Humberto "SilverOne" Carvalho ** Affects: qemu Importance: Undecided Status: Incomplete -- qemu_clock_get_ns does not take into account icount_time_shift https://bugs.launchpad.net/bugs/1783422 You received this bug notification because you are a member of qemu-devel-ml, which is subscribed to QEMU.
Re: [Qemu-devel] [PATCH v4 0/4] Introduction of l2-cache-full option for qcow2 images
Thanks for the review and for the comments, Eric! One quick remark: I do usually leave blank lines around inline replies, but this time Thunderbird made it look as if there are blank lines when I was writing, when apparently there were not. :] Leonid. On 07/25/2018 01:44 AM, Eric Blake wrote: On 07/24/2018 05:20 PM, Leonid Bloch wrote: meta-comment: a hint for more effective emails below - Differences from v2: 1) A separate patch for the grammar fix for 3.0 2) A separate patch for existing documentation fixes for 3.0 3) Separated back the iotests patch, because the grammar fix is separate now - Differences from v2: * from v3 1) Grammar change commit message fix Visually, it's hard to pick out an inline reply prefixed with "*" amid a bunch of lines prefixed with ">", with no other hinting. (Actually, I'm finding it easier to read your email in my reply window, where thunderbird chose to use ">>" for double-quoted lines vs. "> *" for the single quoted line, which has a distinct whitespace change in column 2 that the original email window did not. But then again, I've been bitten by Thunderbird displaying quoting differently to me than it renders to the end recipient, so I don't know if "> *" will still have a space by the time you see this reply of mine). I find that it is much more legible to always include a blank line around both ends of any text I type, as the eye is much quicker at picking out the absence of any character in column 1 than it is on deciphering which marks in column 1 serve as the indicator of transitions between quoted vs. new content in the thread. 2) Rewording the documentation more concisely 3) Squashing the l2-cache-full docs commit to the one that introduces this feature Also, when replying to an archived list, it's okay to trim quoted text down to just the context relevant to the reply, to let the reader quickly reach the new content, rather than preserving the entire original email and forcing the reader to scroll through a wall of text just to locate the added thoughts. (Yes, some mail clients do a better job of coloring quoted text differently, and/or collapsing quoted material, so that not every reader has to scroll, but not everyone agrees on the ideal mail client). This email wasn't too bad, but you'll find instances of me making these same metacomments on other emails over the years if you search the archives :) Finally, thanks for contributing, and for your rapid turnaround incorporating suggestions from my earlier reviews! I know that sometimes when I make observations about making the review process more efficient for everyone involved, it makes me come across as a curmudgeonly old miser. In my efforts to be terse, I often forget to also be human and compliment contributors for making an effort in the first place, regardless of whether future efforts can be made even more efficient.
Re: [Qemu-devel] [PATCH v4 0/4] Introduction of l2-cache-full option for qcow2 images
On 07/24/2018 05:20 PM, Leonid Bloch wrote: meta-comment: a hint for more effective emails below - Differences from v2: 1) A separate patch for the grammar fix for 3.0 2) A separate patch for existing documentation fixes for 3.0 3) Separated back the iotests patch, because the grammar fix is separate now - Differences from v2: * from v3 1) Grammar change commit message fix Visually, it's hard to pick out an inline reply prefixed with "*" amid a bunch of lines prefixed with ">", with no other hinting. (Actually, I'm finding it easier to read your email in my reply window, where thunderbird chose to use ">>" for double-quoted lines vs. "> *" for the single quoted line, which has a distinct whitespace change in column 2 that the original email window did not. But then again, I've been bitten by Thunderbird displaying quoting differently to me than it renders to the end recipient, so I don't know if "> *" will still have a space by the time you see this reply of mine). I find that it is much more legible to always include a blank line around both ends of any text I type, as the eye is much quicker at picking out the absence of any character in column 1 than it is on deciphering which marks in column 1 serve as the indicator of transitions between quoted vs. new content in the thread. 2) Rewording the documentation more concisely 3) Squashing the l2-cache-full docs commit to the one that introduces this feature Also, when replying to an archived list, it's okay to trim quoted text down to just the context relevant to the reply, to let the reader quickly reach the new content, rather than preserving the entire original email and forcing the reader to scroll through a wall of text just to locate the added thoughts. (Yes, some mail clients do a better job of coloring quoted text differently, and/or collapsing quoted material, so that not every reader has to scroll, but not everyone agrees on the ideal mail client). This email wasn't too bad, but you'll find instances of me making these same metacomments on other emails over the years if you search the archives :) Finally, thanks for contributing, and for your rapid turnaround incorporating suggestions from my earlier reviews! I know that sometimes when I make observations about making the review process more efficient for everyone involved, it makes me come across as a curmudgeonly old miser. In my efforts to be terse, I often forget to also be human and compliment contributors for making an effort in the first place, regardless of whether future efforts can be made even more efficient. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [Qemu-devel] [PATCH v4 0/4] Introduction of l2-cache-full option for qcow2 images
On 07/25/2018 01:17 AM, Leonid Bloch wrote: This series introduces an option to calculate and allocate automatically enough qcow2 L2 cache to cover the entire image. Using cache that covers the entire image can benefit performance, while having only a small memory overhead (just 1 MB for every 8 GB of virtual image size with the default cluster size). - Differences from v1: 1) Documentation fixes in qapi/block-core.json and qemu-options.hx 2) Removal of the patch which was made to fix the default sizes in docs/qcow2-cache.txt - it is not needed, as the default sizes imply also default cluster sizes. 3) Documentation fixes in docs/qcow2-cache.txt, mentioning mutual exclusivity of the options. 4) Squashing the iotests patch into the main feature addition patch - Differences from v2: 1) A separate patch for the grammar fix for 3.0 2) A separate patch for existing documentation fixes for 3.0 3) Separated back the iotests patch, because the grammar fix is separate now - Differences from v2: * from v3 1) Grammar change commit message fix 2) Rewording the documentation more concisely 3) Squashing the l2-cache-full docs commit to the one that introduces this feature Leonid Bloch (4): qcow2: A grammar fix in conflicting cache sizing error message qcow2: Options' documentation fixes qcow2: Introduce an option for sufficient L2 cache for the entire image iotests: Add tests for the new l2-cache-full option block/qcow2.c | 37 + block/qcow2.h | 1 + docs/qcow2-cache.txt | 18 ++ qapi/block-core.json | 8 +++- qemu-options.hx| 14 ++ tests/qemu-iotests/103 | 6 ++ tests/qemu-iotests/103.out | 4 +++- tests/qemu-iotests/137 | 2 ++ tests/qemu-iotests/137.out | 4 +++- 9 files changed, 75 insertions(+), 19 deletions(-)
[Qemu-devel] [PATCH v4 2/4 for-3.0] qcow2: Options' documentation fixes
Signed-off-by: Leonid Bloch --- docs/qcow2-cache.txt | 3 +++ qemu-options.hx | 10 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt index 8a09a5cc5f..3673f2be0e 100644 --- a/docs/qcow2-cache.txt +++ b/docs/qcow2-cache.txt @@ -130,6 +130,9 @@ There are a few things that need to be taken into account: memory as possible to the L2 cache before increasing the refcount cache size. +- At most two of "l2-cache-size", "refcount-cache-size", and "cache-size" + can be set simultaneously. + Unlike L2 tables, refcount blocks are not used during normal I/O but only during allocations and internal snapshots. In most cases they are accessed sequentially (even during random guest I/O) so increasing the diff --git a/qemu-options.hx b/qemu-options.hx index b1bf0f485f..13ece21cb6 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -752,15 +752,17 @@ image file) @item cache-size The maximum total size of the L2 table and refcount block caches in bytes -(default: 1048576 bytes or 8 clusters, whichever is larger) @item l2-cache-size -The maximum size of the L2 table cache in bytes -(default: 4/5 of the total cache size) +The maximum size of the L2 table cache. +(default: if cache-size is not defined - 1048576 bytes or 8 clusters, whichever +is larger; otherwise, as large as possible or needed within the cache-size, +while permitting the requested or the minimal refcount cache size) @item refcount-cache-size The maximum size of the refcount block cache in bytes -(default: 1/5 of the total cache size) +(default: 4 times the cluster size, or any portion of the cache-size, if it is +specified and large enough, left over after allocating the full L2 cache) @item cache-clean-interval Clean unused entries in the L2 and refcount caches. The interval is in seconds. -- 2.14.1
[Qemu-devel] [PATCH v4 3/4] qcow2: Introduce an option for sufficient L2 cache for the entire image
An option "l2-cache-full" is introduced to automatically set the qcow2 L2 cache to a sufficient value for covering the entire image. The memory overhead when using this option is not big (1 MB for each 8 GB of virtual image size with the default cluster size) and it can noticeably improve performance when using large images with frequent I/O. Previously, for this functionality the correct L2 cache size needed to be calculated manually or with a script, and then this size needed to be passed to the "l2-cache-size" option. Now it is sufficient to just pass the boolean "l2-cache-full" option. Signed-off-by: Leonid Bloch --- block/qcow2.c| 35 --- block/qcow2.h| 1 + docs/qcow2-cache.txt | 15 +++ qapi/block-core.json | 8 +++- qemu-options.hx | 6 +- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index ec9e6238a0..101b8b474b 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -695,6 +695,11 @@ static QemuOptsList qcow2_runtime_opts = { .type = QEMU_OPT_SIZE, .help = "Maximum L2 table cache size", }, +{ +.name = QCOW2_OPT_L2_CACHE_FULL, +.type = QEMU_OPT_BOOL, +.help = "Create full coverage of the image with the L2 cache", +}, { .name = QCOW2_OPT_L2_CACHE_ENTRY_SIZE, .type = QEMU_OPT_SIZE, @@ -779,10 +784,12 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, BDRVQcow2State *s = bs->opaque; uint64_t combined_cache_size; bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set; +bool l2_cache_full_set; int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE); l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE); +l2_cache_full_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_FULL); refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE); combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0); @@ -793,6 +800,17 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, *l2_cache_entry_size = qemu_opt_get_size( opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE, s->cluster_size); +uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; +uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); + +if (l2_cache_size_set && l2_cache_full_set) { +error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " and " + QCOW2_OPT_L2_CACHE_FULL " may not be set at the same time"); +return; +} else if (l2_cache_full_set) { +*l2_cache_size = max_l2_cache; +} + if (combined_cache_size_set) { if (l2_cache_size_set && refcount_cache_size_set) { error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE @@ -800,8 +818,14 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, "at the same time"); return; } else if (*l2_cache_size > combined_cache_size) { -error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " - QCOW2_OPT_CACHE_SIZE); +if (l2_cache_full_set) { +error_setg(errp, QCOW2_OPT_CACHE_SIZE " must be greater than " + "the full L2 cache if " QCOW2_OPT_L2_CACHE_FULL + " is used"); +} else { +error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " + QCOW2_OPT_CACHE_SIZE); +} return; } else if (*refcount_cache_size > combined_cache_size) { error_setg(errp, QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not exceed " @@ -809,14 +833,11 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, return; } -if (l2_cache_size_set) { +if (l2_cache_size_set || l2_cache_full_set) { *refcount_cache_size = combined_cache_size - *l2_cache_size; } else if (refcount_cache_size_set) { *l2_cache_size = combined_cache_size - *refcount_cache_size; } else { -uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; -uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); - /* Assign as much memory as possible to the L2 cache, and * use the remainder for the refcount cache */ if (combined_cache_size >= max_l2_cache + min_refcount_cache) { @@ -829,7 +850,7 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, } } } else { -if (!l2_cache_size_set) { +if (!l2_cache_size_set && !l2_cache_full_set) { *l2_cache_size = MAX(DEFAULT_L2_CACHE_BYTE_SIZE,
[Qemu-devel] [PATCH v4 4/4] iotests: Add tests for the new l2-cache-full option
Signed-off-by: Leonid Bloch --- tests/qemu-iotests/103 | 6 ++ tests/qemu-iotests/103.out | 2 ++ tests/qemu-iotests/137 | 2 ++ tests/qemu-iotests/137.out | 2 ++ 4 files changed, 12 insertions(+) diff --git a/tests/qemu-iotests/103 b/tests/qemu-iotests/103 index 2841318492..a2886e8569 100755 --- a/tests/qemu-iotests/103 +++ b/tests/qemu-iotests/103 @@ -52,9 +52,15 @@ echo echo '=== Testing invalid option combinations ===' echo +# l2-cache-size and l2-cache-full at the same time +$QEMU_IO -c "open -o l2-cache-full,l2-cache-size=1M $TEST_IMG" 2>&1 | +_filter_testdir | _filter_imgfmt # all sizes set at the same time $QEMU_IO -c "open -o cache-size=1.25M,l2-cache-size=1M,refcount-cache-size=0.25M $TEST_IMG" \ 2>&1 | _filter_testdir | _filter_imgfmt +# cache-size may not be smaller than the full L2 size if l2-cache-full is used +$QEMU_IO -c "open -o l2-cache-full,cache-size=6K $TEST_IMG" 2>&1 | +_filter_testdir | _filter_imgfmt # l2-cache-size may not exceed cache-size $QEMU_IO -c "open -o cache-size=1M,l2-cache-size=2M $TEST_IMG" 2>&1 \ | _filter_testdir | _filter_imgfmt diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out index ab56f03a00..92afbff024 100644 --- a/tests/qemu-iotests/103.out +++ b/tests/qemu-iotests/103.out @@ -5,7 +5,9 @@ wrote 65536/65536 bytes at offset 0 === Testing invalid option combinations === +can't open device TEST_DIR/t.IMGFMT: l2-cache-full and l2-cache-size may not be set at the same time can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time +can't open device TEST_DIR/t.IMGFMT: cache-size must be greater than the full L2 cache if l2-cache-full is used can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137 index 87965625d8..f460b5bfe1 100755 --- a/tests/qemu-iotests/137 +++ b/tests/qemu-iotests/137 @@ -106,7 +106,9 @@ echo $QEMU_IO \ -c "reopen -o lazy-refcounts=42" \ +-c "reopen -o l2-cache-full,l2-cache-size=64k" \ -c "reopen -o cache-size=1M,l2-cache-size=64k,refcount-cache-size=64k" \ +-c "reopen -o l2-cache-full,cache-size=6K" \ -c "reopen -o cache-size=1M,l2-cache-size=2M" \ -c "reopen -o cache-size=1M,refcount-cache-size=2M" \ -c "reopen -o l2-cache-size=256T" \ diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out index 6a2ffc71fd..b15dfc391a 100644 --- a/tests/qemu-iotests/137.out +++ b/tests/qemu-iotests/137.out @@ -16,7 +16,9 @@ read 33554432/33554432 bytes at offset 0 === Try setting some invalid values === Parameter 'lazy-refcounts' expects 'on' or 'off' +l2-cache-full and l2-cache-size may not be set at the same time cache-size, l2-cache-size and refcount-cache-size may not be set at the same time +cache-size must be greater than the full L2 cache if l2-cache-full is used l2-cache-size may not exceed cache-size refcount-cache-size may not exceed cache-size L2 cache size too big -- 2.14.1
[Qemu-devel] [PATCH v4 1/4 for-3.0] qcow2: A grammar fix in conflicting cache sizing error message
Signed-off-by: Leonid Bloch --- block/qcow2.c | 2 +- tests/qemu-iotests/103.out | 2 +- tests/qemu-iotests/137.out | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 6162ed8be2..ec9e6238a0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -797,7 +797,7 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, if (l2_cache_size_set && refcount_cache_size_set) { error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE " and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set " - "the same time"); + "at the same time"); return; } else if (*l2_cache_size > combined_cache_size) { error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out index bd45d3875a..ab56f03a00 100644 --- a/tests/qemu-iotests/103.out +++ b/tests/qemu-iotests/103.out @@ -5,7 +5,7 @@ wrote 65536/65536 bytes at offset 0 === Testing invalid option combinations === -can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time +can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out index 96724a6c33..6a2ffc71fd 100644 --- a/tests/qemu-iotests/137.out +++ b/tests/qemu-iotests/137.out @@ -16,7 +16,7 @@ read 33554432/33554432 bytes at offset 0 === Try setting some invalid values === Parameter 'lazy-refcounts' expects 'on' or 'off' -cache-size, l2-cache-size and refcount-cache-size may not be set the same time +cache-size, l2-cache-size and refcount-cache-size may not be set at the same time l2-cache-size may not exceed cache-size refcount-cache-size may not exceed cache-size L2 cache size too big -- 2.14.1
[Qemu-devel] [PATCH v4 0/4] Introduction of l2-cache-full option for qcow2 images
This series introduces an option to calculate and allocate automatically enough qcow2 L2 cache to cover the entire image. Using cache that covers the entire image can benefit performance, while having only a small memory overhead (just 1 MB for every 8 GB of virtual image size with the default cluster size). - Differences from v1: 1) Documentation fixes in qapi/block-core.json and qemu-options.hx 2) Removal of the patch which was made to fix the default sizes in docs/qcow2-cache.txt - it is not needed, as the default sizes imply also default cluster sizes. 3) Documentation fixes in docs/qcow2-cache.txt, mentioning mutual exclusivity of the options. 4) Squashing the iotests patch into the main feature addition patch - Differences from v2: 1) A separate patch for the grammar fix for 3.0 2) A separate patch for existing documentation fixes for 3.0 3) Separated back the iotests patch, because the grammar fix is separate now - Differences from v2: 1) Grammar change commit message fix 2) Rewording the documentation more concisely 3) Squashing the l2-cache-full docs commit to the one that introduces this feature Leonid Bloch (4): qcow2: A grammar fix in conflicting cache sizing error message qcow2: Options' documentation fixes qcow2: Introduce an option for sufficient L2 cache for the entire image iotests: Add tests for the new l2-cache-full option block/qcow2.c | 37 + block/qcow2.h | 1 + docs/qcow2-cache.txt | 18 ++ qapi/block-core.json | 8 +++- qemu-options.hx| 14 ++ tests/qemu-iotests/103 | 6 ++ tests/qemu-iotests/103.out | 4 +++- tests/qemu-iotests/137 | 2 ++ tests/qemu-iotests/137.out | 4 +++- 9 files changed, 75 insertions(+), 19 deletions(-) -- 2.14.1
Re: [Qemu-devel] qemu-system-ppc -M mac99 and -soundhw es1370 doesn't start
On 23/07/18 00:06, Andrew Randrianasulu wrote: Hello! Currently I'm trying pre-releases of qemu, for avoiding situation when release was too bugged (2.12, for my taste ..qemu-system-alpha was broken, qemu-system-x86_64 -M q35 was broken ..) using qemu-system-ppc --version QEMU emulator version 2.12.91 (v3.0.0-rc1-17-g5b3ecd3d94-dirty) Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers I can't start qemu-system-ppc with -M mac99 and -soundhw es1370: I'm actually surprised that this could ever work at all, since -soundhw is a legacy PC option and certainly isn't included in regular testing of the PPC Mac machines. The confusion comes from the fact that the mac99 machine has multiple PCI buses, and my guess is that recent fixes the 3.0 dev cycle could have broken an assumption in the old option code. In theory you should be able to get the correct configuration with something like this: ./qemu-system-ppc -monitor stdio -device ES1370 -M mac99 But I'm afraid this configuration is effectively unsupported. qemu-system-ppc -monitor stdio -soundhw es1370 -vga std -M mac99 QEMU 2.12.91 monitor - type 'help' for more information (qemu) qemu-system-ppc: PCI bus not available for es1370 qemu-system-ppc64 starts fine: emu-system-ppc64 -monitor stdio -soundhw es1370 -vga std -M mac99 QEMU 2.12.91 monitor - type 'help' for more information (qemu) info pci Bus 0, device 11, function 0: Host bridge: PCI device 106b:004b id "" Bus 0, device 12, function 0: Class 65280: PCI device 106b:0022 BAR0: 32 bit memory at 0x8000 [0x8007]. id "" Bus 0, device 13, function 0: USB controller: PCI device 106b:003f IRQ 28. BAR0: 32 bit memory at 0x8008 [0x800800ff]. id "" Bus 0, device 14, function 0: VGA controller: PCI device 1234: BAR0: 32 bit prefetchable memory at 0x8100 [0x81ff]. BAR2: 32 bit memory at 0x8200 [0x82000fff]. BAR6: 32 bit memory at 0x8201 [0x8201]. id "" Bus 0, device 15, function 0: Ethernet controller: PCI device 10ec:8029 IRQ 30. BAR0: I/O at 0x1000 [0x10ff]. BAR6: 32 bit memory at 0x8204 [0x8207]. id "" Bus 0, device 16, function 0: Audio controller: PCI device 1274:5000 IRQ 27. BAR0: I/O at 0x1100 [0x11ff]. id "" (qemu) Note, I'm using 32-bit qemu build, configured like this: setarch i486 ./configure --prefix=/usr --disable-gtk --enable-virglrenderer --enable-sdl \ --with-sdlabi=2.0 --audio-drv-list=alsa,oss --host-cc=/opt/gcc49/bin/gcc \ --enable-opengl --extra-cflags="-I/usr/X11R7/include -O3 -march=i686 \ -mtune=native -m32 -Wno-maybe-uninitialized -Wno-nested-externs \ -Wno-implicit-function-declaration" --disable-werror for qemu-system-ppc -M mac99 'info pci' shows: qemu-system-ppc -monitor stdio -vga std -M mac99 QEMU 2.12.91 monitor - type 'help' for more information (qemu) info pci Bus 0, device 11, function 0: Host bridge: PCI device 106b:001f id "" Bus 0, device 12, function 0: Class 65280: PCI device 106b:0022 BAR0: 32 bit memory at 0x8000 [0x8007]. id "" Bus 0, device 13, function 0: USB controller: PCI device 106b:003f IRQ 28. BAR0: 32 bit memory at 0x8008 [0x800800ff]. id "" Bus 0, device 14, function 0: VGA controller: PCI device 1234: BAR0: 32 bit prefetchable memory at 0x8100 [0x81ff]. BAR2: 32 bit memory at 0x8200 [0x82000fff]. BAR6: 32 bit memory at 0x8201 [0x8201]. id "" Bus 0, device 15, function 0: Ethernet controller: PCI device 10ec:8029 IRQ 30. BAR0: I/O at 0x1000 [0x10ff]. BAR6: 32 bit memory at 0x8204 [0x8207]. id "" Bus 0, device 14, function 0: Host bridge: PCI device 106b:001e id "" Bus 0, device 11, function 0: Host bridge: PCI device 106b:0020 id "" (qemu) Last two devices seems strange . Also, mouse seems to be confused, try finnix-ppc-110.iso (it enables gpm on startup, start like qemu-system-ppc -monitor stdio -M mac99 -cdrom ~/finnix-ppc-110.iso and try to move mouse inside qemu window. It feels like keyboard got some mouseclicks too? or mouse movement generates mouse button clicks, too) or http://cdimage.ubuntu.com/lubuntu/releases/16.04/release/ -> [ ] lubuntu-16.04-desktop-powerpc.iso (but you must wait for nearly 10 min until it finishes booting) Is this a regression? Certainly it's not an image that is part of my regular test suite. And what is your host platform? Does a 64-bit build make any difference? What about using GTK and/or VNC instead of SDL? Does disabling the sound hardware change the responsiveness? ATB, Mark.
[Qemu-devel] [ANNOUNCE] QEMU 3.0.0-rc2 is now available
Hello, On behalf of the QEMU Team, I'd like to announce the availability of the third release candidate for the QEMU 3.0 release. This release is meant for testing purposes and should not be used in a production environment. http://download.qemu-project.org/qemu-3.0.0-rc2.tar.xz http://download.qemu-project.org/qemu-3.0.0-rc2.tar.xz.sig You can help improve the quality of the QEMU 3.0 release by testing this release and reporting bugs on Launchpad: https://bugs.launchpad.net/qemu/ The release plan, as well a documented known issues for release candidates, are available at: http://wiki.qemu.org/Planning/3.0 Please add entries to the ChangeLog for the 3.0 release below: http://wiki.qemu.org/ChangeLog/3.0 Thank you to everyone involved! Changes since rc1: 18a398f6a3: Update version for v3.0.0-rc2 release (Peter Maydell) db0a8c70f2: tests: fix TLS handshake failure with TLS 1.3 (Daniel P. Berrangé) 68db13183f: tests: use error_abort in places expecting errors (Daniel P. Berrangé) 977a7204ab: tests: don't silence error reporting for all tests (Daniel P. Berrangé) dbddad7026: tests: call qcrypto_init instead of gnutls_global_init (Daniel P. Berrangé) 4b3fb65db9: migration: fix duplicate initialization for expected_downtime and cleanup_bh (Lidong Chen) 829db8b497: tests: only update last_byte when at the edge (Peter Xu) 97ca211c62: migration: disallow recovery for release-ram (Peter Xu) 814bb08f17: migration: update recv bitmap only on dest vm (Peter Xu) 67fa1f5700: audio/hda: Fix migration (Dr. David Alan Gilbert) 57225e5f32: migrate: Fix cancelling state warning (Dr. David Alan Gilbert) 4fcefd44a0: migration: fix potential overflow in multifd send (Peter Xu) 042b757cc7: block/file-posix: add bdrv_attach_aio_context callback for host dev and cdrom (Nishanth Aravamudan) 1a3bdc6111: tests/tcg: remove runcom test (Alex Bennée) 15352decf8: docker: perform basic binfmt_misc validation in docker.py (Alex Bennée) f7b446b5de: docker: ignore distro versioning of debootstrap (Alex Bennée) 11cc24a126: docker: add commentary to debian-bootstrap.docker (Alex Bennée) 571fef5e07: docker: Update debootstrap script after Debian migration from Alioth to Salsa (Philippe Mathieu-Daudé) d19f5fc041: docker: report hint when docker.py check fails (Alex Bennée) 2796346069: docker: drop QEMU_TARGET check, fallback in EXECUTABLE not set (Alex Bennée) ff1a390296: docker: add expansion for docker-test-FOO to Makefile.include (Alex Bennée) d984f24c77: docker: add test-unit runner (Alex Bennée) 77b08f73c8: docker: Makefile.include don't include partial images (Alex Bennée) 56c115a953: docker: gracefully skip check_qemu (Alex Bennée) 3f9747a738: docker: move make check into check_qemu helper (Alex Bennée) e4ce964d94: docker: split configure_qemu from build_qemu (Alex Bennée) 43e1b2ffec: docker: fail more gracefully on docker.py check (Alex Bennée) be5e1f527a: docker: par down QEMU_CONFIGURE_OPTS in debian-tricore-cross (Alex Bennée) e043d73212: docker: base debian-tricore on qemu:debian9 (Alex Bennée) 1818d50179: tests/.gitignore: don't ignore docker tests (Alex Bennée) 1a5182c0d2: target/arm: Escalate to correct HardFault when AIRCR.BFHFNMINS is set (Peter Maydell) 042374c92e: hw/intc/arm_gicv3: Check correct HCR_EL2 bit when routing IRQ (Peter Maydell) 0c6c439554: ui/cocoa.m: prevent stuck command key when going into full screen mode (John Arbuckle) ae7da1e5f6: qga: process_event() simplification and leak fix (Marc-André Lureau) c5840b905e: qga-win: Handle fstrim for OSes lower than Win8 (Sameeh Jubran) 672189cd58: tcg/i386: Mark xmm registers call-clobbered (Richard Henderson) 5f00335aec: i386: Rename enum CacheType members (Eduardo Habkost) 3e31b4e170: block/vvfat: Disable debug message by default (Thomas Huth) 092b9c408f: iotests: Disallow compat=0.10 in 223 (Max Reitz) d6e4ca9021: iotest: Fix filtering order in 226 (Max Reitz) e05eb9f29b: iotests: remove LUKS support from test 226 (John Snow) 6360ab278c: qemu-img: avoid overflow of min_sparse parameter (Peter Lieven) 50d6a8a352: block: Fix typos in comments (found by codespell) (Stefan Weil) 4e04f3d91a: qemu-iotests: Use host_device instead of file in 149 (Kevin Wolf) 1ddc9b98c3: hw/intc/exynos4210_gic: Turn instance_init into realize function (Thomas Huth) 07bc425ea3: hw/arm/spitz: Move problematic nand_init() code to realize function (Thomas Huth) 9d2b5a58f8: target/arm: Correctly handle overlapping small MPU regions (Peter Maydell) 03a31776e8: hw/sd/bcm2835_sdhost: Fix PIO mode writes (Guenter Roeck) 7b6d7b84da: hw/microblaze/xlnx-zynqmp-pmu: Fix introspection problem in 'xlnx, zynqmp-pmu-soc' (Thomas Huth) 62aa1d887f: monitor: Fix unsafe sharing of @cur_mon among threads (Peter Xu) 25b1ef31db: qapi: Make 'allow-oob' optional in SchemaInfoCommand (Markus Armbruster) 6598f0cdad: po: Don't include comments with location (Stefan Weil) fa97e38eed: linux-user/ppc: Implement swapcontext syscall (Richard Henderson) 33143c446e: linux-user: fix ELF
Re: [Qemu-devel] Native Memory Virtualization in qemu-system-aarch64
Thanks! That was super helpful. To confirm, support for IOMMU regions in the CPU's memory access path did NOT exist prior to recent releases, correct? My QEMU version is 2.11, and I believe you're up to 3.0 now. If that's the case, I may stick with the "changing priorities" approach, since I know you've also updated the virt board and refactored the system bus code since I branched. Additionally, you correctly pointed out that I simply want to map a huge chunk of memory in and out at once. However, the IOMMU solution does have the benefit of a more realistic approach than changing the priorities. On Wed, Jul 18, 2018 at 1:58 PM Peter Maydell wrote: > On 18 July 2018 at 02:34, Kevin Loughlin wrote: > > Under my setup, the CPU's MMU translates from VAs to IPAs, and an > external > > memory controller then intercepts all memory transactions and translates > > these IPAs to true PAs. This allows the memory controller to enforce > > physical isolation of environments, and does not expose true PAs to the > > CPU/system software. > > Ah, right, "external custom memory controller" makes sense. > > > My question is how best to emulate the memory controller given this > desired > > setup. I have three primary ideas, and I would love to get feedback on > their > > feasibility. > > > > Implement the controller as an IOMMU region. I would be responsible for > > writing the controller's operations to shift and forward the target > address > > to the appropriate subregion. Would it be possible to trigger the IOMMU > > region on every access to system_memory? For example, even during QEMU's > > loading process? Or would I only be able to trigger the IOMMU operations > on > > access to the subregions that represent my environments? My > understanding of > > the IOMMU regions is shaky. Nonetheless, this sounds like the most > promising > > approach, assuming I can provide the shifting and forwarding operations > and > > hide the PAs from the CPU's TLB as desired. > > I would probably go with implementing it as an IOMMU region. We recently > added code to QEMU that allows you to put IOMMUs in the CPU's > memory-access path, so this works now. The example we have of > that at the moment is hw/misc/tz-mpc.c (which is a simple device > which configurably controls access to the thing "downstream" of it > based on a lookup table and whether the access is S or NS). > > As you've guessed, the way the IOMMU stuff works is that it gates > access to the things sat behind it: the device has a MemoryRegion > "upstream" which it exposes to the code which creates it, and a > MemoryRegion property "downstream". The creating code (ie the board) > passes in whatever the "downstream" is (likely a container MemoryRegion > with RAM and so on), and maps the "upstream" end into the address > space that the CPU sees. (You would probably have one downstream > for each separate subregion). You could either have the IOMMU > only "in front" of one part of the overall address space, or > in front of the whole of the address space, as you liked. > (Assuming you have some kind of "control register" memory mapped > interface for programming it, it can't be behind itself; that > would be "an interesting topological exercise", to quote nethack.) > > What the CPU sees is whatever is in the MemoryRegion passed to it > via > object_property_set_link(cpuobj, ..., "memory", > _abort); > > The virt board happens to currently use get_system_memory() > for that, but you can use a custom container MemoryRegion if you > like. > > > Go into the target/arm code, find every instance of accesses to address > > spaces, and shift the target physical address accordingly. This seems > ugly > > and unlikely to work. > > That's very fragile, and I don't recommend it. > > > Use overlapping subregions with differing priorities, as in done in > QEMU's > > TrustZone implementation. However, these priorities would have to change > on > > an environment context switch, and I don't know if that would lead to > chaos. > > You can model things this way too, yes (both by changing priorities, and by > simply enabling/disabling/mapping/unmapping memory regions). The main > advantage that using IOMMU regions gets you are: > * you can do things at a finer granularity, say changing >permissions at a page-by-page level, without creating a >ton of MemoryRegion objects. Swapping MRs in and out would >work if you only wanted to do it for big chunks of space at once > * you can make the choice of what to do based on the memory >transaction attributes (eg secure/nonsecure, user/privileged) >rather than having to provide a single mapping only > If you really do only want to map 4G of RAM in and out at once, > this might be simpler. > > Note that for both the IOMMU approach and the MemoryRegion map/unmap > approach, changing the mapping will blow away the emulated CPU's > cached TLB entirely. So if you do it very often you'll see a
Re: [Qemu-devel] [PATCH v3 5/5] docs: Document the l2-cache-full option
On 07/24/2018 03:03 PM, Leonid Bloch wrote: Signed-off-by: Leonid Bloch --- docs/qcow2-cache.txt | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) I'd probably squash this with 3/5 introducing the option. diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt index 9d261b7da9..ea61585a4b 100644 --- a/docs/qcow2-cache.txt +++ b/docs/qcow2-cache.txt @@ -110,11 +110,12 @@ How to configure the cache sizes Cache sizes can be configured using the -drive option in the command-line, or the 'blockdev-add' QMP command. -There are three options available, and all of them take bytes: +There are four options available: -"l2-cache-size": maximum size of the L2 table cache -"refcount-cache-size": maximum size of the refcount block cache -"cache-size":maximum size of both caches combined +"l2-cache-size": maximum size of the L2 table cache (bytes, K, M) +"refcount-cache-size": maximum size of the refcount block cache (bytes, K, M) +"cache-size":maximum size of both caches combined (bytes, K, M) +"l2-cache-full": make the L2 cache cover the full image (boolean) There are a few things that need to be taken into account: @@ -130,6 +131,12 @@ There are a few things that need to be taken into account: memory as possible to the L2 cache before increasing the refcount cache size. +- If "l2-cache-full" is specified, QEMU will assign enough memory + to the L2 cache to cover the entire size of the image. + +- "l2-cache-size" and "l2-cache-full" can not be set simultaneously, as + setting "l2-cache-full" already implies a specific size for the L2 cache. + - All three "l2-cache-size", "refcount-cache-size", and "cache-size" options can not be set simultaneously. Might be a rebase conflict here once you polish the wording in 2/5. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [Qemu-devel] [PATCH v3 2/5 for-3.0] qcow2: Options' documentation fixes
On 07/24/2018 03:03 PM, Leonid Bloch wrote: Signed-off-by: Leonid Bloch --- docs/qcow2-cache.txt | 3 +++ qemu-options.hx | 15 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt index 8a09a5cc5f..9d261b7da9 100644 --- a/docs/qcow2-cache.txt +++ b/docs/qcow2-cache.txt @@ -130,6 +130,9 @@ There are a few things that need to be taken into account: memory as possible to the L2 cache before increasing the refcount cache size. +- All three "l2-cache-size", "refcount-cache-size", and "cache-size" options + can not be set simultaneously. Reads awkwardly; maybe: At most two of "l2-cache-size", "refcount-cache-size", and "cache-size" can be set together on the command line (the omitted options are calculated accordingly). +++ b/qemu-options.hx @@ -752,15 +752,22 @@ image file) @item cache-size The maximum total size of the L2 table and refcount block caches in bytes -(default: 1048576 bytes or 8 clusters, whichever is larger) @item l2-cache-size -The maximum size of the L2 table cache in bytes -(default: 4/5 of the total cache size) +The maximum size of the L2 table cache. +(default: if cache-size is not defined - 1048576 bytes or 8 clusters, +whichever is larger; if cache-size is defined and is large enough to +accommodate enough L2 cache to cover the entire virtual size of the image plus +the minimal amount of refcount cache - enough to cover the entire image; +if cache-size is defined and is not large enough - as much as possible while +leaving space for the needed refcount cache) Wordy; maybe: (default: if cache-size is not defined - 1048576 bytes or 8 clusters, whichever is larger; otherwise, as large as possible within cache-size while still permitting the requested or minimum refcount cache size). @item refcount-cache-size The maximum size of the refcount block cache in bytes -(default: 1/5 of the total cache size) +(default: 4 times the cluster size, or if cache-size is defined and is large +enough to accommodate enough L2 cache to cover the entire virtual size of the +image plus the minimal amount of refcount cache - the part of cache-size which +is left after allocating the full L2 cache) Maybe: (default: 4 times the cluster size, plus any portion of a specified cache-size left over after sizing the L2 cache large enough to cover the entire image) -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [Qemu-devel] [PULL 0/7] migration queue for 3.0
On 24 July 2018 at 19:34, Dr. David Alan Gilbert (git) wrote: > From: "Dr. David Alan Gilbert" > > The following changes since commit 3bae150448dbd888a480f892ebbf01caec0d8329: > > Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' > into staging (2018-07-24 15:26:01 +0100) > > are available in the Git repository at: > > git://github.com/dagrh/qemu.git tags/pull-migration-20180724a > > for you to fetch changes up to 4b3fb65db973b51346e3456987ba80b15c1fc75c: > > migration: fix duplicate initialization for expected_downtime and > cleanup_bh (2018-07-24 17:28:57 +0100) > > > Migration pull for 3.0 > > Fixes only > > Applied, thanks. -- PMM
Re: [Qemu-devel] [PATCH v3 1/5 for-3.0] A grammar fix
On 07/24/2018 03:03 PM, Leonid Bloch wrote: Subject line is rather vague; at a bare minimum, mentioning 'qcow2:' might be helpful. But the maintainer can improve that. My suggestion: qcow2: grammar fix for conflicting cache sizing Signed-off-by: Leonid Bloch --- block/qcow2.c | 2 +- tests/qemu-iotests/103.out | 2 +- tests/qemu-iotests/137.out | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) Reviewed-by: Eric Blake diff --git a/block/qcow2.c b/block/qcow2.c index 6162ed8be2..ec9e6238a0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -797,7 +797,7 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, if (l2_cache_size_set && refcount_cache_size_set) { error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE " and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set " - "the same time"); + "at the same time"); return; } else if (*l2_cache_size > combined_cache_size) { error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out index bd45d3875a..ab56f03a00 100644 --- a/tests/qemu-iotests/103.out +++ b/tests/qemu-iotests/103.out @@ -5,7 +5,7 @@ wrote 65536/65536 bytes at offset 0 === Testing invalid option combinations === -can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time +can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out index 96724a6c33..6a2ffc71fd 100644 --- a/tests/qemu-iotests/137.out +++ b/tests/qemu-iotests/137.out @@ -16,7 +16,7 @@ read 33554432/33554432 bytes at offset 0 === Try setting some invalid values === Parameter 'lazy-refcounts' expects 'on' or 'off' -cache-size, l2-cache-size and refcount-cache-size may not be set the same time +cache-size, l2-cache-size and refcount-cache-size may not be set at the same time l2-cache-size may not exceed cache-size refcount-cache-size may not exceed cache-size L2 cache size too big -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [Qemu-devel] VCPU hotplug on KVM/ARM
It's been a few months since this email thread died off. Has anyone started working on a potential solution that would allow VCPU hotplug on KVM/ARM ? Or is this a project that is still waiting for an owner who has the time and inclination to get started? Thanks, -Maran On 2/27/2018 5:21 AM, Andrew Jones wrote: On Tue, Feb 27, 2018 at 01:46:04PM +0100, Christoffer Dall wrote: On Tue, Feb 27, 2018 at 05:34:28PM +0530, btha...@codeaurora.org wrote: Hi Christoffer, Thanks for your reply. On 2018-02-27 16:17, Christoffer Dall wrote: Hi Bhupinder, On Tue, Feb 27, 2018 at 03:01:17PM +0530, btha...@codeaurora.org wrote: I hope it is the right forum to post my query. I am currently looking at the possibility of adding a new VCPU to a running guest VM in KVM/ARM. I see that currently, it is not allowed to add a new VCPU to a guest VM, if it is already initialized. The first check in kvm_arch_vcpu_create() returns failure if it is already initialized. This would require a major rework of a lot of logic surrounding the GIC and other parts of KVM initialization. There was some work done in QEMU to add support for VCPU hotplug: https://lists.gnu.org/archive/html/qemu-arm/2017-05/msg00404.html But I am looking at the KVM side for enabling adding a new VCPU. If you can point me to any relevant work/resources, which I can refer to then it will help me. I don't have any specific pointers, but I was always told that the way we were going to do CPU hotplug would be to instantiate a large number of VCPUs, and hotplug would be equivalent to turning on a VCPU which was previously powered off. Is this not still a feasible solution? It should be a feasible solution provided the guest VM is not able to control the onlining/offlining of VCPUs. It should be controlled by the Host. KVM could simply refuse to turn on some of the CPUs unless given permission from host userspace. How does VCPU hotplug work on x86? On x86, you can add a vcpu through libvirt setvcpu command and it shows up in the guest VM as a new CPU if you do lscpu. Sure, but what is the mechanism, does x86 qemu actually call KVM_CREATE_VCPU, or is this also a question of turning on already created vcpus ? CC'ing Igor and qemu-devel drew ___ kvmarm mailing list kvm...@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
[Qemu-devel] [PATCH v3 3/5] qcow2: Introduce an option for sufficient L2 cache for the entire image
An option "l2-cache-full" is introduced to automatically set the qcow2 L2 cache to a sufficient value for covering the entire image. The memory overhead when using this option is not big (1 MB for each 8 GB of virtual image size with the default cluster size) and it can noticeably improve performance when using large images with frequent I/O. Previously, for this functionality the correct L2 cache size needed to be calculated manually or with a script, and then this size needed to be passed to the "l2-cache-size" option. Now it is sufficient to just pass the boolean "l2-cache-full" option. Signed-off-by: Leonid Bloch --- block/qcow2.c| 35 --- block/qcow2.h| 1 + qapi/block-core.json | 8 +++- qemu-options.hx | 6 +- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index ec9e6238a0..101b8b474b 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -695,6 +695,11 @@ static QemuOptsList qcow2_runtime_opts = { .type = QEMU_OPT_SIZE, .help = "Maximum L2 table cache size", }, +{ +.name = QCOW2_OPT_L2_CACHE_FULL, +.type = QEMU_OPT_BOOL, +.help = "Create full coverage of the image with the L2 cache", +}, { .name = QCOW2_OPT_L2_CACHE_ENTRY_SIZE, .type = QEMU_OPT_SIZE, @@ -779,10 +784,12 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, BDRVQcow2State *s = bs->opaque; uint64_t combined_cache_size; bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set; +bool l2_cache_full_set; int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE); l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE); +l2_cache_full_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_FULL); refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE); combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0); @@ -793,6 +800,17 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, *l2_cache_entry_size = qemu_opt_get_size( opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE, s->cluster_size); +uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; +uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); + +if (l2_cache_size_set && l2_cache_full_set) { +error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " and " + QCOW2_OPT_L2_CACHE_FULL " may not be set at the same time"); +return; +} else if (l2_cache_full_set) { +*l2_cache_size = max_l2_cache; +} + if (combined_cache_size_set) { if (l2_cache_size_set && refcount_cache_size_set) { error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE @@ -800,8 +818,14 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, "at the same time"); return; } else if (*l2_cache_size > combined_cache_size) { -error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " - QCOW2_OPT_CACHE_SIZE); +if (l2_cache_full_set) { +error_setg(errp, QCOW2_OPT_CACHE_SIZE " must be greater than " + "the full L2 cache if " QCOW2_OPT_L2_CACHE_FULL + " is used"); +} else { +error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " + QCOW2_OPT_CACHE_SIZE); +} return; } else if (*refcount_cache_size > combined_cache_size) { error_setg(errp, QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not exceed " @@ -809,14 +833,11 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, return; } -if (l2_cache_size_set) { +if (l2_cache_size_set || l2_cache_full_set) { *refcount_cache_size = combined_cache_size - *l2_cache_size; } else if (refcount_cache_size_set) { *l2_cache_size = combined_cache_size - *refcount_cache_size; } else { -uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; -uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); - /* Assign as much memory as possible to the L2 cache, and * use the remainder for the refcount cache */ if (combined_cache_size >= max_l2_cache + min_refcount_cache) { @@ -829,7 +850,7 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, } } } else { -if (!l2_cache_size_set) { +if (!l2_cache_size_set && !l2_cache_full_set) { *l2_cache_size = MAX(DEFAULT_L2_CACHE_BYTE_SIZE, (uint64_t)DEFAULT_L2_CACHE_CLUSTERS
[Qemu-devel] [PATCH v3 4/5] iotests: Add tests for the new l2-cache-full option
Signed-off-by: Leonid Bloch --- tests/qemu-iotests/103 | 6 ++ tests/qemu-iotests/103.out | 2 ++ tests/qemu-iotests/137 | 2 ++ tests/qemu-iotests/137.out | 2 ++ 4 files changed, 12 insertions(+) diff --git a/tests/qemu-iotests/103 b/tests/qemu-iotests/103 index 2841318492..a2886e8569 100755 --- a/tests/qemu-iotests/103 +++ b/tests/qemu-iotests/103 @@ -52,9 +52,15 @@ echo echo '=== Testing invalid option combinations ===' echo +# l2-cache-size and l2-cache-full at the same time +$QEMU_IO -c "open -o l2-cache-full,l2-cache-size=1M $TEST_IMG" 2>&1 | +_filter_testdir | _filter_imgfmt # all sizes set at the same time $QEMU_IO -c "open -o cache-size=1.25M,l2-cache-size=1M,refcount-cache-size=0.25M $TEST_IMG" \ 2>&1 | _filter_testdir | _filter_imgfmt +# cache-size may not be smaller than the full L2 size if l2-cache-full is used +$QEMU_IO -c "open -o l2-cache-full,cache-size=6K $TEST_IMG" 2>&1 | +_filter_testdir | _filter_imgfmt # l2-cache-size may not exceed cache-size $QEMU_IO -c "open -o cache-size=1M,l2-cache-size=2M $TEST_IMG" 2>&1 \ | _filter_testdir | _filter_imgfmt diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out index ab56f03a00..92afbff024 100644 --- a/tests/qemu-iotests/103.out +++ b/tests/qemu-iotests/103.out @@ -5,7 +5,9 @@ wrote 65536/65536 bytes at offset 0 === Testing invalid option combinations === +can't open device TEST_DIR/t.IMGFMT: l2-cache-full and l2-cache-size may not be set at the same time can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time +can't open device TEST_DIR/t.IMGFMT: cache-size must be greater than the full L2 cache if l2-cache-full is used can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137 index 87965625d8..f460b5bfe1 100755 --- a/tests/qemu-iotests/137 +++ b/tests/qemu-iotests/137 @@ -106,7 +106,9 @@ echo $QEMU_IO \ -c "reopen -o lazy-refcounts=42" \ +-c "reopen -o l2-cache-full,l2-cache-size=64k" \ -c "reopen -o cache-size=1M,l2-cache-size=64k,refcount-cache-size=64k" \ +-c "reopen -o l2-cache-full,cache-size=6K" \ -c "reopen -o cache-size=1M,l2-cache-size=2M" \ -c "reopen -o cache-size=1M,refcount-cache-size=2M" \ -c "reopen -o l2-cache-size=256T" \ diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out index 6a2ffc71fd..b15dfc391a 100644 --- a/tests/qemu-iotests/137.out +++ b/tests/qemu-iotests/137.out @@ -16,7 +16,9 @@ read 33554432/33554432 bytes at offset 0 === Try setting some invalid values === Parameter 'lazy-refcounts' expects 'on' or 'off' +l2-cache-full and l2-cache-size may not be set at the same time cache-size, l2-cache-size and refcount-cache-size may not be set at the same time +cache-size must be greater than the full L2 cache if l2-cache-full is used l2-cache-size may not exceed cache-size refcount-cache-size may not exceed cache-size L2 cache size too big -- 2.14.1
[Qemu-devel] [PATCH v3 2/5 for-3.0] qcow2: Options' documentation fixes
Signed-off-by: Leonid Bloch --- docs/qcow2-cache.txt | 3 +++ qemu-options.hx | 15 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt index 8a09a5cc5f..9d261b7da9 100644 --- a/docs/qcow2-cache.txt +++ b/docs/qcow2-cache.txt @@ -130,6 +130,9 @@ There are a few things that need to be taken into account: memory as possible to the L2 cache before increasing the refcount cache size. +- All three "l2-cache-size", "refcount-cache-size", and "cache-size" options + can not be set simultaneously. + Unlike L2 tables, refcount blocks are not used during normal I/O but only during allocations and internal snapshots. In most cases they are accessed sequentially (even during random guest I/O) so increasing the diff --git a/qemu-options.hx b/qemu-options.hx index b1bf0f485f..ef0706c359 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -752,15 +752,22 @@ image file) @item cache-size The maximum total size of the L2 table and refcount block caches in bytes -(default: 1048576 bytes or 8 clusters, whichever is larger) @item l2-cache-size -The maximum size of the L2 table cache in bytes -(default: 4/5 of the total cache size) +The maximum size of the L2 table cache. +(default: if cache-size is not defined - 1048576 bytes or 8 clusters, +whichever is larger; if cache-size is defined and is large enough to +accommodate enough L2 cache to cover the entire virtual size of the image plus +the minimal amount of refcount cache - enough to cover the entire image; +if cache-size is defined and is not large enough - as much as possible while +leaving space for the needed refcount cache) @item refcount-cache-size The maximum size of the refcount block cache in bytes -(default: 1/5 of the total cache size) +(default: 4 times the cluster size, or if cache-size is defined and is large +enough to accommodate enough L2 cache to cover the entire virtual size of the +image plus the minimal amount of refcount cache - the part of cache-size which +is left after allocating the full L2 cache) @item cache-clean-interval Clean unused entries in the L2 and refcount caches. The interval is in seconds. -- 2.14.1
[Qemu-devel] [PATCH v3 5/5] docs: Document the l2-cache-full option
Signed-off-by: Leonid Bloch --- docs/qcow2-cache.txt | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt index 9d261b7da9..ea61585a4b 100644 --- a/docs/qcow2-cache.txt +++ b/docs/qcow2-cache.txt @@ -110,11 +110,12 @@ How to configure the cache sizes Cache sizes can be configured using the -drive option in the command-line, or the 'blockdev-add' QMP command. -There are three options available, and all of them take bytes: +There are four options available: -"l2-cache-size": maximum size of the L2 table cache -"refcount-cache-size": maximum size of the refcount block cache -"cache-size":maximum size of both caches combined +"l2-cache-size": maximum size of the L2 table cache (bytes, K, M) +"refcount-cache-size": maximum size of the refcount block cache (bytes, K, M) +"cache-size":maximum size of both caches combined (bytes, K, M) +"l2-cache-full": make the L2 cache cover the full image (boolean) There are a few things that need to be taken into account: @@ -130,6 +131,12 @@ There are a few things that need to be taken into account: memory as possible to the L2 cache before increasing the refcount cache size. +- If "l2-cache-full" is specified, QEMU will assign enough memory + to the L2 cache to cover the entire size of the image. + +- "l2-cache-size" and "l2-cache-full" can not be set simultaneously, as + setting "l2-cache-full" already implies a specific size for the L2 cache. + - All three "l2-cache-size", "refcount-cache-size", and "cache-size" options can not be set simultaneously. -- 2.14.1
[Qemu-devel] [PATCH v3 0/5] Introduction of l2-cache-full option for qcow2 images
This series introduces an option to calculate and allocate automatically enough qcow2 L2 cache to cover the entire image. Using cache that covers the entire image can benefit performance, while having only a small memory overhead (just 1 MB for every 8 GB of virtual image size with the default cluster size). - Differences from v1: 1) Documentation fixes in qapi/block-core.json and qemu-options.hx 2) Removal of the patch which was made to fix the default sizes in docs/qcow2-cache.txt - it is not needed, as the default sizes imply also default cluster sizes. 3) Documentation fixes in docs/qcow2-cache.txt, mentioning mutual exclusivity of the options. 4) Squashing the iotests patch into the main feature addition patch - Differences from v2: 1) A separate patch for the grammar fix for 3.0 2) A separate patch for existing documentation fixes for 3.0 3) Separated back the iotests patch, because the grammar fix is separate now Leonid Bloch (5): A grammar fix qcow2: Options' documentation fixes qcow2: Introduce an option for sufficient L2 cache for the entire image iotests: Add tests for the new l2-cache-full option docs: Document the l2-cache-full option block/qcow2.c | 37 + block/qcow2.h | 1 + docs/qcow2-cache.txt | 18 ++ qapi/block-core.json | 8 +++- qemu-options.hx| 19 +++ tests/qemu-iotests/103 | 6 ++ tests/qemu-iotests/103.out | 4 +++- tests/qemu-iotests/137 | 2 ++ tests/qemu-iotests/137.out | 4 +++- 9 files changed, 80 insertions(+), 19 deletions(-) -- 2.14.1
[Qemu-devel] [PATCH v3 1/5 for-3.0] A grammar fix
Signed-off-by: Leonid Bloch --- block/qcow2.c | 2 +- tests/qemu-iotests/103.out | 2 +- tests/qemu-iotests/137.out | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 6162ed8be2..ec9e6238a0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -797,7 +797,7 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, if (l2_cache_size_set && refcount_cache_size_set) { error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE " and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set " - "the same time"); + "at the same time"); return; } else if (*l2_cache_size > combined_cache_size) { error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out index bd45d3875a..ab56f03a00 100644 --- a/tests/qemu-iotests/103.out +++ b/tests/qemu-iotests/103.out @@ -5,7 +5,7 @@ wrote 65536/65536 bytes at offset 0 === Testing invalid option combinations === -can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time +can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out index 96724a6c33..6a2ffc71fd 100644 --- a/tests/qemu-iotests/137.out +++ b/tests/qemu-iotests/137.out @@ -16,7 +16,7 @@ read 33554432/33554432 bytes at offset 0 === Try setting some invalid values === Parameter 'lazy-refcounts' expects 'on' or 'off' -cache-size, l2-cache-size and refcount-cache-size may not be set the same time +cache-size, l2-cache-size and refcount-cache-size may not be set at the same time l2-cache-size may not exceed cache-size refcount-cache-size may not exceed cache-size L2 cache size too big -- 2.14.1
Re: [Qemu-devel] [PULL for-3.0 0/1] Tracing patches
On 24 July 2018 at 16:13, Eric Blake wrote: > On 07/24/2018 09:25 AM, Stefan Hajnoczi wrote: >> >> The following changes since commit >> 768cef2974fb1fa30dd188b043ea737e13fea477: >> >>Merge remote-tracking branch >> 'remotes/ehabkost/tags/x86-next-pull-request' into staging (2018-07-24 >> 10:37:52 +0100) >> >> are available in the Git repository at: >> >>git://github.com/stefanha/qemu.git tags/tracing-pull-request >> >> for you to fetch changes up to b6ad6a528f2356b357bd1d210048dd7988dc9a7b: >> >>trace/simple: fix hang in child after fork(2) (2018-07-24 14:27:51 >> +0100) >> >> >> Pull request >> >> Fix qemu-iotests 147 when QEMU was built with ./configure >> --enable-trace-backend=simple. > > > Design conversation ongoing under patch 1/1 - replying here to make sure > this doesn't get applied if we aren't ready for it yet. OK; I'll drop this pullreq from my queue. Pleas ping me again if the outcome is that it should be applied. thanks -- PMM
Re: [Qemu-devel] [PATCH 01/13] hw/rdma: Make distinction between device init and start modes
On 07/24/2018 10:29 PM, Yuval Shaia wrote: On Tue, Jul 24, 2018 at 03:08:10PM +0300, Marcel Apfelbaum wrote: Hi Yuval, On 07/16/2018 10:40 AM, Yuval Shaia wrote: There are certain operations that are well considered as part of device configuration while others are needed only when "start" command is triggered by the guest driver. An example of device initialization step is msix_init and example of "device start" stage is the creation of a CQ completion handler thread. Driver expects such distinction - implement it. Signed-off-by: Yuval Shaia --- hw/rdma/rdma_backend.c | 96 +-- hw/rdma/rdma_backend.h | 2 + hw/rdma/rdma_backend_defs.h | 3 +- hw/rdma/vmw/pvrdma_main.c | 129 +--- 4 files changed, 155 insertions(+), 75 deletions(-) diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c index e9ced6f9ef..647e16399f 100644 --- a/hw/rdma/rdma_backend.c +++ b/hw/rdma/rdma_backend.c @@ -35,6 +35,7 @@ #define VENDOR_ERR_MR_SMALL 0x208 #define THR_NAME_LEN 16 +#define THR_POLL_TO 5000 typedef struct BackendCtx { uint64_t req_id; @@ -91,35 +92,82 @@ static void *comp_handler_thread(void *arg) int rc; struct ibv_cq *ev_cq; void *ev_ctx; +int flags; +GPollFD pfds[1]; + +/* Change to non-blocking mode */ +flags = fcntl(backend_dev->channel->fd, F_GETFL); +rc = fcntl(backend_dev->channel->fd, F_SETFL, flags | O_NONBLOCK); +if (rc < 0) { +pr_dbg("Fail to change to non-blocking mode\n"); +return NULL; +} pr_dbg("Starting\n"); +pfds[0].fd = backend_dev->channel->fd; +pfds[0].events = G_IO_IN | G_IO_HUP | G_IO_ERR; + +backend_dev->comp_thread.is_running = true; + while (backend_dev->comp_thread.run) { -pr_dbg("Waiting for completion on channel %p\n", backend_dev->channel); -rc = ibv_get_cq_event(backend_dev->channel, _cq, _ctx); -pr_dbg("ibv_get_cq_event=%d\n", rc); -if (unlikely(rc)) { -pr_dbg("---> ibv_get_cq_event (%d)\n", rc); -continue; -} +do { +rc = qemu_poll_ns(pfds, 1, THR_POLL_TO * (int64_t)SCALE_MS); +} while (!rc && backend_dev->comp_thread.run); + +if (backend_dev->comp_thread.run) { +pr_dbg("Waiting for completion on channel %p\n", backend_dev->channel); +rc = ibv_get_cq_event(backend_dev->channel, _cq, _ctx); +pr_dbg("ibv_get_cq_event=%d\n", rc); +if (unlikely(rc)) { +pr_dbg("---> ibv_get_cq_event (%d)\n", rc); +continue; +} -rc = ibv_req_notify_cq(ev_cq, 0); -if (unlikely(rc)) { -pr_dbg("Error %d from ibv_req_notify_cq\n", rc); -} +rc = ibv_req_notify_cq(ev_cq, 0); +if (unlikely(rc)) { +pr_dbg("Error %d from ibv_req_notify_cq\n", rc); +} -poll_cq(backend_dev->rdma_dev_res, ev_cq); +poll_cq(backend_dev->rdma_dev_res, ev_cq); -ibv_ack_cq_events(ev_cq, 1); +ibv_ack_cq_events(ev_cq, 1); +} } pr_dbg("Going down\n"); /* TODO: Post cqe for all remaining buffs that were posted */ +backend_dev->comp_thread.is_running = false; + +qemu_thread_exit(0); + return NULL; } +static void stop_comp_thread(RdmaBackendDev *backend_dev) +{ +backend_dev->comp_thread.run = false; +while (backend_dev->comp_thread.is_running) { +pr_dbg("Waiting for thread to complete\n"); +sleep(THR_POLL_TO / SCALE_US / 2); +} +} + +static void start_comp_thread(RdmaBackendDev *backend_dev) +{ +char thread_name[THR_NAME_LEN] = {0}; + +stop_comp_thread(backend_dev); + +snprintf(thread_name, sizeof(thread_name), "rdma_comp_%s", + ibv_get_device_name(backend_dev->ib_dev)); +backend_dev->comp_thread.run = true; +qemu_thread_create(_dev->comp_thread.thread, thread_name, + comp_handler_thread, backend_dev, QEMU_THREAD_DETACHED); +} + void rdma_backend_register_comp_handler(void (*handler)(int status, unsigned int vendor_err, void *ctx)) { @@ -706,7 +754,6 @@ int rdma_backend_init(RdmaBackendDev *backend_dev, int i; int ret = 0; int num_ibv_devices; -char thread_name[THR_NAME_LEN] = {0}; struct ibv_device **dev_list; struct ibv_port_attr port_attr; @@ -800,11 +847,8 @@ int rdma_backend_init(RdmaBackendDev *backend_dev, pr_dbg("interface_id=0x%" PRIx64 "\n", be64_to_cpu(backend_dev->gid.global.interface_id)); -snprintf(thread_name, sizeof(thread_name), "rdma_comp_%s", - ibv_get_device_name(backend_dev->ib_dev)); -backend_dev->comp_thread.run = true; -qemu_thread_create(_dev->comp_thread.thread, thread_name, - comp_handler_thread, backend_dev,
Re: [Qemu-devel] [PATCH v4 07/55] target/mips: Add emulation of nanoMIPS 16-bit load and store instructions
On 07/24/2018 10:31 AM, Aleksandar Markovic wrote: > +case NM_SB16: > +{ > +int rt = decode_gpr_gpr3_src_store( > + NANOMIPS_EXTRACT_RD(ctx->opcode)); Shadowed variable. > +case NM_SH16: > +{ > +int rt = decode_gpr_gpr3_src_store( > + NANOMIPS_EXTRACT_RD(ctx->opcode)); Likewise. > case NM_LWSP16: > +{ > +int rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); Likewise. > case NM_LW4X4: > +{ > +int rt = (extract32(ctx->opcode, 9, 1) << 3) | > + extract32(ctx->opcode, 5, 3); > +int rs = (extract32(ctx->opcode, 4, 1) << 3) | > + extract32(ctx->opcode, 0, 3); Likewise. > case NM_SW4X4: > +{ > +int rt = (extract32(ctx->opcode, 9, 1) << 3) | > + extract32(ctx->opcode, 5, 3); > +int rs = (extract32(ctx->opcode, 4, 1) << 3) | > + extract32(ctx->opcode, 0, 3); Likewise. > case NM_SWSP16: > +{ > +int rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); Likewise. > case NM_SW16: > +{ > +int rt = decode_gpr_gpr3_src_store( > + NANOMIPS_EXTRACT_RD(ctx->opcode)); > +int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode)); Likewise. > case NM_SWGP16: > +{ > +int rt = decode_gpr_gpr3_src_store( > + NANOMIPS_EXTRACT_RD(ctx->opcode)); Likewise. It might be handy to temporarily add target/mips/translate.o: QEMU_CFLAGS += -Wshadow=local to target/mips/Makefile.objs, but I don't know how prevalent that situation is within the existing code base... r~
Re: [Qemu-devel] [PATCH v4 10/55] target/mips: Add emulation of some common nanoMIPS 32-bit instructions
On 07/24/2018 10:31 AM, Aleksandar Markovic wrote: > +case NM_ADDIUPC: > +if (rt != 0) { > +int32_t offset = sextract32(ctx->opcode, 0, 1) << 21 > +| extract32(ctx->opcode, 1, 20) << 1; > +target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset); > +tcg_gen_movi_tl(cpu_gpr[rt], addr); > +tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); > +} I really need you to address all of the comments from a round of review before posting the next round. I'm going to stop now, let you address all of the v3 review and then post a v5. r~
Re: [Qemu-devel] [PATCH 01/13] hw/rdma: Make distinction between device init and start modes
On Tue, Jul 24, 2018 at 03:08:10PM +0300, Marcel Apfelbaum wrote: > Hi Yuval, > > On 07/16/2018 10:40 AM, Yuval Shaia wrote: > > There are certain operations that are well considered as part of device > > configuration while others are needed only when "start" command is > > triggered by the guest driver. An example of device initialization step > > is msix_init and example of "device start" stage is the creation of a CQ > > completion handler thread. > > > > Driver expects such distinction - implement it. > > > > Signed-off-by: Yuval Shaia > > --- > > hw/rdma/rdma_backend.c | 96 +-- > > hw/rdma/rdma_backend.h | 2 + > > hw/rdma/rdma_backend_defs.h | 3 +- > > hw/rdma/vmw/pvrdma_main.c | 129 +--- > > 4 files changed, 155 insertions(+), 75 deletions(-) > > > > diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c > > index e9ced6f9ef..647e16399f 100644 > > --- a/hw/rdma/rdma_backend.c > > +++ b/hw/rdma/rdma_backend.c > > @@ -35,6 +35,7 @@ > > #define VENDOR_ERR_MR_SMALL 0x208 > > #define THR_NAME_LEN 16 > > +#define THR_POLL_TO 5000 > > typedef struct BackendCtx { > > uint64_t req_id; > > @@ -91,35 +92,82 @@ static void *comp_handler_thread(void *arg) > > int rc; > > struct ibv_cq *ev_cq; > > void *ev_ctx; > > +int flags; > > +GPollFD pfds[1]; > > + > > +/* Change to non-blocking mode */ > > +flags = fcntl(backend_dev->channel->fd, F_GETFL); > > +rc = fcntl(backend_dev->channel->fd, F_SETFL, flags | O_NONBLOCK); > > +if (rc < 0) { > > +pr_dbg("Fail to change to non-blocking mode\n"); > > +return NULL; > > +} > > pr_dbg("Starting\n"); > > +pfds[0].fd = backend_dev->channel->fd; > > +pfds[0].events = G_IO_IN | G_IO_HUP | G_IO_ERR; > > + > > +backend_dev->comp_thread.is_running = true; > > + > > while (backend_dev->comp_thread.run) { > > -pr_dbg("Waiting for completion on channel %p\n", > > backend_dev->channel); > > -rc = ibv_get_cq_event(backend_dev->channel, _cq, _ctx); > > -pr_dbg("ibv_get_cq_event=%d\n", rc); > > -if (unlikely(rc)) { > > -pr_dbg("---> ibv_get_cq_event (%d)\n", rc); > > -continue; > > -} > > +do { > > +rc = qemu_poll_ns(pfds, 1, THR_POLL_TO * (int64_t)SCALE_MS); > > +} while (!rc && backend_dev->comp_thread.run); > > + > > +if (backend_dev->comp_thread.run) { > > +pr_dbg("Waiting for completion on channel %p\n", > > backend_dev->channel); > > +rc = ibv_get_cq_event(backend_dev->channel, _cq, _ctx); > > +pr_dbg("ibv_get_cq_event=%d\n", rc); > > +if (unlikely(rc)) { > > +pr_dbg("---> ibv_get_cq_event (%d)\n", rc); > > +continue; > > +} > > -rc = ibv_req_notify_cq(ev_cq, 0); > > -if (unlikely(rc)) { > > -pr_dbg("Error %d from ibv_req_notify_cq\n", rc); > > -} > > +rc = ibv_req_notify_cq(ev_cq, 0); > > +if (unlikely(rc)) { > > +pr_dbg("Error %d from ibv_req_notify_cq\n", rc); > > +} > > -poll_cq(backend_dev->rdma_dev_res, ev_cq); > > +poll_cq(backend_dev->rdma_dev_res, ev_cq); > > -ibv_ack_cq_events(ev_cq, 1); > > +ibv_ack_cq_events(ev_cq, 1); > > +} > > } > > pr_dbg("Going down\n"); > > /* TODO: Post cqe for all remaining buffs that were posted */ > > +backend_dev->comp_thread.is_running = false; > > + > > +qemu_thread_exit(0); > > + > > return NULL; > > } > > +static void stop_comp_thread(RdmaBackendDev *backend_dev) > > +{ > > +backend_dev->comp_thread.run = false; > > +while (backend_dev->comp_thread.is_running) { > > +pr_dbg("Waiting for thread to complete\n"); > > +sleep(THR_POLL_TO / SCALE_US / 2); > > +} > > +} > > + > > +static void start_comp_thread(RdmaBackendDev *backend_dev) > > +{ > > +char thread_name[THR_NAME_LEN] = {0}; > > + > > +stop_comp_thread(backend_dev); > > + > > +snprintf(thread_name, sizeof(thread_name), "rdma_comp_%s", > > + ibv_get_device_name(backend_dev->ib_dev)); > > +backend_dev->comp_thread.run = true; > > +qemu_thread_create(_dev->comp_thread.thread, thread_name, > > + comp_handler_thread, backend_dev, > > QEMU_THREAD_DETACHED); > > +} > > + > > void rdma_backend_register_comp_handler(void (*handler)(int status, > > unsigned int vendor_err, void > > *ctx)) > > { > > @@ -706,7 +754,6 @@ int rdma_backend_init(RdmaBackendDev *backend_dev, > > int i; > > int ret = 0; > > int num_ibv_devices; > > -char thread_name[THR_NAME_LEN] = {0}; > > struct ibv_device **dev_list; > > struct ibv_port_attr port_attr; > > @@ -800,11 +847,8 @@ int
Re: [Qemu-devel] [PATCH v4 06/55] target/mips: Add emulation of misc nanoMIPS 16-bit instructions
On 07/24/2018 10:31 AM, Aleksandar Markovic wrote: > +/* make sure instructions are on a halfword boundary */ > +if (ctx->base.pc_next & 0x1) { > +TCGv tmp = tcg_const_tl(ctx->base.pc_next); > +tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); > +tcg_temp_free(tmp); > +return 2; > +} You've lost the actual raising of the exception since v3. > +case NM_P16_MV: > +{ > +int rt1 = NANOMIPS_EXTRACT_RD5(ctx->opcode); > +if (rt1 != 0) { > +/* MOVE */ > +int rs1 = NANOMIPS_EXTRACT_RS5(ctx->opcode); > +gen_arith(ctx, OPC_ADDU, rt1, rs1, 0); Why are you creating rt1 and rs1 variables? I see you took my shadowed variables comment to heart, and renamed them, but why not just overwrite the contents of the existing outer variable? > +case NM_P_ADDIURS5: > +{ > +int rt1 = extract32(ctx->opcode, 5, 5); Likewise. > +case NM_P16_4X4: > +{ > +int rt1 = (extract32(ctx->opcode, 9, 1) << 3) | > + extract32(ctx->opcode, 5, 3); > +int rs1 = (extract32(ctx->opcode, 4, 1) << 3) | > + extract32(ctx->opcode, 0, 3); Likewise. r~
Re: [Qemu-devel] [PATCH v4 05/55] target/mips: Add nanoMIPS decoding and extraction utilities
On 07/24/2018 10:31 AM, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > Add some basic utility functions and macros for nanoMIPS decoding > engine. > > Signed-off-by: Yongbok Kim > Signed-off-by: Aleksandar Markovic > Signed-off-by: Stefan Markovic > --- > target/mips/translate.c | 45 + > 1 file changed, 45 insertions(+) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH v4 04/55] target/mips: Add placeholder and invocation of decode_nanomips_opc()
On 07/24/2018 10:31 AM, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > Add empty body and invocation of decode_nanomips_opc() if the bit > ISA_NANOMIPS32 is set in ctx->insn_flags. > > Signed-off-by: Yongbok Kim > Signed-off-by: Aleksandar Markovic > Signed-off-by: Stefan Markovic > --- > target/mips/translate.c | 16 > 1 file changed, 16 insertions(+) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 05/99] s390-ccw: force diag 308 subcode to unsigned long
Quoting Cornelia Huck (2018-07-24 06:07:43) > On Tue, 24 Jul 2018 11:40:04 +0200 > Cornelia Huck wrote: > > > On Mon, 23 Jul 2018 17:14:54 -0500 > > Michael Roth wrote: > > > > > Quoting Michael Roth (2018-07-23 15:16:14) > > > > From: Cornelia Huck > > > > > > > > We currently pass an integer as the subcode parameter. However, > > > > the upper bits of the register containing the subcode need to > > > > be 0, which is not guaranteed unless we explicitly specify the > > > > subcode to be an unsigned long value. > > > > > > > > Fixes: d046c51dad3 ("pc-bios/s390-ccw: Get device address via diag > > > > 308/6") > > > > Cc: qemu-sta...@nongnu.org > > > > Signed-off-by: Cornelia Huck > > > > Acked-by: Christian Borntraeger > > > > Tested-by: Thomas Huth > > > > Signed-off-by: Thomas Huth > > > > (cherry picked from commit 63d8b5ace31c1e1f3996fe4cd551d6d377594d5a) > > > > Signed-off-by: Michael Roth > > > > > > Hi Cornelia, > > > > > > Would you be able to do an s390 BIOS build for this one as well? > > > > Sure, will do a build for 2.12-stable. > > Here we go: > > The following changes since commit e8488edcb3768f08cda7c3cc00def6b1b2f6c615: > > tcg/i386: Mark xmm registers call-clobbered (2018-07-23 14:24:17 -0500) > > are available in the Git repository at: > > git://github.com/cohuck/qemu tags/s390x-20180724-212-stable > > for you to fetch changes up to c16427177a67bc86aa7560331143bfc9c885b27d: > > pc-bios/s390-ccw.img: update image for stable (2018-07-24 06:08:42 -0400) > > > update s390-ccw.img for stable > > > Cornelia Huck (1): > pc-bios/s390-ccw.img: update image for stable > > pc-bios/s390-ccw.img | Bin 30520 -> 30520 bytes > 1 file changed, 0 insertions(+), 0 deletions(-) > > (for-2.12-stable branch) Applied, thanks!
Re: [Qemu-devel] [PULL 0/4] Qcrypto next patches
On 24 July 2018 at 17:44, Daniel P. Berrangé wrote: > The following changes since commit 3bae150448dbd888a480f892ebbf01caec0d8329: > > Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' > into staging (2018-07-24 15:26:01 +0100) > > are available in the Git repository at: > > https://github.com/berrange/qemu tags/qcrypto-next-pull-request > > for you to fetch changes up to db0a8c70f25fe497c4b786d8edac063daa744c0d: > > tests: fix TLS handshake failure with TLS 1.3 (2018-07-24 17:36:12 +0100) > > > Fix unit test compatibility with TLS 1.3 > > Applied, thanks. -- PMM
Re: [Qemu-devel] [PATCH v7 00/10] Mips maintenance and misc fixes and improvements
On 24 July 2018 at 18:38, Aleksandar Markovic wrote: >> From: Peter Maydell >> Sent: Tuesday, July 24, 2018 7:21 PM > >> On 24 July 2018 at 18:04, Aleksandar Markovic >> wrote: >> > From: Aleksandar Markovic >> >> Are you trying to get these into 3.0 or aiming for 3.1? >> Time is running out for the former (and at this point >> in the release cycle "fixes" are OK but "improvements" >> should be postponed til 3.1...) > This is all for 3.1, submitted now just for review. I guess > review process can take place regardless of pending code freeze. Yep, that's fine (looks like you've got review for most of this, which is good). thanks -- PMM
Re: [Qemu-devel] [PATCH 3/5] target/arm: Honour HCR_EL2.TGE when raising synchronous exceptions
On 07/24/2018 04:59 AM, Peter Maydell wrote: > Whene we raise a synchronous exception, if HCR_EL2.TGE is set then > exceptions targeting NS EL1 must be redirected to EL2. Implement > this in raise_exception() -- all synchronous exceptions go through > this function. > > (Asynchronous exceptions go via arm_cpu_exec_interrupt(), which > already honours HCR_EL2.TGE when it determines the target EL > in arm_phys_excp_target_el().) > > Signed-off-by: Peter Maydell > --- > target/arm/op_helper.c | 14 ++ > 1 file changed, 14 insertions(+) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 4/5] target/arm: Provide accessor functions for HCR_EL2.{IMO, FMO, AMO}
On 07/24/2018 04:59 AM, Peter Maydell wrote: > The IMO, FMO and AMO bits in HCR_EL2 are defined to "behave as > 1 for all purposes other than direct reads" if HCR_EL2.TGE > is set and HCR_EL2.E2H is 0, and to "behave as 0 for all > purposes other than direct reads" if HCR_EL2.TGE is set > and HRC_EL2.E2H is 1. > > To avoid having to check E2H and TGE everywhere where we test IMO and > FMO, provide accessors arm_hcr_el2_imo(), arm_hcr_el2_fmo()and > arm_hcr_el2_amo(). We don't implement ARMv8.1-VHE yet, so the E2H > case will never be true, but we include the logic to save effort when > we eventually do get to that. > > (Note that in several of these callsites the change doesn't > actually make a difference as either the callsite is handling > TGE specially anyway, or the CPU can't get into that situation > with TGE set; we change everywhere for consistency.) > > Signed-off-by: Peter Maydell > --- > target/arm/cpu.h | 64 +++ > hw/intc/arm_gicv3_cpuif.c | 19 ++-- > target/arm/helper.c | 6 ++-- > 3 files changed, 71 insertions(+), 18 deletions(-) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 2/5] target/arm: Honour HCR_EL2.TGE and MDCR_EL2.TDE in debug register access checks
On 07/24/2018 04:59 AM, Peter Maydell wrote: > Some debug registers can be trapped via MDCR_EL2 bits TDRA, TDOSA, > and TDA, which we implement in the functions access_tdra(), > access_tdosa() and access_tda(). If MDCR_EL2.TDE or HCR_EL2.TGE > are 1, the TDRA, TDOSA and TDA bits should behave as if they were 1. > Implement this by having the access functions check MDCR_EL2.TDE > and HCR_EL2.TGE. > > Signed-off-by: Peter Maydell > --- > target/arm/helper.c | 18 -- > 1 file changed, 12 insertions(+), 6 deletions(-) Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 5/5] target/arm: Treat SCTLR_EL1.M as if it were zero when HCR_EL2.TGE is set
On 07/24/2018 04:59 AM, Peter Maydell wrote: > One of the required effects of setting HCR_EL2.TGE is that when > SCR_EL3.NS is 1 then SCTLR_EL1.M must behave as if it is zero for > all purposes except direct reads. That is, it effectively disables > the MMU for the NS EL0/EL1 translation regime. > > Signed-off-by: Peter Maydell > --- > target/arm/helper.c | 8 > 1 file changed, 8 insertions(+) Reviewed-by: Richard Henderson r~
[Qemu-devel] [PULL 6/7] tests: only update last_byte when at the edge
From: Peter Xu The only possible change of last_byte is when it reaches the edge. Setting it every time might let last_byte contain an invalid data when memory corruption is detected, then the check of the next byte will be incorrect. For example, a single page corruption at address 0x14ad000 will also lead to a "fake" corruption at 0x14ae000: Memory content inconsistency at 14ad000 first_byte = 44 last_byte = 44 current = ef hit_edge = 0 Memory content inconsistency at 14ae000 first_byte = 44 last_byte = ef current = 44 hit_edge = 0 After the patch, it'll only report the corrputed page: Memory content inconsistency at 14ad000 first_byte = 44 last_byte = 44 current = ef hit_edge = 0 Signed-off-by: Peter Xu Message-Id: <20180723123305.24792-4-pet...@redhat.com> Reviewed-by: Juan Quintela Signed-off-by: Dr. David Alan Gilbert --- tests/migration-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/migration-test.c b/tests/migration-test.c index 086f727b34..e079e0bdb6 100644 --- a/tests/migration-test.c +++ b/tests/migration-test.c @@ -300,6 +300,7 @@ static void check_guests_ram(QTestState *who) * to us yet. */ hit_edge = true; +last_byte = b; } else { fprintf(stderr, "Memory content inconsistency at %x" " first_byte = %x last_byte = %x current = %x" @@ -308,7 +309,6 @@ static void check_guests_ram(QTestState *who) bad = true; } } -last_byte = b; } g_assert_false(bad); } -- 2.17.1
[Qemu-devel] [PULL 0/7] migration queue for 3.0
From: "Dr. David Alan Gilbert" The following changes since commit 3bae150448dbd888a480f892ebbf01caec0d8329: Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2018-07-24 15:26:01 +0100) are available in the Git repository at: git://github.com/dagrh/qemu.git tags/pull-migration-20180724a for you to fetch changes up to 4b3fb65db973b51346e3456987ba80b15c1fc75c: migration: fix duplicate initialization for expected_downtime and cleanup_bh (2018-07-24 17:28:57 +0100) Migration pull for 3.0 Fixes only Dr. David Alan Gilbert (2): migrate: Fix cancelling state warning audio/hda: Fix migration Lidong Chen (1): migration: fix duplicate initialization for expected_downtime and cleanup_bh Peter Xu (4): migration: fix potential overflow in multifd send migration: update recv bitmap only on dest vm migration: disallow recovery for release-ram tests: only update last_byte when at the edge hw/audio/hda-codec.c | 2 +- migration/migration.c | 22 -- migration/ram.c| 13 ++--- tests/migration-test.c | 2 +- 4 files changed, 32 insertions(+), 7 deletions(-)
Re: [Qemu-devel] [PATCH 1/5] target/arm: Mask virtual interrupts if HCR_EL2.TGE is set
On 07/24/2018 04:59 AM, Peter Maydell wrote: > If the "trap general exceptions" bit HCR_EL2.TGE is set, we > must mask all virtual interrupts (as per DDI0487C.a D1.14.3). > Implement this in arm_excp_unmasked(). > > Signed-off-by: Peter Maydell > --- > target/arm/cpu.h | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) Reviewed-by: Richard Henderson r~
[Qemu-devel] [PULL 7/7] migration: fix duplicate initialization for expected_downtime and cleanup_bh
From: Lidong Chen migrate_fd_connect duplicate initialize expected_downtime and cleanup_bh. Signed-off-by: Lidong Chen Message-Id: <1532434585-14732-2-git-send-email-lidongc...@tencent.com> Reviewed-by: Juan Quintela Signed-off-by: Dr. David Alan Gilbert --- migration/migration.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index bfc4d09aae..b7d9854bda 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -3052,8 +3052,6 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) } else { /* This is a fresh new migration */ rate_limit = s->parameters.max_bandwidth / XFER_LIMIT_RATIO; -s->expected_downtime = s->parameters.downtime_limit; -s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); /* Notify before starting migration thread */ notifier_list_notify(_state_notifiers, s); -- 2.17.1
Re: [Qemu-devel] [PATCH v7 10/10] linux-user: Add preprocessor availability control to some syscalls
On 07/24/2018 10:04 AM, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > Add ability to target platforms to individually include user-mode > support for system calls from "stat" group of system calls. > > This change is related to new nanoMIPS platform in the sense that > it supports a different set of "stat" system calls than any other > target. nanoMIPS does not support structures stat and stat64 at > all. Also, support for certain number of other system calls is > dropped in nanoMIPS (those are most of the time obsoleted system > calls). > > Without this patch, build for nanoMIPS would fail. > > Signed-off-by: Aleksandar Markovic > Signed-off-by: Stefan Markovic > Reviewed-by: Aleksandar Markovic > --- > linux-user/strace.c | 14 +- > linux-user/syscall.c | 29 + > 2 files changed, 42 insertions(+), 1 deletion(-) Acked-by: Richard Henderson r~
[Qemu-devel] [PULL 3/7] audio/hda: Fix migration
From: "Dr. David Alan Gilbert" Fix outgoing migration which was crashing in vmstate_hda_audio_stream_buf_needed, I think the problem is that we have room for upto 4 streams in the array but only use 2, when we come to try and save the state of the unused streams we hit st->state == NULL. Fixes: 280c1e1cdb24d80ecdfc Signed-off-by: Dr. David Alan Gilbert Message-Id: <20180724102215.31866-1-dgilb...@redhat.com> Reviewed-by: Daniel P. Berrangé Reviewed-by: Juan Quintela Signed-off-by: Dr. David Alan Gilbert --- hw/audio/hda-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index 2b58c3505b..617a1c1016 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -786,7 +786,7 @@ static void hda_audio_reset(DeviceState *dev) static bool vmstate_hda_audio_stream_buf_needed(void *opaque) { HDAAudioStream *st = opaque; -return st->state->use_timer; +return st->state && st->state->use_timer; } static const VMStateDescription vmstate_hda_audio_stream_buf = { -- 2.17.1
[Qemu-devel] [PULL 5/7] migration: disallow recovery for release-ram
From: Peter Xu Postcopy recovery won't work well with release-ram capability since release-ram will drop the page buffer as long as the page is put into the send buffer. So if there is a network failure happened, any page buffers that have not yet reached the destination VM but have already been sent from the source VM will be lost forever. Let's refuse the client from resuming such a postcopy migration. Luckily release-ram was designed to only be used when src and destination VMs are on the same host, so it should be fine. Signed-off-by: Peter Xu Message-Id: <20180723123305.24792-3-pet...@redhat.com> Reviewed-by: Juan Quintela Signed-off-by: Dr. David Alan Gilbert --- migration/migration.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/migration/migration.c b/migration/migration.c index db6bde7453..bfc4d09aae 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1629,6 +1629,25 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc, "paused migration"); return false; } + +/* + * Postcopy recovery won't work well with release-ram + * capability since release-ram will drop the page buffer as + * long as the page is put into the send buffer. So if there + * is a network failure happened, any page buffers that have + * not yet reached the destination VM but have already been + * sent from the source VM will be lost forever. Let's refuse + * the client from resuming such a postcopy migration. + * Luckily release-ram was designed to only be used when src + * and destination VMs are on the same host, so it should be + * fine. + */ +if (migrate_release_ram()) { +error_setg(errp, "Postcopy recovery cannot work " + "when release-ram capability is set"); +return false; +} + /* This is a resume, skip init status */ return true; } -- 2.17.1
[Qemu-devel] [PULL 4/7] migration: update recv bitmap only on dest vm
From: Peter Xu We shouldn't update the received bitmap if we're the source VM. This fixes a breakage when release-ram is enabled on postcopy. Signed-off-by: Peter Xu Message-Id: <20180723123305.24792-2-pet...@redhat.com> Reviewed-by: Juan Quintela Signed-off-by: Dr. David Alan Gilbert --- migration/ram.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index fdd108475c..24dea2730c 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -2827,8 +2827,15 @@ int ram_discard_range(const char *rbname, uint64_t start, size_t length) goto err; } -bitmap_clear(rb->receivedmap, start >> qemu_target_page_bits(), - length >> qemu_target_page_bits()); +/* + * On source VM, we don't need to update the received bitmap since + * we don't even have one. + */ +if (rb->receivedmap) { +bitmap_clear(rb->receivedmap, start >> qemu_target_page_bits(), + length >> qemu_target_page_bits()); +} + ret = ram_block_discard_range(rb, start, length); err: -- 2.17.1
[Qemu-devel] [PULL 2/7] migrate: Fix cancelling state warning
From: "Dr. David Alan Gilbert" We've been getting the warning: migration_iteration_finish: Unknown ending state 2 on a cancel. I think that's originally due to 39b9e17905c; although I've only seen the warning, I think that in some cases that we could find the VM stays paused after a cancel where it should restart. Signed-off-by: Dr. David Alan Gilbert Message-Id: <20180719092257.12703-1-dgilb...@redhat.com> Reviewed-by: Peter Xu Reviewed-by: Juan Quintela Signed-off-by: Dr. David Alan Gilbert --- migration/migration.c | 1 + 1 file changed, 1 insertion(+) diff --git a/migration/migration.c b/migration/migration.c index 8d56d56930..db6bde7453 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -2877,6 +2877,7 @@ static void migration_iteration_finish(MigrationState *s) /* Fallthrough */ case MIGRATION_STATUS_FAILED: case MIGRATION_STATUS_CANCELLED: +case MIGRATION_STATUS_CANCELLING: if (s->vm_was_running) { vm_start(); } else { -- 2.17.1
[Qemu-devel] [PULL 1/7] migration: fix potential overflow in multifd send
From: Peter Xu I would guess it won't happen normally, but this should ease Coverity. >>> CID 1394385: Integer handling issues (OVERFLOW_BEFORE_WIDEN) >>> Potentially overflowing expression "pages->used * 8192U" with type >>> "unsigned int" (32 bits, unsigned) is evaluated using 32-bit arithmetic, >>> and then used in a context that expects an expression of type "uint64_t" >>> (64 bits, unsigned). 854 transferred = pages->used * TARGET_PAGE_SIZE + p->packet_len; Fixes: CID 1394385 CC: Juan Quintela Signed-off-by: Peter Xu Message-Id: <20180720034713.11711-1-pet...@redhat.com> Reviewed-by: Juan Quintela Signed-off-by: Dr. David Alan Gilbert --- migration/ram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration/ram.c b/migration/ram.c index 52dd678092..fdd108475c 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -851,7 +851,7 @@ static void multifd_send_pages(void) p->pages->block = NULL; multifd_send_state->pages = p->pages; p->pages = pages; -transferred = pages->used * TARGET_PAGE_SIZE + p->packet_len; +transferred = ((uint64_t) pages->used) * TARGET_PAGE_SIZE + p->packet_len; ram_counters.multifd_bytes += transferred; ram_counters.transferred += transferred;; qemu_mutex_unlock(>mutex); -- 2.17.1
[Qemu-devel] [PATCH v4 55/55] linux-user: Add nanoMIPS linux user mode configuration support
From: Stefan Markovic Add new linux user mode configuration for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- configure | 13 - default-configs/nanomips-linux-user.mak | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 default-configs/nanomips-linux-user.mak diff --git a/configure b/configure index 2a7796e..86c8b28 100755 --- a/configure +++ b/configure @@ -742,6 +742,9 @@ case "$cpu" in supported_cpu="yes" cross_cc_mips=$host_cc ;; + nanomips*) +cpu="mips" + ;; sparc|sun4[cdmuv]) cpu="sparc" supported_cpu="yes" @@ -6883,7 +6886,7 @@ target_name=$(echo $target | cut -d '-' -f 1) target_bigendian="no" case "$target_name" in - armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) + armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|nanomipseb|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) target_bigendian=yes ;; esac @@ -6999,6 +7002,11 @@ case "$target_name" in moxie) target_compiler=$cross_cc_moxie ;; + nanomips|nanomipseb) +TARGET_ARCH=nanomips +TARGET_BASE_ARCH=mips +echo "TARGET_ABI_MIPSP32=y" >> $config_target_mak + ;; nios2) target_compiler=$cross_cc_nios2 ;; @@ -7256,6 +7264,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do moxie*) disas_config "MOXIE" ;; + nanomips*) +disas_config "MIPS" + ;; nios2) disas_config "NIOS2" ;; diff --git a/default-configs/nanomips-linux-user.mak b/default-configs/nanomips-linux-user.mak new file mode 100644 index 000..68fc1f7 --- /dev/null +++ b/default-configs/nanomips-linux-user.mak @@ -0,0 +1 @@ +# Default configuration for nanomips-linux-user -- 2.7.4
[Qemu-devel] [PATCH v4 49/55] linux-user: Add target_cpu.h header for nanoMIPS
From: Dimitrije Nikolic Add target_cpu.h header for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_cpu.h | 21 + 1 file changed, 21 insertions(+) create mode 100644 linux-user/nanomips/target_cpu.h diff --git a/linux-user/nanomips/target_cpu.h b/linux-user/nanomips/target_cpu.h new file mode 100644 index 000..bbb51de --- /dev/null +++ b/linux-user/nanomips/target_cpu.h @@ -0,0 +1,21 @@ +#ifndef NANOMIPS_TARGET_CPU_H +#define NANOMIPS_TARGET_CPU_H + +static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp) +{ +if (newsp) { +env->active_tc.gpr[29] = newsp; +} +env->active_tc.gpr[4] = 0; +} + +static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls) +{ +env->active_tc.CP0_UserLocal = newtls; +} + +static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) +{ +return state->active_tc.gpr[29]; +} +#endif -- 2.7.4
[Qemu-devel] [PATCH v4 46/55] linux-user: Add target_fcntl.h header for nanoMIPS
From: Aleksandar Rikalo Add fcntl-related constants and structures for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_fcntl.h | 38 ++ 1 file changed, 38 insertions(+) create mode 100644 linux-user/nanomips/target_fcntl.h diff --git a/linux-user/nanomips/target_fcntl.h b/linux-user/nanomips/target_fcntl.h new file mode 100644 index 000..4203825 --- /dev/null +++ b/linux-user/nanomips/target_fcntl.h @@ -0,0 +1,38 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) any + * later version. See the COPYING file in the top-level directory. + */ + +#ifndef NANOMIPS_TARGET_FCNTL_H +#define NANOMIPS_TARGET_FCNTL_H + +#define TARGET_O_APPEND 0x000400 +#define TARGET_O_DSYNC 0x001000 +#define TARGET_O_NONBLOCK 0x000800 +#define TARGET_O_CREAT 0x40 +#define TARGET_O_TRUNC 0x000200 +#define TARGET_O_EXCL 0x80 +#define TARGET_O_NOCTTY 0x000100 +#define TARGET_FASYNC 0x002000 +#define TARGET_O_LARGEFILE 0x008000 +#define TARGET___O_SYNC 0x101000 +#define TARGET_O_DIRECT 0x004000 +#define TARGET_O_CLOEXEC0x08 + +#define TARGET_F_GETLK 5 +#define TARGET_F_SETLK 6 +#define TARGET_F_SETLKW7 +#define TARGET_F_SETOWN8 /* for sockets. */ +#define TARGET_F_GETOWN9 /* for sockets. */ + +#define TARGET_ARCH_FLOCK_PAD abi_long pad[4]; +#define TARGET_ARCH_FLOCK64_PAD + +#define TARGET_F_GETLK64 12 /* using 'struct flock64' */ +#define TARGET_F_SETLK64 13 +#define TARGET_F_SETLKW64 14 + +#include "../generic/fcntl.h" +#endif -- 2.7.4
[Qemu-devel] [PATCH v4 44/55] linux-user: Add termbits.h header for nanoMIPS
From: Aleksandar Rikalo Add termbits.h header for nanoMIPS. Reuse MIPS' termbits.h as the functionalities are almost identical. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/termbits.h | 4 linux-user/nanomips/termbits.h | 1 + 2 files changed, 5 insertions(+) create mode 100644 linux-user/nanomips/termbits.h diff --git a/linux-user/mips/termbits.h b/linux-user/mips/termbits.h index 49a72c5..c7254f4 100644 --- a/linux-user/mips/termbits.h +++ b/linux-user/mips/termbits.h @@ -1,6 +1,10 @@ /* from asm/termbits.h */ +#ifdef TARGET_NANOMIPS +#define TARGET_NCCS 32 +#else #define TARGET_NCCS 23 +#endif struct target_termios { unsigned int c_iflag; /* input mode flags */ diff --git a/linux-user/nanomips/termbits.h b/linux-user/nanomips/termbits.h new file mode 100644 index 000..ea4e962 --- /dev/null +++ b/linux-user/nanomips/termbits.h @@ -0,0 +1 @@ +#include "../mips/termbits.h" -- 2.7.4
Re: [Qemu-devel] [PATCH for-3.1 2/2] acpi: Decouple ACPI hotplug callbacks from HotplugHandler
On Tue, Jul 24, 2018 at 05:28:44PM +0200, Igor Mammedov wrote: > On Tue, 24 Jul 2018 09:39:16 -0300 > Eduardo Habkost wrote: > > > On Tue, Jul 24, 2018 at 02:29:49PM +0200, Igor Mammedov wrote: > > > On Mon, 23 Jul 2018 16:31:45 -0300 > > > Eduardo Habkost wrote: > > > > > > > The ACPI hotplug callbacks get a HotplugHandler object as > > > > argument. This has two problems: > > > > > > > > 1) The functions require a TYPE_ACPI_DEVICE_IF object, but the > > > >function prototype doesn't indicate that. It's possible to > > > >pass an object that would make the function crash. > > > > 2) The function does not require the object to implement > > > >TYPE_HOTPLUG_HANDLER at all, but the function prototype > > > >imposes that for no reason. > > > > > > > > Change the argument type to AcpiDeviceIf instead of > > > > HotplugHandler. > > > What is the motivation for this patch, > > > do you actually get crashes? > > > > I didn't get crashes, but the idea for the change came when > > Michael asked me how to get the HotplugHandler object. I was > > going to suggest current_machine (which is also a hotplug > > handler), when I noticed he actually needed an AcpiDeviceIf > > object. > > > > The main motivation, however, is to simply make the function > > prototypes make sense. Is there a single reason to make the ACPI > > functions get a HotplugHandler argument instead of AcpiDeviceIf? > I'd rather to keep current *_cb() functions as is, > as we might actually need access to hotplug handler there and in > that case keeping more generic hotplug handler would be better > and it also sort of documents better what is being passed in. > > Also we won't have to rewrite it back from AcpiDeviceIf to > HotplugHandler again if it's needed. Personally I think type-safety is important, changing APIs isn't such a big deal. So I'd rather take Eduardo's patch unless the patches that would need to change it back are just round the corner. what's the status there? -- MST
[Qemu-devel] [PATCH v4 41/55] target/mips: Add definition of nanoMIPS I7200 CPU
From: Stefan Markovic Add definition of the first nanoMIPS processor in QEMU. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate_init.inc.c | 40 1 file changed, 40 insertions(+) diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c index c7ba6ee..d3f32e8 100644 --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -449,6 +449,46 @@ const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS, .mmu_type = MMU_TYPE_R4000, }, +{ +.name = "I7200", +.CP0_PRid = 0x0001, +.CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (0x2 << CP0C0_AR) | +(MMU_TYPE_R4000 << CP0C0_MT), +.CP0_Config1 = (1U << CP0C1_M) | (15 << CP0C1_MMU) | (2 << CP0C1_IS) | + (4 << CP0C1_IL) | (3 << CP0C1_IA) | (2 << CP0C1_DS) | + (4 << CP0C1_DL) | (3 << CP0C1_DA) | (1 << CP0C1_PC) | + (1 << CP0C1_EP), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) | + (1 << CP0C3_BI) | (1 << CP0C3_SC) | (3 << CP0C3_MMAR) | + (1 << CP0C3_ISA_ON_EXC) | (1 << CP0C3_ISA) | + (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | + (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) | + (1 << CP0C3_CTXTC) | (1 << CP0C3_VInt) | + (1 << CP0C3_CDMM) | (1 << CP0C3_MT) | (1 << CP0C3_TL), +.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | + (2 << CP0C4_IE) | (1U << CP0C4_M), +.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB), +.CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | + (1 << CP0C5_UFE), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 0, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x3158FF1F, +.CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | + (1U << CP0PG_RIE), +.CP0_PageGrain_rw_bitmask = 0, +.CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | +(1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | +(1 << FCR0_S) | (0x02 << FCR0_PRID) | (0x0 << FCR0_REV), +.CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_NANOMIPS32 | ASE_MICROMIPS | ASE_DSP | ASE_DSPR2 | + ASE_MT, +.mmu_type = MMU_TYPE_R4000, +}, #if defined(TARGET_MIPS64) { .name = "R4000", -- 2.7.4
[Qemu-devel] [PATCH v4 54/55] linux-user: Amend sigaction syscall support for nanoMIPS
From: Aleksandar Rikalo Amend sigaction syscall support for nanoMIPS. This must be done since nanoMIPS' signal handling is different than MIPS' signal handling. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 3d57966..bced9b8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8825,7 +8825,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, old_act->sa_flags = oact.sa_flags; unlock_user_struct(old_act, arg3, 1); } -#elif defined(TARGET_MIPS) +#elif defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) struct target_sigaction act, oact, *pact, *old_act; if (arg2) { -- 2.7.4
[Qemu-devel] [PATCH v4 51/55] linux-user: Add target_elf.h header for nanoMIPS
From: Dimitrije Nikolic This header includes common elf header, and adds cpu_get_model() function. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_elf.h | 14 ++ 1 file changed, 14 insertions(+) create mode 100644 linux-user/nanomips/target_elf.h diff --git a/linux-user/nanomips/target_elf.h b/linux-user/nanomips/target_elf.h new file mode 100644 index 000..ca68dab --- /dev/null +++ b/linux-user/nanomips/target_elf.h @@ -0,0 +1,14 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) any + * later version. See the COPYING file in the top-level directory. + */ + +#ifndef NANOMIPS_TARGET_ELF_H +#define NANOMIPS_TARGET_ELF_H +static inline const char *cpu_get_model(uint32_t eflags) +{ +return "I7200"; +} +#endif -- 2.7.4
[Qemu-devel] [PATCH v4 39/55] gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub
From: James Hogan nanoMIPS has no ISA bit in the PC, so remove the handling of the low bit of the PC in the MIPS gdbstub for nanoMIPS. This prevents the PC being read as e.g. 0xbfc1, and prevents writing to the PC clearing MIPS_HFLAG_M16. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/gdbstub.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c index 18e0e6d..559b69f 100644 --- a/target/mips/gdbstub.c +++ b/target/mips/gdbstub.c @@ -60,7 +60,8 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause); case 37: return gdb_get_regl(mem_buf, env->active_tc.PC | - !!(env->hflags & MIPS_HFLAG_M16)); + (!(env->insn_flags & ISA_NANOMIPS32) && + env->hflags & MIPS_HFLAG_M16)); case 72: return gdb_get_regl(mem_buf, 0); /* fp */ case 89: @@ -131,10 +132,12 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) break; case 37: env->active_tc.PC = tmp & ~(target_ulong)1; -if (tmp & 1) { -env->hflags |= MIPS_HFLAG_M16; -} else { -env->hflags &= ~(MIPS_HFLAG_M16); +if (!(env->insn_flags & ISA_NANOMIPS32)) { +if (tmp & 1) { +env->hflags |= MIPS_HFLAG_M16; +} else { +env->hflags &= ~(MIPS_HFLAG_M16); +} } break; case 72: /* fp, ignored */ -- 2.7.4
[Qemu-devel] [PATCH v4 53/55] linux-user: Add cpu_loop.c for nanoMIPS
From: Dimitrije Nikolic Amend regular MIPS' cpu_loop.c to include nanoMIPS support. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/cpu_loop.c | 8 +++- linux-user/nanomips/cpu_loop.c | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 linux-user/nanomips/cpu_loop.c diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index c9c20cf..ada5a79 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -546,7 +546,7 @@ void cpu_loop(CPUMIPSState *env) arg5, arg6, arg7, arg8); } done_syscall: -# else +# else /* N32/N64 and P32 */ ret = do_syscall(env, env->active_tc.gpr[2], env->active_tc.gpr[4], env->active_tc.gpr[5], env->active_tc.gpr[6], env->active_tc.gpr[7], @@ -562,6 +562,7 @@ done_syscall: Avoid clobbering register state. */ break; } +#if !defined(TARGET_ABI_MIPSP32) if ((abi_ulong)ret >= (abi_ulong)-1133) { env->active_tc.gpr[7] = 1; /* error flag */ ret = -ret; @@ -569,6 +570,9 @@ done_syscall: env->active_tc.gpr[7] = 0; /* error flag */ } env->active_tc.gpr[2] = ret; +#else +env->active_tc.gpr[4] = ret; +#endif break; case EXCP_TLBL: case EXCP_TLBS: @@ -714,6 +718,8 @@ done_syscall: } else { code = ((trap_instr >> 6) & ((1 << 10) - 1)); } +} else if (env->insn_flags & ISA_NANOMIPS32) { +code = ((trap_instr >> 11) & ((1 << 5) - 1)); } if (do_break(env, , code) != 0) { diff --git a/linux-user/nanomips/cpu_loop.c b/linux-user/nanomips/cpu_loop.c new file mode 100644 index 000..da4949a --- /dev/null +++ b/linux-user/nanomips/cpu_loop.c @@ -0,0 +1 @@ +#include "../mips/cpu_loop.c" -- 2.7.4
[Qemu-devel] [PATCH v4 50/55] linux-user: Add target_structs.h header for nanoMIPS
From: Dimitrije Nikolic Add target_structs.h header for nanoMIPS, that redirects to the corresponding MIPS header. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_structs.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 linux-user/nanomips/target_structs.h diff --git a/linux-user/nanomips/target_structs.h b/linux-user/nanomips/target_structs.h new file mode 100644 index 000..cc6c6ea --- /dev/null +++ b/linux-user/nanomips/target_structs.h @@ -0,0 +1 @@ +#include "../mips/target_structs.h" -- 2.7.4
[Qemu-devel] [PATCH v4 52/55] linux-user: Add signal.c for nanoMIPS
From: Dimitrije Nikolic Add signal.c as a dredirection of regular mips' signal.c, but also amend regular mips' signal.c. this is done to avoid the duplication of large pieces of code. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/signal.c | 36 +++- linux-user/nanomips/signal.c | 1 + 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 linux-user/nanomips/signal.c diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c index 6aa303e..3d7bcbc 100644 --- a/linux-user/mips/signal.c +++ b/linux-user/mips/signal.c @@ -21,7 +21,15 @@ #include "signal-common.h" #include "linux-user/trace.h" -# if defined(TARGET_ABI_MIPSO32) +#if defined(TARGET_ABI_MIPSP32) +struct target_sigcontext { +uint64_t sc_regs[32]; +uint64_t sc_pc; +uint32_t sc_used_math; +uint32_t sc_reserved; +}; +#define TARGET_ALMASK (~15) +#elif defined(TARGET_ABI_MIPSO32) struct target_sigcontext { uint32_t sc_regmask; /* Unused */ uint32_t sc_status; @@ -43,6 +51,7 @@ struct target_sigcontext { target_ulong sc_hi3; target_ulong sc_lo3; }; +#define TARGET_ALMASK (~7) # else /* N32 || N64 */ struct target_sigcontext { uint64_t sc_regs[32]; @@ -61,6 +70,7 @@ struct target_sigcontext { uint32_t sc_dsp; uint32_t sc_reserved; }; +#define TARGET_ALMASK (~15) # endif /* O32 */ struct sigframe { @@ -91,6 +101,17 @@ static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall) { int err = 0; +#if defined(TARGET_ABI_MIPSP32) +uint16_t *tramp16 = (uint16_t *)tramp; +/* + * li $2, __NR__foo_sigreturn + * syscall 0 + */ + __put_user(0x6040 , tramp16 + 0); + __put_user(syscall, tramp16 + 1); + __put_user(0 , tramp16 + 2); + __put_user(0x1008 , tramp16 + 3); +#else /* * Set up the return code ... * @@ -100,6 +121,7 @@ static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall) __put_user(0x2402 + syscall, tramp + 0); __put_user(0x000c , tramp + 1); +#endif return err; } @@ -116,6 +138,7 @@ static inline void setup_sigcontext(CPUMIPSState *regs, __put_user(regs->active_tc.gpr[i], >sc_regs[i]); } +#if !defined(TARGET_ABI_MIPSP32) __put_user(regs->active_tc.HI[0], >sc_mdhi); __put_user(regs->active_tc.LO[0], >sc_mdlo); @@ -137,6 +160,7 @@ static inline void setup_sigcontext(CPUMIPSState *regs, for (i = 0; i < 32; ++i) { __put_user(regs->active_fpu.fpr[i].d, >sc_fpregs[i]); } +#endif } static inline void @@ -146,13 +170,14 @@ restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc) __get_user(regs->CP0_EPC, >sc_pc); -__get_user(regs->active_tc.HI[0], >sc_mdhi); -__get_user(regs->active_tc.LO[0], >sc_mdlo); - for (i = 1; i < 32; ++i) { __get_user(regs->active_tc.gpr[i], >sc_regs[i]); } +#if !defined(TARGET_ABI_MIPSP32) +__get_user(regs->active_tc.HI[0], >sc_mdhi); +__get_user(regs->active_tc.LO[0], >sc_mdlo); + __get_user(regs->active_tc.HI[1], >sc_hi1); __get_user(regs->active_tc.HI[2], >sc_hi2); __get_user(regs->active_tc.HI[3], >sc_hi3); @@ -168,6 +193,7 @@ restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc) for (i = 0; i < 32; ++i) { __get_user(regs->active_fpu.fpr[i].d, >sc_fpregs[i]); } +#endif } /* @@ -185,7 +211,7 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size) */ sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka); -return (sp - frame_size) & ~7; +return (sp - frame_size) & TARGET_ALMASK; } static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env) diff --git a/linux-user/nanomips/signal.c b/linux-user/nanomips/signal.c new file mode 100644 index 000..86efc21 --- /dev/null +++ b/linux-user/nanomips/signal.c @@ -0,0 +1 @@ +#include "../mips/signal.c" -- 2.7.4
[Qemu-devel] [PATCH v4 32/55] target/mips: Fix ERET/ERETNC behavior related to ADEL exception
From: Yongbok Kim Fix ERET/ERETNC so that ADEL exception can be raised. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- target/mips/op_helper.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index c55a1e6..e6749c5 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -2430,6 +2430,13 @@ static void set_pc(CPUMIPSState *env, target_ulong error_pc) env->active_tc.PC = error_pc & ~(target_ulong)1; if (env->insn_flags & ISA_NANOMIPS32) { /* Don't clear MIPS_HFLAG_M16 */ +if (error_pc & 1) { +if (!(env->hflags & MIPS_HFLAG_DM)) { +env->CP0_BadVAddr = error_pc; +} +env->active_tc.PC = error_pc; +do_raise_exception(env, EXCP_AdEL, 0); +} return; } if (error_pc & 1) { @@ -2467,10 +2474,12 @@ void helper_eretnc(CPUMIPSState *env) void helper_deret(CPUMIPSState *env) { debug_pre_eret(env); -set_pc(env, env->CP0_DEPC); env->hflags &= ~MIPS_HFLAG_DM; compute_hflags(env); + +set_pc(env, env->CP0_DEPC); + debug_post_eret(env); } #endif /* !CONFIG_USER_ONLY */ -- 2.7.4
[Qemu-devel] [PATCH v4 47/55] linux-user: Add sockbits.h header for nanoMIPS
From: Aleksandar Rikalo Add sockbits.h header for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/sockbits.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 linux-user/nanomips/sockbits.h diff --git a/linux-user/nanomips/sockbits.h b/linux-user/nanomips/sockbits.h new file mode 100644 index 000..e6b6d31 --- /dev/null +++ b/linux-user/nanomips/sockbits.h @@ -0,0 +1 @@ +#include "../mips/sockbits.h" -- 2.7.4
[Qemu-devel] [PATCH v4 28/55] target/mips: Adjust behavior of Config3's ISAOnExc bit for nanoMIPS
From: Yongbok Kim Config3.ISAOnExc is read only in nanoMIPS. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/op_helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index cb83b6d..5e10286 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -1730,7 +1730,8 @@ void helper_mtc0_config2(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_config3(CPUMIPSState *env, target_ulong arg1) { -if (env->insn_flags & ASE_MICROMIPS) { +if ((env->insn_flags & ASE_MICROMIPS) && +!(env->insn_flags & ISA_NANOMIPS32)) { env->CP0_Config3 = (env->CP0_Config3 & ~(1 << CP0C3_ISA_ON_EXC)) | (arg1 & (1 << CP0C3_ISA_ON_EXC)); } -- 2.7.4
Re: [Qemu-devel] [PATCH 0/2] iotests: Fix 226 on _my_ system
On 07/24/2018 04:47 AM, Fam Zheng wrote: > Something has locked /dev/null on my system (I still don't know what to do > with > the annoying incapability of lslocks, or more precisely /proc/locks, on > inspecting OFD lock information), and as a result 226 cannot pass due to the > unexpected image locking error. > > Fix the test case by disabling locking, and add a doc text about using test > images. > > Fam Zheng (2): > docs: Describe using images in writing iotests > iotests: Don't lock /dev/null in 226 > > docs/devel/testing.rst | 11 +++ > tests/qemu-iotests/226 | 4 ++-- > 2 files changed, 13 insertions(+), 2 deletions(-) > I think this is the better approach for now, yeah. Sorry my test caused so many problems... :[ Reviewed-by: John Snow
[Qemu-devel] [PATCH v4 45/55] linux-user: Update syscall_defs.h header for nanoMIPS
From: Aleksandar Rikalo Update constants and structures related to syscall support in nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/syscall_defs.h | 57 ++- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 40bb60e..abf94b8 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -374,7 +374,7 @@ struct target_dirent64 { #define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ #define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ -#ifdef TARGET_MIPS +#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) #define TARGET_NSIG 128 #else #define TARGET_NSIG 64 @@ -445,7 +445,7 @@ struct target_sigaction { target_sigset_t sa_mask; abi_ulong sa_restorer; }; -#elif defined(TARGET_MIPS) +#elif defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) struct target_sigaction { uint32_tsa_flags; #if defined(TARGET_ABI_MIPSN32) @@ -459,6 +459,14 @@ struct target_sigaction { abi_ulong sa_restorer; #endif }; +#elif defined(TARGET_NANOMIPS) +struct target_sigaction { +abi_ulong _sa_handler; +abi_uint sa_flags; +target_sigset_t sa_mask; +abi_ulong sa_restorer; +}; + #else struct target_old_sigaction { abi_ulong _sa_handler; @@ -537,7 +545,7 @@ typedef struct { #define QEMU_SI_RT 5 typedef struct target_siginfo { -#ifdef TARGET_MIPS +#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) int si_signo; int si_code; int si_errno; @@ -665,13 +673,16 @@ struct target_rlimit { #if defined(TARGET_ALPHA) #define TARGET_RLIM_INFINITY 0x7fffull -#elif defined(TARGET_MIPS) || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32) +#elif (defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)) \ + || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32) #define TARGET_RLIM_INFINITY 0x7fffUL +#elif defined(TARGET_NANOMIPS) +#define TARGET_RLIM_INFINITY0x76ffeec4UL #else #define TARGET_RLIM_INFINITY ((abi_ulong)-1) #endif -#if defined(TARGET_MIPS) +#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS) #define TARGET_RLIMIT_CPU 0 #define TARGET_RLIMIT_FSIZE1 #define TARGET_RLIMIT_DATA 2 @@ -687,6 +698,22 @@ struct target_rlimit { #define TARGET_RLIMIT_MSGQUEUE 12 #define TARGET_RLIMIT_NICE 13 #define TARGET_RLIMIT_RTPRIO 14 +#elif defined(TARGET_NANOMIPS) +#define TARGET_RLIMIT_CPU 0 +#define TARGET_RLIMIT_FSIZE 1 +#define TARGET_RLIMIT_DATA 2 +#define TARGET_RLIMIT_STACK 3 +#define TARGET_RLIMIT_CORE 4 +#define TARGET_RLIMIT_RSS 5 +#define TARGET_RLIMIT_NPROC 6 +#define TARGET_RLIMIT_NOFILE7 +#define TARGET_RLIMIT_MEMLOCK 8 +#define TARGET_RLIMIT_AS9 +#define TARGET_RLIMIT_LOCKS 10 +#define TARGET_RLIMIT_SIGPENDING11 +#define TARGET_RLIMIT_MSGQUEUE 12 +#define TARGET_RLIMIT_NICE 13 +#define TARGET_RLIMIT_RTPRIO14 #else #define TARGET_RLIMIT_CPU 0 #define TARGET_RLIMIT_FSIZE1 @@ -1657,6 +1684,10 @@ struct target_stat64 { int64_t st_blocks; }; +#elif defined(TARGET_ABI_MIPSP32) + +/* No struct stat and struct stat64 structures */ + #elif defined(TARGET_ALPHA) struct target_stat { @@ -2009,6 +2040,22 @@ struct target_statfs { int32_t f_flags; int32_t f_spare[5]; }; +#elif defined(TARGET_ABI_MIPSP32) +struct target_statfs { +abi_longf_type; +abi_longf_bsize; +abi_longf_blocks; +abi_longf_bfree; +abi_longf_bavail; +abi_longf_files; +abi_longf_ffree; + +/* Linux specials */ +target_fsid_t f_fsid; +abi_longf_namelen; +abi_llong f_frsize; /* Fragment size - unsupported */ +abi_longf_spare[6]; +}; #else struct target_statfs { abi_longf_type; -- 2.7.4
[Qemu-devel] [PATCH v4 26/55] target/mips: Add updating BadInstr, BadInstrP, BadInstrX for nanoMIPS
From: Aleksandar Markovic Update BadInstr, BadInstrP,and BadInstrX registers for nanoMIPS. The same support for pre-nanoMIPS remains unimplemented. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/helper.c | 25 + 1 file changed, 25 insertions(+) diff --git a/target/mips/helper.c b/target/mips/helper.c index e215af9..b25e000 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -682,6 +682,31 @@ static void set_hflags_for_handler (CPUMIPSState *env) static inline void set_badinstr_registers(CPUMIPSState *env) { +if (env->insn_flags & ISA_NANOMIPS32) { +if (env->CP0_Config3 & (1 << CP0C3_BI)) { +uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16; +if ((instr & 0x1000) == 0) { +instr |= cpu_lduw_code(env, env->active_tc.PC + 2); +} +env->CP0_BadInstr = instr; + +if ((instr & 0xFC00) == 0x6000) { +instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16; +env->CP0_BadInstrX = instr; +} +} +if ((env->CP0_Config3 & (1 << CP0C3_BP)) && +(env->hflags & MIPS_HFLAG_BMASK)) { +if (!(env->hflags & MIPS_HFLAG_B16)) { +env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4); +} else { +env->CP0_BadInstrP = +(cpu_lduw_code(env, env->active_tc.PC - 2)) << 16; +} +} +return; +} + if (env->hflags & MIPS_HFLAG_M16) { /* TODO: add BadInstr support for microMIPS */ return; -- 2.7.4
[Qemu-devel] [PATCH v4 40/55] gdbstub: Add XML support for GDB for nanoMIPS
From: Stefan Markovic Add XML support files for GDB for nanoMIPS. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- MAINTAINERS| 3 ++- gdb-xml/nanomips-cp0.xml | 13 + gdb-xml/nanomips-cpu.xml | 44 gdb-xml/nanomips-dsp.xml | 20 gdb-xml/nanomips-fpu.xml | 45 + gdb-xml/nanomips-linux.xml | 20 6 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 gdb-xml/nanomips-cp0.xml create mode 100644 gdb-xml/nanomips-cpu.xml create mode 100644 gdb-xml/nanomips-dsp.xml create mode 100644 gdb-xml/nanomips-fpu.xml create mode 100644 gdb-xml/nanomips-linux.xml diff --git a/MAINTAINERS b/MAINTAINERS index 7130807..a4907d0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -190,6 +190,8 @@ M: Aurelien Jarno M: Aleksandar Markovic S: Maintained F: target/mips/ +F: disas/mips.c +F: gdb-xml/*ips*.xml F: hw/mips/ F: hw/misc/mips_* F: hw/intc/mips_gic.c @@ -199,7 +201,6 @@ F: include/hw/misc/mips_* F: include/hw/intc/mips_gic.h F: include/hw/timer/mips_gictimer.h F: tests/tcg/mips/ -F: disas/mips.c Moxie M: Anthony Green diff --git a/gdb-xml/nanomips-cp0.xml b/gdb-xml/nanomips-cp0.xml new file mode 100644 index 000..8095dc6 --- /dev/null +++ b/gdb-xml/nanomips-cp0.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/gdb-xml/nanomips-cpu.xml b/gdb-xml/nanomips-cpu.xml new file mode 100644 index 000..6bba224 --- /dev/null +++ b/gdb-xml/nanomips-cpu.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/nanomips-dsp.xml b/gdb-xml/nanomips-dsp.xml new file mode 100644 index 000..950910f --- /dev/null +++ b/gdb-xml/nanomips-dsp.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/gdb-xml/nanomips-fpu.xml b/gdb-xml/nanomips-fpu.xml new file mode 100644 index 000..fd225a5 --- /dev/null +++ b/gdb-xml/nanomips-fpu.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/nanomips-linux.xml b/gdb-xml/nanomips-linux.xml new file mode 100644 index 000..8a04634 --- /dev/null +++ b/gdb-xml/nanomips-linux.xml @@ -0,0 +1,20 @@ + + + + + + nanomips + GNU/Linux + + + + + + + + + -- 2.7.4
[Qemu-devel] [PATCH v4 37/55] mips_malta: Setup GT64120 BARs in nanoMIPS bootloader
From: Paul Burton Setup the GT64120 BARs in the nanoMIPS bootloader, in the same way that they are setup in the MIPS32 bootloader. This is necessary for Linux to be able to access peripherals, including the UART. Signed-off-by: Paul Burton Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- hw/mips/mips_malta.c | 73 1 file changed, 73 insertions(+) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 4bc9036..d1a7c1f 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -664,6 +664,79 @@ static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr, /* lui a3,%hi(loaderparams.ram_low_size) */ stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size)); /* ori a3,a3,%lo(loaderparams.ram_low_size) */ + +/* Load BAR registers as done by YAMON */ +stw_p(p++, 0xe040); stw_p(p++, 0x0681); +/* lui t1, %hi(0xb400) */ +#ifdef TARGET_WORDS_BIGENDIAN +stw_p(p++, 0xe020); stw_p(p++, 0x0be1); +/* lui t0, %hi(0xdf00) */ +#else +stw_p(p++, 0x0020); stw_p(p++, 0x00df); +/* addiu[32] t0, $0, 0xdf */ +#endif +stw_p(p++, 0x8422); stw_p(p++, 0x9068); +/* sw t0, 0x68(t1) */ + +stw_p(p++, 0xe040); stw_p(p++, 0x077d); +/* lui t1, %hi(0xbbe0) */ +#ifdef TARGET_WORDS_BIGENDIAN +stw_p(p++, 0xe020); stw_p(p++, 0x0801); +/* lui t0, %hi(0xc000) */ +#else +stw_p(p++, 0x0020); stw_p(p++, 0x00c0); +/* addiu[32] t0, $0, 0xc0 */ +#endif +stw_p(p++, 0x8422); stw_p(p++, 0x9048); +/* sw t0, 0x48(t1) */ +#ifdef TARGET_WORDS_BIGENDIAN +stw_p(p++, 0xe020); stw_p(p++, 0x0800); +/* lui t0, %hi(0x4000) */ +#else +stw_p(p++, 0x0020); stw_p(p++, 0x0040); +/* addiu[32] t0, $0, 0x40 */ +#endif +stw_p(p++, 0x8422); stw_p(p++, 0x9050); +/* sw t0, 0x50(t1) */ + +#ifdef TARGET_WORDS_BIGENDIAN +stw_p(p++, 0xe020); stw_p(p++, 0x0001); +/* lui t0, %hi(0x8000) */ +#else +stw_p(p++, 0x0020); stw_p(p++, 0x0080); +/* addiu[32] t0, $0, 0x80 */ +#endif +stw_p(p++, 0x8422); stw_p(p++, 0x9058); +/* sw t0, 0x58(t1) */ +#ifdef TARGET_WORDS_BIGENDIAN +stw_p(p++, 0xe020); stw_p(p++, 0x07e0); +/* lui t0, %hi(0x3f00) */ +#else +stw_p(p++, 0x0020); stw_p(p++, 0x003f); +/* addiu[32] t0, $0, 0x3f */ +#endif +stw_p(p++, 0x8422); stw_p(p++, 0x9060); +/* sw t0, 0x60(t1) */ + +#ifdef TARGET_WORDS_BIGENDIAN +stw_p(p++, 0xe020); stw_p(p++, 0x0821); +/* lui t0, %hi(0xc100) */ +#else +stw_p(p++, 0x0020); stw_p(p++, 0x00c1); +/* addiu[32] t0, $0, 0xc1 */ +#endif +stw_p(p++, 0x8422); stw_p(p++, 0x9080); +/* sw t0, 0x80(t1) */ +#ifdef TARGET_WORDS_BIGENDIAN +stw_p(p++, 0xe020); stw_p(p++, 0x0bc0); +/* lui t0, %hi(0x5e00) */ +#else +stw_p(p++, 0x0020); stw_p(p++, 0x005e); +/* addiu[32] t0, $0, 0x5e */ +#endif +stw_p(p++, 0x8422); stw_p(p++, 0x9088); +/* sw t0, 0x88(t1) */ + stw_p(p++, 0xe320 | NM_HI1(kernel_entry)); stw_p(p++, NM_HI2(kernel_entry)); /* lui t9,%hi(kernel_entry) */ -- 2.7.4
[Qemu-devel] [PATCH v4 25/55] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair
From: Yongbok Kim Implement nanoMIPS LLWP and SCWP instruction pair. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/cpu_loop.c | 25 --- target/mips/cpu.h | 2 + target/mips/helper.h | 2 + target/mips/op_helper.c| 35 +++ target/mips/translate.c| 109 + 5 files changed, 168 insertions(+), 5 deletions(-) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index 084ad6a..1d3dc9e 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -397,10 +397,13 @@ static int do_store_exclusive(CPUMIPSState *env) target_ulong addr; target_ulong page_addr; target_ulong val; +uint32_t val_wp = 0; +uint32_t llnewval_wp = 0; int flags; int segv = 0; int reg; int d; +int wp; addr = env->lladdr; page_addr = addr & TARGET_PAGE_MASK; @@ -412,19 +415,31 @@ static int do_store_exclusive(CPUMIPSState *env) } else { reg = env->llreg & 0x1f; d = (env->llreg & 0x20) != 0; -if (d) { -segv = get_user_s64(val, addr); +wp = (env->llreg & 0x40) != 0; +if (!wp) { +if (d) { +segv = get_user_s64(val, addr); +} else { +segv = get_user_s32(val, addr); +} } else { segv = get_user_s32(val, addr); +segv |= get_user_s32(val_wp, addr); +llnewval_wp = env->llnewval_wp; } if (!segv) { -if (val != env->llval) { +if (val != env->llval && val_wp == llnewval_wp) { env->active_tc.gpr[reg] = 0; } else { -if (d) { -segv = put_user_u64(env->llnewval, addr); +if (!wp) { +if (d) { +segv = put_user_u64(env->llnewval, addr); +} else { +segv = put_user_u32(env->llnewval, addr); +} } else { segv = put_user_u32(env->llnewval, addr); +segv |= put_user_u32(env->llnewval_wp, addr + 4); } if (!segv) { env->active_tc.gpr[reg] = 1; diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 009202c..2d341d7 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -506,6 +506,8 @@ struct CPUMIPSState { uint64_t lladdr; target_ulong llval; target_ulong llnewval; +uint32_t llval_wp; +uint32_t llnewval_wp; target_ulong llreg; uint64_t CP0_LLAddr_rw_bitmask; int CP0_LLAddr_shift; diff --git a/target/mips/helper.h b/target/mips/helper.h index b2a780a..deca307 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -14,6 +14,8 @@ DEF_HELPER_4(swr, void, env, tl, tl, int) #ifndef CONFIG_USER_ONLY DEF_HELPER_3(ll, tl, env, tl, int) DEF_HELPER_4(sc, tl, env, tl, tl, int) +DEF_HELPER_5(llwp, void, env, tl, i32, i32, i32) +DEF_HELPER_4(scwp, tl, env, tl, i64, int) #ifdef TARGET_MIPS64 DEF_HELPER_3(lld, tl, env, tl, int) DEF_HELPER_4(scd, tl, env, tl, tl, int) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index b3eef9f..cb83b6d 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -380,6 +380,19 @@ HELPER_LD_ATOMIC(lld, ld, 0x7) #endif #undef HELPER_LD_ATOMIC +void helper_llwp(CPUMIPSState *env, target_ulong addr, uint32_t reg1, + uint32_t reg2, uint32_t mem_idx) +{ +if (addr & 0x7) { +env->CP0_BadVAddr = addr; +do_raise_exception(env, EXCP_AdEL, GETPC()); +} +env->lladdr = do_translate_address(env, addr, 0, GETPC()); +env->active_tc.gpr[reg1] = env->llval = do_lw(env, addr, mem_idx, GETPC()); +env->active_tc.gpr[reg2] = env->llval_wp = do_lw(env, addr + 4, mem_idx, + GETPC()); +} + #define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask) \ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1, \ target_ulong arg2, int mem_idx)\ @@ -406,6 +419,28 @@ HELPER_ST_ATOMIC(sc, lw, sw, 0x3) HELPER_ST_ATOMIC(scd, ld, sd, 0x7) #endif #undef HELPER_ST_ATOMIC + +target_ulong helper_scwp(CPUMIPSState *env, target_ulong addr, + uint64_t data, int mem_idx) +{ +uint32_t tmp; +uint32_t tmp2; + +if (addr & 0x7) { +env->CP0_BadVAddr = addr; +do_raise_exception(env, EXCP_AdES, GETPC()); +} +if (do_translate_address(env, addr, 1, GETPC()) == env->lladdr) { +tmp = do_lw(env, addr, mem_idx, GETPC()); +tmp2 = do_lw(env, addr + 4, mem_idx, GETPC()); +if (tmp == env->llval && tmp2 == env->llval_wp) { +do_sw(env, addr, (uint32_t) data, mem_idx, GETPC()); +
[Qemu-devel] [PATCH v4 38/55] mips_malta: Fix semihosting argument passing for nanoMIPS bare metal
From: Stefan Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- hw/mips/mips_malta.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index d1a7c1f..8bb1686 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -643,7 +643,12 @@ static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr, stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ /* to_here: */ -stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */ +if (semihosting_get_argc()) { +/* Preserve a0 content as arguments have been passed */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +} else { +stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */ +} stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64)); stw_p(p++, NM_HI2(ENVP_ADDR - 64)); /* lui sp,%hi(ENVP_ADDR - 64) */ -- 2.7.4
[Qemu-devel] [PATCH v4 36/55] mips_malta: Add basic nanoMIPS boot code for MIPS' Malta
From: Matthew Fortune Added very very basic nanoMIPS boot code but this is hacked in unconditionally currently. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- hw/mips/mips_malta.c | 75 +++- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 3467451..4bc9036 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -620,6 +620,58 @@ static void network_init(PCIBus *pci_bus) a2 - 32-bit address of the environment variables table a3 - RAM size in bytes */ +static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr, + int64_t kernel_entry) +{ +uint16_t *p; + +/* Small bootloader */ +p = (uint16_t *)base; + +#define NM_HI1(VAL) (((VAL) >> 16) & 0x1f) +#define NM_HI2(VAL) \ +(((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1)) +#define NM_LO(VAL) ((VAL) & 0xfff) + +stw_p(p++, 0x2800); stw_p(p++, 0x001c); /* bc to_here */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ +stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */ + +/* to_here: */ +stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */ +stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64)); +stw_p(p++, NM_HI2(ENVP_ADDR - 64)); +/* lui sp,%hi(ENVP_ADDR - 64) */ +stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_ADDR - 64)); +/* ori sp,sp,%lo(ENVP_ADDR - 64) */ +stw_p(p++, 0xe0a0 | NM_HI1(ENVP_ADDR)); +stw_p(p++, NM_HI2(ENVP_ADDR)); +/* lui a1,%hi(ENVP_ADDR) */ +stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_ADDR)); +/* ori a1,a1,%lo(ENVP_ADDR) */ +stw_p(p++, 0xe0c0 | NM_HI1(ENVP_ADDR + 8)); +stw_p(p++, NM_HI2(ENVP_ADDR + 8)); +/* lui a2,%hi(ENVP_ADDR + 8) */ +stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_ADDR + 8)); +/* ori a2,a2,%lo(ENVP_ADDR + 8) */ +stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size)); +stw_p(p++, NM_HI2(loaderparams.ram_low_size)); +/* lui a3,%hi(loaderparams.ram_low_size) */ +stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size)); +/* ori a3,a3,%lo(loaderparams.ram_low_size) */ +stw_p(p++, 0xe320 | NM_HI1(kernel_entry)); +stw_p(p++, NM_HI2(kernel_entry)); +/* lui t9,%hi(kernel_entry) */ +stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry)); +/* ori t9,t9,%lo(kernel_entry) */ +stw_p(p++, 0x4bf9); stw_p(p++, 0x); +/* jalrc t8 */ +} static void write_bootloader(uint8_t *base, int64_t run_addr, int64_t kernel_entry) @@ -813,10 +865,16 @@ static int64_t load_kernel (void) NULL, (uint64_t *)_entry, NULL, (uint64_t *)_high, big_endian, EM_MIPS, 1, 0); if (kernel_size < 0) { -error_report("could not load kernel '%s': %s", - loaderparams.kernel_filename, - load_elf_strerror(kernel_size)); -exit(1); +kernel_size = load_elf(loaderparams.kernel_filename, +cpu_mips_kseg0_to_phys, NULL, +(uint64_t *)_entry, NULL, +(uint64_t *)_high, big_endian, EM_NANOMIPS, 1, 0); +if (kernel_size < 0) { +error_report("could not load kernel '%s': %s", + loaderparams.kernel_filename, + load_elf_strerror(kernel_size)); +exit(1); +} } /* Check where the kernel has been linked */ @@ -1096,8 +1154,13 @@ void mips_malta_init(MachineState *machine) loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(); -write_bootloader(memory_region_get_ram_ptr(bios), - bootloader_run_addr, kernel_entry); +if (!cpu_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) { +write_bootloader(memory_region_get_ram_ptr(bios), + bootloader_run_addr, kernel_entry); +} else { +write_bootloader_nanomips(memory_region_get_ram_ptr(bios), + bootloader_run_addr, kernel_entry); +} if (kvm_enabled()) { /* Write the bootloader code @ the end of RAM, 1MB reserved */
[Qemu-devel] [PATCH v4 48/55] linux-user: Add target_syscall.h header for nanoMIPS
From: Aleksandar Rikalo Add target_syscall.h header for nanoMIPS. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_syscall.h | 30 ++ 1 file changed, 30 insertions(+) create mode 100644 linux-user/nanomips/target_syscall.h diff --git a/linux-user/nanomips/target_syscall.h b/linux-user/nanomips/target_syscall.h new file mode 100644 index 000..b40e36b --- /dev/null +++ b/linux-user/nanomips/target_syscall.h @@ -0,0 +1,30 @@ +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct target_pt_regs { +/* Pad bytes for argument save space on the stack. */ +abi_ulong pad0[6]; + +/* Saved main processor registers. */ +abi_ulong regs[32]; + +/* Saved special registers. */ +abi_ulong cp0_status; +abi_ulong lo; +abi_ulong hi; +abi_ulong cp0_badvaddr; +abi_ulong cp0_cause; +abi_ulong cp0_epc; +}; + +/* Nasty hack: define a fake errno value for use by sigreturn. */ +#undef TARGET_QEMU_ESIGRETURN +#define TARGET_QEMU_ESIGRETURN 255 + +#define UNAME_MACHINE "nanomips" +#define UNAME_MINIMUM_RELEASE "2.6.32" + +#define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 6144 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 -- 2.7.4
[Qemu-devel] [PATCH v4 18/55] target/mips: Add emulation of nanoMIPS 32-bit load and store instructions
From: Yongbok Kim Add emulation of various nanoMIPS load and store instructions. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- target/mips/translate.c | 271 1 file changed, 271 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 0977fab..b87a29e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17671,10 +17671,281 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; case NM_P_GP_BH: +{ +uint32_t u = extract32(ctx->opcode, 0, 18); +switch ((ctx->opcode >> 18) & 0x7) { +case NM_LBGP: +gen_ld(ctx, OPC_LB, rt, 28, u); +break; +case NM_SBGP: +gen_st(ctx, OPC_SB, rt, 28, u); +break; +case NM_LBUGP: +gen_ld(ctx, OPC_LBU, rt, 28, u); +break; +case NM_ADDIUGP_B: +gen_arith_imm(ctx, OPC_ADDIU, rt, 28, u); +break; +case NM_P_GP_LH: +u &= ~1; +switch (ctx->opcode & 1) { +case NM_LHGP: +gen_ld(ctx, OPC_LH, rt, 28, u); +break; +case NM_LHUGP: +gen_ld(ctx, OPC_LHU, rt, 28, u); +break; +} +break; +case NM_P_GP_SH: +u &= ~1; +switch (ctx->opcode & 1) { +case NM_SHGP: +gen_st(ctx, OPC_SH, rt, 28, u); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_P_GP_CP1: +u &= ~0x3; +switch ((ctx->opcode & 0x3)) { +case NM_LWC1GP: +gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u); +break; +case NM_LDC1GP: +gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u); +break; +case NM_SWC1GP: +gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u); +break; +case NM_SDC1GP: +gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u); +break; +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +} break; case NM_P_LS_U12: +{ +uint32_t u = extract32(ctx->opcode, 0, 12); +switch ((ctx->opcode >> 12) & 0x0f) { +case NM_P_PREFU12: +if (rt == 31) { +/* SYNCI */ +/* Break the TB to be able to sync copied instructions + immediately */ +ctx->base.is_jmp = DISAS_STOP; +} else { +/* PREF */ +/* Treat as NOP. */ +} +break; +case NM_LB: +gen_ld(ctx, OPC_LB, rt, rs, u); +break; +case NM_LH: +gen_ld(ctx, OPC_LH, rt, rs, u); +break; +case NM_LW: +gen_ld(ctx, OPC_LW, rt, rs, u); +break; +case NM_LBU: +gen_ld(ctx, OPC_LBU, rt, rs, u); +break; +case NM_LHU: +gen_ld(ctx, OPC_LHU, rt, rs, u); +break; +case NM_SB: +gen_st(ctx, OPC_SB, rt, rs, u); +break; +case NM_SH: +gen_st(ctx, OPC_SH, rt, rs, u); +break; +case NM_SW: +gen_st(ctx, OPC_SW, rt, rs, u); +break; +case NM_LWC1: +gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u); +break; +case NM_LDC1: +gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u); +break; +case NM_SWC1: +gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u); +break; +case NM_SDC1: +gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +} break; case NM_P_LS_S9: +{ +int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) | +extract32(ctx->opcode, 0, 8); +switch ((ctx->opcode >> 8) & 0x07) { +case NM_P_LS_S0: +switch ((ctx->opcode >> 11) & 0x0f) { +case NM_LBS9: +gen_ld(ctx, OPC_LB, rt, rs, s); +
[Qemu-devel] [PATCH v4 35/55] elf: Don't check FCR31_NAN2008 bit for nanoMIPS
From: Aleksandar Markovic nanoMIPS is always NaN2008 compliant, and rules for checking FCR31's NAN2008 bit are obsoleted. Reviewed-by: Richard Henderson Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/mips/cpu_loop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index 1d3dc9e..c9c20cf 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -747,6 +747,9 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) if (regs->cp0_epc & 1) { env->hflags |= MIPS_HFLAG_M16; } +if (env->insn_flags & ISA_NANOMIPS32) { +return; +} if (((info->elf_flags & EF_MIPS_NAN2008) != 0) != ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) { if ((env->active_fpu.fcr31_rw_bitmask & -- 2.7.4
[Qemu-devel] [PATCH v4 34/55] elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too
From: Aleksandar Markovic Starting from nanoMIPS introduction, machine variant can be EM_MIPS or EM_NANOMIPS. Reviewed-by: Richard Henderson Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/elfload.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index df07055..8638612 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -853,6 +853,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en #endif #define ELF_ARCHEM_MIPS +#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_NANOMIPS) + static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { -- 2.7.4
[Qemu-devel] [PATCH v4 43/55] linux-user: Add target_signal.h header for nanoMIPS
From: Aleksandar Rikalo nanoMIPS signal handling is much closer to the signal handling in other mainstream platforms that to the signal handling in preceding MIPS platforms. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/target_signal.h | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 linux-user/nanomips/target_signal.h diff --git a/linux-user/nanomips/target_signal.h b/linux-user/nanomips/target_signal.h new file mode 100644 index 000..604e853 --- /dev/null +++ b/linux-user/nanomips/target_signal.h @@ -0,0 +1,22 @@ +#ifndef NANOMIPS_TARGET_SIGNAL_H +#define NANOMIPS_TARGET_SIGNAL_H + +#include "../generic/signal.h" +#undef TARGET_SIGRTMIN +#define TARGET_SIGRTMIN 35 + +/* this struct defines a stack used during syscall handling */ +typedef struct target_sigaltstack { +abi_long ss_sp; +abi_ulong ss_size; +abi_long ss_flags; +} target_stack_t; + +/* sigaltstack controls */ +#define TARGET_SS_ONSTACK 1 +#define TARGET_SS_DISABLE 2 + +#define TARGET_MINSIGSTKSZ6144 +#define TARGET_SIGSTKSZ 12288 + +#endif -- 2.7.4
[Qemu-devel] [PATCH v4 17/55] target/mips: Implement emulation of nanoMIPS EXTW instruction
From: James Hogan Implement emulation of nanoMIPS EXTW instruction. EXTW instruction is similar to the MIPS r6 ALIGN instruction, except that it counts the other way and in bits instead of bytes. We therefore generalise gen_align() function into a new gen_align_bits() function (which counts in bits instead of bytes and optimises when bits = size of the word), and implement gen_align() and a new gen_ext() based on that. Since we need to know the word size to check for when the number of bits == the word size, the opc argument is replaced with a wordsz argument (either 32 or 64). Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Richard Henderson --- target/mips/translate.c | 53 + 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 1d2bc02..0977fab 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4723,8 +4723,8 @@ static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt, return; } -static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt, - int bp) +static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, + int rt, int bits) { TCGv t0; if (rd == 0) { @@ -4732,35 +4732,40 @@ static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt, return; } t0 = tcg_temp_new(); -gen_load_gpr(t0, rt); -if (bp == 0) { -switch (opc) { -case OPC_ALIGN: +if (bits == 0 || bits == wordsz) { +if (bits == 0) { +gen_load_gpr(t0, rt); +} else { +gen_load_gpr(t0, rs); +} +switch (wordsz) { +case 32: tcg_gen_ext32s_tl(cpu_gpr[rd], t0); break; #if defined(TARGET_MIPS64) -case OPC_DALIGN: +case 64: tcg_gen_mov_tl(cpu_gpr[rd], t0); break; #endif } } else { TCGv t1 = tcg_temp_new(); +gen_load_gpr(t0, rt); gen_load_gpr(t1, rs); -switch (opc) { -case OPC_ALIGN: +switch (wordsz) { +case 32: { TCGv_i64 t2 = tcg_temp_new_i64(); tcg_gen_concat_tl_i64(t2, t1, t0); -tcg_gen_shri_i64(t2, t2, 8 * (4 - bp)); +tcg_gen_shri_i64(t2, t2, 32 - bits); gen_move_low32(cpu_gpr[rd], t2); tcg_temp_free_i64(t2); } break; #if defined(TARGET_MIPS64) -case OPC_DALIGN: -tcg_gen_shli_tl(t0, t0, 8 * bp); -tcg_gen_shri_tl(t1, t1, 8 * (8 - bp)); +case 64: +tcg_gen_shli_tl(t0, t0, bits); +tcg_gen_shri_tl(t1, t1, 64 - bits); tcg_gen_or_tl(cpu_gpr[rd], t1, t0); break; #endif @@ -4771,6 +4776,18 @@ static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt, tcg_temp_free(t0); } +static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, + int bp) +{ +gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); +} + +static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt, +int shift) +{ +gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift); +} + static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) { TCGv t0; @@ -14233,8 +14250,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) break; case ALIGN: check_insn(ctx, ISA_MIPS32R6); -gen_align(ctx, OPC_ALIGN, rd, rs, rt, - extract32(ctx->opcode, 9, 2)); +gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2)); break; case EXT: gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd); @@ -17364,6 +17380,9 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_lsa(ctx, OPC_LSA, rd, rs, rt, extract32(ctx->opcode, 9, 2) - 1); break; +case NM_EXTW: +gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5)); +break; case NM_POOL32AXF: gen_pool32axf_nanomips_insn(env, ctx); break; @@ -20264,7 +20283,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) switch (op2) { case OPC_ALIGN: case OPC_ALIGN_END: -gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3); +gen_align(ctx, 32, rd, rs, rt, sa & 3); break; case OPC_BITSWAP: gen_bitswap(ctx, op2, rd, rt); @@ -20290,7 +20309,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
[Qemu-devel] [PATCH v4 31/55] target/mips: Adjust set_pc() for nanoMIPS
From: James Hogan ERET and ERETNC shouldn't clear MIPS_HFLAG_M16 for nanoMIPS since there is no ISA bit, so fix set_pc() to skip the hflags update. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- target/mips/op_helper.c | 4 1 file changed, 4 insertions(+) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 5e10286..c55a1e6 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -2428,6 +2428,10 @@ static void debug_post_eret(CPUMIPSState *env) static void set_pc(CPUMIPSState *env, target_ulong error_pc) { env->active_tc.PC = error_pc & ~(target_ulong)1; +if (env->insn_flags & ISA_NANOMIPS32) { +/* Don't clear MIPS_HFLAG_M16 */ +return; +} if (error_pc & 1) { env->hflags |= MIPS_HFLAG_M16; } else { -- 2.7.4
[Qemu-devel] [PATCH v4 24/55] target/mips: Add handling of branch delay slots for nanoMIPS
From: Matthew Fortune ISA mode bit (LSB of address) is no longer required but is also masked to allow for tools transition. The flag has_isa_mode has the key role in the implementation. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index a8fbbe6..1c86145 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1458,6 +1458,7 @@ typedef struct DisasContext { bool mrp; bool nan2008; bool abs2008; +bool has_isa_mode; } DisasContext; #define DISAS_STOP DISAS_TARGET_0 @@ -4538,7 +4539,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, if (blink > 0) { int post_delay = insn_bytes + delayslot_size; -int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); +int lowbit = ctx->has_isa_mode && !!(ctx->hflags & MIPS_HFLAG_M16); tcg_gen_movi_tl(cpu_gpr[blink], ctx->base.pc_next + post_delay + lowbit); @@ -10991,7 +10992,8 @@ static void gen_branch(DisasContext *ctx, int insn_bytes) break; case MIPS_HFLAG_BR: /* unconditional branch to register */ -if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { +if (ctx->has_isa_mode && +(ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS))) { TCGv t0 = tcg_temp_new(); TCGv_i32 t1 = tcg_temp_new_i32(); @@ -11027,7 +11029,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, int bcond_compute = 0; TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); -int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; +int m16_lowbit = ctx->has_isa_mode && ((ctx->hflags & MIPS_HFLAG_M16) != 0); if (ctx->hflags & MIPS_HFLAG_BMASK) { #ifdef MIPS_DEBUG_DISAS @@ -24751,6 +24753,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; +ctx->has_isa_mode = ((env->CP0_Config3 >> CP0C3_MMAR) & 0x7) != 3; restore_cpu_state(env, ctx); #ifdef CONFIG_USER_ONLY ctx->mem_idx = MIPS_HFLAG_UM; -- 2.7.4
[Qemu-devel] [PATCH v4 42/55] linux-user: Add syscall numbers for nanoMIPS
From: Aleksandar Rikalo Add syscall numbers for nanoMIPS. nanoMIPS redefines its ABI compared to preceding MIPS architectures, and its set of supported system calls is significantly different. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- linux-user/nanomips/syscall_nr.h | 275 +++ 1 file changed, 275 insertions(+) create mode 100644 linux-user/nanomips/syscall_nr.h diff --git a/linux-user/nanomips/syscall_nr.h b/linux-user/nanomips/syscall_nr.h new file mode 100644 index 000..b826e5c --- /dev/null +++ b/linux-user/nanomips/syscall_nr.h @@ -0,0 +1,275 @@ +/* + * Linux mipsp32 style syscalls. + */ +#define TARGET_NR_io_setup 0 +#define TARGET_NR_io_destroy 1 +#define TARGET_NR_io_submit 2 +#define TARGET_NR_io_cancel 3 +#define TARGET_NR_io_getevents 4 +#define TARGET_NR_setxattr 5 +#define TARGET_NR_lsetxattr 6 +#define TARGET_NR_fsetxattr 7 +#define TARGET_NR_getxattr 8 +#define TARGET_NR_lgetxattr 9 +#define TARGET_NR_fgetxattr 10 +#define TARGET_NR_listxattr 11 +#define TARGET_NR_llistxattr 12 +#define TARGET_NR_flistxattr 13 +#define TARGET_NR_removexattr14 +#define TARGET_NR_lremovexattr 15 +#define TARGET_NR_fremovexattr 16 +#define TARGET_NR_getcwd 17 +#define TARGET_NR_lookup_dcookie 18 +#define TARGET_NR_eventfd2 19 +#define TARGET_NR_epoll_create1 20 +#define TARGET_NR_epoll_ctl 21 +#define TARGET_NR_epoll_pwait22 +#define TARGET_NR_dup23 +#define TARGET_NR_dup3 24 +#define TARGET_NR_fcntl6425 +#define TARGET_NR_inotify_init1 26 +#define TARGET_NR_inotify_add_watch 27 +#define TARGET_NR_inotify_rm_watch 28 +#define TARGET_NR_ioctl 29 +#define TARGET_NR_ioprio_set 30 +#define TARGET_NR_ioprio_get 31 +#define TARGET_NR_flock 32 +#define TARGET_NR_mknodat33 +#define TARGET_NR_mkdirat34 +#define TARGET_NR_unlinkat 35 +#define TARGET_NR_symlinkat 36 +#define TARGET_NR_linkat 37 +#define TARGET_NR_umount239 +#define TARGET_NR_mount 40 +#define TARGET_NR_pivot_root 41 +#define TARGET_NR_nfsservctl 42 +#define TARGET_NR_statfs64 43 +#define TARGET_NR_fstatfs64 44 +#define TARGET_NR_truncate64 45 +#define TARGET_NR_ftruncate6446 +#define TARGET_NR_fallocate 47 +#define TARGET_NR_faccessat 48 +#define TARGET_NR_chdir 49 +#define TARGET_NR_fchdir 50 +#define TARGET_NR_chroot 51 +#define TARGET_NR_fchmod 52 +#define TARGET_NR_fchmodat 53 +#define TARGET_NR_fchownat 54 +#define TARGET_NR_fchown 55 +#define TARGET_NR_openat 56 +#define TARGET_NR_close 57 +#define TARGET_NR_vhangup58 +#define TARGET_NR_pipe2 59 +#define TARGET_NR_quotactl 60 +#define TARGET_NR_getdents64 61 +#define TARGET_NR__llseek62 +#define TARGET_NR_read 63 +#define TARGET_NR_write 64 +#define TARGET_NR_readv 65 +#define TARGET_NR_writev 66 +#define TARGET_NR_pread6467 +#define TARGET_NR_pwrite64 68 +#define TARGET_NR_preadv 69 +#define TARGET_NR_pwritev70 +#define TARGET_NR_sendfile64 71 +#define TARGET_NR_pselect6 72 +#define TARGET_NR_ppoll 73 +#define TARGET_NR_signalfd4 74 +#define TARGET_NR_vmsplice 75 +#define TARGET_NR_splice 76 +#define TARGET_NR_tee77 +#define TARGET_NR_readlinkat 78 +#define TARGET_NR_sync 81 +#define TARGET_NR_fsync 82 +#define TARGET_NR_fdatasync 83 +#define TARGET_NR_sync_file_range2 84 +#define TARGET_NR_timerfd_create 85 +#define TARGET_NR_timerfd_settime86 +#define TARGET_NR_timerfd_gettime87 +#define TARGET_NR_utimensat 88 +#define TARGET_NR_acct 89 +#define TARGET_NR_capget
[Qemu-devel] [PATCH v4 13/55] target/mips: Add emulation of misc nanoMIPS instructions (pool32a0)
From: Yongbok Kim Add emulation of nanoMIPS instructions that are situated in pool32a0. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- target/mips/translate.c | 190 1 file changed, 190 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 90b1a1d..e5ebdb9 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16590,6 +16590,186 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx) } } +static void gen_pool32a0_nanomips_insn(DisasContext *ctx) +{ +int rt = (ctx->opcode >> 21) & 0x1f; +int rs = (ctx->opcode >> 16) & 0x1f; +int rd = (ctx->opcode >> 11) & 0x1f; + +switch ((ctx->opcode >> 3) & 0x7f) { +case NM_P_TRAP: +switch ((ctx->opcode >> 10) & 0x1) { +case NM_TEQ: +gen_trap(ctx, OPC_TEQ, rs, rt, -1); +break; +case NM_TNE: +gen_trap(ctx, OPC_TNE, rs, rt, -1); +break; +} +break; +case NM_RDHWR: +gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); +break; +case NM_SEB: +gen_bshfl(ctx, OPC_SEB, rs, rt); +break; +case NM_SEH: +gen_bshfl(ctx, OPC_SEH, rs, rt); +break; +case NM_SLLV: +gen_shift(ctx, OPC_SLLV, rd, rt, rs); +break; +case NM_SRLV: +gen_shift(ctx, OPC_SRLV, rd, rt, rs); +break; +case NM_SRAV: +gen_shift(ctx, OPC_SRAV, rd, rt, rs); +break; +case NM_ROTRV: +gen_shift(ctx, OPC_ROTRV, rd, rt, rs); +break; +case NM_ADD: +gen_arith(ctx, OPC_ADD, rd, rs, rt); +break; +case NM_ADDU: +gen_arith(ctx, OPC_ADDU, rd, rs, rt); +break; +case NM_SUB: +gen_arith(ctx, OPC_SUB, rd, rs, rt); +break; +case NM_SUBU: +gen_arith(ctx, OPC_SUBU, rd, rs, rt); +break; +case NM_P_CMOVE: +switch ((ctx->opcode >> 10) & 1) { +case NM_MOVZ: +gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); +break; +case NM_MOVN: +gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); +break; +} +break; +case NM_AND: +gen_logic(ctx, OPC_AND, rd, rs, rt); +break; +case NM_OR: +gen_logic(ctx, OPC_OR, rd, rs, rt); +break; +case NM_NOR: +gen_logic(ctx, OPC_NOR, rd, rs, rt); +break; +case NM_XOR: +gen_logic(ctx, OPC_XOR, rd, rs, rt); +break; +case NM_SLT: +gen_slt(ctx, OPC_SLT, rd, rs, rt); +break; +case NM_P_SLTU: +if (rd == 0) { +/* P_DVP */ +#ifndef CONFIG_USER_ONLY +TCGv t0 = tcg_temp_new(); +switch ((ctx->opcode >> 10) & 1) { +case NM_DVP: +if (ctx->vp) { +check_cp0_enabled(ctx); +gen_helper_dvp(t0, cpu_env); +gen_store_gpr(t0, rt); +} +break; +case NM_EVP: +if (ctx->vp) { +check_cp0_enabled(ctx); +gen_helper_evp(t0, cpu_env); +gen_store_gpr(t0, rt); +} +break; +} +tcg_temp_free(t0); +#endif +} else { +gen_slt(ctx, OPC_SLTU, rd, rs, rt); +} +break; +case NM_SOV: +{ +TCGv t0 = tcg_temp_local_new(); +TCGv t1 = tcg_temp_new(); +TCGv t2 = tcg_temp_new(); +TCGLabel *l1 = gen_new_label(); + +gen_load_gpr(t1, rs); +gen_load_gpr(t2, rt); +tcg_gen_add_tl(t0, t1, t2); +tcg_gen_ext32s_tl(t0, t0); +tcg_gen_xor_tl(t1, t1, t2); +tcg_gen_xor_tl(t2, t0, t2); +tcg_gen_andc_tl(t1, t2, t1); + +tcg_gen_movi_tl(t0, 0); +tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); +/* operands of same sign, result different sign */ + +tcg_gen_movi_tl(t0, 1); +gen_set_label(l1); +gen_store_gpr(t0, rd); + +tcg_temp_free(t0); +tcg_temp_free(t1); +tcg_temp_free(t2); +} +break; +case NM_MUL: +gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); +break; +case NM_MUH: +gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); +break; +case NM_MULU: +gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); +break; +case NM_MUHU: +gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); +break; +case NM_DIV: +gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); +break; +case NM_MOD: +gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); +break; +case NM_DIVU: +gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); +break; +case NM_MODU: +gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); +break; +#ifndef
[Qemu-devel] [PATCH v4 29/55] target/mips: Adjust exception_resume_pc() for nanoMIPS
From: James Hogan We shouldn't set the ISA bit in CP0_EPC for nanoMIPS. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/mips/helper.c b/target/mips/helper.c index a576fa4..371fecf 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -656,7 +656,8 @@ target_ulong exception_resume_pc (CPUMIPSState *env) target_ulong bad_pc; target_ulong isa_mode; -isa_mode = !!(env->hflags & MIPS_HFLAG_M16); +isa_mode = env->hflags & MIPS_HFLAG_M16 && +!(env->insn_flags & ISA_NANOMIPS32); bad_pc = env->active_tc.PC | isa_mode; if (env->hflags & MIPS_HFLAG_BMASK) { /* If the exception was raised from a delay slot, come back to -- 2.7.4
[Qemu-devel] [PATCH v4 23/55] target/mips: Add emulation of DSP ASE for nanoMIPS - part 3
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 3. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 751 1 file changed, 751 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index cbdb613..a8fbbe6 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16867,13 +16867,758 @@ static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) } } +/* dsp */ +static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc, +int ret, int v1, int v2) +{ +TCGv_i32 t0; +TCGv v0_t; +TCGv v1_t; + +t0 = tcg_temp_new_i32(); + +v0_t = tcg_temp_new(); +v1_t = tcg_temp_new(); + +tcg_gen_movi_i32(t0, v2 >> 3); + +gen_load_gpr(v0_t, ret); +gen_load_gpr(v1_t, v1); + +switch (opc) { +case NM_MAQ_S_W_PHR: +check_dsp(ctx); +gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env); +break; +case NM_MAQ_S_W_PHL: +check_dsp(ctx); +gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env); +break; +case NM_MAQ_SA_W_PHR: +check_dsp(ctx); +gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env); +break; +case NM_MAQ_SA_W_PHL: +check_dsp(ctx); +gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} + +tcg_temp_free_i32(t0); + +tcg_temp_free(v0_t); +tcg_temp_free(v1_t); +} + + +static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, +int ret, int v1, int v2) +{ +int16_t imm; + +TCGv t0; +TCGv t1; +TCGv v0_t; +TCGv v1_t; + +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +v0_t = tcg_temp_new(); +v1_t = tcg_temp_new(); + +gen_load_gpr(v0_t, ret); +gen_load_gpr(v1_t, v1); + +switch (opc) { +case NM_POOL32AXF_1_0: +switch ((ctx->opcode >> 12) & 0x03) { +case NM_MFHI: +gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret); +break; +case NM_MFLO: +gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret); +break; +case NM_MTHI: +gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1); +break; +case NM_MTLO: +gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1); +break; +} +break; +case NM_POOL32AXF_1_1: +switch ((ctx->opcode >> 12) & 0x03) { +case NM_MTHLIP: +tcg_gen_movi_tl(t0, v2); +gen_helper_mthlip(t0, v1_t, cpu_env); +break; +case NM_SHILOV: +tcg_gen_movi_tl(t0, v2 >> 3); +gen_helper_shilo(t0, v1_t, cpu_env); +break; +} +break; +case NM_POOL32AXF_1_3: +imm = (ctx->opcode >> 14) & 0x07F; +switch ((ctx->opcode >> 12) & 0x03) { +case NM_RDDSP: +tcg_gen_movi_tl(t0, imm); +gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); +break; +case NM_WRDSP: +tcg_gen_movi_tl(t0, imm); +gen_helper_wrdsp(v0_t, t0, cpu_env); +break; +case NM_EXTP: +tcg_gen_movi_tl(t0, v2 >> 3); +tcg_gen_movi_tl(t1, v1); +gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); +break; +case NM_EXTPDP: +tcg_gen_movi_tl(t0, v2 >> 3); +tcg_gen_movi_tl(t1, v1); +gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); +break; +} +break; +case NM_POOL32AXF_1_4: +tcg_gen_movi_tl(t0, v2 >> 2); +switch ((ctx->opcode >> 12) & 0x01) { +case NM_SHLL_QB: +check_dsp(ctx); +gen_helper_shll_qb(cpu_gpr[ret], t0, v1_t, cpu_env); +break; +case NM_SHRL_QB: +check_dsp(ctx); +gen_helper_shrl_qb(cpu_gpr[ret], t0, v1_t); +break; +} +break; +case NM_POOL32AXF_1_5: +{ +uint32_t opc = (ctx->opcode >> 12) & 0x03; +gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2); +} +break; +case NM_POOL32AXF_1_7: +tcg_gen_movi_tl(t0, v2 >> 3); +tcg_gen_movi_tl(t1, v1); +switch ((ctx->opcode >> 12) & 0x03) { +case NM_EXTR_W: +gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); +break; +case NM_EXTR_R_W: +gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); +break; +case NM_EXTR_RS_W: +gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); +break; +case NM_EXTR_S_H: +gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); +break; +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +
[Qemu-devel] [PATCH v4 33/55] elf: Add nanoMIPS specific variations in ELF header fields
From: Aleksandar Markovic Add nanoMIPS-related values in ELF header fields as specified in nanoMIPS' "ELF ABI Supplement". Acked-by: Richard Henderson Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- include/elf.h | 20 1 file changed, 20 insertions(+) diff --git a/include/elf.h b/include/elf.h index 2c4fe7a..fff5967 100644 --- a/include/elf.h +++ b/include/elf.h @@ -62,6 +62,24 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_NAN2008 0x0400 #define EF_MIPS_ARCH 0xf000 +/* nanoMIPS architecture bits, EF_NANOMIPS_ARCH */ +#define EF_NANOMIPS_ARCH_32R6 0x /* 32-bit nanoMIPS Release 6 ISA */ +#define EF_NANOMIPS_ARCH_64R6 0x1000 /* 62-bit nanoMIPS Release 6 ISA */ + +/* nanoMIPS ABI bits, EF_NANOMIPS_ABI */ +#define EF_NANOMIPS_ABI_P32 0x1000 /* 32-bit nanoMIPS ABI */ +#define EF_NANOMIPS_ABI_P64 0x2000 /* 64-bit nanoMIPS ABI */ + +/* nanoMIPS processor specific flags, e_flags */ +#define EF_NANOMIPS_LINKRELAX 0x0001 /* Link-time relaxation*/ +#define EF_NANOMIPS_PIC 0x0002 /* Position independant code */ +#define EF_NANOMIPS_32BITMODE 0x0004 /* 32-bit object for 64-bit arch. */ +#define EF_NANOMIPS_PID 0x0008 /* Position independant data */ +#define EF_NANOMIPS_PCREL 0x0010 /* PC-relative mode*/ +#define EF_NANOMIPS_ABI 0xf000 /* nanoMIPS ABI*/ +#define EF_NANOMIPS_MACH 0x00ff /* Machine variant */ +#define EF_NANOMIPS_ARCH 0xf000 /* nanoMIPS architecture */ + /* MIPS machine variant */ #define EF_MIPS_MACH_NONE 0x /* A standard MIPS implementation */ #define EF_MIPS_MACH_3900 0x0081 /* Toshiba R3900 */ @@ -143,6 +161,8 @@ typedef int64_t Elf64_Sxword; #define EM_RISCV243 /* RISC-V */ +#define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */ + /* * This is an interim value that we will use until the committee comes * up with a final number. -- 2.7.4
[Qemu-devel] [PATCH v4 12/55] target/mips: Add emulation of nanoMIPS FP instructions
From: Yongbok Kim Add emulation of basic floating point arithmetic for nanoMIPS. Reviewed-by: Richard Henderson Reviewed-by: Aleksandar Markovic Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 300 1 file changed, 300 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index f5f722d..90b1a1d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16590,6 +16590,305 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx) } } +static void gen_pool32f_nanomips_insn(DisasContext *ctx) +{ +int rt, rs, rd; + +rt = extract32(ctx->opcode, 21, 5); +rs = extract32(ctx->opcode, 16, 5); +rd = extract32(ctx->opcode, 11, 5); + +if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { +generate_exception_end(ctx, EXCP_RI); +return; +} +check_cp1_enabled(ctx); +switch (extract32(ctx->opcode, 0, 3)) { +case NM_POOL32F_0: +switch (extract32(ctx->opcode, 3, 7)) { +case NM_RINT_S: +gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); +break; +case NM_RINT_D: +gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); +break; +case NM_CLASS_S: +gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); +break; +case NM_CLASS_D: +gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); +break; +case NM_ADD_S: +gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0); +break; +case NM_ADD_D: +gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0); +break; +case NM_SUB_S: +gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0); +break; +case NM_SUB_D: +gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0); +break; +case NM_MUL_S: +gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0); +break; +case NM_MUL_D: +gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0); +break; +case NM_DIV_S: +gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0); +break; +case NM_DIV_D: +gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0); +break; +case NM_SELEQZ_S: +gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); +break; +case NM_SELEQZ_D: +gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); +break; +case NM_SELNEZ_S: +gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); +break; +case NM_SELNEZ_D: +gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); +break; +case NM_SEL_S: +gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); +break; +case NM_SEL_D: +gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); +break; +case NM_MADDF_S: +gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0); +break; +case NM_MADDF_D: +gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0); +break; +case NM_MSUBF_S: +gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0); +break; +case NM_MSUBF_D: +gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} +break; +case NM_POOL32F_3: +switch (extract32(ctx->opcode, 3, 3)) { +case NM_MIN_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); +break; +} +break; +case NM_MAX_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); +break; +} +break; +case NM_MINA_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); +break; +} +break; +case NM_MAXA_FMT: +switch (extract32(ctx->opcode, 9, 1)) { +case FMT_SDPS_S: +gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); +break; +case FMT_SDPS_D: +gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); +break; +} +break; +case NM_POOL32FXF: +switch (extract32(ctx->opcode, 6, 8)) { +case NM_CFC1: +
[Qemu-devel] [PATCH v4 21/55] target/mips: Add emulation of DSP ASE for nanoMIPS - part 1
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 1. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 525 1 file changed, 525 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index c09416b..e70359d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17541,6 +17541,525 @@ static void gen_pool32f_nanomips_insn(DisasContext *ctx) } } +static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, + int rd, int rs, int rt) +{ +int ret = rd; + +TCGv t1; +TCGv v1_t; +TCGv v2_t; + +t1 = tcg_temp_new(); +v1_t = tcg_temp_new(); +v2_t = tcg_temp_new(); + +gen_load_gpr(v1_t, rs); +gen_load_gpr(v2_t, rt); + +switch (opc) { +case OPC_CMP_EQ_PH: +check_dsp(ctx); +gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); +break; +case OPC_CMP_LT_PH: +check_dsp(ctx); +gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); +break; +case OPC_CMP_LE_PH: +check_dsp(ctx); +gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); +break; +case OPC_CMPU_EQ_QB: +check_dsp(ctx); +gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); +break; +case OPC_CMPU_LT_QB: +check_dsp(ctx); +gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); +break; +case OPC_CMPU_LE_QB: +check_dsp(ctx); +gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); +break; +case OPC_CMPGU_EQ_QB: +check_dsp(ctx); +gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); +break; +case OPC_CMPGU_LT_QB: +check_dsp(ctx); +gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); +break; +case OPC_CMPGU_LE_QB: +check_dsp(ctx); +gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); +break; +case OPC_CMPGDU_EQ_QB: +check_dspr2(ctx); +gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); +tcg_gen_mov_tl(cpu_gpr[ret], t1); +tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FF); +tcg_gen_shli_tl(t1, t1, 24); +tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); +break; +case OPC_CMPGDU_LT_QB: +check_dspr2(ctx); +gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); +tcg_gen_mov_tl(cpu_gpr[ret], t1); +tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FF); +tcg_gen_shli_tl(t1, t1, 24); +tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); +break; +case OPC_CMPGDU_LE_QB: +check_dspr2(ctx); +gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); +tcg_gen_mov_tl(cpu_gpr[ret], t1); +tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FF); +tcg_gen_shli_tl(t1, t1, 24); +tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); +break; +case OPC_PACKRL_PH: +check_dsp(ctx); +gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); +break; +case OPC_PICK_QB: +check_dsp(ctx); +gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); +break; +case OPC_PICK_PH: +check_dsp(ctx); +gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); +break; +case OPC_ADDQ_S_W: +check_dsp(ctx); +gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); +break; +case OPC_SUBQ_S_W: +check_dsp(ctx); +gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); +break; +case OPC_ADDSC: +check_dsp(ctx); +gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); +break; +case OPC_ADDWC: +check_dsp(ctx); +gen_helper_addwc(cpu_gpr[rd], v1_t, v2_t, cpu_env); +break; +case OPC_ADDQ_S_PH: +switch ((ctx->opcode >> 10) & 0x1) { +case 0: +/* ADDQ_PH */ +check_dsp(ctx); +gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); +break; +case 1: +/* ADDQ_S_PH */ +check_dsp(ctx); +gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); +break; +} +break; +case OPC_ADDQH_R_PH: +switch ((ctx->opcode >> 10) & 0x1) { +case 0: +/* ADDQH_PH */ +gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); +break; +case 1: +/* ADDQH_R_PH */ +gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); +break; +} +break; +case OPC_ADDQH_R_W: +switch ((ctx->opcode >> 10) & 0x1) { +case 0: +/* ADDQH_W */ +gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); +break; +case 1: +/* ADDQH_R_W */ +gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); +break; +} +break; +case OPC_ADDU_S_QB: +switch
[Qemu-devel] [PATCH v4 22/55] target/mips: Add emulation of DSP ASE for nanoMIPS - part 2
From: Stefan Markovic Add emulation of DSP ASE instructions for nanoMIPS - part 2. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/translate.c | 12 1 file changed, 12 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index e70359d..cbdb613 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -18777,6 +18777,18 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) case NM_BC1NEZC: gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rt, s, 0); break; +case NM_BPOSGE32C: +check_dsp(ctx); +{ +int32_t imm = ctx->opcode; +imm >>= 1; +imm &= 0x1fff; +imm |= (ctx->opcode & 1) << 13; + +gen_compute_branch(ctx, OPC_BPOSGE32, 4, -1, -2, + (int32_t)imm, 4); +} +break; default: generate_exception_end(ctx, EXCP_RI); break; -- 2.7.4
[Qemu-devel] [PATCH v4 30/55] target/mips: Adjust set_hflags_for_handler() for nanoMIPS
From: James Hogan We shouldn't clear M16 mode when entering an interrupt on nanoMIPS, otherwise we'll start interpreting the code as normal MIPS code. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/mips/helper.c b/target/mips/helper.c index 371fecf..a734e86 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -671,6 +671,9 @@ target_ulong exception_resume_pc (CPUMIPSState *env) #if !defined(CONFIG_USER_ONLY) static void set_hflags_for_handler (CPUMIPSState *env) { +if (env->insn_flags & ISA_NANOMIPS32) { +return; +} /* Exception handlers are entered in 32-bit mode. */ env->hflags &= ~(MIPS_HFLAG_M16); /* ...except that microMIPS lets you choose. */ -- 2.7.4
[Qemu-devel] [PATCH v4 11/55] target/mips: Add emulation of nanoMIPS 48-bit instructions
From: Yongbok Kim Add emulation of LI48, ADDIU48, ADDIUGP48, ADDIUPC48, LWPC48, and SWPC48 instructions. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- target/mips/translate.c | 66 + 1 file changed, 66 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 0b69ceb..f5f722d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16684,6 +16684,72 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; case NM_P48I: +insn = cpu_lduw_code(env, ctx->base.pc_next + 4); +switch ((ctx->opcode >> 16) & 0x1f) { +case NM_LI48: +if (rt != 0) { +tcg_gen_movi_tl(cpu_gpr[rt], +extract32(ctx->opcode, 0, 16) | insn << 16); +} +break; +case NM_ADDIU48: +if (rt != 0) { +tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], +extract32(ctx->opcode, 0, 16) | insn << 16); +tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); +} +break; +case NM_ADDIUGP48: +if (rt != 0) { +tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[28], +extract32(ctx->opcode, 0, 16) | insn << 16); +tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); +} +break; +case NM_ADDIUPC48: +if (rt != 0) { +int32_t offset = extract32(ctx->opcode, 0, 16) | insn << 16; +target_long addr = addr_add(ctx, ctx->base.pc_next + 6, offset); + +tcg_gen_movi_tl(cpu_gpr[rt], addr); +tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); +} +break; +case NM_LWPC48: +if (rt != 0) { +TCGv t0; +t0 = tcg_temp_new(); + +int32_t offset = extract32(ctx->opcode, 0, 16) | insn << 16; +target_long addr = addr_add(ctx, ctx->base.pc_next + 6, offset); + +tcg_gen_movi_tl(t0, addr); +tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL); +tcg_temp_free(t0); +} +break; +case NM_SWPC48: +{ +TCGv t0, t1; +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +int32_t offset = extract32(ctx->opcode, 0, 16) | insn << 16; +target_long addr = addr_add(ctx, ctx->base.pc_next + 6, offset); + +tcg_gen_movi_tl(t0, addr); +gen_load_gpr(t1, rt); + +tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + +tcg_temp_free(t0); +tcg_temp_free(t1); +} +break; +default: +generate_exception_end(ctx, EXCP_RI); +break; +} return 6; case NM_P_U12: switch ((ctx->opcode >> 12) & 0x0f) { -- 2.7.4
[Qemu-devel] [PATCH v4 19/55] target/mips: Add emulation of nanoMIPS branch instructions
From: Yongbok Kim Add emulation of various flavors of nanoMIPS branch instructions. Signed-off-by: Yongbok Kim Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic Reviewed-by: Aleksandar Markovic --- target/mips/translate.c | 277 1 file changed, 277 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index b87a29e..9baacff 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -16873,6 +16873,168 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) } } +/* Immediate Value Compact Branches */ +static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, + int rt, int32_t imm, int32_t offset) +{ +int bcond_compute = 0; +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +if (ctx->hflags & MIPS_HFLAG_BMASK) { +#ifdef MIPS_DEBUG_DISAS +LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx + "\n", ctx->base.pc_next); +#endif +generate_exception_end(ctx, EXCP_RI); +goto out; +} + +gen_load_gpr(t0, rt); +tcg_gen_movi_tl(t1, imm); +ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); + +/* Load needed operands and calculate btarget */ +switch (opc) { +case NM_BEQIC: +if (rt == 0 && imm == 0) { +/* Unconditional branch */ +} else if (rt == 0 && imm != 0) { +/* Treat as NOP */ +goto out; +} else { +bcond_compute = 1; +} +break; +case NM_BBEQZC: +case NM_BBNEZC: +if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) { +generate_exception_end(ctx, EXCP_RI); +goto out; +} else if (rt == 0 && opc == NM_BBEQZC) { +/* Unconditional branch */ +} else if (rt == 0 && opc == NM_BBNEZC) { +/* Treat as NOP */ +goto out; +} else { +tcg_gen_shri_tl(t0, t0, imm); +tcg_gen_andi_tl(t0, t0, 1); +tcg_gen_movi_tl(t1, 0); +bcond_compute = 1; +} +break; +case NM_BNEIC: +if (rt == 0 && imm == 0) { +/* Treat as NOP */ +goto out; +} else if (rt == 0 && imm != 0) { +/* Unconditional branch */ +} else { +bcond_compute = 1; +} +break; +case NM_BGEIC: +if (rt == 0 && imm == 0) { +/* Unconditional branch */ +} else { +bcond_compute = 1; +} +break; +case NM_BLTIC: +bcond_compute = 1; +break; +case NM_BGEIUC: +if (rt == 0 && imm == 0) { +/* Unconditional branch */ +} else { +bcond_compute = 1; +} +break; +case NM_BLTIUC: +bcond_compute = 1; +break; +default: +MIPS_INVAL("Immediate Value Compact branch"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + +if (bcond_compute == 0) { +/* Uncoditional compact branch */ +ctx->hflags |= MIPS_HFLAG_B; +/* Generating branch here as compact branches don't have delay slot */ +gen_branch(ctx, 4); +} else { +/* Conditional compact branch */ +TCGLabel *fs = gen_new_label(); +save_cpu_state(ctx, 0); + +switch (opc) { +case NM_BEQIC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); +break; +case NM_BBEQZC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); +break; +case NM_BNEIC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); +break; +case NM_BBNEZC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); +break; +case NM_BGEIC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); +break; +case NM_BLTIC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); +break; +case NM_BGEIUC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); +break; +case NM_BLTIUC: +tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); +break; +} + +/* Generating branch here as compact branches don't have delay slot */ +gen_goto_tb(ctx, 1, ctx->btarget); +gen_set_label(fs); + +ctx->hflags |= MIPS_HFLAG_FBNSLOT; +} + +out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + +/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */ +static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs, +int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +/* load rs */ +gen_load_gpr(t0,
[Qemu-devel] [PATCH v4 27/55] target/mips: Implement CP0 Config0.WR bit functionality
From: Stefan Markovic Add testing Config0.WR bit into watch exception handling logic. Signed-off-by: Aleksandar Markovic Signed-off-by: Stefan Markovic --- target/mips/helper.c| 12 +++- target/mips/translate.c | 22 -- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/target/mips/helper.c b/target/mips/helper.c index b25e000..a576fa4 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -747,6 +747,14 @@ void mips_cpu_do_interrupt(CPUState *cs) (env->hflags & MIPS_HFLAG_DM)) { cs->exception_index = EXCP_DINT; } + +if ((cs->exception_index == EXCP_DWATCH || +cs->exception_index == EXCP_DFWATCH || +cs->exception_index == EXCP_IWATCH) && +(env->CP0_Config1 & (1 << CP0C1_WR))) { +cs->exception_index = EXCP_NONE; +} + offset = 0x180; switch (cs->exception_index) { case EXCP_DSS: @@ -797,7 +805,9 @@ void mips_cpu_do_interrupt(CPUState *cs) break; case EXCP_SRESET: env->CP0_Status |= (1 << CP0St_SR); -memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo)); +if (env->CP0_Config1 & (1 << CP0C1_WR)) { +memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo)); +} goto set_error_EPC; case EXCP_NMI: env->CP0_Status |= (1 << CP0St_NMI); diff --git a/target/mips/translate.c b/target/mips/translate.c index cf28c60..68f1879 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -5622,6 +5622,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -5639,6 +5640,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -6321,6 +6323,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -6338,6 +6341,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -7024,6 +7028,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(dmfc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -7041,6 +7046,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -7705,6 +7711,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -7722,6 +7729,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 5: case 6: case 7: +CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -25285,14 +25293,16 @@ void cpu_state_reset(CPUMIPSState *env) no performance counters. */ env->CP0_IntCtl = 0xe000; { -int i; +if (env->CP0_Config1 & (1 << CP0C1_WR)) { +int i; -for (i = 0; i < 7; i++) { -env->CP0_WatchLo[i] = 0; -env->CP0_WatchHi[i] = 0x8000; +for (i = 0; i < 7; i++) { +env->CP0_WatchLo[i] = 0; +env->CP0_WatchHi[i] = 0x8000; +} +env->CP0_WatchLo[7] = 0; +env->CP0_WatchHi[7] = 0; } -env->CP0_WatchLo[7] = 0; -env->CP0_WatchHi[7] = 0; } /* Count register increments in debug mode, EJTAG version 1 */ env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); -- 2.7.4