Re: [Qemu-devel] Qemu the right way.

2018-12-25 Thread Thomas Huth
On 2018-12-25 23:46, liebre...@grossmann-venter.com wrote:
> I have been using Qemu in the past about 8 years ago or so to run legacy
> windows software.
> 
> I installed the latest qemu and noticed a lot changed and cant find
> conclusive answers online.
> 
> I am writing this post to find what is the right way to start to set up
> qemu with a windows 7 pro guest. I want to try and eliminate the
> iterations and find out what is really possible for the guest.
> 
> Hardware used"
> 24 Core AMD rackserver.
> Host OS Debian 9 Stretch
> Guest Windows 7 Pro 32 bit
> 
> Requirements:
> 1) I need to be able to run at least 4 processors in the guest. Is this
> possible with qemu as hosts ?

Try to run QEMU with "-smp 4".

> 2) I need to at least have sound working from applications in the guest
> with pulseaudio on the Debian host. Is it  possible ?

Should be possible. Run the configure script before compiling with

 --audio-drv-list=pa

and then make sure to give a soundcard to the guest (e.g. with the
-soundhw option).

> 3) USB, what is the level of support 2.0 3.0 ?
> ( However windo$ 7 cannot really do USB3. so usb-3 is moot anyway)

QEMU supports both, e.g. with "-device usb-ehci" for a USB 2.0
controller or with "-device nec-usb-xhci" for a USB 3.0 controller.

> 4) What kind of devices can be run through usb ?

Do you mean emulated devices? You can get a list with:

 qemu-system-x86_64 -device help | grep usb

Or do you want to pass-through a real device from the host?

> The answers to 1-4 will be really helpful to decide if I should even be
> using it. The documentation is schetchy about all this.
> I tried Virtualbox, but it is just a nice looking empty promisebox
> yielding nothing. Since Qemu helped me a lot in the past I will have
> better chances here.
> 
> 5) I am currently installing win7pro guest with command
> $] qemu-system-x86_64 -boot c -cdrom /dev/cdrom -m 2048M
> 
> and left out all the network card and sound driver switches as I have no
> clue what I should choose.
> Can they be configured afterwards ?

I don't have much clue about Windows, but I think you can change it
afterwards - it's like you're changing PCI cards of a real system in
that case.

 HTH,
  Thomas



Re: [Qemu-devel] [PATCH v5 2/3] tcg: introduce dynamic TLB sizing

2018-12-25 Thread Richard Henderson
On 12/15/18 4:42 AM, Emilio G. Cota wrote:
> +#if TCG_TARGET_IMPLEMENTS_DYN_TLB
> +#define CPU_TLB_DYN_MIN_BITS 6
> +#define CPU_TLB_DYN_DEFAULT_BITS 8
> +/*
> + * Assuming TARGET_PAGE_BITS==12, with 2**22 entries we can cover 2**(22+12) 
> ==
> + * 2**34 == 16G of address space. This is roughly what one would expect a
> + * TLB to cover in a modern (as of 2018) x86_64 CPU. For instance, Intel
> + * Skylake's Level-2 STLB has 16 1G entries.
> + */
> +#define CPU_TLB_DYN_MAX_BITS 22

For 32-bit hosts, we need to limit this to (32 - TARGET_PAGE_BITS) so that we
do not require a double-word shift when implementing the tlb load.  We probably
want to restrict it even further because a 32-bit host may well not have 2**27
bytes of available memory.

For 64-bit hosts, we should limit this to (TARGET_VIRT_ADDR_SPACE_BITS -
TARGET_PAGE_BITS) so that we do not grow the tlb past the guest's address space.

> +env->tlb_table[mmu_idx] = g_new(CPUTLBEntry, new_size);
> +env->iotlb[mmu_idx] = g_new(CPUIOTLBEntry, new_size);

For 32-bit hosts, we should probably be prepared for this to fail; see above re
large tlb sizes.  If it fails, we should be able to go back to the previous tlb
size, since we just freed that memory.


r~



Re: [Qemu-devel] [PATCH v3 2/2] intel-iommu: extend VTD emulation to allow 57-bit IOVA address width.

2018-12-25 Thread Yu Zhang
On Tue, Dec 25, 2018 at 12:00:08PM -0500, Michael S. Tsirkin wrote:
> On Sat, Dec 22, 2018 at 08:41:37AM +0800, Yu Zhang wrote:
> > On Fri, Dec 21, 2018 at 01:10:13PM -0500, Michael S. Tsirkin wrote:
> > > On Sat, Dec 22, 2018 at 01:34:01AM +0800, Yu Zhang wrote:
> > > > On Fri, Dec 21, 2018 at 12:15:26PM -0500, Michael S. Tsirkin wrote:
> > > > > On Sat, Dec 22, 2018 at 12:19:20AM +0800, Yu Zhang wrote:
> > > > > > > I'd like to avoid poking at the CPU from VTD code. That's all.
> > > > > > 
> > > > > > OK. So for the short term,how about I remove the check of host cpu, 
> > > > > > and add a TODO
> > > > > > in the comments in vtd_decide_config()? 
> > > > > 
> > > > > My question would be what happens on an incorrect use?
> > > > 
> > > > I believe the vfio_dma_map will return failure for an incorrect use.
> > > > 
> > > > > And how does user figure out which values to set?
> > > > 
> > > > Well, for now I don't think user can figure out. E.g. if we expose a 
> > > > vIOMMU with
> > > > 48-bit IOVA capability, yet host only supports 39-bit IOVA, vfio shall 
> > > > return failure,
> > > > but the user does not know whose fault it is.
> > > > > 
> > > > > > As to the check against hardware IOMMU, Peter once had a proposal in
> > > > > > http://lists.nongnu.org/archive/html/qemu-devel/2018-11/msg02281.html
> > > > > > 
> > > > > > Do you have any comment or suggestion on Peter's proposal?
> > > > > 
> > > > > Sounds reasonable to me. Do we do it on vfio attach or 
> > > > > unconditionally?
> > > > > 
> > > > 
> > > > I guess on vfio attach? Will need more thinking in it.
> > > 
> > > 
> > > Things like live migration (e.g. after hot removal of the vfio device)
> > > are also concerns.
> > 
> > Sorry, why live migration shall be a problem? I mean, if the DMA address
> > width of vIOMMU does not match the host IOMMU's, we can just stop creating
> > the VM, there's no live migration. 
> 
> I don't see code like this though.
> 
> Also management needs to somehow be able to figure out that migration
> will fail. It's not nice to transfer all memory and then have it fail
> when viommu is migrated.  So from that POV a flag is better. It can be
> validated agains host capabilities.
> 
> We can still have something like aw=host just like cpu host.

Well, I think vIOMMU's requirement is kind of different:
1> the vIOMMU could be an emulated one, and there can be no physical
IOMMU underneath. And the emulated device can still use this vIOMMU;
2> there might be multiple physical IOMMUs on one platform, I am not
sure if all these IOMMUs will have the same capability setting.

So I think we should have a more generic solution, to check the host
capability, e.g. like Kevin's and Peter's suggestion. It's not just
about 5-level vIOMMU, existing 4-level vIOMMU and future virtual SVM
have similar requirement. :)

> 
> > > 
> > > > > 
> > > > > > I still do not quite know
> > > > > > how to do it for now...
> > > > > > 
> > > > > > [...]
> > > > > > 
> > > > > > 
> > > > > > B.R.
> > > > > > Yu
> > > > > 
> > > > > 
> > > > > 
> > > > > -- 
> > > > > MST
> > > > 
> > > > B.R.
> > > > Yu
> > 
> > B.R.
> > Yu
> 

B.R.
Yu



Re: [Qemu-devel] [PATCH v3 1/2] intel-iommu: differentiate host address width from IOVA address width.

2018-12-25 Thread Yu Zhang
On Tue, Dec 25, 2018 at 11:56:19AM -0500, Michael S. Tsirkin wrote:
> On Sat, Dec 22, 2018 at 09:11:26AM +0800, Yu Zhang wrote:
> > On Fri, Dec 21, 2018 at 02:02:28PM -0500, Michael S. Tsirkin wrote:
> > > On Sat, Dec 22, 2018 at 01:37:58AM +0800, Yu Zhang wrote:
> > > > On Fri, Dec 21, 2018 at 12:04:49PM -0500, Michael S. Tsirkin wrote:
> > > > > On Sat, Dec 22, 2018 at 12:09:44AM +0800, Yu Zhang wrote:
> > > > > > Well, my understanding of the vt-d spec is that the address 
> > > > > > limitation in
> > > > > > DMAR are referring to the same concept of CPUID.MAXPHYSADDR. I do 
> > > > > > not think
> > > > > > there's any different in the native scenario. :)
> > > > > 
> > > > > I think native machines exist on which the two values are different.
> > > > > Is that true?
> > > > 
> > > > I think the answer is not. My understanding is that HAW(host address 
> > > > wdith) is
> > > > the maximum physical address width a CPU can detects(by 
> > > > cpuid.0x8008).
> > > > 
> > > > I agree there are some addresses the CPU does not touch, but they are 
> > > > still in
> > > > the physical address space, and there's only one physical address 
> > > > space...
> > > > 
> > > > B.R.
> > > > Yu
> > > 
> > > Ouch I thought we are talking about the virtual address size.
> > > I think I did have a box where VTD's virtual address size was
> > > smaller than CPU's.
> > > For physical one - we just need to make it as big as max supported
> > > memory right?
> > 
> > Well, my understanding of the physical one is the maximum physical address
> > width. Sorry, this explain seems nonsense... I mean, it's not just about
> > the max supported memory, but also covers MMIO. It shall be detectable
> > from cpuid, or ACPI's DMAR table, instead of calculated by the max memory
> > size. One common usage of this value is to tell the paging structure 
> > entries(
> > CPU's or IOMMU's) which bits shall be reserved. There are also some 
> > registers
> > e.g. apic base reg etc, whose contents are physical addresses, therefore 
> > also
> > need to follow the similar requirement for the reserved bits.
> > 
> > So I think the correct direction might be to define this property in the
> > machine status level, instead of the CPU level. Is this reasonable to you?
> 
> At that level yes. But isn't this already specified by "pci-hole64-end"?

But this value is set by guest firmware? Will PCI hotplug change this address?

@Eduardo, do you have any plan to calculate the phys-bits by "pci-hole64-end"?
Or introduce another property, say "max-phys-bits" in machine status?

> 
> 
> 
> > > 
> > > -- 
> > > MST
> > 
> > B.R.
> > Yu
> 

B.R.
Yu



Re: [Qemu-devel] [PULL v3 00/44] pci, pc, virtio: fixes, features

2018-12-25 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20181220183059.20726-1-...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20181220183059.20726-1-...@redhat.com
Type: series
Subject: [Qemu-devel] [PULL v3 00/44] pci, pc, virtio: fixes, features

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
00bb933 x86-iommu: turn on IR by default if proper
84205d7 x86-iommu: switch intr_supported to OnOffAuto type
e90352f q35: set split kernel irqchip as default
5b42631 pci: Adjust PCI config limit based on bus topology
10af565 spapr_pci: perform unplug via the hotplug handler
19d636e pci/shpc: perform unplug via the hotplug handler
547f401 pci: Reuse pci-bridge hotplug handler handlers for pcie-pci-bridge
54491be pci/pcie: perform unplug via the hotplug handler
d48a499 pci/pcihp: perform unplug via the hotplug handler
69293f5 pci/pcihp: overwrite hotplug handler recursively from the start
cb4db34 pci/pcihp: perform check for bus capability in pre_plug handler
1966b59 s390x/pci: rename hotplug handler callbacks
c9b84c2 pci/shpc: rename hotplug handler callbacks
7d3cc09 pci/pcie: rename hotplug handler callbacks
14b804a hw/i386: Remove deprecated machines pc-0.10 and pc-0.11
2ecba91 hw: acpi: Remove AcpiRsdpDescriptor and fix tests
6eec914 hw: acpi: Export and share the ARM RSDP build
6ce7573 hw: arm: Support both legacy and current RSDP build
05e6bb6 hw: arm: Convert the RSDP build to the buid_append_foo() API
1e3f0b8 hw: arm: Carry RSDP specific data through AcpiRsdpData
1149d53 hw: i386: Use correct RSDT length for checksum
08f1f3d hw: arm: acpi: Fix incorrect checksums in RSDP
833c5a9 hw: acpi: The RSDP build API can return void
6764083 intel_iommu: remove "x-" prefix for "aw-bits"
073d52a intel_iommu: dma read/write draining support
f3f77a5 intel_iommu: convert invalid traces into error reports
3d38fe7 intel_iommu: dump correct iova when failed
bf967a3 pcie: Fast PCIe root ports for new machines
c116234 vfio/pci: Remove PCIe Link Status emulation
b2b0199 pcie: Allow generic PCIe root port to specify link speed and width
de6a18a pcie: Fill PCIESlot link fields to support higher speeds and widths
b19b53a pcie: Add link speed and width fields to PCIESlot
e909a5f qapi: Define PCIe link speed and width properties
2b940de pci: Sync PCIe downstream port LNKSTA on read
e9a0604 pcie: Create enums for link speed and width
d1ef1d5 hw/pci-bridge: Fix invalid free()
3f5466b hw/smbios: Move to the hw/firmware/ subdirectory
22e0d61 hw/smbios: Remove "smbios_ipmi.h"
8f50a34 hw/smbios: Restrict access to "hw/smbios/ipmi.h"
6075c5e tests: Remove unused include
b4cf945 virtio: Provide version-specific variants of virtio PCI devices
4dff116 virtio: Helper for registering virtio device types
be858a5 pc:piix4: Update smbus I/O space after a migration
9a3c2f2 pcie: set link state inactive/active after hot unplug/plug

=== OUTPUT BEGIN ===
Checking PATCH 1/44: pcie: set link state inactive/active after hot 
unplug/plug...
Checking PATCH 2/44: pc:piix4: Update smbus I/O space after a migration...
Checking PATCH 3/44: virtio: Helper for registering virtio device types...
WARNING: line over 80 characters
#498: FILE: hw/virtio/virtio-pci.h:443:
+ * Implements both INTERFACE_PCIE_DEVICE and 
INTERFACE_CONVENTIONAL_PCI_DEVICE,

WARNING: line over 80 characters
#507: FILE: hw/virtio/virtio-pci.h:452:
+ * Implements both INTERFACE_PCIE_DEVICE and 
INTERFACE_CONVENTIONAL_PCI_DEVICE.

total: 0 errors, 2 warnings, 469 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 4/44: virtio: Provide version-specific variants of virtio PCI 
devices...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#318: 
new file mode 100644

ERROR: line over 90 characters
#374: FILE: tests/acceptance/virtio_version.py:52:
+return devtype in [d['name'] for d in vm.command('qom-list-types', 
implements=implements)]

WARNING: line over 80 characters
#429: FILE: tests/acceptance/virtio_version.py:107:
+dev_1_0, nt_ifaces = self.run_device('%s-non-transitional' % 
(qemu_devtype))

WARNING: line over 80 characters
#453: FILE: tests/acceptance/virtio_version.py:131:
+dev_trans, trans_ifaces = self.run_device('%s-transitional' % 
(qemu_devtype))

total: 1 errors, 3 

Re: [Qemu-devel] [PATCH 0/3] Fix & improve icon display on GTK and SDL frontends

2018-12-25 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20181218142629.15943-1-berra...@redhat.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=8
=== TEST SCRIPT END ===

  CC  chardev/char-serial.o
  CC  chardev/char-socket.o
/tmp/qemu-test/src/ui/sdl2.c: In function 'sdl2_display_init':
/tmp/qemu-test/src/ui/sdl2.c:847:40: error: 'image' undeclared (first use in 
this function)
 uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
^
/tmp/qemu-test/src/ui/sdl2.c:847:40: note: each undeclared identifier is 
reported only once for each function it appears in


The full log is available at
http://patchew.org/logs/20181218142629.15943-1-berra...@redhat.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Qemu-devel] [PATCH] slirp: Use lduw_be_p in slirp_input

2018-12-25 Thread Richard Henderson
The pointer may be unaligned, so we must use our routines for that.
At the same time, we might as well use the big-endian version
instead of ntohs.

This fixes sparc64 host SIGBUS during pxe boot.

Signed-off-by: Richard Henderson 
---
 slirp/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 322edf51eb..a116f43878 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -851,7 +851,7 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 if (pkt_len < ETH_HLEN)
 return;
 
-proto = ntohs(*(uint16_t *)(pkt + 12));
+proto = lduw_be_p(pkt + 12);
 switch(proto) {
 case ETH_P_ARP:
 arp_input(slirp, pkt, pkt_len);
-- 
2.17.2




[Qemu-devel] [PATCH] qom: Include qemu/fprintf-fn.h in cpu.h

2018-12-25 Thread Priit Laes
QOM cpu.h uses fprintf_function which requires Qemu's
qemu/fprintf-fn.h header. Include it.

Signed-off-by: Priit Laes 
---
 include/qom/cpu.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 1396f53e5b..6d1ba53d72 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -26,6 +26,7 @@
 #include "exec/memattrs.h"
 #include "qapi/qapi-types-run-state.h"
 #include "qemu/bitmap.h"
+#include "qemu/fprintf-fn.h"
 #include "qemu/rcu_queue.h"
 #include "qemu/queue.h"
 #include "qemu/thread.h"
-- 
2.20.1




Re: [Qemu-devel] [PATCH v2 00/23] Add RISC-V TCG backend support

2018-12-25 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/cover.1545246859.git.alistair.fran...@wdc.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: cover.1545246859.git.alistair.fran...@wdc.com
Type: series
Subject: [Qemu-devel] [PATCH v2 00/23]  Add RISC-V TCG backend support

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
2236221 configure: Add support for building RISC-V host
e990378 dias: Add RISC-V support
713b47c tcg: Add RISC-V cpu signal handler
8ec51ee riscv: tcg-target: Add the target init code
3feff31 riscv: tcg-target: Add the prologue generation and register the JIT
702fdc0 riscv: tcg-target: Add the out op decoder
ed66ad3 riscv: tcg-target: Add direct load and store instructions
fd97412 riscv: tcg-target: Add slowpath load and store instructions
5e6bb90 riscv: tcg-target: Add branch and jump instructions
a066182 riscv: tcg-target: Add the add2 and sub2 instructions
8192923 riscv: tcg-target: Add the out load and store instructions
65e8bfc riscv: tcg-target: Add the extract instructions
37fba48 riscv: tcg-target: Add the mov and movi instruction
e015e10 riscv: tcg-target: Add the relocation functions
67927da riscv: tcg-target: Add the instruction emitters
def52f9 riscv: tcg-target: Add the immediate encoders
db3a876 riscv: tcg-target: Add support for the constraints
472711b riscv: Add the tcg target registers
cb5271e riscv: Add the tcg-target header file
c053c44 exec: Add RISC-V GCC poison macro
a4660da linux-user: Add host dependency for RISC-V 64-bit
cec4a16 linux-user: Add host dependency for RISC-V 32-bit
52105f5 elf.h: Add the RISCV ELF magic numbers

=== OUTPUT BEGIN ===
Checking PATCH 1/23: elf.h: Add the RISCV ELF magic numbers...
Checking PATCH 2/23: linux-user: Add host dependency for RISC-V 32-bit...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#24: 
new file mode 100644

total: 0 errors, 1 warnings, 18 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 3/23: linux-user: Add host dependency for RISC-V 64-bit...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#24: 
new file mode 100644

total: 0 errors, 1 warnings, 18 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 4/23: exec: Add RISC-V GCC poison macro...
Checking PATCH 5/23: riscv: Add the tcg-target header file...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#40: 
new file mode 100644

WARNING: architecture specific defines should be avoided
#72: FILE: tcg/riscv/tcg-target.h:28:
+#if __riscv_xlen == 32

total: 0 errors, 2 warnings, 199 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 6/23: riscv: Add the tcg target registers...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#12: 
new file mode 100644

total: 0 errors, 1 warnings, 118 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 7/23: riscv: tcg-target: Add support for the constraints...
Checking PATCH 8/23: riscv: tcg-target: Add the immediate encoders...
Checking PATCH 9/23: riscv: tcg-target: Add the instruction emitters...
Checking PATCH 10/23: riscv: tcg-target: Add the relocation functions...
Checking PATCH 11/23: riscv: tcg-target: Add the mov and movi instruction...
Checking PATCH 12/23: riscv: tcg-target: Add the extract instructions...
Checking PATCH 13/23: riscv: tcg-target: Add the out load and store 
instructions...
Checking PATCH 14/23: riscv: tcg-target: Add the add2 and sub2 instructions...
WARNING: Block comments use a leading /* on a separate line
#30: FILE: tcg/riscv/tcg-target.inc.c:710:
+/* If we have a negative constant such that negating it would

WARNING: Block comments use * on subsequent lines
#31: FILE: tcg/riscv/tcg-target.inc.c:711:
+/* If we have a negative constant such that negating it would
+   make the high part zero, we can (usually) eliminate one insn.  */

WARNING: Block 

Re: [Qemu-devel] AVX support for TCG

2018-12-25 Thread Richard Henderson
On 12/26/18 12:28 PM, Nick Renieris wrote:
> Hi Richard,
> 
> I did know about https://github.com/andikleen/qemu-avx but didn't
> mention it as it seems abandoned and quite old (also it doesn't use
> `TCGv_vec`).

Yep.  Mine pre-dates tcg-op-gvec.h as well.

> Do you think this could work as a GSoC project? I'm potentially
> interested in working on it this summer.

Could be.  My first guess is something like 4 months work for this.


r~



Re: [Qemu-devel] AVX support for TCG

2018-12-25 Thread Nick Renieris
Hi Richard,

I did know about https://github.com/andikleen/qemu-avx but didn't
mention it as it seems abandoned and quite old (also it doesn't use
`TCGv_vec`).
Do you think this could work as a GSoC project? I'm potentially
interested in working on it this summer.

Thanks,
Nick R.

Στις Τετ, 26 Δεκ 2018 στις 3:07 π.μ., ο/η Richard Henderson
 έγραψε:
>
> On 12/26/18 10:43 AM, Nick Renieris wrote:
> > Hello,
> >
> > What's the current status on AVX support for TCG? Is there anyone working 
> > on it?
> > Is there interest for it?
>
> A couple of people, including myself, have started on it, but no results 
> posted
> so far.  It's a large amount of work to clean up the exiting sse support 
> before
> avx could be added.
>
>
> r~



Re: [Qemu-devel] AVX support for TCG

2018-12-25 Thread Richard Henderson
On 12/26/18 10:43 AM, Nick Renieris wrote:
> Hello,
> 
> What's the current status on AVX support for TCG? Is there anyone working on 
> it?
> Is there interest for it?

A couple of people, including myself, have started on it, but no results posted
so far.  It's a large amount of work to clean up the exiting sse support before
avx could be added.


r~



[Qemu-devel] AVX support for TCG

2018-12-25 Thread Nick Renieris
Hello,

What's the current status on AVX support for TCG? Is there anyone working on it?
Is there interest for it?

Effort was put into making 'TCGv_vec', as elaborated in this talk:

"[2017] Vectoring in on QEMU's TCG Engine by Alex Bennée"
(https://www.youtube.com/watch?v=IYHTwnde0g8)

,yet there doesn't seem to be a front-end (except for VEX prefix
parsing) nor a backend for AVX, a pretty common x86 extension.

I'd appreciate any info on this,

Regards,
Nick Renieris.



[Qemu-devel] Qemu the right way.

2018-12-25 Thread liebrecht
I have been using Qemu in the past about 8 years ago or so to run legacy 
windows software.


I installed the latest qemu and noticed a lot changed and cant find 
conclusive answers online.


I am writing this post to find what is the right way to start to set up 
qemu with a windows 7 pro guest. I want to try and eliminate the 
iterations and find out what is really possible for the guest.


Hardware used"
24 Core AMD rackserver.
Host OS Debian 9 Stretch
Guest Windows 7 Pro 32 bit

Requirements:
1) I need to be able to run at least 4 processors in the guest. Is this 
possible with qemu as hosts ?
2) I need to at least have sound working from applications in the guest 
with pulseaudio on the Debian host. Is it  possible ?

3) USB, what is the level of support 2.0 3.0 ?
( However windo$ 7 cannot really do USB3. so usb-3 is moot anyway)
4) What kind of devices can be run through usb ?

The answers to 1-4 will be really helpful to decide if I should even be 
using it. The documentation is schetchy about all this.
I tried Virtualbox, but it is just a nice looking empty promisebox 
yielding nothing. Since Qemu helped me a lot in the past I will have 
better chances here.


5) I am currently installing win7pro guest with command
$] qemu-system-x86_64 -boot c -cdrom /dev/cdrom -m 2048M

and left out all the network card and sound driver switches as I have no 
clue what I should choose.

Can they be configured afterwards ?

Thanks



[Qemu-devel] Qemu the right way.

2018-12-25 Thread liebrecht
I have been using Qemu in the past about 8 years ago or so to run legacy 
windows software.


I installed the latest qemu and noticed a lot changed and cant find 
conclusive answers online.


I am writing this post to find what is the right way to start to set up 
qemu with a windows 7 pro guest. I want to try and eliminate the 
iterations and find out what is really possible for the guest.


Hardware used"
24 Core AMD rackserver.
Host OS Debian 9 Stretch
Guest Windows 7 Pro 32 bit

Requirements:
1) I need to be able to run at least 4 processors in the guest. Is this 
possible with qemu as hosts ?
2) I need to at least have sound working from applications in the guest 
with pulseaudio on the Debian host. Is it  possible ?

3) USB, what is the level of support 2.0 3.0 ?
( However windo$ 7 cannot really do USB3. so usb-3 is moot anyway)
4) What kind of devices can be run through usb ?

The answers to 1-4 will be really helpful to decide if I should even be 
using it. The documentation is schetchy about all this.
I tried Virtualbox, but it is just a nice looking empty promisebox 
yielding nothing. Since Qemu helped me a lot in the past I will have 
better chances here.


5) I am currently installing win7pro guest with command
$] qemu-system-x86_64 -boot c -cdrom /dev/cdrom -m 2048M

and left out all the network card and sound driver switches as I have no 
clue what I should choose.

Can they be configured afterwards ?

Thanks



[Qemu-devel] [PULL 36/42] tcg: Dump register preference info with liveness

2018-12-25 Thread Richard Henderson
Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.h |  3 ---
 tcg/tcg.c | 44 +---
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index c6721cc7a7..5e5cf686a3 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -1082,9 +1082,6 @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, 
TCGOpcode opc);
 
 void tcg_optimize(TCGContext *s);
 
-/* only used for debugging purposes */
-void tcg_dump_ops(TCGContext *s);
-
 TCGv_i32 tcg_const_i32(int32_t val);
 TCGv_i64 tcg_const_i64(int64_t val);
 TCGv_i32 tcg_const_local_i32(int32_t val);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 32bac5e792..e2ae04d1d0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1901,7 +1901,7 @@ static inline TCGReg tcg_regset_first(TCGRegSet d)
 }
 }
 
-void tcg_dump_ops(TCGContext *s)
+static void tcg_dump_ops(TCGContext *s, bool have_prefs)
 {
 char buf[128];
 TCGOp *op;
@@ -2036,12 +2036,15 @@ void tcg_dump_ops(TCGContext *s)
 col += qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", op->args[k]);
 }
 }
-if (op->life) {
-unsigned life = op->life;
 
-for (; col < 48; ++col) {
+if (have_prefs || op->life) {
+for (; col < 40; ++col) {
 putc(' ', qemu_logfile);
 }
+}
+
+if (op->life) {
+unsigned life = op->life;
 
 if (life & (SYNC_ARG * 3)) {
 qemu_log("  sync:");
@@ -2061,6 +2064,33 @@ void tcg_dump_ops(TCGContext *s)
 }
 }
 }
+
+if (have_prefs) {
+for (i = 0; i < nb_oargs; ++i) {
+TCGRegSet set = op->output_pref[i];
+
+if (i == 0) {
+qemu_log("  pref=");
+} else {
+qemu_log(",");
+}
+if (set == 0) {
+qemu_log("none");
+} else if (set == MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS)) {
+qemu_log("all");
+#ifdef CONFIG_DEBUG_TCG
+} else if (tcg_regset_single(set)) {
+TCGReg reg = tcg_regset_first(set);
+qemu_log("%s", tcg_target_reg_names[reg]);
+#endif
+} else if (TCG_TARGET_NB_REGS <= 32) {
+qemu_log("%#x", (uint32_t)set);
+} else {
+qemu_log("%#" PRIx64, (uint64_t)set);
+}
+}
+}
+
 qemu_log("\n");
 }
 }
@@ -3647,7 +3677,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
  && qemu_log_in_addr_range(tb->pc))) {
 qemu_log_lock();
 qemu_log("OP:\n");
-tcg_dump_ops(s);
+tcg_dump_ops(s, false);
 qemu_log("\n");
 qemu_log_unlock();
 }
@@ -3675,7 +3705,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
  && qemu_log_in_addr_range(tb->pc))) {
 qemu_log_lock();
 qemu_log("OP before indirect lowering:\n");
-tcg_dump_ops(s);
+tcg_dump_ops(s, false);
 qemu_log("\n");
 qemu_log_unlock();
 }
@@ -3696,7 +3726,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
  && qemu_log_in_addr_range(tb->pc))) {
 qemu_log_lock();
 qemu_log("OP after optimization and liveness analysis:\n");
-tcg_dump_ops(s);
+tcg_dump_ops(s, true);
 qemu_log("\n");
 qemu_log_unlock();
 }
-- 
2.17.2




[Qemu-devel] [PULL 33/42] tcg: Add preferred_reg argument to tcg_reg_alloc_do_movi

2018-12-25 Thread Richard Henderson
Pass this through to temp_sync.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index fe060c481a..7844158a8a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3077,7 +3077,8 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet 
allocated_regs)
 }
 
 static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
-  tcg_target_ulong val, TCGLifeData arg_life)
+  tcg_target_ulong val, TCGLifeData arg_life,
+  TCGRegSet preferred_regs)
 {
 if (ots->fixed_reg) {
 /* For fixed registers, we do not do any constant propagation.  */
@@ -3093,7 +3094,7 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp 
*ots,
 ots->val = val;
 ots->mem_coherent = 0;
 if (NEED_SYNC_ARG(0)) {
-temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
+temp_sync(s, ots, s->reserved_regs, preferred_regs, IS_DEAD_ARG(0));
 } else if (IS_DEAD_ARG(0)) {
 temp_dead(s, ots);
 }
@@ -3104,7 +3105,7 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp 
*op)
 TCGTemp *ots = arg_temp(op->args[0]);
 tcg_target_ulong val = op->args[1];
 
-tcg_reg_alloc_do_movi(s, ots, val, op->life);
+tcg_reg_alloc_do_movi(s, ots, val, op->life, 0);
 }
 
 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
@@ -3128,7 +3129,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 if (IS_DEAD_ARG(1)) {
 temp_dead(s, ts);
 }
-tcg_reg_alloc_do_movi(s, ots, val, arg_life);
+tcg_reg_alloc_do_movi(s, ots, val, arg_life, 0);
 return;
 }
 
-- 
2.17.2




[Qemu-devel] [PULL 29/42] tcg: Add reachable_code_pass

2018-12-25 Thread Richard Henderson
Delete trivially dead code that follows unconditional branches and
noreturn helpers.  These can occur either via optimization or via
the structure of a target's translator following an exception.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 76 +++
 1 file changed, 76 insertions(+)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 99afc65126..d2be550ab4 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2239,6 +2239,81 @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op, 
TCGOpcode opc)
 return new_op;
 }
 
+/* Reachable analysis : remove unreachable code.  */
+static void reachable_code_pass(TCGContext *s)
+{
+TCGOp *op, *op_next;
+bool dead = false;
+
+QTAILQ_FOREACH_SAFE(op, >ops, link, op_next) {
+bool remove = dead;
+TCGLabel *label;
+int call_flags;
+
+switch (op->opc) {
+case INDEX_op_set_label:
+label = arg_label(op->args[0]);
+if (label->refs == 0) {
+/*
+ * While there is an occasional backward branch, virtually
+ * all branches generated by the translators are forward.
+ * Which means that generally we will have already removed
+ * all references to the label that will be, and there is
+ * little to be gained by iterating.
+ */
+remove = true;
+} else {
+/* Once we see a label, insns become live again.  */
+dead = false;
+remove = false;
+
+/*
+ * Optimization can fold conditional branches to unconditional.
+ * If we find a label with one reference which is preceded by
+ * an unconditional branch to it, remove both.  This needed to
+ * wait until the dead code in between them was removed.
+ */
+if (label->refs == 1) {
+TCGOp *op_prev = QTAILQ_PREV(op, TCGOpHead, link);
+if (op_prev->opc == INDEX_op_br &&
+label == arg_label(op_prev->args[0])) {
+tcg_op_remove(s, op_prev);
+remove = true;
+}
+}
+}
+break;
+
+case INDEX_op_br:
+case INDEX_op_exit_tb:
+case INDEX_op_goto_ptr:
+/* Unconditional branches; everything following is dead.  */
+dead = true;
+break;
+
+case INDEX_op_call:
+/* Notice noreturn helper calls, raising exceptions.  */
+call_flags = op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
+if (call_flags & TCG_CALL_NO_RETURN) {
+dead = true;
+}
+break;
+
+case INDEX_op_insn_start:
+/* Never remove -- we need to keep these for unwind.  */
+remove = false;
+break;
+
+default:
+break;
+}
+
+if (remove) {
+tcg_op_remove(s, op);
+}
+}
+}
+
 #define TS_DEAD  1
 #define TS_MEM   2
 
@@ -3515,6 +3590,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
 atomic_set(>la_time, prof->la_time - profile_getclock());
 #endif
 
+reachable_code_pass(s);
 liveness_pass_1(s);
 
 if (s->nb_indirects > 0) {
-- 
2.17.2




[Qemu-devel] [PULL 27/42] tcg: Add TCG_CALL_NO_RETURN

2018-12-25 Thread Richard Henderson
Remember which helpers have been marked noreturn.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 include/exec/helper-head.h | 13 +
 include/exec/helper-tcg.h  | 21 ++---
 tcg/tcg.h  |  2 ++
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
index 276dd5afce..ab4f8b6623 100644
--- a/include/exec/helper-head.h
+++ b/include/exec/helper-head.h
@@ -108,6 +108,19 @@
 #define dh_is_signed_env dh_is_signed_ptr
 #define dh_is_signed(t) dh_is_signed_##t
 
+#define dh_callflag_i32  0
+#define dh_callflag_s32  0
+#define dh_callflag_int  0
+#define dh_callflag_i64  0
+#define dh_callflag_s64  0
+#define dh_callflag_f16  0
+#define dh_callflag_f32  0
+#define dh_callflag_f64  0
+#define dh_callflag_ptr  0
+#define dh_callflag_void 0
+#define dh_callflag_noreturn TCG_CALL_NO_RETURN
+#define dh_callflag(t) glue(dh_callflag_, dh_alias(t))
+
 #define dh_sizemask(t, n) \
   ((dh_is_64bit(t) << (n*2)) | (dh_is_signed(t) << (n*2+1)))
 
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
index b3bdb0c399..268e0f804b 100644
--- a/include/exec/helper-tcg.h
+++ b/include/exec/helper-tcg.h
@@ -11,36 +11,43 @@
 #define str(s) #s
 
 #define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
-  { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
+  { .func = HELPER(NAME), .name = str(NAME), \
+.flags = FLAGS | dh_callflag(ret), \
 .sizemask = dh_sizemask(ret, 0) },
 
 #define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
-  { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
+  { .func = HELPER(NAME), .name = str(NAME), \
+.flags = FLAGS | dh_callflag(ret), \
 .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },
 
 #define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
-  { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
+  { .func = HELPER(NAME), .name = str(NAME), \
+.flags = FLAGS | dh_callflag(ret), \
 .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
 | dh_sizemask(t2, 2) },
 
 #define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
-  { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
+  { .func = HELPER(NAME), .name = str(NAME), \
+.flags = FLAGS | dh_callflag(ret), \
 .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
 | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },
 
 #define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
-  { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
+  { .func = HELPER(NAME), .name = str(NAME), \
+.flags = FLAGS | dh_callflag(ret), \
 .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
 | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },
 
 #define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
-  { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
+  { .func = HELPER(NAME), .name = str(NAME), \
+.flags = FLAGS | dh_callflag(ret), \
 .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
 | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
 | dh_sizemask(t5, 5) },
 
 #define DEF_HELPER_FLAGS_6(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6) \
-  { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
+  { .func = HELPER(NAME), .name = str(NAME), \
+.flags = FLAGS | dh_callflag(ret), \
 .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
 | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
 | dh_sizemask(t5, 5) | dh_sizemask(t6, 6) },
diff --git a/tcg/tcg.h b/tcg/tcg.h
index d9b101e2f8..492d8dcf10 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -467,6 +467,8 @@ typedef TCGv_ptr TCGv_env;
 #define TCG_CALL_NO_WRITE_GLOBALS   0x0002
 /* Helper can be safely suppressed if the return value is not used. */
 #define TCG_CALL_NO_SIDE_EFFECTS0x0004
+/* Helper is QEMU_NORETURN.  */
+#define TCG_CALL_NO_RETURN  0x0008
 
 /* convenience version of most used call flags */
 #define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
-- 
2.17.2




[Qemu-devel] [PULL 26/42] tcg: Renumber TCG_CALL_* flags

2018-12-25 Thread Richard Henderson
Previously, the low 4 bits were used for TCG_CALL_TYPE_MASK,
which was removed in 6a18ae2d2947532d5c26439548afa0481c4529f9.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index ade692fdf5..d9b101e2f8 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -462,11 +462,11 @@ typedef TCGv_ptr TCGv_env;
 /* call flags */
 /* Helper does not read globals (either directly or through an exception). It
implies TCG_CALL_NO_WRITE_GLOBALS. */
-#define TCG_CALL_NO_READ_GLOBALS0x0010
+#define TCG_CALL_NO_READ_GLOBALS0x0001
 /* Helper does not write globals */
-#define TCG_CALL_NO_WRITE_GLOBALS   0x0020
+#define TCG_CALL_NO_WRITE_GLOBALS   0x0002
 /* Helper can be safely suppressed if the return value is not used. */
-#define TCG_CALL_NO_SIDE_EFFECTS0x0040
+#define TCG_CALL_NO_SIDE_EFFECTS0x0004
 
 /* convenience version of most used call flags */
 #define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
-- 
2.17.2




[Qemu-devel] [PULL 42/42] tcg: Improve call argument loading

2018-12-25 Thread Richard Henderson
Free the argument register only after we have verified that the
temporary is not already in that register.  This case is likely
now that we are back propagating the preferred register.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 5f8c09b0b4..c54b119020 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3611,15 +3611,16 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 if (arg != TCG_CALL_DUMMY_ARG) {
 ts = arg_temp(arg);
 reg = tcg_target_call_iarg_regs[i];
-tcg_reg_free(s, reg, allocated_regs);
 
 if (ts->val_type == TEMP_VAL_REG) {
 if (ts->reg != reg) {
+tcg_reg_free(s, reg, allocated_regs);
 tcg_out_mov(s, ts->type, reg, ts->reg);
 }
 } else {
 TCGRegSet arg_set = 0;
 
+tcg_reg_free(s, reg, allocated_regs);
 tcg_regset_set_reg(arg_set, reg);
 temp_load(s, ts, arg_set, allocated_regs, 0);
 }
-- 
2.17.2




[Qemu-devel] [PULL 24/42] disas/microblaze: Remove unused REG_SP macro

2018-12-25 Thread Richard Henderson
This causes a build error with debian sid, riscv64 host:

disas/microblaze.c:179: error: "REG_SP" redefined [-Werror]
 #define REG_SP  1 /* stack pointer */

In file included from /usr/include/signal.h:306,
 from include/qemu/osdep.h:101,
 from disas/microblaze.c:36:
/usr/include/riscv64-linux-gnu/sys/ucontext.h:36: note: this is the location of 
the previous definition
 # define REG_SP 2

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 disas/microblaze.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/disas/microblaze.c b/disas/microblaze.c
index 598ecbc89d..c23605043a 100644
--- a/disas/microblaze.c
+++ b/disas/microblaze.c
@@ -176,7 +176,6 @@ enum microblaze_instr_type {
 #define REG_TLBSX 36869 /* MMU: TLB Search Index reg */
 
 /* alternate names for gen purpose regs */
-#define REG_SP  1 /* stack pointer */
 #define REG_ROSDP 2 /* read-only small data pointer */
 #define REG_RWSDP 13 /* read-write small data pointer */
 
-- 
2.17.2




[Qemu-devel] [PULL 22/42] disas: Add RISC-V support

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 disas.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/disas.c b/disas.c
index f9c517b358..d9aa713a40 100644
--- a/disas.c
+++ b/disas.c
@@ -522,8 +522,14 @@ void disas(FILE *out, void *code, unsigned long size)
 # ifdef _ARCH_PPC64
 s.info.cap_mode = CS_MODE_64;
 # endif
-#elif defined(__riscv__)
-print_insn = print_insn_riscv;
+#elif defined(__riscv) && defined(CONFIG_RISCV_DIS)
+#if defined(_ILP32) || (__riscv_xlen == 32)
+print_insn = print_insn_riscv32;
+#elif defined(_LP64)
+print_insn = print_insn_riscv64;
+#else
+#error unsupported RISC-V ABI
+#endif
 #elif defined(__aarch64__) && defined(CONFIG_ARM_A64_DIS)
 print_insn = print_insn_arm_a64;
 s.info.cap_arch = CS_ARCH_ARM64;
-- 
2.17.2




[Qemu-devel] [PULL 40/42] tcg: Add TCG_OPF_BB_EXIT

2018-12-25 Thread Richard Henderson
Use this to notice the opcodes that exit the TB, which implies
that local temps are really dead and need not be synced.

Previously we so marked the true end of the TB, but that was
immediately overwritten by the la_bb_end invoked by any
TCG_OPF_BB_END opcode, like exit_tb.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg-opc.h |  7 ---
 tcg/tcg.h | 14 --
 tcg/tcg.c |  5 -
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index e3a43aabb6..7a8a3edb5b 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -191,9 +191,10 @@ DEF(mulsh_i64, 1, 2, 0, IMPL64 | 
IMPL(TCG_TARGET_HAS_mulsh_i64))
 /* QEMU specific */
 DEF(insn_start, 0, 0, TLADDR_ARGS * TARGET_INSN_START_WORDS,
 TCG_OPF_NOT_PRESENT)
-DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END)
-DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END)
-DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr))
+DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(goto_ptr, 0, 1, 0,
+TCG_OPF_BB_EXIT | TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr))
 
 DEF(qemu_ld_i32, 1, TLADDR_ARGS, 1,
 TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 5e5cf686a3..3a629991ca 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -1030,20 +1030,22 @@ typedef struct TCGArgConstraint {
 
 /* Bits for TCGOpDef->flags, 8 bits available.  */
 enum {
+/* Instruction exits the translation block.  */
+TCG_OPF_BB_EXIT  = 0x01,
 /* Instruction defines the end of a basic block.  */
-TCG_OPF_BB_END   = 0x01,
+TCG_OPF_BB_END   = 0x02,
 /* Instruction clobbers call registers and potentially update globals.  */
-TCG_OPF_CALL_CLOBBER = 0x02,
+TCG_OPF_CALL_CLOBBER = 0x04,
 /* Instruction has side effects: it cannot be removed if its outputs
are not used, and might trigger exceptions.  */
-TCG_OPF_SIDE_EFFECTS = 0x04,
+TCG_OPF_SIDE_EFFECTS = 0x08,
 /* Instruction operands are 64-bits (otherwise 32-bits).  */
-TCG_OPF_64BIT= 0x08,
+TCG_OPF_64BIT= 0x10,
 /* Instruction is optional and not implemented by the host, or insn
is generic and should not be implemened by the host.  */
-TCG_OPF_NOT_PRESENT  = 0x10,
+TCG_OPF_NOT_PRESENT  = 0x20,
 /* Instruction operands are vectors.  */
-TCG_OPF_VECTOR   = 0x20,
+TCG_OPF_VECTOR   = 0x40,
 };
 
 typedef struct TCGOpDef {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 4f0acf8863..d40edb4f57 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2424,6 +2424,7 @@ static void liveness_pass_1(TCGContext *s)
 int nb_temps = s->nb_temps;
 TCGOp *op, *op_prev;
 
+/* ??? Should be redundant with the exit_tb that ends the TB.  */
 la_func_end(s, nb_globals, nb_temps);
 
 QTAILQ_FOREACH_REVERSE_SAFE(op, >ops, TCGOpHead, link, op_prev) {
@@ -2612,7 +2613,9 @@ static void liveness_pass_1(TCGContext *s)
 }
 
 /* if end of basic block, update */
-if (def->flags & TCG_OPF_BB_END) {
+if (def->flags & TCG_OPF_BB_EXIT) {
+la_func_end(s, nb_globals, nb_temps);
+} else if (def->flags & TCG_OPF_BB_END) {
 la_bb_end(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
 la_global_sync(s, nb_globals);
-- 
2.17.2




[Qemu-devel] [PULL 41/42] tcg: Record register preferences during liveness

2018-12-25 Thread Richard Henderson
With these preferences, we can arrange for function call arguments to
be computed into the proper registers instead of requiring extra moves.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 197 +-
 1 file changed, 165 insertions(+), 32 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index d40edb4f57..5f8c09b0b4 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2365,6 +2365,21 @@ static void reachable_code_pass(TCGContext *s)
 #define IS_DEAD_ARG(n)   (arg_life & (DEAD_ARG << (n)))
 #define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
 
+/* For liveness_pass_1, the register preferences for a given temp.  */
+static inline TCGRegSet *la_temp_pref(TCGTemp *ts)
+{
+return ts->state_ptr;
+}
+
+/* For liveness_pass_1, reset the preferences for a given temp to the
+ * maximal regset for its type.
+ */
+static inline void la_reset_pref(TCGTemp *ts)
+{
+*la_temp_pref(ts)
+= (ts->state == TS_DEAD ? 0 : tcg_target_available_regs[ts->type]);
+}
+
 /* liveness analysis: end of function: all temps are dead, and globals
should be in memory. */
 static void la_func_end(TCGContext *s, int ng, int nt)
@@ -2373,9 +2388,11 @@ static void la_func_end(TCGContext *s, int ng, int nt)
 
 for (i = 0; i < ng; ++i) {
 s->temps[i].state = TS_DEAD | TS_MEM;
+la_reset_pref(>temps[i]);
 }
 for (i = ng; i < nt; ++i) {
 s->temps[i].state = TS_DEAD;
+la_reset_pref(>temps[i]);
 }
 }
 
@@ -2387,11 +2404,13 @@ static void la_bb_end(TCGContext *s, int ng, int nt)
 
 for (i = 0; i < ng; ++i) {
 s->temps[i].state = TS_DEAD | TS_MEM;
+la_reset_pref(>temps[i]);
 }
 for (i = ng; i < nt; ++i) {
 s->temps[i].state = (s->temps[i].temp_local
  ? TS_DEAD | TS_MEM
  : TS_DEAD);
+la_reset_pref(>temps[i]);
 }
 }
 
@@ -2401,7 +2420,12 @@ static void la_global_sync(TCGContext *s, int ng)
 int i;
 
 for (i = 0; i < ng; ++i) {
-s->temps[i].state |= TS_MEM;
+int state = s->temps[i].state;
+s->temps[i].state = state | TS_MEM;
+if (state == TS_DEAD) {
+/* If the global was previously dead, reset prefs.  */
+la_reset_pref(>temps[i]);
+}
 }
 }
 
@@ -2412,6 +2436,29 @@ static void la_global_kill(TCGContext *s, int ng)
 
 for (i = 0; i < ng; i++) {
 s->temps[i].state = TS_DEAD | TS_MEM;
+la_reset_pref(>temps[i]);
+}
+}
+
+/* liveness analysis: note live globals crossing calls.  */
+static void la_cross_call(TCGContext *s, int nt)
+{
+TCGRegSet mask = ~tcg_target_call_clobber_regs;
+int i;
+
+for (i = 0; i < nt; i++) {
+TCGTemp *ts = >temps[i];
+if (!(ts->state & TS_DEAD)) {
+TCGRegSet *pset = la_temp_pref(ts);
+TCGRegSet set = *pset;
+
+set &= mask;
+/* If the combination is not possible, restart.  */
+if (set == 0) {
+set = tcg_target_available_regs[ts->type] & mask;
+}
+*pset = set;
+}
 }
 }
 
@@ -2423,16 +2470,23 @@ static void liveness_pass_1(TCGContext *s)
 int nb_globals = s->nb_globals;
 int nb_temps = s->nb_temps;
 TCGOp *op, *op_prev;
+TCGRegSet *prefs;
+int i;
+
+prefs = tcg_malloc(sizeof(TCGRegSet) * nb_temps);
+for (i = 0; i < nb_temps; ++i) {
+s->temps[i].state_ptr = prefs + i;
+}
 
 /* ??? Should be redundant with the exit_tb that ends the TB.  */
 la_func_end(s, nb_globals, nb_temps);
 
 QTAILQ_FOREACH_REVERSE_SAFE(op, >ops, TCGOpHead, link, op_prev) {
-int i, nb_iargs, nb_oargs;
+int nb_iargs, nb_oargs;
 TCGOpcode opc_new, opc_new2;
 bool have_opc_new2;
 TCGLifeData arg_life = 0;
-TCGTemp *arg_ts;
+TCGTemp *ts;
 TCGOpcode opc = op->opc;
 const TCGOpDef *def = _op_defs[opc];
 
@@ -2440,6 +2494,7 @@ static void liveness_pass_1(TCGContext *s)
 case INDEX_op_call:
 {
 int call_flags;
+int nb_call_regs;
 
 nb_oargs = TCGOP_CALLO(op);
 nb_iargs = TCGOP_CALLI(op);
@@ -2448,8 +2503,8 @@ static void liveness_pass_1(TCGContext *s)
 /* pure functions can be removed if their result is unused */
 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
 for (i = 0; i < nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts->state != TS_DEAD) {
+ts = arg_temp(op->args[i]);
+if (ts->state != TS_DEAD) {
 goto do_not_remove_call;
 }
 }
@@ -2457,16 +2512,20 @@ static void liveness_pass_1(TCGContext *s)
 }
 do_not_remove_call:
 
-  

[Qemu-devel] [PULL 37/42] tcg: Reindent parts of liveness_pass_1

2018-12-25 Thread Richard Henderson
There are two blocks of the form

if (foo) {
stuff1;
goto bar;
} else {
baz:
stuff2;
}

which have unnecessary and confusing indentation.
Remove the else and unindent stuff2.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 139 --
 1 file changed, 71 insertions(+), 68 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index e2ae04d1d0..696a45f7f8 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2436,47 +2436,46 @@ static void liveness_pass_1(TCGContext *s)
 }
 }
 goto do_remove;
-} else {
-do_not_remove_call:
+}
+do_not_remove_call:
 
-/* output args are dead */
-for (i = 0; i < nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts->state & TS_DEAD) {
-arg_life |= DEAD_ARG << i;
-}
-if (arg_ts->state & TS_MEM) {
-arg_life |= SYNC_ARG << i;
-}
-arg_ts->state = TS_DEAD;
+/* output args are dead */
+for (i = 0; i < nb_oargs; i++) {
+arg_ts = arg_temp(op->args[i]);
+if (arg_ts->state & TS_DEAD) {
+arg_life |= DEAD_ARG << i;
 }
+if (arg_ts->state & TS_MEM) {
+arg_life |= SYNC_ARG << i;
+}
+arg_ts->state = TS_DEAD;
+}
 
-if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
-TCG_CALL_NO_READ_GLOBALS))) {
-/* globals should go back to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state = TS_DEAD | TS_MEM;
-}
-} else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
-/* globals should be synced to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state |= TS_MEM;
-}
+if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
+TCG_CALL_NO_READ_GLOBALS))) {
+/* globals should go back to memory */
+for (i = 0; i < nb_globals; i++) {
+s->temps[i].state = TS_DEAD | TS_MEM;
 }
+} else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
+/* globals should be synced to memory */
+for (i = 0; i < nb_globals; i++) {
+s->temps[i].state |= TS_MEM;
+}
+}
 
-/* record arguments that die in this helper */
-for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts && arg_ts->state & TS_DEAD) {
-arg_life |= DEAD_ARG << i;
-}
+/* record arguments that die in this helper */
+for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
+arg_ts = arg_temp(op->args[i]);
+if (arg_ts && arg_ts->state & TS_DEAD) {
+arg_life |= DEAD_ARG << i;
 }
-/* input arguments are live for preceding opcodes */
-for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts) {
-arg_ts->state &= ~TS_DEAD;
-}
+}
+/* input arguments are live for preceding opcodes */
+for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
+arg_ts = arg_temp(op->args[i]);
+if (arg_ts) {
+arg_ts->state &= ~TS_DEAD;
 }
 }
 }
@@ -2580,43 +2579,47 @@ static void liveness_pass_1(TCGContext *s)
 goto do_not_remove;
 }
 }
-do_remove:
-tcg_op_remove(s, op);
-} else {
-do_not_remove:
-/* output args are dead */
-for (i = 0; i < nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts->state & TS_DEAD) {
-arg_life |= DEAD_ARG << i;
-}
-if (arg_ts->state & TS_MEM) {
-arg_life |= SYNC_ARG << i;
-  

[Qemu-devel] [PULL 18/42] tcg/riscv: Add the out op decoder

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<7c47f00cb4a9a777120456e0704b4076a5d943ab.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 496 +
 1 file changed, 496 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 154315787c..014c5287f5 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1309,3 +1309,499 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
 #endif
 }
+
+static tcg_insn_unit *tb_ret_addr;
+
+static void tcg_out_op(TCGContext *s, TCGOpcode opc,
+   const TCGArg *args, const int *const_args)
+{
+TCGArg a0 = args[0];
+TCGArg a1 = args[1];
+TCGArg a2 = args[2];
+int c2 = const_args[2];
+
+switch (opc) {
+case INDEX_op_exit_tb:
+/* Reuse the zeroing that exists for goto_ptr.  */
+if (a0 == 0) {
+tcg_out_call_int(s, s->code_gen_epilogue, true);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0);
+tcg_out_call_int(s, tb_ret_addr, true);
+}
+break;
+
+case INDEX_op_goto_tb:
+assert(s->tb_jmp_insn_offset == 0);
+/* indirect jump method */
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO,
+   (uintptr_t)(s->tb_jmp_target_addr + a0));
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_TMP0, 0);
+set_jmp_reset_offset(s, a0);
+break;
+
+case INDEX_op_goto_ptr:
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, a0, 0);
+break;
+
+case INDEX_op_br:
+tcg_out_reloc(s, s->code_ptr, R_RISCV_JAL, arg_label(a0), 0);
+tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, 0);
+break;
+
+case INDEX_op_ld8u_i32:
+case INDEX_op_ld8u_i64:
+tcg_out_ldst(s, OPC_LBU, a0, a1, a2);
+break;
+case INDEX_op_ld8s_i32:
+case INDEX_op_ld8s_i64:
+tcg_out_ldst(s, OPC_LB, a0, a1, a2);
+break;
+case INDEX_op_ld16u_i32:
+case INDEX_op_ld16u_i64:
+tcg_out_ldst(s, OPC_LHU, a0, a1, a2);
+break;
+case INDEX_op_ld16s_i32:
+case INDEX_op_ld16s_i64:
+tcg_out_ldst(s, OPC_LH, a0, a1, a2);
+break;
+case INDEX_op_ld32u_i64:
+tcg_out_ldst(s, OPC_LWU, a0, a1, a2);
+break;
+case INDEX_op_ld_i32:
+case INDEX_op_ld32s_i64:
+tcg_out_ldst(s, OPC_LW, a0, a1, a2);
+break;
+case INDEX_op_ld_i64:
+tcg_out_ldst(s, OPC_LD, a0, a1, a2);
+break;
+
+case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
+tcg_out_ldst(s, OPC_SB, a0, a1, a2);
+break;
+case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
+tcg_out_ldst(s, OPC_SH, a0, a1, a2);
+break;
+case INDEX_op_st_i32:
+case INDEX_op_st32_i64:
+tcg_out_ldst(s, OPC_SW, a0, a1, a2);
+break;
+case INDEX_op_st_i64:
+tcg_out_ldst(s, OPC_SD, a0, a1, a2);
+break;
+
+case INDEX_op_add_i32:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ADDIW, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_ADDW, a0, a1, a2);
+}
+break;
+case INDEX_op_add_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ADDI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_ADD, a0, a1, a2);
+}
+break;
+
+case INDEX_op_sub_i32:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ADDIW, a0, a1, -a2);
+} else {
+tcg_out_opc_reg(s, OPC_SUBW, a0, a1, a2);
+}
+break;
+case INDEX_op_sub_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ADDI, a0, a1, -a2);
+} else {
+tcg_out_opc_reg(s, OPC_SUB, a0, a1, a2);
+}
+break;
+
+case INDEX_op_and_i32:
+case INDEX_op_and_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ANDI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_AND, a0, a1, a2);
+}
+break;
+
+case INDEX_op_or_i32:
+case INDEX_op_or_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ORI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_OR, a0, a1, a2);
+}
+break;
+
+case INDEX_op_xor_i32:
+case INDEX_op_xor_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_XORI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_XOR, a0, a1, a2);
+}
+break;
+
+case INDEX_op_not_i32:
+case INDEX_op_not_i64:
+tcg_out_opc_imm(s, OPC_XORI, a0, a1, -1);
+break;
+
+case INDEX_op_neg_i32:
+tcg_out_opc_reg(s, OPC_SUBW, a0, TCG_REG_ZERO, a1);
+break;
+case INDEX_op_neg_i64:
+tcg_out_opc_reg(s, 

[Qemu-devel] [PULL 39/42] tcg: Split out more subroutines from liveness_pass_1

2018-12-25 Thread Richard Henderson
Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 35 +++
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0afc6ba1e6..4f0acf8863 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2395,6 +2395,26 @@ static void la_bb_end(TCGContext *s, int ng, int nt)
 }
 }
 
+/* liveness analysis: sync globals back to memory.  */
+static void la_global_sync(TCGContext *s, int ng)
+{
+int i;
+
+for (i = 0; i < ng; ++i) {
+s->temps[i].state |= TS_MEM;
+}
+}
+
+/* liveness analysis: sync globals back to memory and kill.  */
+static void la_global_kill(TCGContext *s, int ng)
+{
+int i;
+
+for (i = 0; i < ng; i++) {
+s->temps[i].state = TS_DEAD | TS_MEM;
+}
+}
+
 /* Liveness analysis : update the opc_arg_life array to tell if a
given input arguments is dead. Instructions updating dead
temporaries are removed. */
@@ -2450,15 +2470,9 @@ static void liveness_pass_1(TCGContext *s)
 
 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
 TCG_CALL_NO_READ_GLOBALS))) {
-/* globals should go back to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state = TS_DEAD | TS_MEM;
-}
+la_global_kill(s, nb_globals);
 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
-/* globals should be synced to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state |= TS_MEM;
-}
+la_global_sync(s, nb_globals);
 }
 
 /* record arguments that die in this helper */
@@ -2601,10 +2615,7 @@ static void liveness_pass_1(TCGContext *s)
 if (def->flags & TCG_OPF_BB_END) {
 la_bb_end(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
-/* globals should be synced to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state |= TS_MEM;
-}
+la_global_sync(s, nb_globals);
 }
 
 /* record arguments that die in this opcode */
-- 
2.17.2




[Qemu-devel] [PULL 34/42] tcg: Add output_pref to TCGOp

2018-12-25 Thread Richard Henderson
Allocate storage for, but do not yet fill in, per-opcode
preferences for the output operands.  Pass it in to the
register allocation routines for output operands.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.h |  3 +++
 tcg/tcg.c | 18 +++---
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index db2d91867f..c6721cc7a7 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -619,6 +619,9 @@ typedef struct TCGOp {
 
 /* Arguments for the opcode.  */
 TCGArg args[MAX_OPC_PARAM];
+
+/* Register preferences for the output(s).  */
+TCGRegSet output_pref[2];
 } TCGOp;
 
 #define TCGOP_CALLI(X)(X)->param1
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 7844158a8a..32c66dae7d 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2591,6 +2591,8 @@ static void liveness_pass_1(TCGContext *s)
 break;
 }
 op->life = arg_life;
+op->output_pref[0] = 0;
+op->output_pref[1] = 0;
 }
 }
 
@@ -3105,17 +3107,18 @@ static void tcg_reg_alloc_movi(TCGContext *s, const 
TCGOp *op)
 TCGTemp *ots = arg_temp(op->args[0]);
 tcg_target_ulong val = op->args[1];
 
-tcg_reg_alloc_do_movi(s, ots, val, op->life, 0);
+tcg_reg_alloc_do_movi(s, ots, val, op->life, op->output_pref[0]);
 }
 
 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
 {
 const TCGLifeData arg_life = op->life;
-TCGRegSet allocated_regs;
+TCGRegSet allocated_regs, preferred_regs;
 TCGTemp *ts, *ots;
 TCGType otype, itype;
 
 allocated_regs = s->reserved_regs;
+preferred_regs = op->output_pref[0];
 ots = arg_temp(op->args[0]);
 ts = arg_temp(op->args[1]);
 
@@ -3129,7 +3132,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 if (IS_DEAD_ARG(1)) {
 temp_dead(s, ts);
 }
-tcg_reg_alloc_do_movi(s, ots, val, arg_life, 0);
+tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs);
 return;
 }
 
@@ -3138,7 +3141,8 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
the SOURCE value into its own register first, that way we
don't have to reload SOURCE the next time it is used. */
 if (ts->val_type == TEMP_VAL_MEM) {
-temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs, 0);
+temp_load(s, ts, tcg_target_available_regs[itype],
+  allocated_regs, preferred_regs);
 }
 
 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
@@ -3168,7 +3172,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
input one. */
 tcg_regset_set_reg(allocated_regs, ts->reg);
 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
- allocated_regs, 0,
+ allocated_regs, preferred_regs,
  ots->indirect_base);
 }
 tcg_out_mov(s, otype, ots->reg, ts->reg);
@@ -3302,7 +3306,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 } else if (arg_ct->ct & TCG_CT_NEWREG) {
 reg = tcg_reg_alloc(s, arg_ct->u.regs,
 i_allocated_regs | o_allocated_regs,
-0, ts->indirect_base);
+op->output_pref[k], ts->indirect_base);
 } else {
 /* if fixed register, we try to use it */
 reg = ts->reg;
@@ -3311,7 +3315,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 goto oarg_end;
 }
 reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs,
-0, ts->indirect_base);
+op->output_pref[k], ts->indirect_base);
 }
 tcg_regset_set_reg(o_allocated_regs, reg);
 /* if a fixed register is used, then a move will be done 
afterwards */
-- 
2.17.2




[Qemu-devel] [PULL 16/42] tcg/riscv: Add slowpath load and store instructions

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<1a0a7e8f3347764f212c5efa5c07c9be17efdec6.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 256 +
 1 file changed, 256 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index ecc76c9ef8..7216bad086 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -895,3 +895,259 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit 
*arg)
 {
 tcg_out_call_int(s, arg, false);
 }
+
+static void tcg_out_mb(TCGContext *s, TCGArg a0)
+{
+tcg_insn_unit insn = OPC_FENCE;
+
+if (a0 & TCG_MO_LD_LD) {
+insn |= 0x0220;
+}
+if (a0 & TCG_MO_ST_LD) {
+insn |= 0x0120;
+}
+if (a0 & TCG_MO_LD_ST) {
+insn |= 0x0210;
+}
+if (a0 & TCG_MO_ST_ST) {
+insn |= 0x0220;
+}
+tcg_out32(s, insn);
+}
+
+/*
+ * Load/store and TLB
+ */
+
+#if defined(CONFIG_SOFTMMU)
+#include "tcg-ldst.inc.c"
+
+/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
+ * TCGMemOpIdx oi, uintptr_t ra)
+ */
+static void * const qemu_ld_helpers[16] = {
+[MO_UB]   = helper_ret_ldub_mmu,
+[MO_SB]   = helper_ret_ldsb_mmu,
+[MO_LEUW] = helper_le_lduw_mmu,
+[MO_LESW] = helper_le_ldsw_mmu,
+[MO_LEUL] = helper_le_ldul_mmu,
+#if TCG_TARGET_REG_BITS == 64
+[MO_LESL] = helper_le_ldsl_mmu,
+#endif
+[MO_LEQ]  = helper_le_ldq_mmu,
+[MO_BEUW] = helper_be_lduw_mmu,
+[MO_BESW] = helper_be_ldsw_mmu,
+[MO_BEUL] = helper_be_ldul_mmu,
+#if TCG_TARGET_REG_BITS == 64
+[MO_BESL] = helper_be_ldsl_mmu,
+#endif
+[MO_BEQ]  = helper_be_ldq_mmu,
+};
+
+/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
+ * uintxx_t val, TCGMemOpIdx oi,
+ * uintptr_t ra)
+ */
+static void * const qemu_st_helpers[16] = {
+[MO_UB]   = helper_ret_stb_mmu,
+[MO_LEUW] = helper_le_stw_mmu,
+[MO_LEUL] = helper_le_stl_mmu,
+[MO_LEQ]  = helper_le_stq_mmu,
+[MO_BEUW] = helper_be_stw_mmu,
+[MO_BEUL] = helper_be_stl_mmu,
+[MO_BEQ]  = helper_be_stq_mmu,
+};
+
+static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
+ TCGReg addrh, TCGMemOpIdx oi,
+ tcg_insn_unit **label_ptr, bool is_load)
+{
+TCGMemOp opc = get_memop(oi);
+unsigned s_bits = opc & MO_SIZE;
+unsigned a_bits = get_alignment_bits(opc);
+target_ulong mask;
+int mem_index = get_mmuidx(oi);
+int cmp_off
+= (is_load
+   ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
+   : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
+int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
+RISCVInsn load_cmp_op = (TARGET_LONG_BITS == 64 ? OPC_LD :
+ TCG_TARGET_REG_BITS == 64 ? OPC_LWU : OPC_LW);
+RISCVInsn load_add_op = TCG_TARGET_REG_BITS == 64 ? OPC_LD : OPC_LW;
+TCGReg base = TCG_AREG0;
+
+/* We don't support oversize guests */
+if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
+g_assert_not_reached();
+}
+
+/* We don't support unaligned accesses. */
+if (a_bits < s_bits) {
+a_bits = s_bits;
+}
+mask = (target_ulong)TARGET_PAGE_MASK | ((1 << a_bits) - 1);
+
+
+/* Compensate for very large offsets.  */
+if (add_off >= 0x1000) {
+int adj;
+base = TCG_REG_TMP2;
+if (cmp_off <= 2 * 0xfff) {
+adj = 0xfff;
+tcg_out_opc_imm(s, OPC_ADDI, base, TCG_AREG0, adj);
+} else {
+adj = cmp_off - sextreg(cmp_off, 0, 12);
+tcg_debug_assert(add_off - adj >= -0x1000
+ && add_off - adj < 0x1000);
+
+tcg_out_opc_upper(s, OPC_LUI, base, adj);
+tcg_out_opc_reg(s, OPC_ADD, base, base, TCG_AREG0);
+}
+add_off -= adj;
+cmp_off -= adj;
+}
+
+/* Extract the page index.  */
+if (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS < 12) {
+tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP0, addrl,
+TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP0, TCG_REG_TMP0,
+MAKE_64BIT_MASK(CPU_TLB_ENTRY_BITS, CPU_TLB_BITS));
+} else if (TARGET_PAGE_BITS >= 12) {
+tcg_out_opc_upper(s, OPC_LUI, TCG_REG_TMP0,
+  MAKE_64BIT_MASK(TARGET_PAGE_BITS, CPU_TLB_BITS));
+tcg_out_opc_reg(s, OPC_AND, TCG_REG_TMP0, TCG_REG_TMP0, addrl);
+tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP0, TCG_REG_TMP0,
+CPU_TLB_BITS - CPU_TLB_ENTRY_BITS);
+} else {
+tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP0, addrl, 

[Qemu-devel] [PULL 38/42] tcg: Rename and adjust liveness_pass_1 helpers

2018-12-25 Thread Richard Henderson
No need for a "tcg_" prefix for a static function; we already
have another "la_" prefix for indicating liveness analysis.
Pass in nb_globals and nb_temps, as we will already have them
in registers for other loops within the parent function.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 696a45f7f8..0afc6ba1e6 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2367,10 +2367,8 @@ static void reachable_code_pass(TCGContext *s)
 
 /* liveness analysis: end of function: all temps are dead, and globals
should be in memory. */
-static void tcg_la_func_end(TCGContext *s)
+static void la_func_end(TCGContext *s, int ng, int nt)
 {
-int ng = s->nb_globals;
-int nt = s->nb_temps;
 int i;
 
 for (i = 0; i < ng; ++i) {
@@ -2383,10 +2381,8 @@ static void tcg_la_func_end(TCGContext *s)
 
 /* liveness analysis: end of basic block: all temps are dead, globals
and local temps should be in memory. */
-static void tcg_la_bb_end(TCGContext *s)
+static void la_bb_end(TCGContext *s, int ng, int nt)
 {
-int ng = s->nb_globals;
-int nt = s->nb_temps;
 int i;
 
 for (i = 0; i < ng; ++i) {
@@ -2405,9 +2401,10 @@ static void tcg_la_bb_end(TCGContext *s)
 static void liveness_pass_1(TCGContext *s)
 {
 int nb_globals = s->nb_globals;
+int nb_temps = s->nb_temps;
 TCGOp *op, *op_prev;
 
-tcg_la_func_end(s);
+la_func_end(s, nb_globals, nb_temps);
 
 QTAILQ_FOREACH_REVERSE_SAFE(op, >ops, TCGOpHead, link, op_prev) {
 int i, nb_iargs, nb_oargs;
@@ -2602,7 +2599,7 @@ static void liveness_pass_1(TCGContext *s)
 
 /* if end of basic block, update */
 if (def->flags & TCG_OPF_BB_END) {
-tcg_la_bb_end(s);
+la_bb_end(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
 /* globals should be synced to memory */
 for (i = 0; i < nb_globals; i++) {
-- 
2.17.2




[Qemu-devel] [PULL 35/42] tcg: Improve register allocation for matching constraints

2018-12-25 Thread Richard Henderson
Try harder to honor the output_pref.  When we're forced to allocate
a second register for the input, it does not need to use the input
constraint; that will be honored by the register we allocate for the
output and a move is already required.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 36 
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 32c66dae7d..32bac5e792 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3213,6 +3213,8 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 
 /* satisfy input constraints */ 
 for (k = 0; k < nb_iargs; k++) {
+TCGRegSet i_preferred_regs, o_preferred_regs;
+
 i = def->sorted_args[nb_oargs + k];
 arg = op->args[i];
 arg_ct = >args_ct[i];
@@ -3223,17 +3225,18 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 /* constant is OK for instruction */
 const_args[i] = 1;
 new_args[i] = ts->val;
-goto iarg_end;
+continue;
 }
 
-temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, 0);
-
+i_preferred_regs = o_preferred_regs = 0;
 if (arg_ct->ct & TCG_CT_IALIAS) {
+o_preferred_regs = op->output_pref[arg_ct->alias_index];
 if (ts->fixed_reg) {
 /* if fixed register, we must allocate a new register
if the alias is not the same register */
-if (arg != op->args[arg_ct->alias_index])
+if (arg != op->args[arg_ct->alias_index]) {
 goto allocate_in_reg;
+}
 } else {
 /* if the input is aliased to an output and if it is
not dead after the instruction, we must allocate
@@ -3241,33 +3244,42 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 if (!IS_DEAD_ARG(i)) {
 goto allocate_in_reg;
 }
+
 /* check if the current register has already been allocated
for another input aliased to an output */
-int k2, i2;
-for (k2 = 0 ; k2 < k ; k2++) {
-i2 = def->sorted_args[nb_oargs + k2];
-if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
-(new_args[i2] == ts->reg)) {
-goto allocate_in_reg;
+if (ts->val_type == TEMP_VAL_REG) {
+int k2, i2;
+reg = ts->reg;
+for (k2 = 0 ; k2 < k ; k2++) {
+i2 = def->sorted_args[nb_oargs + k2];
+if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
+reg == new_args[i2]) {
+goto allocate_in_reg;
+}
 }
 }
+i_preferred_regs = o_preferred_regs;
 }
 }
+
+temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, i_preferred_regs);
 reg = ts->reg;
+
 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
 /* nothing to do : the constraint is satisfied */
 } else {
 allocate_in_reg:
 /* allocate a new register matching the constraint 
and move the temporary register into it */
+temp_load(s, ts, tcg_target_available_regs[ts->type],
+  i_allocated_regs, 0);
 reg = tcg_reg_alloc(s, arg_ct->u.regs, i_allocated_regs,
-0, ts->indirect_base);
+o_preferred_regs, ts->indirect_base);
 tcg_out_mov(s, ts->type, reg, ts->reg);
 }
 new_args[i] = reg;
 const_args[i] = 0;
 tcg_regset_set_reg(i_allocated_regs, reg);
-iarg_end: ;
 }
 
 /* mark dead temporaries and free the associated registers */
-- 
2.17.2




[Qemu-devel] [PULL 31/42] tcg: Add preferred_reg argument to temp_load

2018-12-25 Thread Richard Henderson
Pass this through to tcg_reg_alloc.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 210bd5c6b9..351d302a68 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2837,7 +2837,7 @@ static void temp_allocate_frame(TCGContext *s, TCGTemp 
*ts)
 s->current_frame_offset += sizeof(tcg_target_long);
 }
 
-static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet);
+static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, 
TCGRegSet);
 
 /* Mark a temporary as free or dead.  If 'free_or_dead' is negative,
mark it free; otherwise mark it dead.  */
@@ -2886,7 +2886,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts,
 break;
 }
 temp_load(s, ts, tcg_target_available_regs[ts->type],
-  allocated_regs);
+  allocated_regs, 0);
 /* fallthrough */
 
 case TEMP_VAL_REG:
@@ -2992,7 +2992,7 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet 
required_regs,
 /* Make sure the temporary is in a register.  If needed, allocate the register
from DESIRED while avoiding ALLOCATED.  */
 static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
-  TCGRegSet allocated_regs)
+  TCGRegSet allocated_regs, TCGRegSet preferred_regs)
 {
 TCGReg reg;
 
@@ -3001,13 +3001,13 @@ static void temp_load(TCGContext *s, TCGTemp *ts, 
TCGRegSet desired_regs,
 return;
 case TEMP_VAL_CONST:
 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
-0, ts->indirect_base);
+preferred_regs, ts->indirect_base);
 tcg_out_movi(s, ts->type, reg, ts->val);
 ts->mem_coherent = 0;
 break;
 case TEMP_VAL_MEM:
 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
-0, ts->indirect_base);
+preferred_regs, ts->indirect_base);
 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
 ts->mem_coherent = 1;
 break;
@@ -3137,7 +3137,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
the SOURCE value into its own register first, that way we
don't have to reload SOURCE the next time it is used. */
 if (ts->val_type == TEMP_VAL_MEM) {
-temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs);
+temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs, 0);
 }
 
 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
@@ -3221,7 +3221,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 goto iarg_end;
 }
 
-temp_load(s, ts, arg_ct->u.regs, i_allocated_regs);
+temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, 0);
 
 if (arg_ct->ct & TCG_CT_IALIAS) {
 if (ts->fixed_reg) {
@@ -3402,7 +3402,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 if (arg != TCG_CALL_DUMMY_ARG) {
 ts = arg_temp(arg);
 temp_load(s, ts, tcg_target_available_regs[ts->type],
-  s->reserved_regs);
+  s->reserved_regs, 0);
 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
 }
 #ifndef TCG_TARGET_STACK_GROWSUP
@@ -3427,7 +3427,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 TCGRegSet arg_set = 0;
 
 tcg_regset_set_reg(arg_set, reg);
-temp_load(s, ts, arg_set, allocated_regs);
+temp_load(s, ts, arg_set, allocated_regs, 0);
 }
 
 tcg_regset_set_reg(allocated_regs, reg);
-- 
2.17.2




[Qemu-devel] [PULL 14/42] tcg/riscv: Add the add2 and sub2 instructions

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Message-Id: 
<5665a57809e32b35775e8e98fdab898853af37b8.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 55 ++
 1 file changed, 55 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 65718df7ad..5da850b957 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -695,3 +695,58 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, 
TCGArg val,
 }
 return false;
 }
+
+static void tcg_out_addsub2(TCGContext *s,
+TCGReg rl, TCGReg rh,
+TCGReg al, TCGReg ah,
+TCGArg bl, TCGArg bh,
+bool cbl, bool cbh, bool is_sub, bool is32bit)
+{
+const RISCVInsn opc_add = is32bit ? OPC_ADDW : OPC_ADD;
+const RISCVInsn opc_addi = is32bit ? OPC_ADDIW : OPC_ADDI;
+const RISCVInsn opc_sub = is32bit ? OPC_SUBW : OPC_SUB;
+TCGReg th = TCG_REG_TMP1;
+
+/* If we have a negative constant such that negating it would
+   make the high part zero, we can (usually) eliminate one insn.  */
+if (cbl && cbh && bh == -1 && bl != 0) {
+bl = -bl;
+bh = 0;
+is_sub = !is_sub;
+}
+
+/* By operating on the high part first, we get to use the final
+   carry operation to move back from the temporary.  */
+if (!cbh) {
+tcg_out_opc_reg(s, (is_sub ? opc_sub : opc_add), th, ah, bh);
+} else if (bh != 0 || ah == rl) {
+tcg_out_opc_imm(s, opc_addi, th, ah, (is_sub ? -bh : bh));
+} else {
+th = ah;
+}
+
+/* Note that tcg optimization should eliminate the bl == 0 case.  */
+if (is_sub) {
+if (cbl) {
+tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, al, bl);
+tcg_out_opc_imm(s, opc_addi, rl, al, -bl);
+} else {
+tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0, al, bl);
+tcg_out_opc_reg(s, opc_sub, rl, al, bl);
+}
+tcg_out_opc_reg(s, opc_sub, rh, th, TCG_REG_TMP0);
+} else {
+if (cbl) {
+tcg_out_opc_imm(s, opc_addi, rl, al, bl);
+tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, rl, bl);
+} else if (rl == al && rl == bl) {
+tcg_out_opc_imm(s, OPC_SLTI, TCG_REG_TMP0, al, 0);
+tcg_out_opc_reg(s, opc_addi, rl, al, bl);
+} else {
+tcg_out_opc_reg(s, opc_add, rl, al, bl);
+tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0,
+rl, (rl == bl ? al : bl));
+}
+tcg_out_opc_reg(s, opc_add, rh, th, TCG_REG_TMP0);
+}
+}
-- 
2.17.2




[Qemu-devel] [PULL 23/42] configure: Add support for building RISC-V host

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<52160afacecc5b109dc43a412fa3e74ddd6277fb.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 configure | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 224d3071ac..79375affc1 100755
--- a/configure
+++ b/configure
@@ -710,6 +710,12 @@ elif check_define __s390__ ; then
   else
 cpu="s390"
   fi
+elif check_define __riscv ; then
+  if check_define _LP64 ; then
+cpu="riscv64"
+  else
+cpu="riscv32"
+  fi
 elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
@@ -722,7 +728,7 @@ ARCH=
 # Normalise host CPU name and set ARCH.
 # Note that this case should only have supported host CPUs, not guests.
 case "$cpu" in
-  ppc|ppc64|s390|s390x|sparc64|x32)
+  ppc|ppc64|s390|s390x|sparc64|x32|riscv32|riscv64)
 cpu="$cpu"
 supported_cpu="yes"
 eval "cross_cc_${cpu}=\$host_cc"
@@ -6937,6 +6943,8 @@ elif test "$ARCH" = "x86_64" -o "$ARCH" = "x32" ; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/i386 $QEMU_INCLUDES"
 elif test "$ARCH" = "ppc64" ; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/ppc $QEMU_INCLUDES"
+elif test "$ARCH" = "riscv32" -o "$ARCH" = "riscv64" ; then
+  QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/riscv $QEMU_INCLUDES"
 else
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/\$(ARCH) $QEMU_INCLUDES"
 fi
@@ -7433,7 +7441,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   ppc*)
 disas_config "PPC"
   ;;
-  riscv)
+  riscv*)
 disas_config "RISCV"
   ;;
   s390*)
-- 
2.17.2




[Qemu-devel] [PULL 32/42] tcg: Add preferred_reg argument to temp_sync

2018-12-25 Thread Richard Henderson
Pass this through to tcg_reg_alloc.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 351d302a68..fe060c481a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2865,8 +2865,8 @@ static inline void temp_dead(TCGContext *s, TCGTemp *ts)
registers needs to be allocated to store a constant.  If 'free_or_dead'
is non-zero, subsequently release the temporary; if it is positive, the
temp is dead; if it is negative, the temp is free.  */
-static void temp_sync(TCGContext *s, TCGTemp *ts,
-  TCGRegSet allocated_regs, int free_or_dead)
+static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs,
+  TCGRegSet preferred_regs, int free_or_dead)
 {
 if (ts->fixed_reg) {
 return;
@@ -2886,7 +2886,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts,
 break;
 }
 temp_load(s, ts, tcg_target_available_regs[ts->type],
-  allocated_regs, 0);
+  allocated_regs, preferred_regs);
 /* fallthrough */
 
 case TEMP_VAL_REG:
@@ -2913,7 +2913,7 @@ static void tcg_reg_free(TCGContext *s, TCGReg reg, 
TCGRegSet allocated_regs)
 {
 TCGTemp *ts = s->reg_to_temp[reg];
 if (ts != NULL) {
-temp_sync(s, ts, allocated_regs, -1);
+temp_sync(s, ts, allocated_regs, 0, -1);
 }
 }
 
@@ -3093,7 +3093,7 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp 
*ots,
 ots->val = val;
 ots->mem_coherent = 0;
 if (NEED_SYNC_ARG(0)) {
-temp_sync(s, ots, s->reserved_regs, IS_DEAD_ARG(0));
+temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
 } else if (IS_DEAD_ARG(0)) {
 temp_dead(s, ots);
 }
@@ -3176,7 +3176,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 ots->mem_coherent = 0;
 s->reg_to_temp[ots->reg] = ots;
 if (NEED_SYNC_ARG(0)) {
-temp_sync(s, ots, allocated_regs, 0);
+temp_sync(s, ots, allocated_regs, 0, 0);
 }
 }
 }
@@ -3346,7 +3346,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 tcg_out_mov(s, ts->type, ts->reg, reg);
 }
 if (NEED_SYNC_ARG(i)) {
-temp_sync(s, ts, o_allocated_regs, IS_DEAD_ARG(i));
+temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i));
 } else if (IS_DEAD_ARG(i)) {
 temp_dead(s, ts);
 }
@@ -3480,7 +3480,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 ts->mem_coherent = 0;
 s->reg_to_temp[reg] = ts;
 if (NEED_SYNC_ARG(i)) {
-temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
+temp_sync(s, ts, allocated_regs, 0, IS_DEAD_ARG(i));
 } else if (IS_DEAD_ARG(i)) {
 temp_dead(s, ts);
 }
-- 
2.17.2




[Qemu-devel] [PULL 10/42] tcg/riscv: Add the relocation functions

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<6ac4f4b0d5ea93cb0ee9a3b8b47ee9f7b3711494.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 88 ++
 1 file changed, 88 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index d198cfd5f7..a26744052f 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -422,3 +422,91 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
 p[i] = encode_i(OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
 }
 }
+
+/*
+ * Relocations
+ */
+
+static bool reloc_sbimm12(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
+{
+intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
+
+if (offset == sextreg(offset, 1, 12) << 1) {
+code_ptr[0] |= encode_sbimm12(offset);
+return true;
+}
+
+return false;
+}
+
+static bool reloc_jimm20(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
+{
+intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
+
+if (offset == sextreg(offset, 1, 20) << 1) {
+code_ptr[0] |= encode_ujimm20(offset);
+return true;
+}
+
+return false;
+}
+
+static bool reloc_call(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
+{
+intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
+int32_t lo = sextreg(offset, 0, 12);
+int32_t hi = offset - lo;
+
+if (offset == hi + lo) {
+code_ptr[0] |= encode_uimm20(hi);
+code_ptr[1] |= encode_imm12(lo);
+return true;
+}
+
+return false;
+}
+
+static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
+intptr_t value, intptr_t addend)
+{
+uint32_t insn = *code_ptr;
+intptr_t diff;
+bool short_jmp;
+
+tcg_debug_assert(addend == 0);
+
+switch (type) {
+case R_RISCV_BRANCH:
+diff = value - (uintptr_t)code_ptr;
+short_jmp = diff == sextreg(diff, 0, 12);
+if (short_jmp) {
+return reloc_sbimm12(code_ptr, (tcg_insn_unit *)value);
+} else {
+/* Invert the condition */
+insn = insn ^ (1 << 12);
+/* Clear the offset */
+insn &= 0x01fff07f;
+/* Set the offset to the PC + 8 */
+insn |= encode_sbimm12(8);
+
+/* Move forward */
+code_ptr[0] = insn;
+
+/* Overwrite the NOP with jal x0,value */
+diff = value - (uintptr_t)(code_ptr + 1);
+insn = encode_uj(OPC_JAL, TCG_REG_ZERO, diff);
+code_ptr[1] = insn;
+
+return true;
+}
+break;
+case R_RISCV_JAL:
+return reloc_jimm20(code_ptr, (tcg_insn_unit *)value);
+break;
+case R_RISCV_CALL:
+return reloc_call(code_ptr, (tcg_insn_unit *)value);
+break;
+default:
+tcg_abort();
+}
+}
-- 
2.17.2




[Qemu-devel] [PULL 30/42] tcg: Add preferred_reg argument to tcg_reg_alloc

2018-12-25 Thread Richard Henderson
This new argument will aid register allocation by indicating how
the temporary will be used in future.  If the preference cannot
be satisfied, fall back to the constraints of the current insn.

Short circuit the preference when it cannot be satisfied or if
it does not further constrain the operation.

With an eye toward optimizing function call sequences, optimize
for the preferred_reg set containing a single register.

For the moment, all users pass 0 for preference.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 103 ++
 1 file changed, 81 insertions(+), 22 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index d2be550ab4..210bd5c6b9 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1887,6 +1887,20 @@ static const char * const alignment_name[(MO_AMASK >> 
MO_ASHIFT) + 1] = {
 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
 };
 
+static inline bool tcg_regset_single(TCGRegSet d)
+{
+return (d & (d - 1)) == 0;
+}
+
+static inline TCGReg tcg_regset_first(TCGRegSet d)
+{
+if (TCG_TARGET_NB_REGS <= 32) {
+return ctz32(d);
+} else {
+return ctz64(d);
+}
+}
+
 void tcg_dump_ops(TCGContext *s)
 {
 char buf[128];
@@ -1902,6 +1916,7 @@ void tcg_dump_ops(TCGContext *s)
 def = _op_defs[c];
 
 if (c == INDEX_op_insn_start) {
+nb_oargs = 0;
 col += qemu_log("\n ");
 
 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
@@ -2902,31 +2917,72 @@ static void tcg_reg_free(TCGContext *s, TCGReg reg, 
TCGRegSet allocated_regs)
 }
 }
 
-/* Allocate a register belonging to reg1 & ~reg2 */
-static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
-TCGRegSet allocated_regs, bool rev)
+/**
+ * tcg_reg_alloc:
+ * @required_regs: Set of registers in which we must allocate.
+ * @allocated_regs: Set of registers which must be avoided.
+ * @preferred_regs: Set of registers we should prefer.
+ * @rev: True if we search the registers in "indirect" order.
+ *
+ * The allocated register must be in @required_regs & ~@allocated_regs,
+ * but if we can put it in @preferred_regs we may save a move later.
+ */
+static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs,
+TCGRegSet allocated_regs,
+TCGRegSet preferred_regs, bool rev)
 {
-int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
+int i, j, f, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
+TCGRegSet reg_ct[2];
 const int *order;
-TCGReg reg;
-TCGRegSet reg_ct;
 
-reg_ct = desired_regs & ~allocated_regs;
+reg_ct[1] = required_regs & ~allocated_regs;
+tcg_debug_assert(reg_ct[1] != 0);
+reg_ct[0] = reg_ct[1] & preferred_regs;
+
+/* Skip the preferred_regs option if it cannot be satisfied,
+   or if the preference made no difference.  */
+f = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
+
 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
 
-/* first try free registers */
-for(i = 0; i < n; i++) {
-reg = order[i];
-if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL)
-return reg;
+/* Try free registers, preferences first.  */
+for (j = f; j < 2; j++) {
+TCGRegSet set = reg_ct[j];
+
+if (tcg_regset_single(set)) {
+/* One register in the set.  */
+TCGReg reg = tcg_regset_first(set);
+if (s->reg_to_temp[reg] == NULL) {
+return reg;
+}
+} else {
+for (i = 0; i < n; i++) {
+TCGReg reg = order[i];
+if (s->reg_to_temp[reg] == NULL &&
+tcg_regset_test_reg(set, reg)) {
+return reg;
+}
+}
+}
 }
 
-/* XXX: do better spill choice */
-for(i = 0; i < n; i++) {
-reg = order[i];
-if (tcg_regset_test_reg(reg_ct, reg)) {
+/* We must spill something.  */
+for (j = f; j < 2; j++) {
+TCGRegSet set = reg_ct[j];
+
+if (tcg_regset_single(set)) {
+/* One register in the set.  */
+TCGReg reg = tcg_regset_first(set);
 tcg_reg_free(s, reg, allocated_regs);
 return reg;
+} else {
+for (i = 0; i < n; i++) {
+TCGReg reg = order[i];
+if (tcg_regset_test_reg(set, reg)) {
+tcg_reg_free(s, reg, allocated_regs);
+return reg;
+}
+}
 }
 }
 
@@ -2944,12 +3000,14 @@ static void temp_load(TCGContext *s, TCGTemp *ts, 
TCGRegSet desired_regs,
 case TEMP_VAL_REG:
 return;
 case TEMP_VAL_CONST:
-reg = tcg_reg_alloc(s, desired_regs, allocated_regs, 
ts->indirect_base);
+reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
+0, ts->indirect_base);
 

[Qemu-devel] [PULL 20/42] tcg/riscv: Add the target init code

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 8a5f1deefc..6cf8de32b5 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1872,6 +1872,37 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0);
 }
 
+static void tcg_target_init(TCGContext *s)
+{
+tcg_target_available_regs[TCG_TYPE_I32] = 0x;
+if (TCG_TARGET_REG_BITS == 64) {
+tcg_target_available_regs[TCG_TYPE_I64] = 0x;
+}
+
+tcg_target_call_clobber_regs = -1u;
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S10);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S11);
+
+s->reserved_regs = 0;
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
+}
+
 typedef struct {
 DebugFrameHeader h;
 uint8_t fde_def_cfa[4];
-- 
2.17.2




[Qemu-devel] [PULL 28/42] tcg: Reference count labels

2018-12-25 Thread Richard Henderson
Increment when adding branches, and decrement when removing them.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/tcg-op.h |  1 +
 tcg/tcg.h|  3 ++-
 tcg/tcg-op.c |  2 ++
 tcg/tcg.c| 20 
 4 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index db4e9188f4..7007ec0d4d 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -260,6 +260,7 @@ static inline void gen_set_label(TCGLabel *l)
 
 static inline void tcg_gen_br(TCGLabel *l)
 {
+l->refs++;
 tcg_gen_op1(INDEX_op_br, label_arg(l));
 }
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 492d8dcf10..db2d91867f 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -244,7 +244,8 @@ typedef struct TCGRelocation {
 
 typedef struct TCGLabel {
 unsigned has_value : 1;
-unsigned id : 31;
+unsigned id : 15;
+unsigned refs : 16;
 union {
 uintptr_t value;
 tcg_insn_unit *value_ptr;
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 38652db32c..1bd7ef24af 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -240,6 +240,7 @@ void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, 
TCGv_i32 arg2, TCGLabel *l)
 if (cond == TCG_COND_ALWAYS) {
 tcg_gen_br(l);
 } else if (cond != TCG_COND_NEVER) {
+l->refs++;
 tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l));
 }
 }
@@ -1405,6 +1406,7 @@ void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, 
TCGv_i64 arg2, TCGLabel *l)
 if (cond == TCG_COND_ALWAYS) {
 tcg_gen_br(l);
 } else if (cond != TCG_COND_NEVER) {
+l->refs++;
 if (TCG_TARGET_REG_BITS == 32) {
 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
   TCGV_HIGH(arg1), TCGV_LOW(arg2),
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 963cb37892..99afc65126 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2171,6 +2171,26 @@ static void process_op_defs(TCGContext *s)
 
 void tcg_op_remove(TCGContext *s, TCGOp *op)
 {
+TCGLabel *label;
+
+switch (op->opc) {
+case INDEX_op_br:
+label = arg_label(op->args[0]);
+label->refs--;
+break;
+case INDEX_op_brcond_i32:
+case INDEX_op_brcond_i64:
+label = arg_label(op->args[3]);
+label->refs--;
+break;
+case INDEX_op_brcond2_i32:
+label = arg_label(op->args[5]);
+label->refs--;
+break;
+default:
+break;
+}
+
 QTAILQ_REMOVE(>ops, op, link);
 QTAILQ_INSERT_TAIL(>free_ops, op, link);
 s->nb_ops--;
-- 
2.17.2




[Qemu-devel] [PULL 25/42] linux-user: Add safe_syscall for riscv64 host

2018-12-25 Thread Richard Henderson
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 linux-user/host/riscv64/hostdep.h  | 23 +++
 linux-user/host/riscv64/safe-syscall.inc.S | 77 ++
 2 files changed, 100 insertions(+)
 create mode 100644 linux-user/host/riscv64/safe-syscall.inc.S

diff --git a/linux-user/host/riscv64/hostdep.h 
b/linux-user/host/riscv64/hostdep.h
index 28467ba00b..865f0fb9ff 100644
--- a/linux-user/host/riscv64/hostdep.h
+++ b/linux-user/host/riscv64/hostdep.h
@@ -8,4 +8,27 @@
 #ifndef RISCV64_HOSTDEP_H
 #define RISCV64_HOSTDEP_H
 
+/* We have a safe-syscall.inc.S */
+#define HAVE_SAFE_SYSCALL
+
+#ifndef __ASSEMBLER__
+
+/* These are defined by the safe-syscall.inc.S file */
+extern char safe_syscall_start[];
+extern char safe_syscall_end[];
+
+/* Adjust the signal context to rewind out of safe-syscall if we're in it */
+static inline void rewind_if_in_safe_syscall(void *puc)
+{
+ucontext_t *uc = puc;
+unsigned long *pcreg = >uc_mcontext.__gregs[REG_PC];
+
+if (*pcreg > (uintptr_t)safe_syscall_start
+&& *pcreg < (uintptr_t)safe_syscall_end) {
+*pcreg = (uintptr_t)safe_syscall_start;
+}
+}
+
+#endif /* __ASSEMBLER__ */
+
 #endif
diff --git a/linux-user/host/riscv64/safe-syscall.inc.S 
b/linux-user/host/riscv64/safe-syscall.inc.S
new file mode 100644
index 00..9ca3fbfd1e
--- /dev/null
+++ b/linux-user/host/riscv64/safe-syscall.inc.S
@@ -0,0 +1,77 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by linux-user/safe-syscall.S
+ *
+ * Written by Richard Henderson 
+ * Copyright (C) 2018 Linaro, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+   .global safe_syscall_base
+   .global safe_syscall_start
+   .global safe_syscall_end
+   .type   safe_syscall_base, @function
+   .type   safe_syscall_start, @function
+   .type   safe_syscall_end, @function
+
+   /*
+* This is the entry point for making a system call. The calling
+* convention here is that of a C varargs function with the
+* first argument an 'int *' to the signal_pending flag, the
+* second one the system call number (as a 'long'), and all further
+* arguments being syscall arguments (also 'long').
+* We return a long which is the syscall's return value, which
+* may be negative-errno on failure. Conversion to the
+* -1-and-errno-set convention is done by the calling wrapper.
+*/
+safe_syscall_base:
+   .cfi_startproc
+   /*
+* The syscall calling convention is nearly the same as C:
+* we enter with a0 == *signal_pending
+*   a1 == syscall number
+*   a2 ... a7 == syscall arguments
+*   and return the result in a0
+* and the syscall instruction needs
+*   a7 == syscall number
+*   a0 ... a5 == syscall arguments
+*   and returns the result in a0
+* Shuffle everything around appropriately.
+*/
+   mv  t0, a0  /* signal_pending pointer */
+   mv  t1, a1  /* syscall number */
+   mv  a0, a2  /* syscall arguments */
+   mv  a1, a3
+   mv  a2, a4
+   mv  a3, a5
+   mv  a4, a6
+   mv  a5, a7
+   mv  a7, t1
+
+   /*
+* This next sequence of code works in conjunction with the
+* rewind_if_safe_syscall_function(). If a signal is taken
+* and the interrupted PC is anywhere between 'safe_syscall_start'
+* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+* The code sequence must therefore be able to cope with this, and
+* the syscall instruction must be the final one in the sequence.
+*/
+safe_syscall_start:
+   /* If signal_pending is non-zero, don't do the call */
+   lw  t1, 0(t0)
+   bnezt1, 0f
+   scall
+safe_syscall_end:
+   /* code path for having successfully executed the syscall */
+   ret
+
+0:
+   /* code path when we didn't execute the syscall */
+   li  a0, -TARGET_ERESTARTSYS
+   ret
+   .cfi_endproc
+
+   .size   safe_syscall_base, .-safe_syscall_base
-- 
2.17.2




[Qemu-devel] [PULL 09/42] tcg/riscv: Add the instruction emitters

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 48 ++
 1 file changed, 48 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 08838027cd..d198cfd5f7 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -374,3 +374,51 @@ static int32_t encode_uj(RISCVInsn opc, TCGReg rd, 
uint32_t imm)
 {
 return opc | (rd & 0x1f) << 7 | encode_ujimm20(imm);
 }
+
+/*
+ * RISC-V instruction emitters
+ */
+
+static void tcg_out_opc_reg(TCGContext *s, RISCVInsn opc,
+TCGReg rd, TCGReg rs1, TCGReg rs2)
+{
+tcg_out32(s, encode_r(opc, rd, rs1, rs2));
+}
+
+static void tcg_out_opc_imm(TCGContext *s, RISCVInsn opc,
+TCGReg rd, TCGReg rs1, TCGArg imm)
+{
+tcg_out32(s, encode_i(opc, rd, rs1, imm));
+}
+
+static void tcg_out_opc_store(TCGContext *s, RISCVInsn opc,
+  TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+tcg_out32(s, encode_s(opc, rs1, rs2, imm));
+}
+
+static void tcg_out_opc_branch(TCGContext *s, RISCVInsn opc,
+   TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+tcg_out32(s, encode_sb(opc, rs1, rs2, imm));
+}
+
+static void tcg_out_opc_upper(TCGContext *s, RISCVInsn opc,
+  TCGReg rd, uint32_t imm)
+{
+tcg_out32(s, encode_u(opc, rd, imm));
+}
+
+static void tcg_out_opc_jump(TCGContext *s, RISCVInsn opc,
+ TCGReg rd, uint32_t imm)
+{
+tcg_out32(s, encode_uj(opc, rd, imm));
+}
+
+static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
+{
+int i;
+for (i = 0; i < count; ++i) {
+p[i] = encode_i(OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
+}
+}
-- 
2.17.2




[Qemu-devel] [PULL 17/42] tcg/riscv: Add direct load and store instructions

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<2e047a95c39c007c66cda024c095e29b0ac4c43e.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 158 +
 1 file changed, 158 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 7216bad086..154315787c 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1151,3 +1151,161 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *l)
 tcg_out_goto(s, l->raddr);
 }
 #endif /* CONFIG_SOFTMMU */
+
+static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
+   TCGReg base, TCGMemOp opc, bool is_64)
+{
+const TCGMemOp bswap = opc & MO_BSWAP;
+
+/* We don't yet handle byteswapping, assert */
+g_assert(!bswap);
+
+switch (opc & (MO_SSIZE)) {
+case MO_UB:
+tcg_out_opc_imm(s, OPC_LBU, lo, base, 0);
+break;
+case MO_SB:
+tcg_out_opc_imm(s, OPC_LB, lo, base, 0);
+break;
+case MO_UW:
+tcg_out_opc_imm(s, OPC_LHU, lo, base, 0);
+break;
+case MO_SW:
+tcg_out_opc_imm(s, OPC_LH, lo, base, 0);
+break;
+case MO_UL:
+if (TCG_TARGET_REG_BITS == 64 && is_64) {
+tcg_out_opc_imm(s, OPC_LWU, lo, base, 0);
+break;
+}
+/* FALLTHRU */
+case MO_SL:
+tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
+break;
+case MO_Q:
+/* Prefer to load from offset 0 first, but allow for overlap.  */
+if (TCG_TARGET_REG_BITS == 64) {
+tcg_out_opc_imm(s, OPC_LD, lo, base, 0);
+} else if (lo != base) {
+tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
+tcg_out_opc_imm(s, OPC_LW, hi, base, 4);
+} else {
+tcg_out_opc_imm(s, OPC_LW, hi, base, 4);
+tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
+}
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
+{
+TCGReg addr_regl, addr_regh __attribute__((unused));
+TCGReg data_regl, data_regh;
+TCGMemOpIdx oi;
+TCGMemOp opc;
+#if defined(CONFIG_SOFTMMU)
+tcg_insn_unit *label_ptr[1];
+#endif
+TCGReg base = TCG_REG_TMP0;
+
+data_regl = *args++;
+data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
+addr_regl = *args++;
+addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
+oi = *args++;
+opc = get_memop(oi);
+
+#if defined(CONFIG_SOFTMMU)
+tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
+tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
+add_qemu_ldst_label(s, 1, oi,
+(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
+data_regl, data_regh, addr_regl, addr_regh,
+s->code_ptr, label_ptr);
+#else
+if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+tcg_out_ext32u(s, base, addr_regl);
+addr_regl = base;
+}
+
+if (guest_base == 0) {
+tcg_out_opc_reg(s, OPC_ADD, base, addr_regl, TCG_REG_ZERO);
+} else {
+tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
+}
+tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
+#endif
+}
+
+static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi,
+   TCGReg base, TCGMemOp opc)
+{
+const TCGMemOp bswap = opc & MO_BSWAP;
+
+/* We don't yet handle byteswapping, assert */
+g_assert(!bswap);
+
+switch (opc & (MO_SSIZE)) {
+case MO_8:
+tcg_out_opc_store(s, OPC_SB, base, lo, 0);
+break;
+case MO_16:
+tcg_out_opc_store(s, OPC_SH, base, lo, 0);
+break;
+case MO_32:
+tcg_out_opc_store(s, OPC_SW, base, lo, 0);
+break;
+case MO_64:
+if (TCG_TARGET_REG_BITS == 64) {
+tcg_out_opc_store(s, OPC_SD, base, lo, 0);
+} else {
+tcg_out_opc_store(s, OPC_SW, base, lo, 0);
+tcg_out_opc_store(s, OPC_SW, base, hi, 4);
+}
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
+{
+TCGReg addr_regl, addr_regh __attribute__((unused));
+TCGReg data_regl, data_regh;
+TCGMemOpIdx oi;
+TCGMemOp opc;
+#if defined(CONFIG_SOFTMMU)
+tcg_insn_unit *label_ptr[1];
+#endif
+TCGReg base = TCG_REG_TMP0;
+
+data_regl = *args++;
+data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
+addr_regl = *args++;
+addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
+oi = *args++;
+opc = get_memop(oi);
+
+#if defined(CONFIG_SOFTMMU)
+tcg_out_tlb_load(s, 

[Qemu-devel] [PULL 19/42] tcg/riscv: Add the prologue generation and register the JIT

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 111 +
 1 file changed, 111 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 014c5287f5..8a5f1deefc 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1805,3 +1805,114 @@ static const TCGTargetOpDef 
*tcg_target_op_def(TCGOpcode op)
 return NULL;
 }
 }
+
+static const int tcg_target_callee_save_regs[] = {
+TCG_REG_S0,   /* used for the global env (TCG_AREG0) */
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_S10,
+TCG_REG_S11,
+TCG_REG_RA,   /* should be last for ABI compliance */
+};
+
+/* Stack frame parameters.  */
+#define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
+#define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
+#define TEMP_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
+#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
+ + TCG_TARGET_STACK_ALIGN - 1) \
+& -TCG_TARGET_STACK_ALIGN)
+#define SAVE_OFS   (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
+
+/* We're expecting to be able to use an immediate for frame allocation.  */
+QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff);
+
+/* Generate global QEMU prologue and epilogue code */
+static void tcg_target_qemu_prologue(TCGContext *s)
+{
+int i;
+
+tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
+
+/* TB prologue */
+tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+#if !defined(CONFIG_SOFTMMU)
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
+tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+#endif
+
+/* Call generated code */
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 
0);
+
+/* Return path for goto_ptr. Set return value to 0 */
+s->code_gen_epilogue = s->code_ptr;
+tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
+
+/* TB epilogue */
+tb_ret_addr = s->code_ptr;
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0);
+}
+
+typedef struct {
+DebugFrameHeader h;
+uint8_t fde_def_cfa[4];
+uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
+} DebugFrame;
+
+#define ELF_HOST_MACHINE EM_RISCV
+
+static const DebugFrame debug_frame = {
+.h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
+.h.cie.id = -1,
+.h.cie.version = 1,
+.h.cie.code_align = 1,
+.h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */
+.h.cie.return_column = TCG_REG_RA,
+
+/* Total FDE size does not include the "len" member.  */
+.h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
+
+.fde_def_cfa = {
+12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */
+(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
+(FRAME_SIZE >> 7)
+},
+.fde_reg_ofs = {
+0x80 + 9,  12,  /* DW_CFA_offset, s1,  -96 */
+0x80 + 18, 11,  /* DW_CFA_offset, s2,  -88 */
+0x80 + 19, 10,  /* DW_CFA_offset, s3,  -80 */
+0x80 + 20, 9,   /* DW_CFA_offset, s4,  -72 */
+0x80 + 21, 8,   /* DW_CFA_offset, s5,  -64 */
+0x80 + 22, 7,   /* DW_CFA_offset, s6,  -56 */
+0x80 + 23, 6,   /* DW_CFA_offset, s7,  -48 */
+0x80 + 24, 5,   /* DW_CFA_offset, s8,  -40 */
+0x80 + 25, 4,   /* DW_CFA_offset, s9,  -32 */
+0x80 + 26, 3,   /* DW_CFA_offset, s10, -24 */
+0x80 + 27, 2,   /* DW_CFA_offset, s11, -16 */
+0x80 + 1 , 1,   /* DW_CFA_offset, ra,  -8 */
+}
+};
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+tcg_register_jit_int(buf, buf_size, _frame, sizeof(debug_frame));
+}
-- 
2.17.2




[Qemu-devel] [PULL 21/42] tcg: Add RISC-V cpu signal handler

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 accel/tcg/user-exec.c | 75 +++
 1 file changed, 75 insertions(+)

diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index cd75829cf2..941295ea49 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -571,6 +571,81 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 return handle_cpu_signal(pc, info, is_write, >uc_sigmask);
 }
 
+#elif defined(__riscv)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+   void *puc)
+{
+siginfo_t *info = pinfo;
+ucontext_t *uc = puc;
+greg_t pc = uc->uc_mcontext.__gregs[REG_PC];
+uint32_t insn = *(uint32_t *)pc;
+int is_write = 0;
+
+/* Detect store by reading the instruction at the program
+   counter. Note: we currently only generate 32-bit
+   instructions so we thus only detect 32-bit stores */
+switch (((insn >> 0) & 0b11)) {
+case 3:
+switch (((insn >> 2) & 0b1)) {
+case 8:
+switch (((insn >> 12) & 0b111)) {
+case 0: /* sb */
+case 1: /* sh */
+case 2: /* sw */
+case 3: /* sd */
+case 4: /* sq */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+case 9:
+switch (((insn >> 12) & 0b111)) {
+case 2: /* fsw */
+case 3: /* fsd */
+case 4: /* fsq */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+default:
+break;
+}
+}
+
+/* Check for compressed instructions */
+switch (((insn >> 13) & 0b111)) {
+case 7:
+switch (insn & 0b11) {
+case 0: /*c.sd */
+case 2: /* c.sdsp */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+case 6:
+switch (insn & 0b11) {
+case 0: /* c.sw */
+case 3: /* c.swsp */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+default:
+break;
+}
+
+return handle_cpu_signal(pc, info, is_write, >uc_sigmask);
+}
+
 #else
 
 #error host CPU specific signal handler needed
-- 
2.17.2




[Qemu-devel] [PULL 15/42] tcg/riscv: Add branch and jump instructions

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 145 +
 1 file changed, 145 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 5da850b957..ecc76c9ef8 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -750,3 +750,148 @@ static void tcg_out_addsub2(TCGContext *s,
 tcg_out_opc_reg(s, opc_add, rh, th, TCG_REG_TMP0);
 }
 }
+
+static const struct {
+RISCVInsn op;
+bool swap;
+} tcg_brcond_to_riscv[] = {
+[TCG_COND_EQ] =  { OPC_BEQ,  false },
+[TCG_COND_NE] =  { OPC_BNE,  false },
+[TCG_COND_LT] =  { OPC_BLT,  false },
+[TCG_COND_GE] =  { OPC_BGE,  false },
+[TCG_COND_LE] =  { OPC_BGE,  true  },
+[TCG_COND_GT] =  { OPC_BLT,  true  },
+[TCG_COND_LTU] = { OPC_BLTU, false },
+[TCG_COND_GEU] = { OPC_BGEU, false },
+[TCG_COND_LEU] = { OPC_BGEU, true  },
+[TCG_COND_GTU] = { OPC_BLTU, true  }
+};
+
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
+   TCGReg arg2, TCGLabel *l)
+{
+RISCVInsn op = tcg_brcond_to_riscv[cond].op;
+
+tcg_debug_assert(op != 0);
+
+if (tcg_brcond_to_riscv[cond].swap) {
+TCGReg t = arg1;
+arg1 = arg2;
+arg2 = t;
+}
+
+if (l->has_value) {
+intptr_t diff = tcg_pcrel_diff(s, l->u.value_ptr);
+if (diff == sextreg(diff, 0, 12)) {
+tcg_out_opc_branch(s, op, arg1, arg2, diff);
+} else {
+/* Invert the conditional branch.  */
+tcg_out_opc_branch(s, op ^ (1 << 12), arg1, arg2, 8);
+tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, diff - 4);
+}
+} else {
+tcg_out_reloc(s, s->code_ptr, R_RISCV_BRANCH, l, 0);
+tcg_out_opc_branch(s, op, arg1, arg2, 0);
+/* NOP to allow patching later */
+tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
+}
+}
+
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+TCGReg arg1, TCGReg arg2)
+{
+switch (cond) {
+case TCG_COND_EQ:
+tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
+tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
+break;
+case TCG_COND_NE:
+tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
+tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
+break;
+case TCG_COND_LT:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
+break;
+case TCG_COND_GE:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_LE:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_GT:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
+break;
+case TCG_COND_LTU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
+break;
+case TCG_COND_GEU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_LEU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_GTU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
+break;
+default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
+TCGReg bl, TCGReg bh, TCGLabel *l)
+{
+/* todo */
+g_assert_not_reached();
+}
+
+static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
+{
+/* todo */
+g_assert_not_reached();
+}
+
+static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
+{
+ptrdiff_t offset = tcg_pcrel_diff(s, target);
+tcg_debug_assert(offset == sextreg(offset, 1, 20) << 1);
+tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset);
+}
+
+static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
+{
+TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
+ptrdiff_t offset = tcg_pcrel_diff(s, arg);
+int ret;
+
+if (offset == sextreg(offset, 1, 20) << 1) {
+/* short jump: -2097150 to 2097152 */
+tcg_out_opc_jump(s, OPC_JAL, link, offset);
+} else if (TCG_TARGET_REG_BITS == 32 ||
+offset == sextreg(offset, 1, 31) << 1) {
+/* long jump: -2147483646 to 2147483648 */
+tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0);
+tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0);
+ret = reloc_call(s->code_ptr - 2, arg);\
+tcg_debug_assert(ret == true);
+} else if (TCG_TARGET_REG_BITS == 64) {
+

[Qemu-devel] [PULL 08/42] tcg/riscv: Add the immediate encoders

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 90 ++
 1 file changed, 90 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index f853d01803..08838027cd 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -284,3 +284,93 @@ typedef enum {
 
 OPC_FENCE = 0x000f,
 } RISCVInsn;
+
+/*
+ * RISC-V immediate and instruction encoders (excludes 16-bit RVC)
+ */
+
+/* Type-R */
+
+static int32_t encode_r(RISCVInsn opc, TCGReg rd, TCGReg rs1, TCGReg rs2)
+{
+return opc | (rd & 0x1f) << 7 | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20;
+}
+
+/* Type-I */
+
+static int32_t encode_imm12(uint32_t imm)
+{
+return (imm & 0xfff) << 20;
+}
+
+static int32_t encode_i(RISCVInsn opc, TCGReg rd, TCGReg rs1, uint32_t imm)
+{
+return opc | (rd & 0x1f) << 7 | (rs1 & 0x1f) << 15 | encode_imm12(imm);
+}
+
+/* Type-S */
+
+static int32_t encode_simm12(uint32_t imm)
+{
+int32_t ret = 0;
+
+ret |= (imm & 0xFE0) << 20;
+ret |= (imm & 0x1F) << 7;
+
+return ret;
+}
+
+static int32_t encode_s(RISCVInsn opc, TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+return opc | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20 | encode_simm12(imm);
+}
+
+/* Type-SB */
+
+static int32_t encode_sbimm12(uint32_t imm)
+{
+int32_t ret = 0;
+
+ret |= (imm & 0x1000) << 19;
+ret |= (imm & 0x7e0) << 20;
+ret |= (imm & 0x1e) << 7;
+ret |= (imm & 0x800) >> 4;
+
+return ret;
+}
+
+static int32_t encode_sb(RISCVInsn opc, TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+return opc | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20 | encode_sbimm12(imm);
+}
+
+/* Type-U */
+
+static int32_t encode_uimm20(uint32_t imm)
+{
+return imm & 0xf000;
+}
+
+static int32_t encode_u(RISCVInsn opc, TCGReg rd, uint32_t imm)
+{
+return opc | (rd & 0x1f) << 7 | encode_uimm20(imm);
+}
+
+/* Type-UJ */
+
+static int32_t encode_ujimm20(uint32_t imm)
+{
+int32_t ret = 0;
+
+ret |= (imm & 0x0007fe) << (21 - 1);
+ret |= (imm & 0x000800) << (20 - 11);
+ret |= (imm & 0x0ff000) << (12 - 12);
+ret |= (imm & 0x10) << (31 - 20);
+
+return ret;
+}
+
+static int32_t encode_uj(RISCVInsn opc, TCGReg rd, uint32_t imm)
+{
+return opc | (rd & 0x1f) << 7 | encode_ujimm20(imm);
+}
-- 
2.17.2




[Qemu-devel] [PULL 13/42] tcg/riscv: Add the out load and store instructions

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 65 ++
 1 file changed, 65 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 48399480b2..65718df7ad 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -630,3 +630,68 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, 
TCGReg arg)
 {
 tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0);
 }
+
+static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
+ TCGReg addr, intptr_t offset)
+{
+intptr_t imm12 = sextreg(offset, 0, 12);
+
+if (offset != imm12) {
+intptr_t diff = offset - (uintptr_t)s->code_ptr;
+
+if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
+imm12 = sextreg(diff, 0, 12);
+tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP2, diff - imm12);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12);
+if (addr != TCG_REG_ZERO) {
+tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP2, TCG_REG_TMP2, addr);
+}
+}
+addr = TCG_REG_TMP2;
+}
+
+switch (opc) {
+case OPC_SB:
+case OPC_SH:
+case OPC_SW:
+case OPC_SD:
+tcg_out_opc_store(s, opc, addr, data, imm12);
+break;
+case OPC_LB:
+case OPC_LBU:
+case OPC_LH:
+case OPC_LHU:
+case OPC_LW:
+case OPC_LWU:
+case OPC_LD:
+tcg_out_opc_imm(s, opc, data, addr, imm12);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32);
+tcg_out_ldst(s, is32bit ? OPC_LW : OPC_LD, arg, arg1, arg2);
+}
+
+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32);
+tcg_out_ldst(s, is32bit ? OPC_SW : OPC_SD, arg, arg1, arg2);
+}
+
+static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
+TCGReg base, intptr_t ofs)
+{
+if (val == 0) {
+tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
+return true;
+}
+return false;
+}
-- 
2.17.2




[Qemu-devel] [PULL 12/42] tcg/riscv: Add the extract instructions

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 01b4443d6d..48399480b2 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -596,3 +596,37 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
 tcg_out_opc_imm(s, OPC_LD, rd, rd, 0);
 }
+
+static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_ANDI, ret, arg, 0xff);
+}
+
+static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
+tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16);
+}
+
+static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
+tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
+}
+
+static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
+tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
+}
+
+static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
+tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
+}
+
+static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0);
+}
-- 
2.17.2




[Qemu-devel] [PULL 07/42] tcg/riscv: Add support for the constraints

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 168 +
 1 file changed, 168 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 6c969e3973..f853d01803 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -116,3 +116,171 @@ static const int tcg_target_call_oarg_regs[] = {
 TCG_REG_A0,
 TCG_REG_A1,
 };
+
+#define TCG_CT_CONST_ZERO  0x100
+#define TCG_CT_CONST_S12   0x200
+#define TCG_CT_CONST_N12   0x400
+#define TCG_CT_CONST_M12   0x800
+
+static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
+{
+if (TCG_TARGET_REG_BITS == 32) {
+return sextract32(val, pos, len);
+} else {
+return sextract64(val, pos, len);
+}
+}
+
+/* parse target specific constraints */
+static const char *target_parse_constraint(TCGArgConstraint *ct,
+   const char *ct_str, TCGType type)
+{
+switch (*ct_str++) {
+case 'r':
+ct->ct |= TCG_CT_REG;
+ct->u.regs = 0x;
+break;
+case 'L':
+/* qemu_ld/qemu_st constraint */
+ct->ct |= TCG_CT_REG;
+ct->u.regs = 0x;
+/* qemu_ld/qemu_st uses TCG_REG_TMP0 */
+#if defined(CONFIG_SOFTMMU)
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[3]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[4]);
+#endif
+break;
+case 'I':
+ct->ct |= TCG_CT_CONST_S12;
+break;
+case 'N':
+ct->ct |= TCG_CT_CONST_N12;
+break;
+case 'M':
+ct->ct |= TCG_CT_CONST_M12;
+break;
+case 'Z':
+/* we can use a zero immediate as a zero register argument. */
+ct->ct |= TCG_CT_CONST_ZERO;
+break;
+default:
+return NULL;
+}
+return ct_str;
+}
+
+/* test if a constant matches the constraint */
+static int tcg_target_const_match(tcg_target_long val, TCGType type,
+  const TCGArgConstraint *arg_ct)
+{
+int ct = arg_ct->ct;
+if (ct & TCG_CT_CONST) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_M12) && val >= -0xfff && val <= 0xfff) {
+return 1;
+}
+return 0;
+}
+
+/*
+ * RISC-V Base ISA opcodes (IM)
+ */
+
+typedef enum {
+OPC_ADD = 0x33,
+OPC_ADDI = 0x13,
+OPC_AND = 0x7033,
+OPC_ANDI = 0x7013,
+OPC_AUIPC = 0x17,
+OPC_BEQ = 0x63,
+OPC_BGE = 0x5063,
+OPC_BGEU = 0x7063,
+OPC_BLT = 0x4063,
+OPC_BLTU = 0x6063,
+OPC_BNE = 0x1063,
+OPC_DIV = 0x2004033,
+OPC_DIVU = 0x2005033,
+OPC_JAL = 0x6f,
+OPC_JALR = 0x67,
+OPC_LB = 0x3,
+OPC_LBU = 0x4003,
+OPC_LD = 0x3003,
+OPC_LH = 0x1003,
+OPC_LHU = 0x5003,
+OPC_LUI = 0x37,
+OPC_LW = 0x2003,
+OPC_LWU = 0x6003,
+OPC_MUL = 0x233,
+OPC_MULH = 0x2001033,
+OPC_MULHSU = 0x2002033,
+OPC_MULHU = 0x2003033,
+OPC_OR = 0x6033,
+OPC_ORI = 0x6013,
+OPC_REM = 0x2006033,
+OPC_REMU = 0x2007033,
+OPC_SB = 0x23,
+OPC_SD = 0x3023,
+OPC_SH = 0x1023,
+OPC_SLL = 0x1033,
+OPC_SLLI = 0x1013,
+OPC_SLT = 0x2033,
+OPC_SLTI = 0x2013,
+OPC_SLTIU = 0x3013,
+OPC_SLTU = 0x3033,
+OPC_SRA = 0x40005033,
+OPC_SRAI = 0x40005013,
+OPC_SRL = 0x5033,
+OPC_SRLI = 0x5013,
+OPC_SUB = 0x4033,
+OPC_SW = 0x2023,
+OPC_XOR = 0x4033,
+OPC_XORI = 0x4013,
+
+#if TCG_TARGET_REG_BITS == 64
+OPC_ADDIW = 0x1b,
+OPC_ADDW = 0x3b,
+OPC_DIVUW = 0x200503b,
+OPC_DIVW = 0x200403b,
+OPC_MULW = 0x23b,
+OPC_REMUW = 0x200703b,
+OPC_REMW = 0x200603b,
+OPC_SLLIW = 0x101b,
+OPC_SLLW = 0x103b,
+OPC_SRAIW = 0x4000501b,
+OPC_SRAW = 0x4000503b,
+OPC_SRLIW = 0x501b,
+OPC_SRLW = 0x503b,
+OPC_SUBW = 0x403b,
+#else
+/* Simplify code throughout by defining aliases for RV32.  */
+OPC_ADDIW = OPC_ADDI,
+OPC_ADDW = OPC_ADD,
+OPC_DIVUW = OPC_DIVU,
+OPC_DIVW = OPC_DIV,
+OPC_MULW = OPC_MUL,
+OPC_REMUW = OPC_REMU,
+OPC_REMW = OPC_REM,
+OPC_SLLIW = OPC_SLLI,
+OPC_SLLW = OPC_SLL,
+OPC_SRAIW = OPC_SRAI,
+OPC_SRAW = OPC_SRA,
+OPC_SRLIW = OPC_SRLI,
+OPC_SRLW = OPC_SRL,
+OPC_SUBW = OPC_SUB,
+#endif
+
+OPC_FENCE = 0x000f,
+} RISCVInsn;
-- 
2.17.2




[Qemu-devel] [PULL 11/42] tcg/riscv: Add the mov and movi instruction

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 86 ++
 1 file changed, 86 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index a26744052f..01b4443d6d 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -510,3 +510,89 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 tcg_abort();
 }
 }
+
+/*
+ * TCG intrinsics
+ */
+
+static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+{
+if (ret == arg) {
+return;
+}
+switch (type) {
+case TCG_TYPE_I32:
+case TCG_TYPE_I64:
+tcg_out_opc_imm(s, OPC_ADDI, ret, arg, 0);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
+ tcg_target_long val)
+{
+tcg_target_long lo, hi, tmp;
+int shift, ret;
+
+if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
+val = (int32_t)val;
+}
+
+lo = sextreg(val, 0, 12);
+if (val == lo) {
+tcg_out_opc_imm(s, OPC_ADDI, rd, TCG_REG_ZERO, lo);
+return;
+}
+
+hi = val - lo;
+if (TCG_TARGET_REG_BITS == 32 || val == (int32_t)val) {
+tcg_out_opc_upper(s, OPC_LUI, rd, hi);
+if (lo != 0) {
+tcg_out_opc_imm(s, OPC_ADDIW, rd, rd, lo);
+}
+return;
+}
+
+/* We can only be here if TCG_TARGET_REG_BITS != 32 */
+tmp = tcg_pcrel_diff(s, (void *)val);
+if (tmp == (int32_t)tmp) {
+tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
+tcg_out_opc_imm(s, OPC_ADDI, rd, rd, 0);
+ret = reloc_call(s->code_ptr - 2, (tcg_insn_unit *)val);
+tcg_debug_assert(ret == true);
+return;
+}
+
+/* Look for a single 20-bit section.  */
+shift = ctz64(val);
+tmp = val >> shift;
+if (tmp == sextreg(tmp, 0, 20)) {
+tcg_out_opc_upper(s, OPC_LUI, rd, tmp << 12);
+if (shift > 12) {
+tcg_out_opc_imm(s, OPC_SLLI, rd, rd, shift - 12);
+} else {
+tcg_out_opc_imm(s, OPC_SRAI, rd, rd, 12 - shift);
+}
+return;
+}
+
+/* Look for a few high zero bits, with lots of bits set in the middle.  */
+shift = clz64(val);
+tmp = val << shift;
+if (tmp == sextreg(tmp, 12, 20) << 12) {
+tcg_out_opc_upper(s, OPC_LUI, rd, tmp);
+tcg_out_opc_imm(s, OPC_SRLI, rd, rd, shift);
+return;
+} else if (tmp == sextreg(tmp, 0, 12)) {
+tcg_out_opc_imm(s, OPC_ADDI, rd, TCG_REG_ZERO, tmp);
+tcg_out_opc_imm(s, OPC_SRLI, rd, rd, shift);
+return;
+}
+
+/* Drop into the constant pool.  */
+new_pool_label(s, val, R_RISCV_CALL, s->code_ptr, 0);
+tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
+tcg_out_opc_imm(s, OPC_LD, rd, rd, 0);
+}
-- 
2.17.2




[Qemu-devel] [PULL 02/42] linux-user: Add host dependency for RISC-V 32-bit

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<76f8f9383a766dbcade883e897dec8cfef669799.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 linux-user/host/riscv32/hostdep.h | 11 +++
 MAINTAINERS   |  1 +
 2 files changed, 12 insertions(+)
 create mode 100644 linux-user/host/riscv32/hostdep.h

diff --git a/linux-user/host/riscv32/hostdep.h 
b/linux-user/host/riscv32/hostdep.h
new file mode 100644
index 00..adf9edbf2d
--- /dev/null
+++ b/linux-user/host/riscv32/hostdep.h
@@ -0,0 +1,11 @@
+/*
+ * hostdep.h : things which are dependent on the host architecture
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef RISCV32_HOSTDEP_H
+#define RISCV32_HOSTDEP_H
+
+#endif
diff --git a/MAINTAINERS b/MAINTAINERS
index 180695f5d3..067629b10e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -266,6 +266,7 @@ S: Maintained
 F: target/riscv/
 F: hw/riscv/
 F: include/hw/riscv/
+F: linux-user/host/riscv32/
 F: disas/riscv.c
 
 S390
-- 
2.17.2




[Qemu-devel] [PULL 06/42] tcg/riscv: Add the tcg target registers

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<6e43abaa64361d57b9bc9439820d0e7701f2d47e.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 118 +
 1 file changed, 118 insertions(+)
 create mode 100644 tcg/riscv/tcg-target.inc.c

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
new file mode 100644
index 00..6c969e3973
--- /dev/null
+++ b/tcg/riscv/tcg-target.inc.c
@@ -0,0 +1,118 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2018 SiFive, Inc
+ * Copyright (c) 2008-2009 Arnaud Patard 
+ * Copyright (c) 2009 Aurelien Jarno 
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Based on i386/tcg-target.c and mips/tcg-target.c
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "tcg-pool.inc.c"
+
+#ifdef CONFIG_DEBUG_TCG
+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+"zero",
+"ra",
+"sp",
+"gp",
+"tp",
+"t0",
+"t1",
+"t2",
+"s0",
+"s1",
+"a0",
+"a1",
+"a2",
+"a3",
+"a4",
+"a5",
+"a6",
+"a7",
+"s2",
+"s3",
+"s4",
+"s5",
+"s6",
+"s7",
+"s8",
+"s9",
+"s10",
+"s11",
+"t3",
+"t4",
+"t5",
+"t6"
+};
+#endif
+
+static const int tcg_target_reg_alloc_order[] = {
+/* Call saved registers */
+/* TCG_REG_S0 reservered for TCG_AREG0 */
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_S10,
+TCG_REG_S11,
+
+/* Call clobbered registers */
+TCG_REG_T0,
+TCG_REG_T1,
+TCG_REG_T2,
+TCG_REG_T3,
+TCG_REG_T4,
+TCG_REG_T5,
+TCG_REG_T6,
+
+/* Argument registers */
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+};
+
+static const int tcg_target_call_iarg_regs[] = {
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+};
+
+static const int tcg_target_call_oarg_regs[] = {
+TCG_REG_A0,
+TCG_REG_A1,
+};
-- 
2.17.2




[Qemu-devel] [PULL 03/42] linux-user: Add host dependency for RISC-V 64-bit

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<9d777f619840a8dd8e4f3834dcfc3bd28e052ccd.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 linux-user/host/riscv64/hostdep.h | 11 +++
 MAINTAINERS   |  1 +
 2 files changed, 12 insertions(+)
 create mode 100644 linux-user/host/riscv64/hostdep.h

diff --git a/linux-user/host/riscv64/hostdep.h 
b/linux-user/host/riscv64/hostdep.h
new file mode 100644
index 00..28467ba00b
--- /dev/null
+++ b/linux-user/host/riscv64/hostdep.h
@@ -0,0 +1,11 @@
+/*
+ * hostdep.h : things which are dependent on the host architecture
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef RISCV64_HOSTDEP_H
+#define RISCV64_HOSTDEP_H
+
+#endif
diff --git a/MAINTAINERS b/MAINTAINERS
index 067629b10e..7a4cf30a04 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -267,6 +267,7 @@ F: target/riscv/
 F: hw/riscv/
 F: include/hw/riscv/
 F: linux-user/host/riscv32/
+F: linux-user/host/riscv64/
 F: disas/riscv.c
 
 S390
-- 
2.17.2




[Qemu-devel] [PULL 05/42] tcg/riscv: Add the tcg-target.h file

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.h | 177 +
 MAINTAINERS|  10 ++-
 2 files changed, 186 insertions(+), 1 deletion(-)
 create mode 100644 tcg/riscv/tcg-target.h

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
new file mode 100644
index 00..60918cacb4
--- /dev/null
+++ b/tcg/riscv/tcg-target.h
@@ -0,0 +1,177 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2018 SiFive, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef RISCV_TCG_TARGET_H
+#define RISCV_TCG_TARGET_H
+
+#if __riscv_xlen == 32
+# define TCG_TARGET_REG_BITS 32
+#elif __riscv_xlen == 64
+# define TCG_TARGET_REG_BITS 64
+#endif
+
+#define TCG_TARGET_INSN_UNIT_SIZE 4
+#define TCG_TARGET_TLB_DISPLACEMENT_BITS 20
+#define TCG_TARGET_NB_REGS 32
+
+typedef enum {
+TCG_REG_ZERO,
+TCG_REG_RA,
+TCG_REG_SP,
+TCG_REG_GP,
+TCG_REG_TP,
+TCG_REG_T0,
+TCG_REG_T1,
+TCG_REG_T2,
+TCG_REG_S0,
+TCG_REG_S1,
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_S10,
+TCG_REG_S11,
+TCG_REG_T3,
+TCG_REG_T4,
+TCG_REG_T5,
+TCG_REG_T6,
+
+/* aliases */
+TCG_AREG0  = TCG_REG_S0,
+TCG_GUEST_BASE_REG = TCG_REG_S1,
+TCG_REG_TMP0   = TCG_REG_T6,
+TCG_REG_TMP1   = TCG_REG_T5,
+TCG_REG_TMP2   = TCG_REG_T4,
+} TCGReg;
+
+/* used for function call generation */
+#define TCG_REG_CALL_STACK  TCG_REG_SP
+#define TCG_TARGET_STACK_ALIGN  16
+#define TCG_TARGET_CALL_ALIGN_ARGS  1
+#define TCG_TARGET_CALL_STACK_OFFSET0
+
+/* optional instructions */
+#define TCG_TARGET_HAS_goto_ptr 1
+#define TCG_TARGET_HAS_movcond_i32  0
+#define TCG_TARGET_HAS_div_i32  1
+#define TCG_TARGET_HAS_rem_i32  1
+#define TCG_TARGET_HAS_div2_i32 0
+#define TCG_TARGET_HAS_rot_i32  0
+#define TCG_TARGET_HAS_deposit_i32  0
+#define TCG_TARGET_HAS_extract_i32  0
+#define TCG_TARGET_HAS_sextract_i32 0
+#define TCG_TARGET_HAS_add2_i32 1
+#define TCG_TARGET_HAS_sub2_i32 1
+#define TCG_TARGET_HAS_mulu2_i320
+#define TCG_TARGET_HAS_muls2_i320
+#define TCG_TARGET_HAS_muluh_i32(TCG_TARGET_REG_BITS == 32)
+#define TCG_TARGET_HAS_mulsh_i32(TCG_TARGET_REG_BITS == 32)
+#define TCG_TARGET_HAS_ext8s_i321
+#define TCG_TARGET_HAS_ext16s_i32   1
+#define TCG_TARGET_HAS_ext8u_i321
+#define TCG_TARGET_HAS_ext16u_i32   1
+#define TCG_TARGET_HAS_bswap16_i32  0
+#define TCG_TARGET_HAS_bswap32_i32  0
+#define TCG_TARGET_HAS_not_i32  1
+#define TCG_TARGET_HAS_neg_i32  1
+#define TCG_TARGET_HAS_andc_i32 0
+#define TCG_TARGET_HAS_orc_i32  0
+#define TCG_TARGET_HAS_eqv_i32  0
+#define TCG_TARGET_HAS_nand_i32 0
+#define TCG_TARGET_HAS_nor_i32  0
+#define TCG_TARGET_HAS_clz_i32  0
+#define TCG_TARGET_HAS_ctz_i32  0
+#define TCG_TARGET_HAS_ctpop_i320
+#define TCG_TARGET_HAS_direct_jump  0
+#define TCG_TARGET_HAS_brcond2  1
+#define TCG_TARGET_HAS_setcond2 1
+
+#if TCG_TARGET_REG_BITS == 64
+#define TCG_TARGET_HAS_movcond_i64  0
+#define TCG_TARGET_HAS_div_i64  1
+#define TCG_TARGET_HAS_rem_i64  1
+#define TCG_TARGET_HAS_div2_i64 0
+#define TCG_TARGET_HAS_rot_i64  0
+#define TCG_TARGET_HAS_deposit_i64  0
+#define TCG_TARGET_HAS_extract_i64  0
+#define TCG_TARGET_HAS_sextract_i64 0
+#define TCG_TARGET_HAS_extrl_i64_i321

[Qemu-devel] [PULL 04/42] exec: Add RISC-V GCC poison macro

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<00d02e34f10b87fd61f8dc69ac93d1eb63df949c.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 include/exec/poison.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/exec/poison.h b/include/exec/poison.h
index 32d53789f8..ecdc83c147 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -79,6 +79,7 @@
 #pragma GCC poison CONFIG_MOXIE_DIS
 #pragma GCC poison CONFIG_NIOS2_DIS
 #pragma GCC poison CONFIG_PPC_DIS
+#pragma GCC poison CONFIG_RISCV_DIS
 #pragma GCC poison CONFIG_S390_DIS
 #pragma GCC poison CONFIG_SH4_DIS
 #pragma GCC poison CONFIG_SPARC_DIS
-- 
2.17.2




[Qemu-devel] [PULL 01/42] elf.h: Add the RISCV ELF magic numbers

2018-12-25 Thread Richard Henderson
From: Alistair Francis 

Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
Message-Id: 
<02fc0b3a733f5f08eb396bee5afd3d327941f0c9.1545246859.git.alistair.fran...@wdc.com>
Signed-off-by: Richard Henderson 
---
 include/elf.h | 55 +++
 1 file changed, 55 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index c151164b63..0ac7911b7b 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -1338,6 +1338,61 @@ typedef struct {
 #define R_IA64_DTPREL64LSB 0xb7/* @dtprel(sym + add), data8 LSB */
 #define R_IA64_LTOFF_DTPREL22  0xba/* @ltoff(@dtprel(s+a)), imm22 */
 
+/* RISC-V relocations.  */
+#define R_RISCV_NONE  0
+#define R_RISCV_321
+#define R_RISCV_642
+#define R_RISCV_RELATIVE  3
+#define R_RISCV_COPY  4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32  6
+#define R_RISCV_TLS_DTPMOD64  7
+#define R_RISCV_TLS_DTPREL32  8
+#define R_RISCV_TLS_DTPREL64  9
+#define R_RISCV_TLS_TPREL32   10
+#define R_RISCV_TLS_TPREL64   11
+#define R_RISCV_BRANCH16
+#define R_RISCV_JAL   17
+#define R_RISCV_CALL  18
+#define R_RISCV_CALL_PLT  19
+#define R_RISCV_GOT_HI20  20
+#define R_RISCV_TLS_GOT_HI20  21
+#define R_RISCV_TLS_GD_HI20   22
+#define R_RISCV_PCREL_HI2023
+#define R_RISCV_PCREL_LO12_I  24
+#define R_RISCV_PCREL_LO12_S  25
+#define R_RISCV_HI20  26
+#define R_RISCV_LO12_I27
+#define R_RISCV_LO12_S28
+#define R_RISCV_TPREL_HI2029
+#define R_RISCV_TPREL_LO12_I  30
+#define R_RISCV_TPREL_LO12_S  31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8  33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8  37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY   42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH44
+#define R_RISCV_RVC_JUMP  45
+#define R_RISCV_RVC_LUI   46
+#define R_RISCV_GPREL_I   47
+#define R_RISCV_GPREL_S   48
+#define R_RISCV_TPREL_I   49
+#define R_RISCV_TPREL_S   50
+#define R_RISCV_RELAX 51
+#define R_RISCV_SUB6  52
+#define R_RISCV_SET6  53
+#define R_RISCV_SET8  54
+#define R_RISCV_SET16 55
+#define R_RISCV_SET32 56
+
 typedef struct elf32_rel {
   Elf32_Addr   r_offset;
   Elf32_Word   r_info;
-- 
2.17.2




[Qemu-devel] [PULL 00/42] tcg queued patches

2018-12-25 Thread Richard Henderson
The following changes since commit 9b2e891ec5ccdb4a7d583b77988848282606fdea:

  Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into 
staging (2018-12-22 11:25:31 +)

are available in the Git repository at:

  https://github.com/rth7680/qemu.git tags/pull-tcg-20181226

for you to fetch changes up to 4250da10923347c9ee907f8d72bd93dfa5ee8742:

  tcg: Improve call argument loading (2018-12-26 06:58:43 +1100)


Host support for riscv64.
Dead code elimination pass.
Register allocation improvements.


Alistair Francis (23):
  elf.h: Add the RISCV ELF magic numbers
  linux-user: Add host dependency for RISC-V 32-bit
  linux-user: Add host dependency for RISC-V 64-bit
  exec: Add RISC-V GCC poison macro
  tcg/riscv: Add the tcg-target.h file
  tcg/riscv: Add the tcg target registers
  tcg/riscv: Add support for the constraints
  tcg/riscv: Add the immediate encoders
  tcg/riscv: Add the instruction emitters
  tcg/riscv: Add the relocation functions
  tcg/riscv: Add the mov and movi instruction
  tcg/riscv: Add the extract instructions
  tcg/riscv: Add the out load and store instructions
  tcg/riscv: Add the add2 and sub2 instructions
  tcg/riscv: Add branch and jump instructions
  tcg/riscv: Add slowpath load and store instructions
  tcg/riscv: Add direct load and store instructions
  tcg/riscv: Add the out op decoder
  tcg/riscv: Add the prologue generation and register the JIT
  tcg/riscv: Add the target init code
  tcg: Add RISC-V cpu signal handler
  disas: Add RISC-V support
  configure: Add support for building RISC-V host

Richard Henderson (19):
  disas/microblaze: Remove unused REG_SP macro
  linux-user: Add safe_syscall for riscv64 host
  tcg: Renumber TCG_CALL_* flags
  tcg: Add TCG_CALL_NO_RETURN
  tcg: Reference count labels
  tcg: Add reachable_code_pass
  tcg: Add preferred_reg argument to tcg_reg_alloc
  tcg: Add preferred_reg argument to temp_load
  tcg: Add preferred_reg argument to temp_sync
  tcg: Add preferred_reg argument to tcg_reg_alloc_do_movi
  tcg: Add output_pref to TCGOp
  tcg: Improve register allocation for matching constraints
  tcg: Dump register preference info with liveness
  tcg: Reindent parts of liveness_pass_1
  tcg: Rename and adjust liveness_pass_1 helpers
  tcg: Split out more subroutines from liveness_pass_1
  tcg: Add TCG_OPF_BB_EXIT
  tcg: Record register preferences during liveness
  tcg: Improve call argument loading

 include/elf.h  |   55 +
 include/exec/helper-head.h |   13 +
 include/exec/helper-tcg.h  |   21 +-
 include/exec/poison.h  |1 +
 linux-user/host/riscv32/hostdep.h  |   11 +
 linux-user/host/riscv64/hostdep.h  |   34 +
 tcg/riscv/tcg-target.h |  177 +++
 tcg/tcg-op.h   |1 +
 tcg/tcg-opc.h  |7 +-
 tcg/tcg.h  |   31 +-
 accel/tcg/user-exec.c  |   75 ++
 disas.c|   10 +-
 disas/microblaze.c |1 -
 tcg/riscv/tcg-target.inc.c | 1949 
 tcg/tcg-op.c   |2 +
 tcg/tcg.c  |  626 +++--
 MAINTAINERS|   12 +-
 configure  |   12 +-
 linux-user/host/riscv64/safe-syscall.inc.S |   77 ++
 19 files changed, 2948 insertions(+), 167 deletions(-)
 create mode 100644 linux-user/host/riscv32/hostdep.h
 create mode 100644 linux-user/host/riscv64/hostdep.h
 create mode 100644 tcg/riscv/tcg-target.h
 create mode 100644 tcg/riscv/tcg-target.inc.c
 create mode 100644 linux-user/host/riscv64/safe-syscall.inc.S



Re: [Qemu-devel] [PATCH 2/2] fp-bench: remove wrong exponent raise in fill_random

2018-12-25 Thread Richard Henderson
On 12/22/18 6:52 AM, Emilio G. Cota wrote:
> At this point random_ops[] only contains normals, so there's
> no need to do anything to them. In fact, raising the exponent
> here can make the output !normal, which is precisely
> what the comment says we want to avoid.
> 
> Signed-off-by: Emilio G. Cota 
> ---
>  tests/fp/fp-bench.c | 4 
>  1 file changed, 4 deletions(-)

Reviewed-by: Richard Henderson 

r~




Re: [Qemu-devel] [PATCH 1/2] fp-bench: fix update_random_ops

2018-12-25 Thread Richard Henderson
On 12/22/18 6:51 AM, Emilio G. Cota wrote:
> The second test in the branches is wrong; fix while converting
> to a switch statement, which is easier to get right.
> 
> Signed-off-by: Emilio G. Cota 
> ---
>  tests/fp/fp-bench.c | 11 ---
>  1 file changed, 8 insertions(+), 3 deletions(-)

Whoops.

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH 6/6] target/ppc: remove various HOST_WORDS_BIGENDIAN hacks in int_helper.c

2018-12-25 Thread Richard Henderson
On 12/23/18 10:38 PM, Mark Cave-Ayland wrote:
> -#define VEXT_SIGNED(name, element, mask, cast, recast)  \
> +#define VEXT_SIGNED(name, element, access, mask, cast, recast)  \
>  void helper_##name(ppc_avr_t *r, ppc_avr_t *b)  \
>  {   \
>  int i;  \
> -VECTOR_FOR_INORDER_I(i, element) {  \
> -r->element[i] = (recast)((cast)(b->element[i] & mask)); \
> +for (i = 0; i < ARRAY_SIZE(r->element); i++) {  \
> +r->access(i) = (recast)((cast)(b->access(i) & mask));   \
>  }   \
>  }
> -VEXT_SIGNED(vextsb2w, s32, UINT8_MAX, int8_t, int32_t)
> -VEXT_SIGNED(vextsb2d, s64, UINT8_MAX, int8_t, int64_t)
> -VEXT_SIGNED(vextsh2w, s32, UINT16_MAX, int16_t, int32_t)
> -VEXT_SIGNED(vextsh2d, s64, UINT16_MAX, int16_t, int64_t)
> -VEXT_SIGNED(vextsw2d, s64, UINT32_MAX, int32_t, int64_t)
> +VEXT_SIGNED(vextsb2w, s32, VsrSW, UINT8_MAX, int8_t, int32_t)
> +VEXT_SIGNED(vextsb2d, s64, VsrSD, UINT8_MAX, int8_t, int64_t)
> +VEXT_SIGNED(vextsh2w, s32, VsrSW, UINT16_MAX, int16_t, int32_t)
> +VEXT_SIGNED(vextsh2d, s64, VsrSD, UINT16_MAX, int16_t, int64_t)
> +VEXT_SIGNED(vextsw2d, s64, VsrSD, UINT32_MAX, int32_t, int64_t)

Your conversion is technically fine, but this macro is just confused.

It does not need the mask argument, nor does it need the recast argument.
The masking is implied by the cast argument, and the recast is implied by the
assignment.

Nor, really, does it need the access argument.  The data is handled in strict
lanes, and it does not matter in which order the lanes are processed.

> -#define VNEG(name, element) \
> +#define VNEG(name, element, access) \
>  void helper_##name(ppc_avr_t *r, ppc_avr_t *b)  \
>  {   \
>  int i;  \
> -VECTOR_FOR_INORDER_I(i, element) {  \
> -r->element[i] = -b->element[i]; \
> +for (i = 0; i < ARRAY_SIZE(r->element); i++) {  \
> +r->access(i) = -b->access(i);   \
>  }   \
>  }
> -VNEG(vnegw, s32)
> -VNEG(vnegd, s64)
> +VNEG(vnegw, s32, VsrSW)
> +VNEG(vnegd, s64, VsrSD)

Similarly, this does not require access nor in-order processing.

> -#define VGENERIC_DO(name, element)  \
> +#define VGENERIC_DO(name, element, access)  \
>  void helper_v##name(ppc_avr_t *r, ppc_avr_t *b) \
>  {   \
>  int i;  \
>  \
> -VECTOR_FOR_INORDER_I(i, element) {  \
> -r->element[i] = name(b->element[i]);\
> +for (i = 0; i < ARRAY_SIZE(r->element); i++) {  \
> +r->access(i) = name(b->access(i));  \
>  }   \
>  }

Likewise.


r~



Re: [Qemu-devel] [PATCH 5/6] target/ppc: eliminate use of EL_IDX macros from int_helper.c

2018-12-25 Thread Richard Henderson
On 12/23/18 10:38 PM, Mark Cave-Ayland wrote:
> These macros can be eliminated by instead using the relavant Vsr* macros in
> the few locations where they appear.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  target/ppc/int_helper.c | 66 
> -
>  1 file changed, 27 insertions(+), 39 deletions(-)

Reviewed-by: Richard Henderson 


> -#define ROTRu32(v, n) (((v) >> (n)) | ((v) << (32-n)))
> +#define ROTRu32(v, n) (((v) >> (n)) | ((v) << (32 - n)))

For a different patch, this is ror32().

This version contains a -fsanitize=shift bug, in that it improperly handles n
== 0 into a shift by 32.


>  #define ROTRu64(v, n) (((v) >> (n)) | ((v) << (64-n)))

Similarly.


r~



Re: [Qemu-devel] [PATCH 3/6] target/ppc: rework vmul{e, o}{s, u}{b, h, w} instructions to use Vsr* macros

2018-12-25 Thread Richard Henderson
On 12/23/18 10:38 PM, Mark Cave-Ayland wrote:
> -#define VMUL_DO(name, mul_element, prod_element, cast, evenp)   \
> +#define VMUL_DO_EVN(name, mul_element, mul_access, prod_access, cast)   \
>  void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)   \
>  {   \
>  int i;  \
>  \
> +for (i = 0; i < ARRAY_SIZE(r->mul_element); i += 2) {   \
> +r->prod_access(i >> 1) = (cast)a->mul_access(i) *   \
> + (cast)b->mul_access(i);\
> +}   \
> +}
> +
> +#define VMUL_DO_ODD(name, mul_element, mul_access, prod_access, cast)   \
> +void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)   \
> +{   \
> +int i;  \
> +\
> +for (i = 0; i < ARRAY_SIZE(r->mul_element); i += 2) {   \
> +r->prod_access(i >> 1) = (cast)a->mul_access(i + 1) *   \
> + (cast)b->mul_access(i + 1);\
>  }   \
>  }

FWIW,

  for (i = odd; i < ARRAY_SIZE; i += 2) {
r->pacc(i >> 1) = (cast)a->macc(i) * b->macc(i);
  }

is sufficient to unify these two.  But what you have isn't wrong.

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH 1/6] target/ppc: implement complete set of Vsr* macros

2018-12-25 Thread Richard Henderson
On 12/23/18 10:38 PM, Mark Cave-Ayland wrote:
> This prepares us for eliminating the use of direct array access within the VMX
> instruction implementations.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  target/ppc/internal.h | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH 5/6] target/mips: MXU: Add handlers for max/min instructions

2018-12-25 Thread Richard Henderson
Sorry I missed the original post, but:

> +} else if (unlikely((XRb == 0) && (XRc == 0))) {
> +/* both operands zero registers -> just set destination to zero */
> +tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
> +} else if (unlikely((XRb == 0) || (XRc == 0))) {
> +/* exactly one operand is zero register - find which one is not...*/
> +uint32_t XRx = XRb ? XRb : XRc;
> +/* ...and do max/min operation with one operand 0 */
> +if (opc == OPC_MXU_S32MAX) {
> +tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
> +} else {
> +tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
> +}
> +} else if (unlikely(XRb == XRc)) {
> +/* both operands same -> just set destination to one of them */
> +tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);

You should not special case unlikely events, especially when ...

> +} else {
> +/* the most general case */
> +if (opc == OPC_MXU_S32MAX) {
> +tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
> +   mxu_gpr[XRc - 1]);
> +} else {
> +tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
> +   mxu_gpr[XRc - 1]);
> +}

... the normal case will handle those special cases just fine.



Re: [Qemu-devel] [RFC PATCH v2 0/7] ui: add generic keyboard state tracker, fix keymap

2018-12-25 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20181219120904.17643-1-kra...@redhat.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-quick@centos7 SHOW_ENV=1 J=8
=== TEST SCRIPT END ===

libpmem support   no
libudev   no

WARNING: Use of SDL 1.2 is deprecated and will be removed in
WARNING: future releases. Please switch to using SDL 2.0

NOTE: cross-compilers enabled:  'cc'
  GEN x86_64-softmmu/config-devices.mak.tmp
---
  CC  chardev/char.o
  CC  chardev/char-fd.o
/tmp/qemu-test/src/ui/sdl.c: In function 'sdl_keyevent_to_keycode_generic':
/tmp/qemu-test/src/ui/sdl.c:218:28: error: incompatible type for argument 3 of 
'keysym2scancode'
shift, altgr, ctrl) & SCANCODE_KEYMASK;
^
In file included from /tmp/qemu-test/src/ui/sdl_keysym.h:2:0,
---
/tmp/qemu-test/src/ui/keymaps.h:58:5: note: expected 'struct KbdState *' but 
argument is of type '_Bool'
 int keysym2scancode(kbd_layout_t *k, int keysym,
 ^
/tmp/qemu-test/src/ui/sdl.c:218:28: error: too many arguments to function 
'keysym2scancode'
shift, altgr, ctrl) & SCANCODE_KEYMASK;
^
In file included from /tmp/qemu-test/src/ui/sdl_keysym.h:2:0,


The full log is available at
http://patchew.org/logs/20181219120904.17643-1-kra...@redhat.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PATCH v3 2/2] intel-iommu: extend VTD emulation to allow 57-bit IOVA address width.

2018-12-25 Thread Michael S. Tsirkin
On Sat, Dec 22, 2018 at 08:41:37AM +0800, Yu Zhang wrote:
> On Fri, Dec 21, 2018 at 01:10:13PM -0500, Michael S. Tsirkin wrote:
> > On Sat, Dec 22, 2018 at 01:34:01AM +0800, Yu Zhang wrote:
> > > On Fri, Dec 21, 2018 at 12:15:26PM -0500, Michael S. Tsirkin wrote:
> > > > On Sat, Dec 22, 2018 at 12:19:20AM +0800, Yu Zhang wrote:
> > > > > > I'd like to avoid poking at the CPU from VTD code. That's all.
> > > > > 
> > > > > OK. So for the short term,how about I remove the check of host cpu, 
> > > > > and add a TODO
> > > > > in the comments in vtd_decide_config()? 
> > > > 
> > > > My question would be what happens on an incorrect use?
> > > 
> > > I believe the vfio_dma_map will return failure for an incorrect use.
> > > 
> > > > And how does user figure out which values to set?
> > > 
> > > Well, for now I don't think user can figure out. E.g. if we expose a 
> > > vIOMMU with
> > > 48-bit IOVA capability, yet host only supports 39-bit IOVA, vfio shall 
> > > return failure,
> > > but the user does not know whose fault it is.
> > > > 
> > > > > As to the check against hardware IOMMU, Peter once had a proposal in
> > > > > http://lists.nongnu.org/archive/html/qemu-devel/2018-11/msg02281.html
> > > > > 
> > > > > Do you have any comment or suggestion on Peter's proposal?
> > > > 
> > > > Sounds reasonable to me. Do we do it on vfio attach or unconditionally?
> > > > 
> > > 
> > > I guess on vfio attach? Will need more thinking in it.
> > 
> > 
> > Things like live migration (e.g. after hot removal of the vfio device)
> > are also concerns.
> 
> Sorry, why live migration shall be a problem? I mean, if the DMA address
> width of vIOMMU does not match the host IOMMU's, we can just stop creating
> the VM, there's no live migration. 

I don't see code like this though.

Also management needs to somehow be able to figure out that migration
will fail. It's not nice to transfer all memory and then have it fail
when viommu is migrated.  So from that POV a flag is better. It can be
validated agains host capabilities.

We can still have something like aw=host just like cpu host.

> > 
> > > > 
> > > > > I still do not quite know
> > > > > how to do it for now...
> > > > > 
> > > > > [...]
> > > > > 
> > > > > 
> > > > > B.R.
> > > > > Yu
> > > > 
> > > > 
> > > > 
> > > > -- 
> > > > MST
> > > 
> > > B.R.
> > > Yu
> 
> B.R.
> Yu



Re: [Qemu-devel] [PATCH v3 1/2] intel-iommu: differentiate host address width from IOVA address width.

2018-12-25 Thread Michael S. Tsirkin
On Sat, Dec 22, 2018 at 09:11:26AM +0800, Yu Zhang wrote:
> On Fri, Dec 21, 2018 at 02:02:28PM -0500, Michael S. Tsirkin wrote:
> > On Sat, Dec 22, 2018 at 01:37:58AM +0800, Yu Zhang wrote:
> > > On Fri, Dec 21, 2018 at 12:04:49PM -0500, Michael S. Tsirkin wrote:
> > > > On Sat, Dec 22, 2018 at 12:09:44AM +0800, Yu Zhang wrote:
> > > > > Well, my understanding of the vt-d spec is that the address 
> > > > > limitation in
> > > > > DMAR are referring to the same concept of CPUID.MAXPHYSADDR. I do not 
> > > > > think
> > > > > there's any different in the native scenario. :)
> > > > 
> > > > I think native machines exist on which the two values are different.
> > > > Is that true?
> > > 
> > > I think the answer is not. My understanding is that HAW(host address 
> > > wdith) is
> > > the maximum physical address width a CPU can detects(by cpuid.0x8008).
> > > 
> > > I agree there are some addresses the CPU does not touch, but they are 
> > > still in
> > > the physical address space, and there's only one physical address space...
> > > 
> > > B.R.
> > > Yu
> > 
> > Ouch I thought we are talking about the virtual address size.
> > I think I did have a box where VTD's virtual address size was
> > smaller than CPU's.
> > For physical one - we just need to make it as big as max supported
> > memory right?
> 
> Well, my understanding of the physical one is the maximum physical address
> width. Sorry, this explain seems nonsense... I mean, it's not just about
> the max supported memory, but also covers MMIO. It shall be detectable
> from cpuid, or ACPI's DMAR table, instead of calculated by the max memory
> size. One common usage of this value is to tell the paging structure entries(
> CPU's or IOMMU's) which bits shall be reserved. There are also some registers
> e.g. apic base reg etc, whose contents are physical addresses, therefore also
> need to follow the similar requirement for the reserved bits.
> 
> So I think the correct direction might be to define this property in the
> machine status level, instead of the CPU level. Is this reasonable to you?

At that level yes. But isn't this already specified by "pci-hole64-end"?



> > 
> > -- 
> > MST
> 
> B.R.
> Yu



Re: [Qemu-devel] [PATCH] tests/tcg: add barrier test for ARM

2018-12-25 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20181219183902.27273-1-alex.ben...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20181219183902.27273-1-alex.ben...@linaro.org
Type: series
Subject: [Qemu-devel] [PATCH] tests/tcg: add barrier test for ARM

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
308bf65 tests/tcg: add barrier test for ARM

=== OUTPUT BEGIN ===
Checking PATCH 1/1: tests/tcg: add barrier test for ARM...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#37: 
new file mode 100644

ERROR: spaces required around that '::' (ctx:WxO)
#68: FILE: tests/tcg/arm/barrier.c:27:
+#define barrier()  ({ asm volatile("" ::: "memory"); (void)0; })
   ^

ERROR: spaces required around that ':' (ctx:OxW)
#68: FILE: tests/tcg/arm/barrier.c:27:
+#define barrier()  ({ asm volatile("" ::: "memory"); (void)0; })
 ^

WARNING: line over 80 characters
#69: FILE: tests/tcg/arm/barrier.c:28:
+#define smp_mb()   ({ barrier(); 
__atomic_thread_fence(__ATOMIC_SEQ_CST); })

ERROR: memory barrier without comment
#69: FILE: tests/tcg/arm/barrier.c:28:
+#define smp_mb()   ({ barrier(); 
__atomic_thread_fence(__ATOMIC_SEQ_CST); })

WARNING: line over 80 characters
#70: FILE: tests/tcg/arm/barrier.c:29:
+#define smp_mb_release()   ({ barrier(); 
__atomic_thread_fence(__ATOMIC_RELEASE); })

WARNING: line over 80 characters
#71: FILE: tests/tcg/arm/barrier.c:30:
+#define smp_mb_acquire()   ({ barrier(); 
__atomic_thread_fence(__ATOMIC_ACQUIRE); })

ERROR: memory barrier without comment
#73: FILE: tests/tcg/arm/barrier.c:32:
+#define smp_wmb()  smp_mb_release()

ERROR: memory barrier without comment
#74: FILE: tests/tcg/arm/barrier.c:33:
+#define smp_rmb()  smp_mb_acquire()

ERROR: do not initialise statics to 0 or NULL
#82: FILE: tests/tcg/arm/barrier.c:41:
+static int wait_if_ahead = 0;

ERROR: open brace '{' following struct go on the same line
#93: FILE: tests/tcg/arm/barrier.c:52:
+typedef struct test_array
+{

ERROR: Use of volatile is usually wrong, please add a comment
#94: FILE: tests/tcg/arm/barrier.c:53:
+volatile unsigned int x;

ERROR: Use of volatile is usually wrong, please add a comment
#96: FILE: tests/tcg/arm/barrier.c:55:
+volatile unsigned int y;

ERROR: Use of volatile is usually wrong, please add a comment
#98: FILE: tests/tcg/arm/barrier.c:57:
+volatile unsigned int r[MAX_THREADS];

WARNING: Block comments use a leading /* on a separate line
#101: FILE: tests/tcg/arm/barrier.c:60:
+/* Test definition structure

ERROR: memory barrier without comment
#127: FILE: tests/tcg/arm/barrier.c:86:
+smp_mb();

WARNING: Block comments use a leading /* on a separate line
#144: FILE: tests/tcg/arm/barrier.c:103:
+/* Simple Message Passing

ERROR: "foo * bar" should be "foo *bar"
#152: FILE: tests/tcg/arm/barrier.c:111:
+static void * message_passing_write(void *arg)

ERROR: Use of volatile is usually wrong, please add a comment
#160: FILE: tests/tcg/arm/barrier.c:119:
+volatile test_array *entry = [i];

ERROR: Use of volatile is usually wrong, please add a comment
#177: FILE: tests/tcg/arm/barrier.c:136:
+volatile test_array *entry = [i];

ERROR: space required after that ',' (ctx:VxV)
#178: FILE: tests/tcg/arm/barrier.c:137:
+unsigned int x,y;
   ^

ERROR: braces {} are necessary for all arms of this statement
#182: FILE: tests/tcg/arm/barrier.c:141:
+if (y && !x)
[...]

ERROR: "foo * bar" should be "foo *bar"
#191: FILE: tests/tcg/arm/barrier.c:150:
+static void * message_passing_write_barrier(void *arg)

ERROR: spaces required around that '<' (ctx:VxW)
#198: FILE: tests/tcg/arm/barrier.c:157:
+for (i = 0; i< array_size; i++) {
  ^

ERROR: Use of volatile is usually wrong, please add a comment
#199: FILE: tests/tcg/arm/barrier.c:158:
+volatile test_array *entry = [i];

ERROR: memory barrier without comment
#201: FILE: tests/tcg/arm/barrier.c:160:
+smp_wmb();

ERROR: Use of volatile is usually wrong, please add a comment
#217: FILE: tests/tcg/arm/barrier.c:176:
+volatile test_array *entry = [i];

ERROR: memory barrier without comment
#220: FILE: tests/tcg/arm/barrier.c:179:
+smp_rmb();

ERROR: 

Re: [Qemu-devel] [PULL v2 00/35] Misc patches for 2018-12-18

2018-12-25 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20181219151917.3874-1-pbonz...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20181219151917.3874-1-pbonz...@redhat.com
Type: series
Subject: [Qemu-devel] [PULL v2 00/35] Misc patches for 2018-12-18

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
27038c1 avoid TABs in files that only contain a few
8380bfa remove space-tab sequences
dfd008b scripts: add script to convert multiline comments into 4-line format
b882f38 hw/watchdog/wdt_i6300esb: remove a unnecessary comment
623f846 checkpatch: warn about qemu/queue.h head structs that are not typedef-ed
d02ffd9 qemu/queue.h: simplify reverse access to QTAILQ
3810871 qemu/queue.h: reimplement QTAILQ without pointer-to-pointers
2008a06 qemu/queue.h: remove Q_TAILQ_{HEAD, ENTRY}
47cf78f qemu/queue.h: typedef QTAILQ heads
20e1b87 qemu/queue.h: leave head structs anonymous unless necessary
f23f8d2 vfio: make vfio_address_spaces static
cc4e7ee qemu/queue.h: do not access tqe_prev directly
d563f32 test: replace gtester with a TAP driver
602d090 test: execute g_test_run when tests are skipped
19c5978 qga: drop < Vista compatibility
7ab6ef5 build-sys: build with Vista API by default
9597923 build-sys: move windows defines in osdep.h header
f00ee90 build-sys: don't include windows.h, osdep.h does it
d397fb2 scsi: esp: Defer command completion until previous interrupts have been 
handled
5868a6a esp-pci: Fix status register write erase control
21c3d03 block/iscsi: cancel libiscsi task when ABORT TASK TMF completes
04719ab block/iscsi: fix ioctl cancel use-after-free
a43e64e block/iscsi: take iscsilun->mutex in iscsi_timed_check_events()
67cce60 block/iscsi: drop unused IscsiAIOCB->buf field
6359fe7 hax: Support for Linux hosts
9a32ae1 memory: update coalesced_range on transaction_commit
8ddf23e memory: avoid unnecessary coalesced_io_del operations
922cf0d memory: extract flat_range_coalesced_io_{del, add}
2b40f43 pam: wrap MemoryRegion initialization in a transaction
a01d8ca6 checkpatch: colorize output to terminal
0848388 checkpatch: improve handling of multiple patches or files
9ca8c73 checkpatch: check Signed-off-by in --mailback mode
35c41e7 checkpatch: fix premature exit when no input or --mailback
d2ba5b1 vhost-user-bridge: fix "unknown type name" compilation error
60fb207 accel: Improve selection of the default accelerator

=== OUTPUT BEGIN ===
Checking PATCH 1/35: accel: Improve selection of the default accelerator...
Checking PATCH 2/35: vhost-user-bridge: fix "unknown type name" compilation 
error...
Checking PATCH 3/35: checkpatch: fix premature exit when no input or 
--mailback...
Checking PATCH 4/35: checkpatch: check Signed-off-by in --mailback mode...
Checking PATCH 5/35: checkpatch: improve handling of multiple patches or 
files...
ERROR: line over 90 characters
#33: FILE: scripts/checkpatch.pl:344:
+   open($HASH, "-|", "git", "log", "--reverse", "--no-merges", 
"--format=%H %s", $ARGV[0]) ||

ERROR: line over 90 characters
#34: FILE: scripts/checkpatch.pl:345:
+   die "$P: git log --reverse --no-merges --format='%H %s' 
$ARGV[0] failed - $!\n";

WARNING: line over 80 characters
#65: FILE: scripts/checkpatch.pl:372:
+   $vname = substr($hash, 0, 12) . ' (' . $git_commits{$hash} . 
')';

total: 2 errors, 1 warnings, 62 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 6/35: checkpatch: colorize output to terminal...
Checking PATCH 7/35: pam: wrap MemoryRegion initialization in a transaction...
Checking PATCH 8/35: memory: extract flat_range_coalesced_io_{del, add}...
Checking PATCH 9/35: memory: avoid unnecessary coalesced_io_del operations...
Checking PATCH 10/35: memory: update coalesced_range on transaction_commit...
Checking PATCH 11/35: hax: Support for Linux hosts...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#62: 
rename from target/i386/hax-darwin.c

total: 0 errors, 1 warnings, 31 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 12/35: block/iscsi: drop unused IscsiAIOCB->buf field...
Checking PATCH 13/35: block/iscsi: take iscsilun->mutex in 

[Qemu-devel] [PATCH for-4.0 v9 16/16] qemu_thread_join: fix segmentation fault

2018-12-25 Thread Fei Li
To avoid the segmentation fault in qemu_thread_join(), just directly
return when the QemuThread *thread failed to be created in either
qemu-thread-posix.c or qemu-thread-win32.c.

Cc: Stefan Weil 
Signed-off-by: Fei Li 
Reviewed-by: Fam Zheng 
---
 util/qemu-thread-posix.c | 3 +++
 util/qemu-thread-win32.c | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index 39834b0551..3548935dac 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -571,6 +571,9 @@ void *qemu_thread_join(QemuThread *thread)
 int err;
 void *ret;
 
+if (!thread->thread) {
+return NULL;
+}
 err = pthread_join(thread->thread, );
 if (err) {
 error_exit(err, __func__);
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index 57b1143e97..ca4d5329e3 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -367,7 +367,7 @@ void *qemu_thread_join(QemuThread *thread)
 HANDLE handle;
 
 data = thread->data;
-if (data->mode == QEMU_THREAD_DETACHED) {
+if (data == NULL || data->mode == QEMU_THREAD_DETACHED) {
 return NULL;
 }
 
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 13/16] qemu_thread: supplement error handling for migration

2018-12-25 Thread Fei Li
Update qemu_thread_create()'s callers by
- setting an error on qemu_thread_create() failure for callers that
  set an error on failure;
- reporting the error and returning failure for callers that return
  an error code on failure;
- reporting the error and setting some state for callers that just
  report errors and choose not to continue on.

Cc: Markus Armbruster 
Cc: Dr. David Alan Gilbert 
Cc: Peter Xu 
Signed-off-by: Fei Li 
---
 migration/migration.c| 33 ++---
 migration/postcopy-ram.c | 16 
 migration/ram.c  | 44 ++--
 migration/savevm.c   | 12 
 4 files changed, 72 insertions(+), 33 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index ea5839ff0d..9654bde101 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -447,10 +447,13 @@ static void process_incoming_migration_co(void *opaque)
 goto fail;
 }
 
-/* TODO: let the further caller handle the error instead of abort() */
-qemu_thread_create(>colo_incoming_thread, "COLO incoming",
-   colo_process_incoming_thread, mis,
-   QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(>colo_incoming_thread, "COLO incoming",
+colo_process_incoming_thread, mis,
+QEMU_THREAD_JOINABLE, _err)) {
+error_reportf_err(local_err, "failed to create "
+  "colo_process_incoming_thread: ");
+goto fail;
+}
 mis->have_colo_incoming_thread = true;
 qemu_coroutine_yield();
 
@@ -2347,6 +2350,7 @@ out:
 static int open_return_path_on_source(MigrationState *ms,
   bool create_thread)
 {
+Error *local_err = NULL;
 
 ms->rp_state.from_dst_file = qemu_file_get_return_path(ms->to_dst_file);
 if (!ms->rp_state.from_dst_file) {
@@ -2360,10 +2364,13 @@ static int open_return_path_on_source(MigrationState 
*ms,
 return 0;
 }
 
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>rp_state.rp_thread, "return path",
-   source_return_path_thread, ms,
-   QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(>rp_state.rp_thread, "return path",
+source_return_path_thread, ms,
+QEMU_THREAD_JOINABLE, _err)) {
+error_reportf_err(local_err,
+  "failed to create source_return_path_thread: ");
+return -1;
+ }
 
 trace_open_return_path_on_source_continue();
 
@@ -3193,9 +3200,13 @@ void migrate_fd_connect(MigrationState *s, Error 
*error_in)
 migrate_fd_cleanup(s);
 return;
 }
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>thread, "live_migration", migration_thread, s,
-   QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(>thread, "live_migration", migration_thread, s,
+QEMU_THREAD_JOINABLE, _in)) {
+error_reportf_err(error_in, "failed to create migration_thread: ");
+migrate_set_state(>state, s->state, MIGRATION_STATUS_FAILED);
+migrate_fd_cleanup(s);
+return;
+}
 s->migration_thread_running = true;
 }
 
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 221ea24919..80bfa9c4a2 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -1083,6 +1083,8 @@ retry:
 
 int postcopy_ram_enable_notify(MigrationIncomingState *mis)
 {
+Error *local_err = NULL;
+
 /* Open the fd for the kernel to give us userfaults */
 mis->userfault_fd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
 if (mis->userfault_fd == -1) {
@@ -1109,10 +,16 @@ int postcopy_ram_enable_notify(MigrationIncomingState 
*mis)
 }
 
 qemu_sem_init(>fault_thread_sem, 0);
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>fault_thread, "postcopy/fault",
-   postcopy_ram_fault_thread, mis,
-   QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(>fault_thread, "postcopy/fault",
+postcopy_ram_fault_thread, mis,
+QEMU_THREAD_JOINABLE, _err)) {
+error_reportf_err(local_err,
+  "failed to create postcopy_ram_fault_thread: ");
+close(mis->userfault_event_fd);
+close(mis->userfault_fd);
+qemu_sem_destroy(>fault_thread_sem);
+return -1;
+}
 qemu_sem_wait(>fault_thread_sem);
 qemu_sem_destroy(>fault_thread_sem);
 mis->have_fault_thread = true;
diff --git a/migration/ram.c b/migration/ram.c
index eed1daf302..1e24a78eaa 100644
--- 

[Qemu-devel] [PATCH for-4.0 v9 06/16] qemu_thread: Make qemu_thread_create() handle errors properly

2018-12-25 Thread Fei Li
qemu_thread_create() abort()s on error. Not nice. Give it a return
value and an Error ** argument, so it can return success/failure.

Considering qemu_thread_create() is quite widely used in qemu, split
this into two steps: this patch passes the _abort to
qemu_thread_create() everywhere, and the next 9 patches will improve
on _abort for callers who need.

Cc: Markus Armbruster 
Cc: Paolo Bonzini 
Signed-off-by: Fei Li 
---
 cpus.c  | 23 +++
 dump.c  |  3 ++-
 hw/misc/edu.c   |  4 +++-
 hw/ppc/spapr_hcall.c|  4 +++-
 hw/rdma/rdma_backend.c  |  3 ++-
 hw/usb/ccid-card-emulated.c |  5 +++--
 include/qemu/thread.h   |  4 ++--
 io/task.c   |  3 ++-
 iothread.c  |  3 ++-
 migration/migration.c   | 11 ---
 migration/postcopy-ram.c|  4 +++-
 migration/ram.c | 12 
 migration/savevm.c  |  3 ++-
 tests/atomic_add-bench.c|  3 ++-
 tests/iothread.c|  2 +-
 tests/qht-bench.c   |  3 ++-
 tests/rcutorture.c  |  3 ++-
 tests/test-aio.c|  2 +-
 tests/test-rcu-list.c   |  3 ++-
 ui/vnc-jobs.c   |  6 --
 util/compatfd.c |  6 --
 util/oslib-posix.c  |  3 ++-
 util/qemu-thread-posix.c| 27 ---
 util/qemu-thread-win32.c| 16 
 util/rcu.c  |  3 ++-
 util/thread-pool.c  |  4 +++-
 26 files changed, 112 insertions(+), 51 deletions(-)

diff --git a/cpus.c b/cpus.c
index 0ddeeefc14..25df03326b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1961,15 +1961,17 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
  cpu->cpu_index);
 
+/* TODO: let the callers handle the error instead of abort() here 
*/
 qemu_thread_create(cpu->thread, thread_name, 
qemu_tcg_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE);
+   cpu, QEMU_THREAD_JOINABLE, _abort);
 
 } else {
 /* share a single thread for all cpus with TCG */
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG");
+/* TODO: let the callers handle the error instead of abort() here 
*/
 qemu_thread_create(cpu->thread, thread_name,
qemu_tcg_rr_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE);
+   cpu, QEMU_THREAD_JOINABLE, _abort);
 
 single_tcg_halt_cond = cpu->halt_cond;
 single_tcg_cpu_thread = cpu->thread;
@@ -1997,8 +1999,9 @@ static void qemu_hax_start_vcpu(CPUState *cpu)
 
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HAX",
  cpu->cpu_index);
+/* TODO: let the further caller handle the error instead of abort() here */
 qemu_thread_create(cpu->thread, thread_name, qemu_hax_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE);
+   cpu, QEMU_THREAD_JOINABLE, _abort);
 #ifdef _WIN32
 cpu->hThread = qemu_thread_get_handle(cpu->thread);
 #endif
@@ -2013,8 +2016,9 @@ static void qemu_kvm_start_vcpu(CPUState *cpu)
 qemu_cond_init(cpu->halt_cond);
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM",
  cpu->cpu_index);
+/* TODO: let the further caller handle the error instead of abort() here */
 qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE);
+   cpu, QEMU_THREAD_JOINABLE, _abort);
 }
 
 static void qemu_hvf_start_vcpu(CPUState *cpu)
@@ -2031,8 +2035,9 @@ static void qemu_hvf_start_vcpu(CPUState *cpu)
 
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF",
  cpu->cpu_index);
+/* TODO: let the further caller handle the error instead of abort() here */
 qemu_thread_create(cpu->thread, thread_name, qemu_hvf_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE);
+   cpu, QEMU_THREAD_JOINABLE, _abort);
 }
 
 static void qemu_whpx_start_vcpu(CPUState *cpu)
@@ -2044,8 +2049,9 @@ static void qemu_whpx_start_vcpu(CPUState *cpu)
 qemu_cond_init(cpu->halt_cond);
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX",
  cpu->cpu_index);
+/* TODO: let the further caller handle the error instead of abort() here */
 qemu_thread_create(cpu->thread, thread_name, qemu_whpx_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE);
+   cpu, QEMU_THREAD_JOINABLE, _abort);
 #ifdef _WIN32
 cpu->hThread = qemu_thread_get_handle(cpu->thread);
 #endif
@@ -2060,8 +2066,9 @@ static void qemu_dummy_start_vcpu(CPUState *cpu)
 qemu_cond_init(cpu->halt_cond);
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY",
  cpu->cpu_index);
-

[Qemu-devel] [PATCH for-4.0 v9 07/16] qemu_thread: supplement error handling for qemu_X_start_vcpu

2018-12-25 Thread Fei Li
The callers of qemu_init_vcpu() already passed the **errp to handle
errors. In view of this, add a new Error parameter to qemu_init_vcpu()
and all qemu_X_start_vcpu() functions called by qemu_init_vcpu() to
propagate the error and let the further callers check it.

Besides, make qemu_init_vcpu() return a Boolean value to let its
callers know whether it succeeds.

Cc: Paolo Bonzini 
Signed-off-by: Fei Li 
Reviewed-by: Fam Zheng 
Reviewed-by: Juan Quintela 
---
 accel/tcg/user-exec-stub.c  |  3 +-
 cpus.c  | 86 -
 include/qom/cpu.h   |  2 +-
 target/alpha/cpu.c  |  4 +-
 target/arm/cpu.c|  4 +-
 target/cris/cpu.c   |  4 +-
 target/hppa/cpu.c   |  4 +-
 target/i386/cpu.c   |  4 +-
 target/lm32/cpu.c   |  4 +-
 target/m68k/cpu.c   |  4 +-
 target/microblaze/cpu.c |  4 +-
 target/mips/cpu.c   |  4 +-
 target/moxie/cpu.c  |  4 +-
 target/nios2/cpu.c  |  4 +-
 target/openrisc/cpu.c   |  4 +-
 target/ppc/translate_init.inc.c |  4 +-
 target/riscv/cpu.c  |  4 +-
 target/s390x/cpu.c  |  4 +-
 target/sh4/cpu.c|  4 +-
 target/sparc/cpu.c  |  4 +-
 target/tilegx/cpu.c |  4 +-
 target/tricore/cpu.c|  4 +-
 target/unicore32/cpu.c  |  4 +-
 target/xtensa/cpu.c |  4 +-
 24 files changed, 117 insertions(+), 58 deletions(-)

diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c
index a32b4496af..f8c38a375c 100644
--- a/accel/tcg/user-exec-stub.c
+++ b/accel/tcg/user-exec-stub.c
@@ -10,8 +10,9 @@ void cpu_resume(CPUState *cpu)
 {
 }
 
-void qemu_init_vcpu(CPUState *cpu)
+bool qemu_init_vcpu(CPUState *cpu, Error **errp)
 {
+return true;
 }
 
 /* User mode emulation does not support record/replay yet.  */
diff --git a/cpus.c b/cpus.c
index 25df03326b..e8450e518a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1931,7 +1931,7 @@ void cpu_remove_sync(CPUState *cpu)
 /* For temporary buffers for forming a name */
 #define VCPU_THREAD_NAME_SIZE 16
 
-static void qemu_tcg_init_vcpu(CPUState *cpu)
+static void qemu_tcg_init_vcpu(CPUState *cpu, Error **errp)
 {
 char thread_name[VCPU_THREAD_NAME_SIZE];
 static QemuCond *single_tcg_halt_cond;
@@ -1961,17 +1961,20 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
  cpu->cpu_index);
 
-/* TODO: let the callers handle the error instead of abort() here 
*/
-qemu_thread_create(cpu->thread, thread_name, 
qemu_tcg_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(cpu->thread, thread_name,
+qemu_tcg_cpu_thread_fn, cpu,
+QEMU_THREAD_JOINABLE, errp)) {
+return;
+}
 
 } else {
 /* share a single thread for all cpus with TCG */
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG");
-/* TODO: let the callers handle the error instead of abort() here 
*/
-qemu_thread_create(cpu->thread, thread_name,
-   qemu_tcg_rr_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(cpu->thread, thread_name,
+qemu_tcg_rr_cpu_thread_fn, cpu,
+QEMU_THREAD_JOINABLE, errp)) {
+return;
+}
 
 single_tcg_halt_cond = cpu->halt_cond;
 single_tcg_cpu_thread = cpu->thread;
@@ -1989,7 +1992,7 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
 }
 }
 
-static void qemu_hax_start_vcpu(CPUState *cpu)
+static void qemu_hax_start_vcpu(CPUState *cpu, Error **errp)
 {
 char thread_name[VCPU_THREAD_NAME_SIZE];
 
@@ -1999,15 +2002,16 @@ static void qemu_hax_start_vcpu(CPUState *cpu)
 
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HAX",
  cpu->cpu_index);
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(cpu->thread, thread_name, qemu_hax_cpu_thread_fn,
-   cpu, QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(cpu->thread, thread_name, qemu_hax_cpu_thread_fn,
+cpu, QEMU_THREAD_JOINABLE, errp)) {
+return;
+}
 #ifdef _WIN32
 cpu->hThread = qemu_thread_get_handle(cpu->thread);
 #endif
 }
 
-static void qemu_kvm_start_vcpu(CPUState *cpu)
+static void qemu_kvm_start_vcpu(CPUState *cpu, Error **errp)
 {
 char thread_name[VCPU_THREAD_NAME_SIZE];
 
@@ -2016,12 +2020,13 @@ static void qemu_kvm_start_vcpu(CPUState *cpu)
 qemu_cond_init(cpu->halt_cond);
 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, 

[Qemu-devel] [PATCH for-4.0 v9 12/16] qemu_thread: supplement error handling for iothread_complete/qemu_signalfd_compat

2018-12-25 Thread Fei Li
For iothread_complete: utilize the existed errp to propagate the
error and do the corresponding cleanup to replace the temporary
_abort.

For qemu_signalfd_compat: add a local_err to hold the error, and
return the corresponding error code to replace the temporary
_abort.

Cc: Markus Armbruster 
Cc: Eric Blake 
Signed-off-by: Fei Li 
---
 iothread.c  | 17 +++--
 util/compatfd.c | 11 ---
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/iothread.c b/iothread.c
index 8e8aa01999..7335dacf0b 100644
--- a/iothread.c
+++ b/iothread.c
@@ -164,9 +164,7 @@ static void iothread_complete(UserCreatable *obj, Error 
**errp)
 _error);
 if (local_error) {
 error_propagate(errp, local_error);
-aio_context_unref(iothread->ctx);
-iothread->ctx = NULL;
-return;
+goto fail;
 }
 
 qemu_mutex_init(>init_done_lock);
@@ -178,9 +176,12 @@ static void iothread_complete(UserCreatable *obj, Error 
**errp)
  */
 name = object_get_canonical_path_component(OBJECT(obj));
 thread_name = g_strdup_printf("IO %s", name);
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>thread, thread_name, iothread_run,
-   iothread, QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(>thread, thread_name, iothread_run,
+iothread, QEMU_THREAD_JOINABLE, errp)) {
+g_free(thread_name);
+g_free(name);
+goto fail;
+}
 g_free(thread_name);
 g_free(name);
 
@@ -191,6 +192,10 @@ static void iothread_complete(UserCreatable *obj, Error 
**errp)
>init_done_lock);
 }
 qemu_mutex_unlock(>init_done_lock);
+return;
+fail:
+aio_context_unref(iothread->ctx);
+iothread->ctx = NULL;
 }
 
 typedef struct {
diff --git a/util/compatfd.c b/util/compatfd.c
index c3d8448264..9cb13381e4 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -71,6 +71,7 @@ static int qemu_signalfd_compat(const sigset_t *mask)
 struct sigfd_compat_info *info;
 QemuThread thread;
 int fds[2];
+Error *local_err = NULL;
 
 info = malloc(sizeof(*info));
 if (info == NULL) {
@@ -89,9 +90,13 @@ static int qemu_signalfd_compat(const sigset_t *mask)
 memcpy(>mask, mask, sizeof(*mask));
 info->fd = fds[1];
 
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(, "signalfd_compat", sigwait_compat,
-   info, QEMU_THREAD_DETACHED, _abort);
+if (!qemu_thread_create(, "signalfd_compat", sigwait_compat,
+info, QEMU_THREAD_DETACHED, _err)) {
+close(fds[0]);
+close(fds[1]);
+free(info);
+return -1;
+}
 
 return fds[0];
 }
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 10/16] qemu_thread: supplement error handling for h_resize_hpt_prepare

2018-12-25 Thread Fei Li
Add a local_err to hold the error, and return the corresponding
error code to replace the temporary _abort.

Cc: Markus Armbruster 
Cc: David Gibson 
Signed-off-by: Fei Li 
---
 hw/ppc/spapr_hcall.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 5bc2cf4540..7c16ade04a 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -478,6 +478,7 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
 sPAPRPendingHPT *pending = spapr->pending_hpt;
 uint64_t current_ram_size;
 int rc;
+Error *local_err = NULL;
 
 if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) {
 return H_AUTHORITY;
@@ -538,10 +539,13 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
 pending->shift = shift;
 pending->ret = H_HARDWARE;
 
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>thread, "sPAPR HPT prepare",
-   hpt_prepare_thread, pending,
-   QEMU_THREAD_DETACHED, _abort);
+if (!qemu_thread_create(>thread, "sPAPR HPT prepare",
+hpt_prepare_thread, pending,
+QEMU_THREAD_DETACHED, _err)) {
+error_reportf_err(local_err, "failed to create hpt_prepare_thread: ");
+g_free(pending);
+return H_RESOURCE;
+}
 
 spapr->pending_hpt = pending;
 
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 03/16] migration: remove unused _err parameter in multifd_save_cleanup

2018-12-25 Thread Fei Li
Always call migrate_set_error() to set the error state without relying
on whether multifd_save_cleanup() succeeds.  As the passed _err
is never used in multifd_save_cleanup(), remove it. And make the
function be: void multifd_save_cleanup(void).

Cc: Dr. David Alan Gilbert 
Signed-off-by: Fei Li 
Reviewed-by: Juan Quintela 
---
 migration/migration.c |  5 +
 migration/ram.c   | 11 ---
 migration/ram.h   |  2 +-
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 24cb4b9d0d..5d322eb9d6 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1386,7 +1386,6 @@ static void migrate_fd_cleanup(void *opaque)
 qemu_savevm_state_cleanup();
 
 if (s->to_dst_file) {
-Error *local_err = NULL;
 QEMUFile *tmp;
 
 trace_migrate_fd_cleanup();
@@ -1397,9 +1396,7 @@ static void migrate_fd_cleanup(void *opaque)
 }
 qemu_mutex_lock_iothread();
 
-if (multifd_save_cleanup(_err) != 0) {
-error_report_err(local_err);
-}
+multifd_save_cleanup();
 qemu_mutex_lock(>qemu_file_lock);
 tmp = s->to_dst_file;
 s->to_dst_file = NULL;
diff --git a/migration/ram.c b/migration/ram.c
index 1671dedc97..435a8d2946 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -917,13 +917,12 @@ static void multifd_send_terminate_threads(Error *err)
 }
 }
 
-int multifd_save_cleanup(Error **errp)
+void multifd_save_cleanup(void)
 {
 int i;
-int ret = 0;
 
 if (!migrate_use_multifd()) {
-return 0;
+return;
 }
 multifd_send_terminate_threads(NULL);
 for (i = 0; i < migrate_multifd_channels(); i++) {
@@ -953,7 +952,6 @@ int multifd_save_cleanup(Error **errp)
 multifd_send_state->pages = NULL;
 g_free(multifd_send_state);
 multifd_send_state = NULL;
-return ret;
 }
 
 static void multifd_send_sync_main(void)
@@ -1071,9 +1069,8 @@ static void multifd_new_send_channel_async(QIOTask *task, 
gpointer opaque)
 Error *local_err = NULL;
 
 if (qio_task_propagate_error(task, _err)) {
-if (multifd_save_cleanup(_err) != 0) {
-migrate_set_error(migrate_get_current(), local_err);
-}
+migrate_set_error(migrate_get_current(), local_err);
+multifd_save_cleanup();
 } else {
 p->c = QIO_CHANNEL(sioc);
 qio_channel_set_delay(p->c, false);
diff --git a/migration/ram.h b/migration/ram.h
index 046d3074be..936177b3e9 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -43,7 +43,7 @@ uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_total(void);
 
 int multifd_save_setup(void);
-int multifd_save_cleanup(Error **errp);
+void multifd_save_cleanup(void);
 int multifd_load_setup(void);
 int multifd_load_cleanup(Error **errp);
 bool multifd_recv_all_channels_created(void);
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 15/16] qemu_thread: supplement error handling for touch_all_pages

2018-12-25 Thread Fei Li
Supplement the error handling for touch_all_pages: add an Error
parameter for it to propagate the error to its caller to do the
handling in case it fails.

Cc: Markus Armbruster 
Signed-off-by: Fei Li 
---
 util/oslib-posix.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 251e2f1aea..afc1d99093 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -431,15 +431,17 @@ static inline int get_memset_num_threads(int smp_cpus)
 }
 
 static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages,
-int smp_cpus)
+int smp_cpus, Error **errp)
 {
 size_t numpages_per_thread;
 size_t size_per_thread;
 char *addr = area;
 int i = 0;
+int started_thread = 0;
 
 memset_thread_failed = false;
 memset_num_threads = get_memset_num_threads(smp_cpus);
+started_thread = memset_num_threads;
 memset_thread = g_new0(MemsetThread, memset_num_threads);
 numpages_per_thread = (numpages / memset_num_threads);
 size_per_thread = (hpagesize * numpages_per_thread);
@@ -448,14 +450,18 @@ static bool touch_all_pages(char *area, size_t hpagesize, 
size_t numpages,
 memset_thread[i].numpages = (i == (memset_num_threads - 1)) ?
 numpages : numpages_per_thread;
 memset_thread[i].hpagesize = hpagesize;
-/* TODO: let the callers handle the error instead of abort() here */
-qemu_thread_create(_thread[i].pgthread, "touch_pages",
-   do_touch_pages, _thread[i],
-   QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(_thread[i].pgthread, "touch_pages",
+do_touch_pages, _thread[i],
+QEMU_THREAD_JOINABLE, errp)) {
+memset_thread_failed = true;
+started_thread = i;
+goto out;
+}
 addr += size_per_thread;
 numpages -= numpages_per_thread;
 }
-for (i = 0; i < memset_num_threads; i++) {
+out:
+for (i = 0; i < started_thread; i++) {
 qemu_thread_join(_thread[i].pgthread);
 }
 g_free(memset_thread);
@@ -471,6 +477,7 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int 
smp_cpus,
 struct sigaction act, oldact;
 size_t hpagesize = qemu_fd_getpagesize(fd);
 size_t numpages = DIV_ROUND_UP(memory, hpagesize);
+Error *local_err = NULL;
 
 memset(, 0, sizeof(act));
 act.sa_handler = _handler;
@@ -484,9 +491,9 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int 
smp_cpus,
 }
 
 /* touch pages simultaneously */
-if (touch_all_pages(area, hpagesize, numpages, smp_cpus)) {
-error_setg(errp, "os_mem_prealloc: Insufficient free host memory "
-"pages available to allocate guest RAM");
+if (touch_all_pages(area, hpagesize, numpages, smp_cpus, _err)) {
+error_propagate_prepend(errp, local_err, "os_mem_prealloc: 
Insufficient"
+" free host memory pages available to allocate guest RAM: ");
 }
 
 ret = sigaction(SIGBUS, , NULL);
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 11/16] qemu_thread: supplement error handling for emulated_realize

2018-12-25 Thread Fei Li
Utilize the existed errp to propagate the error and do the
corresponding cleanup to replace the temporary _abort.

Cc: Cc: Markus Armbruster 
Cc: Gerd Hoffmann 
Signed-off-by: Fei Li 
---
 hw/usb/ccid-card-emulated.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index f8ff7ff4a3..9245b4fcad 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -32,7 +32,6 @@
 #include "qemu/thread.h"
 #include "qemu/main-loop.h"
 #include "ccid.h"
-#include "qapi/error.h"
 
 #define DPRINTF(card, lvl, fmt, ...) \
 do {\
@@ -544,11 +543,15 @@ static void emulated_realize(CCIDCardState *base, Error 
**errp)
 error_setg(errp, "%s: failed to initialize vcard", TYPE_EMULATED_CCID);
 goto out2;
 }
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>event_thread_id, "ccid/event", event_thread,
-   card, QEMU_THREAD_JOINABLE, _abort);
-qemu_thread_create(>apdu_thread_id, "ccid/apdu", handle_apdu_thread,
-   card, QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(>event_thread_id, "ccid/event", event_thread,
+card, QEMU_THREAD_JOINABLE, errp)) {
+goto out2;
+}
+if (!qemu_thread_create(>apdu_thread_id, "ccid/apdu",
+handle_apdu_thread, card,
+QEMU_THREAD_JOINABLE, errp)) {
+goto out2;
+}
 
 out2:
 clean_event_notifier(card);
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 05/16] migration: unify error handling for process_incoming_migration_co

2018-12-25 Thread Fei Li
In the current code, if process_incoming_migration_co() fails we do
the same error handing: set the error state, close the source file,
do the cleanup for multifd, and then exit(EXIT_FAILURE). To make the
code clearer, add a "goto fail" to unify the error handling.

Cc: Markus Armbruster 
Cc: Dr. David Alan Gilbert 
Cc: Peter Xu 
Signed-off-by: Fei Li 
---
 migration/migration.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 5d322eb9d6..ded151b1bf 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -438,15 +438,13 @@ static void process_incoming_migration_co(void *opaque)
 /* Make sure all file formats flush their mutable metadata */
 bdrv_invalidate_cache_all(_err);
 if (local_err) {
-migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
-MIGRATION_STATUS_FAILED);
 error_report_err(local_err);
-exit(EXIT_FAILURE);
+goto fail;
 }
 
 if (colo_init_ram_cache() < 0) {
 error_report("Init ram cache failed");
-exit(EXIT_FAILURE);
+goto fail;
 }
 
 qemu_thread_create(>colo_incoming_thread, "COLO incoming",
@@ -461,20 +459,22 @@ static void process_incoming_migration_co(void *opaque)
 }
 
 if (ret < 0) {
-Error *local_err = NULL;
-
-migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
-  MIGRATION_STATUS_FAILED);
 error_report("load of migration failed: %s", strerror(-ret));
-qemu_fclose(mis->from_src_file);
-if (multifd_load_cleanup(_err) != 0) {
-error_report_err(local_err);
-}
-exit(EXIT_FAILURE);
+goto fail;
 }
 mis->bh = qemu_bh_new(process_incoming_migration_bh, mis);
 qemu_bh_schedule(mis->bh);
 mis->migration_incoming_co = NULL;
+return;
+fail:
+local_err = NULL;
+migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
+  MIGRATION_STATUS_FAILED);
+qemu_fclose(mis->from_src_file);
+if (multifd_load_cleanup(_err) != 0) {
+error_report_err(local_err);
+}
+exit(EXIT_FAILURE);
 }
 
 static void migration_incoming_setup(QEMUFile *f)
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 14/16] qemu_thread: supplement error handling for vnc_start_worker_thread

2018-12-25 Thread Fei Li
Supplement the error handling for vnc_thread_worker_thread: add
an Error parameter for it to propagate the error to its caller to
handle in case it fails, and make it return a Boolean to indicate
whether it succeeds.

Cc: Markus Armbruster 
Cc: Gerd Hoffmann 
Signed-off-by: Fei Li 
---
 ui/vnc-jobs.c | 17 +++--
 ui/vnc-jobs.h |  2 +-
 ui/vnc.c  |  4 +++-
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
index 5712f1f501..35a652d1fd 100644
--- a/ui/vnc-jobs.c
+++ b/ui/vnc-jobs.c
@@ -332,16 +332,21 @@ static bool vnc_worker_thread_running(void)
 return queue; /* Check global queue */
 }
 
-void vnc_start_worker_thread(void)
+bool vnc_start_worker_thread(Error **errp)
 {
 VncJobQueue *q;
 
-if (vnc_worker_thread_running())
-return ;
+if (vnc_worker_thread_running()) {
+goto out;
+}
 
 q = vnc_queue_init();
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>thread, "vnc_worker", vnc_worker_thread,
-   q, QEMU_THREAD_DETACHED, _abort);
+if (!qemu_thread_create(>thread, "vnc_worker", vnc_worker_thread,
+q, QEMU_THREAD_DETACHED, errp)) {
+vnc_queue_clear(q);
+return false;
+}
 queue = q; /* Set global queue */
+out:
+return true;
 }
diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h
index 59f66bcc35..14640593db 100644
--- a/ui/vnc-jobs.h
+++ b/ui/vnc-jobs.h
@@ -37,7 +37,7 @@ void vnc_job_push(VncJob *job);
 void vnc_jobs_join(VncState *vs);
 
 void vnc_jobs_consume_buffer(VncState *vs);
-void vnc_start_worker_thread(void);
+bool vnc_start_worker_thread(Error **errp);
 
 /* Locks */
 static inline int vnc_trylock_display(VncDisplay *vd)
diff --git a/ui/vnc.c b/ui/vnc.c
index 0c1b477425..0ffe9e6a5d 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3236,7 +3236,9 @@ void vnc_display_init(const char *id, Error **errp)
 vd->connections_limit = 32;
 
 qemu_mutex_init(>mutex);
-vnc_start_worker_thread();
+if (!vnc_start_worker_thread(errp)) {
+return;
+}
 
 vd->dcl.ops = _ops;
 register_displaychangelistener(>dcl);
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 08/16] qemu_thread: supplement error handling for qmp_dump_guest_memory

2018-12-25 Thread Fei Li
Utilize the existed errp to propagate the error instead of the
temporary _abort.

Cc: Markus Armbruster 
Cc: Marc-André Lureau 
Signed-off-by: Fei Li 
---
 dump.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/dump.c b/dump.c
index c35d6ddd22..ef5ea324fa 100644
--- a/dump.c
+++ b/dump.c
@@ -2020,9 +2020,10 @@ void qmp_dump_guest_memory(bool paging, const char *file,
 if (detach_p) {
 /* detached dump */
 s->detached = true;
-/* TODO: let the further caller handle the error instead of abort() */
-qemu_thread_create(>dump_thread, "dump_thread", dump_thread,
-   s, QEMU_THREAD_DETACHED, _abort);
+if (!qemu_thread_create(>dump_thread, "dump_thread", dump_thread,
+   s, QEMU_THREAD_DETACHED, errp)) {
+/* keep 'if' here in case there is further error handling logic */
+}
 } else {
 /* sync dump */
 dump_process(s, errp);
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 02/16] migration: fix the multifd code when receiving less channels

2018-12-25 Thread Fei Li
In our current code, when multifd is used during migration, if there
is an error before the destination receives all new channels, the
source keeps running, however the destination does not exit but keeps
waiting until the source is killed deliberately.

Fix this by dumping the specific error and let users decide whether
to quit from the destination side when failing to receive packet via
some channel. And update the comment for multifd_recv_new_channel().

Cc: Dr. David Alan Gilbert 
Cc: Peter Xu 
Cc: Markus Armbruster 
Signed-off-by: Fei Li 
Reviewed-by: Peter Xu 
---
 migration/channel.c   | 11 ++-
 migration/migration.c |  9 +++--
 migration/migration.h |  2 +-
 migration/ram.c   | 17 ++---
 migration/ram.h   |  2 +-
 5 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/migration/channel.c b/migration/channel.c
index 33e0e9b82f..20e4c8e2dc 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -30,6 +30,7 @@
 void migration_channel_process_incoming(QIOChannel *ioc)
 {
 MigrationState *s = migrate_get_current();
+Error *local_err = NULL;
 
 trace_migration_set_incoming_channel(
 ioc, object_get_typename(OBJECT(ioc)));
@@ -38,13 +39,13 @@ void migration_channel_process_incoming(QIOChannel *ioc)
 *s->parameters.tls_creds &&
 !object_dynamic_cast(OBJECT(ioc),
  TYPE_QIO_CHANNEL_TLS)) {
-Error *local_err = NULL;
 migration_tls_channel_process_incoming(s, ioc, _err);
-if (local_err) {
-error_report_err(local_err);
-}
 } else {
-migration_ioc_process_incoming(ioc);
+migration_ioc_process_incoming(ioc, _err);
+}
+
+if (local_err) {
+error_report_err(local_err);
 }
 }
 
diff --git a/migration/migration.c b/migration/migration.c
index ffc4d9e556..24cb4b9d0d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -541,7 +541,7 @@ void migration_fd_process_incoming(QEMUFile *f)
 migration_incoming_process();
 }
 
-void migration_ioc_process_incoming(QIOChannel *ioc)
+void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
 {
 MigrationIncomingState *mis = migration_incoming_get_current();
 bool start_migration;
@@ -563,9 +563,14 @@ void migration_ioc_process_incoming(QIOChannel *ioc)
  */
 start_migration = !migrate_use_multifd();
 } else {
+Error *local_err = NULL;
 /* Multiple connections */
 assert(migrate_use_multifd());
-start_migration = multifd_recv_new_channel(ioc);
+start_migration = multifd_recv_new_channel(ioc, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
 }
 
 if (start_migration) {
diff --git a/migration/migration.h b/migration/migration.h
index e413d4d8b6..02b7304610 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -229,7 +229,7 @@ struct MigrationState
 void migrate_set_state(int *state, int old_state, int new_state);
 
 void migration_fd_process_incoming(QEMUFile *f);
-void migration_ioc_process_incoming(QIOChannel *ioc);
+void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
 void migration_incoming_process(void);
 
 bool  migration_has_all_channels(void);
diff --git a/migration/ram.c b/migration/ram.c
index 7e7deec4d8..1671dedc97 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1322,8 +1322,13 @@ bool multifd_recv_all_channels_created(void)
 return thread_count == atomic_read(_recv_state->count);
 }
 
-/* Return true if multifd is ready for the migration, otherwise false */
-bool multifd_recv_new_channel(QIOChannel *ioc)
+/*
+ * Try to receive all multifd channels to get ready for the migration.
+ * - Return true and do not set @errp when correctly receving all channels;
+ * - Return false and do not set @errp when correctly receiving the current 
one;
+ * - Return false and set @errp when failing to receive the current channel.
+ */
+bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
 {
 MultiFDRecvParams *p;
 Error *local_err = NULL;
@@ -1332,6 +1337,10 @@ bool multifd_recv_new_channel(QIOChannel *ioc)
 id = multifd_recv_initial_packet(ioc, _err);
 if (id < 0) {
 multifd_recv_terminate_threads(local_err);
+error_propagate_prepend(errp, local_err,
+"failed to receive packet"
+" via multifd channel %d: ",
+atomic_read(_recv_state->count));
 return false;
 }
 
@@ -1340,6 +1349,7 @@ bool multifd_recv_new_channel(QIOChannel *ioc)
 error_setg(_err, "multifd: received id '%d' already setup'",
id);
 multifd_recv_terminate_threads(local_err);
+error_propagate(errp, local_err);
 return false;
 }
 p->c = ioc;
@@ -1351,7 +1361,8 @@ bool multifd_recv_new_channel(QIOChannel *ioc)
 

[Qemu-devel] [PATCH for-4.0 v9 09/16] qemu_thread: supplement error handling for pci_edu_realize

2018-12-25 Thread Fei Li
Utilize the existed errp to propagate the error instead of the
temporary _abort.

Cc: Markus Armbruster 
Cc: Jiri Slaby 
Signed-off-by: Fei Li 
---
 hw/misc/edu.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/misc/edu.c b/hw/misc/edu.c
index 3f4ba7ded3..011fe6e0b7 100644
--- a/hw/misc/edu.c
+++ b/hw/misc/edu.c
@@ -356,9 +356,10 @@ static void pci_edu_realize(PCIDevice *pdev, Error **errp)
 
 qemu_mutex_init(>thr_mutex);
 qemu_cond_init(>thr_cond);
-/* TODO: let the further caller handle the error instead of abort() here */
-qemu_thread_create(>thread, "edu", edu_fact_thread,
-   edu, QEMU_THREAD_JOINABLE, _abort);
+if (!qemu_thread_create(>thread, "edu", edu_fact_thread,
+edu, QEMU_THREAD_JOINABLE, errp)) {
+return;
+}
 
 memory_region_init_io(>mmio, OBJECT(edu), _mmio_ops, edu,
 "edu-mmio", 1 * MiB);
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 04/16] migration: add more error handling for postcopy_ram_enable_notify

2018-12-25 Thread Fei Li
Call postcopy_ram_incoming_cleanup() to do the cleanup when
postcopy_ram_enable_notify fails. Besides, report the error
message when qemu_ram_foreach_migratable_block() fails.

Cc: Dr. David Alan Gilbert 
Signed-off-by: Fei Li 
Reviewed-by: Dr. David Alan Gilbert 
---
 migration/postcopy-ram.c | 1 +
 migration/savevm.c   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index e5c02a32c5..fa09dba534 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -1117,6 +1117,7 @@ int postcopy_ram_enable_notify(MigrationIncomingState 
*mis)
 
 /* Mark so that we get notified of accesses to unwritten areas */
 if (qemu_ram_foreach_migratable_block(ram_block_enable_notify, mis)) {
+error_report("ram_block_enable_notify failed");
 return -1;
 }
 
diff --git a/migration/savevm.c b/migration/savevm.c
index 9e45fb4f3f..d784e8aa40 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1729,6 +1729,7 @@ static int 
loadvm_postcopy_handle_listen(MigrationIncomingState *mis)
  */
 if (migrate_postcopy_ram()) {
 if (postcopy_ram_enable_notify(mis)) {
+postcopy_ram_incoming_cleanup(mis);
 return -1;
 }
 }
-- 
2.13.7




[Qemu-devel] [PATCH for-4.0 v9 00/16] qemu_thread_create: propagate the error to callers to handle

2018-12-25 Thread Fei Li
Hi,

This idea comes from BiteSizedTasks, and this patch series implement
the error checking of qemu_thread_create: make qemu_thread_create
return a flag to indicate if it succeeded rather than failing with an
error; make all callers check it.

The first and the last patch fixes some segmentation faults occured
during the debugging.   The 6/7 patch modifies the
qemu_thread_create() by passing _abort and makes it return a
bool to all direct callers to indicate if it succeeds.   The next 9
patches will improve on _abort for callers who can handle more
properly.   The middle four fix some migration issues.

BTW, I am leaving my current company now, and will use
"Fei Li " to continue with this patch series.

Please help to review, thanks a lot! :)

v9:
- To ease the review and involve the appropriate maintainers, split
  the previous 6/7 patch into 10 patches: the 6/16 patch passes
  the _abort to qemu_thread_create() everywhere, and the next
  9 patches will improve on _abort for callers who need.
- Add a new patch 5/7 to unify error handling for
  process_incoming_migration_co().
- Merge the previous 2/7 to current 7/16 to collaboratively handle
  for qemu_X_start_vcpu and for the qemu_init_vpcu in each arch.
- Add comment for multifd_recv_new_channel() in current patch 2/7.

v8:
- Remove previous two patches trying to fix the multifd issue on the
  source side, as we are still waiting for maintainer's opinions.
- Use atomic_read to get multifd_recv_state->count in patch 3/7.
- Get three more "Reviewed-by:".

v7:
- Split the previous multifd-migration into two patches: the src and
  the dst. For the dst, only dump the error instead of quitting.
- Safely do the cleanup for postcopy_ram_enable_notify().
- Split the previous migration-error-handling patch into two patches.

v6:
- Add a new migration-multifd related patch. BTW, delete the previous
  vnc related patch as it has been upstreamed.
- Use error_setg_errno() to set the errno when qemu_thread_create()
  fails for both Linux and Windows implementation.
- Optimize the first patch, less codes are needed

v5:
- Remove `errno = err` in qemu_thread_create() for Linux, and change
  `return errno` to `return -1` in qemu_signal_init() to indicate
  the error in case qemu_thread_create() fails.
- Delete the v4-added qemu_cond/mutex_destroy() in iothread_complete()
  as the destroy() will be done by its callers' object_unref().

v4:
- Separate the migration compression patch from this series
- Add one more error handling patch related with migration
- Add more cleaning up code for touched functions

v3:
- Add two migration related patches to fix the segmentaion fault
- Extract the segmentation fault fix from v2's last patch to be a 
  separate patch

v2:
- Pass errp straightly instead of using a local_err & error_propagate
- Return a bool: false/true to indicate if one function succeeds
- Merge v1's last two patches into one to avoid the compile error
- Fix one omitted error in patch1 and update some error messages


Fei Li (16):
  Fix segmentation fault when qemu_signal_init fails
  migration: fix the multifd code when receiving less channels
  migration: remove unused _err parameter in multifd_save_cleanup
  migration: add more error handling for postcopy_ram_enable_notify
  migration: unify error handling for process_incoming_migration_co
  qemu_thread: Make qemu_thread_create() handle errors properly
  qemu_thread: supplement error handling for qemu_X_start_vcpu
  qemu_thread: supplement error handling for qmp_dump_guest_memory
  qemu_thread: supplement error handling for pci_edu_realize
  qemu_thread: supplement error handling for h_resize_hpt_prepare
  qemu_thread: supplement error handling for emulated_realize
  qemu_thread: supplement error handling for
iothread_complete/qemu_signalfd_compat
  qemu_thread: supplement error handling for migration
  qemu_thread: supplement error handling for vnc_start_worker_thread
  qemu_thread: supplement error handling for touch_all_pages
  qemu_thread_join: fix segmentation fault

 accel/tcg/user-exec-stub.c  |  3 +-
 cpus.c  | 79 ++---
 dump.c  |  6 ++--
 hw/misc/edu.c   |  7 ++--
 hw/ppc/spapr_hcall.c| 10 --
 hw/rdma/rdma_backend.c  |  3 +-
 hw/usb/ccid-card-emulated.c | 14 +---
 include/qemu/thread.h   |  4 +--
 include/qom/cpu.h   |  2 +-
 io/task.c   |  3 +-
 iothread.c  | 16 ++---
 migration/channel.c | 11 +++---
 migration/migration.c   | 68 ++-
 migration/migration.h   |  2 +-
 migration/postcopy-ram.c| 15 ++--
 migration/ram.c | 68 ---
 migration/ram.h |  4 +--
 migration/savevm.c  | 12 +--
 target/alpha/cpu.c  |  4 ++-
 target/arm/cpu.c  

[Qemu-devel] [PATCH for-4.0 v9 01/16] Fix segmentation fault when qemu_signal_init fails

2018-12-25 Thread Fei Li
When qemu_signal_init() fails in qemu_init_main_loop(), we return
without setting an error.  Its callers crash then when they try to
report the error with error_report_err().

To avoid such segmentation fault, add a new Error parameter to make
the call trace to propagate the err to the final caller.

Fixes: 2f78e491d7b46542158ce0b8132ee4e05bc0ade4
Cc: Paolo Bonzini 
Signed-off-by: Fei Li 
Reviewed-by: Fam Zheng 
Reviewed-by: Markus Armbruster 
---
 util/main-loop.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/util/main-loop.c b/util/main-loop.c
index affe0403c5..443cb4cfe8 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -71,7 +71,7 @@ static void sigfd_handler(void *opaque)
 }
 }
 
-static int qemu_signal_init(void)
+static int qemu_signal_init(Error **errp)
 {
 int sigfd;
 sigset_t set;
@@ -96,7 +96,7 @@ static int qemu_signal_init(void)
 sigdelset(, SIG_IPI);
 sigfd = qemu_signalfd();
 if (sigfd == -1) {
-fprintf(stderr, "failed to create signalfd\n");
+error_setg_errno(errp, errno, "failed to create signalfd");
 return -errno;
 }
 
@@ -109,7 +109,7 @@ static int qemu_signal_init(void)
 
 #else /* _WIN32 */
 
-static int qemu_signal_init(void)
+static int qemu_signal_init(Error **errp)
 {
 return 0;
 }
@@ -148,7 +148,7 @@ int qemu_init_main_loop(Error **errp)
 
 init_clocks(qemu_timer_notify_cb);
 
-ret = qemu_signal_init();
+ret = qemu_signal_init(errp);
 if (ret) {
 return ret;
 }
-- 
2.13.7




[Qemu-devel] [PATCH v1] dump: Set correct vaddr for ELF dump

2018-12-25 Thread Jon Doron
vaddr needs to be equal to the paddr since the dump file represents the
physical memory image.

Without setting vaddr correctly, GDB would load all the different memory
regions on top of each other to vaddr 0, thus making GDB showing the wrong
memory data for a given address.

Signed-off-by: Jon Doron 
---
 dump.c   | 4 ++--
 scripts/dump-guest-memory.py | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/dump.c b/dump.c
index 4ec94c5e25..bf77a119ea 100644
--- a/dump.c
+++ b/dump.c
@@ -192,7 +192,7 @@ static void write_elf64_load(DumpState *s, MemoryMapping 
*memory_mapping,
 phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
 phdr.p_filesz = cpu_to_dump64(s, filesz);
 phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
-phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr);
+phdr.p_vaddr = phdr.p_paddr;
 
 assert(memory_mapping->length >= filesz);
 
@@ -216,7 +216,7 @@ static void write_elf32_load(DumpState *s, MemoryMapping 
*memory_mapping,
 phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
 phdr.p_filesz = cpu_to_dump32(s, filesz);
 phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
-phdr.p_vaddr = cpu_to_dump32(s, memory_mapping->virt_addr);
+phdr.p_vaddr = phdr.p_paddr;
 
 assert(memory_mapping->length >= filesz);
 
diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
index 198cd0fe40..2c587cbefc 100644
--- a/scripts/dump-guest-memory.py
+++ b/scripts/dump-guest-memory.py
@@ -163,6 +163,7 @@ class ELF(object):
 phdr = get_arch_phdr(self.endianness, self.elfclass)
 phdr.p_type = p_type
 phdr.p_paddr = p_paddr
+phdr.p_vaddr = p_paddr
 phdr.p_filesz = p_size
 phdr.p_memsz = p_size
 self.segments.append(phdr)
-- 
2.19.2




Re: [Qemu-devel] [PATCH for-4.0 v8 6/7] qemu_thread_create: propagate the error to callers to handle

2018-12-25 Thread Fei Li

Hi all,

As I am leaving my current company and most reviewers are on holiday,
I'd like to send a new version now:
v9: "qemu_thread: Make qemu_thread_create() handle errors properly",
although some details like whether it is appropriate to report the error
to be seen by the management layer. And I will use my new personal
email address (shirley17...@gmail.com ) 
to follow the new version. :)


Merry Christmas, and have a nice day, thanks all!
Fei

On 12/24/2018 02:53 PM, Fei Li wrote:



On 12/24/2018 11:34 AM, Peter Xu wrote:

On Fri, Dec 21, 2018 at 05:36:57PM +0800, Fei Li wrote:

On 12/19/2018 08:14 PM, Fei Li wrote:

On 12/19/2018 06:10 PM, Markus Armbruster wrote:

Fei Li  writes:


On 12/13/2018 03:26 PM, Markus Armbruster wrote:
There's a question for David Gibson inline.  Please search for 
/ppc/.


Fei Li  writes:

Make qemu_thread_create() return a Boolean to indicate if it 
succeeds
rather than failing with an error. And add an Error parameter 
to hold

the error message and let the callers handle it.

The "rather than failing with an error" is misleading. Before the
patch, we report to stderr and abort().  What about:

   qemu-thread: Make qemu_thread_create() handle errors 
properly


   qemu_thread_create() abort()s on error.  Not nice. Give it a
   return value and an Error ** argument, so it can
return success /
   failure.

A nice commit-amend! Thanks!

Still missing from the commit message then: how you update
the callers.

Yes, agree. I think the-how should also be noted here, like
- propagating the err to callers whose call trace already have the
Error paramater;
- just add an _abort for qemu_thread_create() and make it a
"TODO: xxx";

Let's see below.


Cc: Markus Armbruster 
Cc: Daniel P. Berrangé 
Cc: Dr. David Alan Gilbert 
Signed-off-by: Fei Li 
---
    cpus.c  | 45
-
    dump.c  |  6 +++--
    hw/misc/edu.c   |  6 +++--
    hw/ppc/spapr_hcall.c    | 10 +++--
    hw/rdma/rdma_backend.c  |  4 +++-
    hw/usb/ccid-card-emulated.c | 16 ++
    include/qemu/thread.h   |  4 ++--
    io/task.c   |  3 ++-
    iothread.c  | 16 +-
    migration/migration.c   | 54
+
    migration/postcopy-ram.c    | 14 ++--
    migration/ram.c | 40 
-

    migration/savevm.c  | 11 ++---
    tests/atomic_add-bench.c    |  3 ++-
    tests/iothread.c    |  2 +-
    tests/qht-bench.c   |  3 ++-
    tests/rcutorture.c  |  3 ++-
    tests/test-aio.c    |  2 +-
    tests/test-rcu-list.c   |  3 ++-
    ui/vnc-jobs.c   | 17 +-
    ui/vnc-jobs.h   |  2 +-
    ui/vnc.c    |  4 +++-
    util/compatfd.c | 12 --
    util/oslib-posix.c  | 17 ++
    util/qemu-thread-posix.c    | 24 +---
    util/qemu-thread-win32.c    | 16 ++
    util/rcu.c  |  3 ++-
    util/thread-pool.c  |  4 +++-
    28 files changed, 243 insertions(+), 101 deletions(-)


...snip, and only leave the three uncertain small topics...

diff --git a/migration/ram.c b/migration/ram.c
index 658dfa88a3..6e0cccf066 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -473,6 +473,7 @@ static void 
compress_threads_save_cleanup(void)

    static int compress_threads_save_setup(void)
    {
    int i, thread_count;
+    Error *local_err = NULL;
  if (!migrate_use_compression()) {
    return 0;
@@ -502,9 +503,12 @@ static int compress_threads_save_setup(void)
    comp_param[i].quit = false;
qemu_mutex_init(_param[i].mutex);
    qemu_cond_init(_param[i].cond);
-    qemu_thread_create(compress_threads + i, "compress",
-   do_data_compress, comp_param + i,
-   QEMU_THREAD_JOINABLE);
+    if (!qemu_thread_create(compress_threads + i, "compress",
+    do_data_compress, comp_param + i,
+ QEMU_THREAD_JOINABLE, _err)) {
+    error_reportf_err(local_err, "failed to
create do_data_compress: ");
+    goto exit;

[1]


+    }
    }
    return 0;

Reviewing the migration changes is getting tiresome...
Yes, indeed, the migration involves a lot! Thanks so much for 
helping

to review!

    Is reporting the
error appropriate here, and why?
I think the qemu monitor should display the obvious and exact 
failing

reason for administrators, esp considering that qemu_thread_create()
itself does not print any message thus we have no idea which direct
function fails if gdb is not enabled.
IOW, I think David's answer to that ppc's error_reportf_err() also
apply here:

"The error returns are for the guest, the reported errors are for 
the

guest 

Re: [Qemu-devel] [PATCH] hw/core: fix whitespace in a sentence

2018-12-25 Thread Philippe Mathieu-Daudé
On 12/24/18 4:49 PM, Wainer dos Santos Moschetta wrote:
> Signed-off-by: Wainer dos Santos Moschetta 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  hw/core/machine.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 4439ea663f..a0beeeb2a9 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -591,7 +591,7 @@ static void machine_class_init(ObjectClass *oc, void 
> *data)
>  object_class_property_add_bool(oc, "dump-guest-core",
>  machine_get_dump_guest_core, machine_set_dump_guest_core, 
> _abort);
>  object_class_property_set_description(oc, "dump-guest-core",
> -"Include guest memory in  a core dump", _abort);
> +"Include guest memory in a core dump", _abort);
>  
>  object_class_property_add_bool(oc, "mem-merge",
>  machine_get_mem_merge, machine_set_mem_merge, _abort);
> 



Re: [Qemu-devel] [PATCH v2] softfloat: enforce softfloat if the host's FMA is broken

2018-12-25 Thread Philippe Mathieu-Daudé
On Tue, Dec 25, 2018 at 12:15 PM Philippe Mathieu-Daudé  wrote:
>
> Hi Emilio,
>
> On 12/25/18 8:03 AM, Emilio G. Cota wrote:
> > The added branch to the FMA ops is marked as unlikely and therefore
> > its impact on performance (measured with fp-bench) is within noise range
> > when measured on an Intel(R) Xeon(R) Gold 6142 CPU @ 2.60GHz.
>
> Did you forget to write here the result of your measurements?
>
> >
> > Reported-by: Laurent Desnogues 
>
> Suggested-by: Richard Henderson 
>
> > Signed-off-by: Emilio G. Cota 
>
> Reviewed-by: Philippe Mathieu-Daudé 

Oops I meant:
Reviewed-by: Philippe Mathieu-Daudé 

>
> > ---
> > v2: drop the cpuid bits, since that work (1) is only a performance
> > optimization, not a correctness fix and (2) requires additional
> > consolidation work that I do not have time to do right now.
> >
> >  fpu/softfloat.c | 33 +
> >  1 file changed, 33 insertions(+)
> >
> > diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> > index 59eac97d10..9132d7a0b0 100644
> > --- a/fpu/softfloat.c
> > +++ b/fpu/softfloat.c
> > @@ -1542,6 +1542,8 @@ soft_f64_muladd(float64 a, float64 b, float64 c, int 
> > flags,
> >  return float64_round_pack_canonical(pr, status);
> >  }
> >
> > +static bool force_soft_fma;
> > +
> >  float32 QEMU_FLATTEN
> >  float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status 
> > *s)
> >  {
> > @@ -1562,6 +1564,11 @@ float32_muladd(float32 xa, float32 xb, float32 xc, 
> > int flags, float_status *s)
> >  if (unlikely(!f32_is_zon3(ua, ub, uc))) {
> >  goto soft;
> >  }
> > +
> > +if (unlikely(force_soft_fma)) {
> > +goto soft;
> > +}
> > +
> >  /*
> >   * When (a || b) == 0, there's no need to check for under/over flow,
> >   * since we know the addend is (normal || 0) and the product is 0.
> > @@ -1623,6 +1630,11 @@ float64_muladd(float64 xa, float64 xb, float64 xc, 
> > int flags, float_status *s)
> >  if (unlikely(!f64_is_zon3(ua, ub, uc))) {
> >  goto soft;
> >  }
> > +
> > +if (unlikely(force_soft_fma)) {
> > +goto soft;
> > +}
> > +
> >  /*
> >   * When (a || b) == 0, there's no need to check for under/over flow,
> >   * since we know the addend is (normal || 0) and the product is 0.
> > @@ -7974,3 +7986,24 @@ float128 float128_scalbn(float128 a, int n, 
> > float_status *status)
> >   , status);
> >
> >  }
> > +
> > +static void __attribute__((constructor)) softfloat_init(void)
> > +{
> > +union_float64 ua, ub, uc, ur;
> > +
> > +if (QEMU_NO_HARDFLOAT) {
> > +return;
> > +}
> > +/*
> > + * Test that the host's FMA is not obviously broken. For example,
> > + * glibc < 2.23 can perform an incorrect FMA on certain hosts; see
> > + *   https://sourceware.org/bugzilla/show_bug.cgi?id=13304
> > + */
> > +ua.s = 0x0021ULL;
> > +ub.s = 0x3ca0ULL;
> > +uc.s = 0x0020ULL;
> > +ur.h = fma(ua.h, ub.h, uc.h);
> > +if (ur.s != 0x0021ULL) {
> > +force_soft_fma = true;
> > +}
> > +}
> >



Re: [Qemu-devel] [PATCH v2] softfloat: enforce softfloat if the host's FMA is broken

2018-12-25 Thread Philippe Mathieu-Daudé
Hi Emilio,

On 12/25/18 8:03 AM, Emilio G. Cota wrote:
> The added branch to the FMA ops is marked as unlikely and therefore
> its impact on performance (measured with fp-bench) is within noise range
> when measured on an Intel(R) Xeon(R) Gold 6142 CPU @ 2.60GHz.

Did you forget to write here the result of your measurements?

> 
> Reported-by: Laurent Desnogues 

Suggested-by: Richard Henderson 

> Signed-off-by: Emilio G. Cota 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
> v2: drop the cpuid bits, since that work (1) is only a performance
> optimization, not a correctness fix and (2) requires additional
> consolidation work that I do not have time to do right now.
> 
>  fpu/softfloat.c | 33 +
>  1 file changed, 33 insertions(+)
> 
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 59eac97d10..9132d7a0b0 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -1542,6 +1542,8 @@ soft_f64_muladd(float64 a, float64 b, float64 c, int 
> flags,
>  return float64_round_pack_canonical(pr, status);
>  }
>  
> +static bool force_soft_fma;
> +
>  float32 QEMU_FLATTEN
>  float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status 
> *s)
>  {
> @@ -1562,6 +1564,11 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int 
> flags, float_status *s)
>  if (unlikely(!f32_is_zon3(ua, ub, uc))) {
>  goto soft;
>  }
> +
> +if (unlikely(force_soft_fma)) {
> +goto soft;
> +}
> +
>  /*
>   * When (a || b) == 0, there's no need to check for under/over flow,
>   * since we know the addend is (normal || 0) and the product is 0.
> @@ -1623,6 +1630,11 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int 
> flags, float_status *s)
>  if (unlikely(!f64_is_zon3(ua, ub, uc))) {
>  goto soft;
>  }
> +
> +if (unlikely(force_soft_fma)) {
> +goto soft;
> +}
> +
>  /*
>   * When (a || b) == 0, there's no need to check for under/over flow,
>   * since we know the addend is (normal || 0) and the product is 0.
> @@ -7974,3 +7986,24 @@ float128 float128_scalbn(float128 a, int n, 
> float_status *status)
>   , status);
>  
>  }
> +
> +static void __attribute__((constructor)) softfloat_init(void)
> +{
> +union_float64 ua, ub, uc, ur;
> +
> +if (QEMU_NO_HARDFLOAT) {
> +return;
> +}
> +/*
> + * Test that the host's FMA is not obviously broken. For example,
> + * glibc < 2.23 can perform an incorrect FMA on certain hosts; see
> + *   https://sourceware.org/bugzilla/show_bug.cgi?id=13304
> + */
> +ua.s = 0x0021ULL;
> +ub.s = 0x3ca0ULL;
> +uc.s = 0x0020ULL;
> +ur.h = fma(ua.h, ub.h, uc.h);
> +if (ur.s != 0x0021ULL) {
> +force_soft_fma = true;
> +}
> +}
> 



Re: [Qemu-devel] [PATCH v2 27/52] audio: use size_t where makes sense

2018-12-25 Thread Philippe Mathieu-Daudé
Hi Zoltán,

On 12/23/18 9:52 PM, Kővágó, Zoltán wrote:
> Signed-off-by: Kővágó, Zoltán 
> ---
>  audio/alsaaudio.c   |   8 +-
>  audio/audio.c   | 162 
>  audio/audio.h   |   4 +-
>  audio/audio_int.h   |  22 +++---
>  audio/audio_template.h  |   6 +-
>  audio/mixeng.h  |  11 ++-
>  audio/ossaudio.c|  18 ++---
>  audio/paaudio.c |   8 +-
>  audio/rate_template.h   |   2 +-
>  audio/sdlaudio.c|   3 +-
>  audio/wavaudio.c|   4 +-
>  include/sysemu/replay.h |   4 +-
>  replay/replay-audio.c   |  16 ++--
>  13 files changed, 133 insertions(+), 135 deletions(-)
> 
> diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
> index 19de7d01cb..69e7a3868c 100644
> --- a/audio/alsaaudio.c
> +++ b/audio/alsaaudio.c
> @@ -747,8 +747,8 @@ static int alsa_init_out(HWVoiceOut *hw, struct 
> audsettings *as,
>  
>  alsa->pcm_buf = audio_calloc(__func__, obt.samples, 1 << hw->info.shift);
>  if (!alsa->pcm_buf) {
> -dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
> -   hw->samples, 1 << hw->info.shift);
> +dolog("Could not allocate DAC buffer (%zu samples, each %d bytes)\n",
> +  hw->samples, 1 << hw->info.shift);
>  alsa_anal_close1 ();
>  return -1;
>  }
> @@ -849,8 +849,8 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings 
> *as, void *drv_opaque)
>  
>  alsa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift);
>  if (!alsa->pcm_buf) {
> -dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
> -   hw->samples, 1 << hw->info.shift);
> +dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n",
> +  hw->samples, 1 << hw->info.shift);
>  alsa_anal_close1 ();
>  return -1;
>  }
> diff --git a/audio/audio.c b/audio/audio.c
> index 1ea80ba6a7..27a8a31a64 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -530,10 +530,10 @@ static int audio_attach_capture (HWVoiceOut *hw)
>  /*
>   * Hard voice (capture)
>   */
> -static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
> +static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw)
>  {
>  SWVoiceIn *sw;
> -int m = hw->total_samples_captured;
> +size_t m = hw->total_samples_captured;
>  
>  for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
>  if (sw->active) {
> @@ -543,28 +543,28 @@ static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
>  return m;
>  }
>  
> -int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
> +size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)
>  {
> -int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
> -if (audio_bug(__func__, live < 0 || live > hw->samples)) {
> -dolog ("live=%d hw->samples=%d\n", live, hw->samples);
> +size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
> +if (audio_bug(__func__, live > hw->samples)) {
> +dolog("live=%zu hw->samples=%zu\n", live, hw->samples);
>  return 0;
>  }
>  return live;
>  }
>  
> -int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
> -   int live, int pending)
> +size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf,
> + size_t live, size_t pending)
>  {
> -int left = hw->samples - pending;
> -int len = MIN (left, live);
> -int clipped = 0;
> +size_t left = hw->samples - pending;
> +size_t len = MIN (left, live);
> +size_t clipped = 0;
>  
>  while (len) {
>  struct st_sample *src = hw->mix_buf + hw->rpos;
>  uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift);
> -int samples_till_end_of_buf = hw->samples - hw->rpos;
> -int samples_to_clip = MIN (len, samples_till_end_of_buf);
> +size_t samples_till_end_of_buf = hw->samples - hw->rpos;
> +size_t samples_to_clip = MIN (len, samples_till_end_of_buf);
>  
>  hw->clip (dst, src, samples_to_clip);
>  
> @@ -578,14 +578,14 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void 
> *pcm_buf,
>  /*
>   * Soft voice (capture)
>   */
> -static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
> +static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn *sw)
>  {
>  HWVoiceIn *hw = sw->hw;
> -int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
> -int rpos;
> +ssize_t live = hw->total_samples_captured - 
> sw->total_hw_samples_acquired;
> +ssize_t rpos;
>  
>  if (audio_bug(__func__, live < 0 || live > hw->samples)) {
> -dolog ("live=%d hw->samples=%d\n", live, hw->samples);
> +dolog("live=%zu hw->samples=%zu\n", live, hw->samples);
>  return 0;
>  }
>  
> @@ -598,17 +598,17 @@ static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
>  }
>  }
>  
> -static int audio_pcm_sw_read(SWVoiceIn *sw, void *buf, int size)
> +static size_t 

Re: [Qemu-devel] [PATCH v2 52/52] usbaudio: change playback counters to 64 bit

2018-12-25 Thread Philippe Mathieu-Daudé
On 12/23/18 9:52 PM, Kővágó, Zoltán wrote:
> With stereo playback, they need about 375 minutes of continuous audio
> playback to overflow, which is usually not a problem (as stopping and
> later resuming playback resets the counters).  But with 7.1 audio, they
> only need about 95 minutes to overflow.
> 
> After the overflow, the buf->prod % USBAUDIO_PACKET_SIZE(channels)
> assertion no longer holds true, which will result in overflowing the
> buffer.  With 64 bit variables, it would take about 762000 years to
> overflow.
> 
> Signed-off-by: Kővágó, Zoltán 
> ---
>  hw/usb/dev-audio.c | 12 +++-
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
> index 29475a2b70..45ffc3ebb3 100644
> --- a/hw/usb/dev-audio.c
> +++ b/hw/usb/dev-audio.c
> @@ -577,9 +577,9 @@ static const USBDesc desc_audio_multi = {
>  
>  struct streambuf {
>  uint8_t *data;
> -uint32_t size;
> -uint32_t prod;
> -uint32_t cons;
> +size_t size;
> +uint64_t prod;
> +uint64_t cons;

OK.

>  };
>  
>  static void streambuf_init(struct streambuf *buf, uint32_t size,
> @@ -600,12 +600,14 @@ static void streambuf_fini(struct streambuf *buf)
>  
>  static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t 
> channels)
>  {
> -uint32_t free = buf->size - (buf->prod - buf->cons);
> +uint64_t free = buf->size - (buf->prod - buf->cons);

I'd use ssize_t here.

>  
>  if (free < USBAUDIO_PACKET_SIZE(channels)) {
>  return 0;
>  }
>  
> +/* can happen if prod overflows */
> +assert(buf->prod % USBAUDIO_PACKET_SIZE(channels) == 0);
>  usb_packet_copy(p, buf->data + (buf->prod % buf->size),
>  USBAUDIO_PACKET_SIZE(channels));
>  buf->prod += USBAUDIO_PACKET_SIZE(channels);
> @@ -614,7 +616,7 @@ static int streambuf_put(struct streambuf *buf, USBPacket 
> *p, uint32_t channels)
>  
>  static uint8_t *streambuf_get(struct streambuf *buf, size_t *len)
>  {
> -uint32_t used = buf->prod - buf->cons;
> +uint64_t used = buf->prod - buf->cons;
>  uint8_t *data;
>  
>  if (!used) {

Eventually here:

ssize_t used = buf->prod - buf->cons;

if (used <= 0) {
return NULL;
}



Re: [Qemu-devel] [PATCH v2 00/52] Audio 5.1 patches

2018-12-25 Thread Philippe Mathieu-Daudé
Hi Zoltán,

On 12/23/18 9:51 PM, Kővágó, Zoltán wrote:
> I've updated my audio patchset to the current git master. Other than that not
> much happened since my last update [1], fixed a few small problems that I
> noticed while rebasing my patches.

For a such series with refactors and typedefs changes, I recommend you
to use/setup the scripts/git.orderfile script: Headers are showed first,
then the sources, which makes review easier (no need to constantly scroll).
No need to resend, but if you have to respin, this will be appreciated.

Regards,

Phil.



Re: [Qemu-devel] [PATCH v2 23/52] audio: remove audio_MIN, audio_MAX

2018-12-25 Thread Philippe Mathieu-Daudé
On 12/24/18 9:48 PM, Kővágó Zoltán wrote:
> On 2018-12-24 18:16, Philippe Mathieu-Daudé wrote:
>> On 12/24/18 3:16 AM, Zoltán Kővágó wrote:
>>> Hi Phil,
>>>
>>> On 2018-12-24 00:49, Philippe Mathieu-Daudé wrote:
 Hi Zoltán,

 On 12/23/18 9:51 PM, Kővágó, Zoltán wrote:
> There's already a MIN and MAX macro in include/qemu/osdep.h, use them
> instead.
>
> Signed-off-by: Kővágó, Zoltán 
>
> ---
>
> Changes from v1:
> * removed audio_MIN, audio_MAX macros
> ---
 [...]>
> diff --git a/audio/audio.h b/audio/audio.h
> index ccfef9e10a..bcbe56d639 100644
> --- a/audio/audio.h
> +++ b/audio/audio.h
> @@ -148,23 +148,6 @@ static inline void *advance (void *p, int incr)
>  return (d + incr);
>  }
>  
> -#ifdef __GNUC__
> -#define audio_MIN(a, b) ( __extension__ ({  \
> -__typeof (a) ta = a;\
> -__typeof (b) tb = b;\
> -((ta)>(tb)?(tb):(ta));  \
> -}))
> -
> -#define audio_MAX(a, b) ( __extension__ ({  \
> -__typeof (a) ta = a;\
> -__typeof (b) tb = b;\
> -((ta)<(tb)?(tb):(ta));  \
> -}))
> -#else
> -#define audio_MIN(a, b) ((a)>(b)?(b):(a))
> -#define audio_MAX(a, b) ((a)<(b)?(b):(a))
> -#endif
> -

 Those MIN/MAX are smarter than the ones in "qemu/osdep.h", I'd keep them
 moving them there.
>>>
>>> Yes, but only when using gcc (or clang when it emulates gcc).
>>> Unfortunately, they work differently when one of the expressions has
>>> side effects, which is a disaster waiting to happen (when some poor folk
>>> finally tries to compile it with a non-gcc compiler).
>>
>> We already use the typeof extension:
>>
>> $ git grep typeof|wc -l
>> 145
>>
>> For MIN/MAX I'd use rather use the __auto_type extension.
>>
>>> Or do we support any compilers beside gcc and clang? Because if not,
>>> sure, do it, just remove the #ifdef and keep only the gcc version.
>>
>> Yes, this is checked by the ./configure script:
>>
>> 1850 # Check whether the compiler matches our minimum requirements:
>> ...
>> 1859 #   error You need at least Clang v3.4 to compile QEMU
>> ...
>> 1864 #  error You need at least GCC v4.8 to compile QEMU
>> ...
>> 1867 # error You either need GCC or Clang to compiler QEMU
> 
> Fair enough. I've tried to check the documentation for supported
> compilers, but I haven't found any info. Well, I didn't look at the
> configure script, I admit that.

You haven't found any info because the minimum requirements are not well
documented on the wiki.

> 
> This is what I came up with:
> 
> #ifndef MIN
> #define MIN(a, b) ( __extension__ ({  \
> __auto_type _a = (a); \
> __auto_type _b = (b); \
> _a > _b ? _b : _a;\
> }))
> #endif
> #ifndef MAX
> #define MAX(a, b) ( __extension__ ({  \
> __auto_type _a = (a); \
> __auto_type _b = (b); \
> _a < _b ? _b : _a;\
> }))
> #endif
> 
> 
> I changed it a bit, since a and b are the macro parameters, so they are
> the variables that we should put into parentheses, and I renamed ta/tb
> to _a/_b, this way they're less likely to clobber some other variables.

Sounds good. Now the parentheses around a/b are not necessary.

I wonder however if it wouldn't be cleaner to previously add:

#ifdef MIN
# undef MIN
#endif

and for MAX, rather than only use these macros if undefs.

> To be honest, we could probably drop the __extension__ keyword too,
> we're not compiling with -pedantic. Other than audio_MIN and audio_MAX,
> it only appears in the DO_UPCAST macro.

Fine with me!

If you have this patch ready, you can send it alone out of this series,
no need to resend this whole series for this patch.

Thanks,

Phil.



Re: [Qemu-devel] [Qemu-block] do not lseek in qcow2 block_status

2018-12-25 Thread Vladimir Sementsov-Ogievskiy
24.12.2018 23:42, Nir Soffer wrote:
> On Mon, Dec 24, 2018 at 5:50 PM Vladimir Sementsov-Ogievskiy 
> mailto:vsement...@virtuozzo.com>> wrote:
> 
> Hi all!
> 
> bdrv_co_block_status digs bs->file for additional, more accurate search 
> for hole
> inside region, reported as DATA by bs since long-ago
> 
>     commit 5daa74a6ebce7543aaad178c4061dc087bb4c705
>     Author: Paolo Bonzini  >
>     Date:   Wed Sep 4 19:00:38 2013 +0200
> 
>         block: look for zero blocks in bs->file
> 
> This accuracy is not free: assume we have qcow2 disk. Actually, qcow2 
> knows,
> where are holes and where is data. But every block_status request calls 
> lseek
> additionally. Recently (and not the first time) we have faced the 
> situation,
> when lseek works slow. Of course, it is more about kernel implementation 
> of it,
> but why to involve lseek at all, if we have the information on qcow2 
> level?
> Assume a big disk, full of data, in any iterative copying block job (or 
> img
> convert) we'll call lseek(HOLE) on every iteration, and each of these 
> lseeks
> will have to iterate through all metadata up to the end of file. It's 
> obviously
> ineffective behavior.
> 
> I'm thinking about, how to properly workaround this thing, and I have some
> questions.
> 
> What are the cases, when we really need digging for zeros in bs->file?
> 
> Why in mirror we care about discard vs write_zeros, keeping in mind, that
> block_status will return ZERO instead for unallocated regions in some 
> cases, not
> related to guest view of disk (bdrv_unallocated_blocks_are_zero, backing 
> file is
> smaller than request.start)?
> 
> And finally, what to do with the problem?
> 
> Obviously, the simplest thing is just revert 5daa74a. What will it break?
> 
> Otherwise, I need to "revert" it in some cases, and, may be, it should be 
> a
> user-defined parameter.. Should it?  And what are the cases? We need to 
> "free"
> of 5daa74a at least qcow2.. But again, should it be format-specific 
> option, or
> something more generic?
> 
> Then, if it would be separate parameter, how should it interfere with
> want_zeros, or even, should it be want_zeros, reworked a bit to be 
> want_lseek?
> 
> 
> How about having 2 passes:
> 1. seek DATA/HOLE for entire image, keep result in memory
> 2. use the result when modifying ranges
Yes I think this is possible, but in case of qcow2, again, we don't need lseek 
at all,
and most optimal way is not call it.

> 
> This can also help allocation of clusters in a destination image:
> 1. seek DATA/HOLE in source image
> 2. allocate blocks in destination
> 3. convert using out of order writes *without* causing fragmentation in the 
> destination image.

Interesting idea, I've thought about something like this too. It should work 
for img convert, as
disk is static, but not for mirror..

Ok, for not static disk, we can implement cache filter driver for caching 
block_status results
(and to cache lseek results, we need to allow block_status return more 
information than requested,
like we do in NBD protocol), but again, for qcow2 we already have additional 
metadata layer which
is qcow2 itself, so lseek is redundant.

> 
> Here is an example using this approach when copying images to qem-nbd. This 
> is a pretty
> simplistic single threaded implementation in python, using "qemu-img map" to 
> find the data
> and zero ranges. It is faster than qemu-img convert :-)
> 
> https://github.com/oVirt/ovirt-imageio/blob/master/examples/nbd-client
> https://github.com/oVirt/ovirt-imageio/commit/bec7cb677e33c6d0a7645c367af3d56b70b666db
> 
> Nir


-- 
Best regards,
Vladimir


Re: [Qemu-devel] [PATCH] i386: mark the 'INTEL_PT' CPUID bit as unmigratable

2018-12-25 Thread Kang, Luwei
> From: Qemu-devel [mailto:qemu-devel-bounces+luwei.kang=intel@nongnu.org] 
> On Behalf Of Paolo Bonzini
> Sent: Friday, December 21, 2018 8:44 PM
> To: qemu-devel@nongnu.org
> Cc: ehabk...@redhat.com; qemu-sta...@nongnu.org
> Subject: [Qemu-devel] [PATCH] i386: mark the 'INTEL_PT' CPUID bit as 
> unmigratable
> 
> Marshaling of processor tracing MSRs is not yet implemented in QEMU, mark the 
> feature as unmigratable.

Hi Paolo,
I think Intel PT has supported live migration. I don't understand what you 
mean.

commit b77146e9a129bcdb60edc23639211679ae846a92
Author: Chao Peng 
Date:   Mon Mar 5 00:48:36 2018 +0800
i386: Add support to get/set/migrate Intel Processor Trace feature

Thanks,
Luwei Kang

> 
> Cc: qemu-sta...@nongnu.org
> Signed-off-by: Paolo Bonzini 
> ---
>  target/i386/cpu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 
> 9c54c41e7a..a6a597d2bf 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -1012,6 +1012,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] 
> = {
>  .needs_ecx = true, .ecx = 0,
>  .reg = R_EBX,
>  },
> +.unmigratable_features = CPUID_7_0_EBX_INTEL_PT,
>  .tcg_features = TCG_7_0_EBX_FEATURES,
>  },
>  [FEAT_7_0_ECX] = {
> --
> 2.20.1
>