Re: [Qemu-devel] USB PCI host bus adapter hot plug
On 08/13/2014 03:00 PM, Gonglei (Arei) wrote: I noticed that QMP's device_add usb-ehci,id=i2,bus=pci.0 fails on PCI hotplug. The same for pci-ohci and this is because their initfn() do dc-hotpluggable = false. So I removed those and now I can hotplug USB hosts but none of them is able to actually work: root@aiktest-le:~# echo 1 /sys/bus/pci/rescan [ 41.143062] ohci-pci :00:01.0: init err (c870 ) [ 41.143133] ohci-pci :00:01.0: can't start [ 41.143227] ohci-pci :00:01.0: startup error -75 [ 41.144202] ohci-pci :00:01.0: init :00:01.0 fail, -75 root@aiktest-le:~# echo 1 /sys/bus/pci/rescan [ 43.691067] ehci-pci :00:01.0: can't setup: -110 [ 43.692424] ehci-pci :00:01.0: init :00:01.0 fail, -110 Why is that? Is QEMU just missing some bits or there is some fundamental issue which I just do not see? Thanks! Cc'ing Gerd. Actually I have post a patch serials for supporting usb host adapter hotplugging, Which has been involved in Gerd's (the USB mantainer) usb-next tree. Please see: https://www.kraxel.org/cgit/qemu/log/?h=rebase/usb-next The function of usb host adapter hotplugging is ok. You are welcome to test it. It does not work for me though. The device appears in the system but the driver fails to bring it up: [root@localhost ~]# echo 1 /sys/bus/pci/rescan [ 43.482378] pci :00:01.0: BAR 0: assigned [mem 0x100a000-0x100afff] [ 43.488851] ehci-pci :00:01.0: EHCI Host Controller [ 43.490153] ehci-pci :00:01.0: new USB bus registered, assigned bus number 1 [ 43.504957] ehci-pci :00:01.0: can't setup: -110 [ 43.505028] ehci-pci :00:01.0: USB bus 1 deregistered [ 43.507660] ehci-pci :00:01.0: init :00:01.0 fail, -110 [ 43.507808] ehci-pci: probe of :00:01.0 failed with error -110 BTW, What's your guest os type? Fedora20/ppc64 or Ubuntu14/ppc64le. I tried your tree merged with https://github.com/mdroth/qemu/tree/spapr-pci-hotplug-ppc-next-cleanup2 I am adding PCIhotplug-on-PPC experts to the thread, may be they have ideas... More precise - this fails: drivers/usb/host/ehci-hcd.c: int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, u32 mask, u32 done, int usec) { u32 result; do { result = ehci_readl(ehci, ptr); if (result == ~(u32)0) /* card removed */ return -ENODEV; result = mask; if (result == done) return 0; udelay (1); usec--; } while (usec 0); return -ETIMEDOUT; // -- } -- Alexey Hi, Alexey. Does this work when you configure EHCI at the command line, not hotplugging? Yes, all possible USB hosts work just fine when added in the command line. BTW, I'm not familiar with PCIhotplug-on-PPC. Sorry for this. I doubt this is because of PPC but there is always a chance :) -- Alexey
Re: [Qemu-devel] Bug#757927: [qemu-kvm] TRIM (discard=unmap) broken in 2.1
[This is http://bugs.debian.org/757927 -- trim stopped working in qemu 2.1] 12.08.2014 18:46, Michael Tokarev wrote: 12.08.2014 17:35, Roman Mamedov wrote: Package: qemu-kvm Version: 2.1+dfsg-2~bpo70+2 Severity: normal Hello, I was able to successfully use the passthrough TRIM support with an IDE interface virtual disk in Qemu-KVM version 2.0. However after upgrading to 2.1 and restarting my VM, TRIM now fails in it with messages like those quoted below (dmesg from the guest). There are no messages in dmesg related to that on the host. BTW, I found a system here with an SSD which supports discard, and tried my guests against it -- everything works fine when I use sata/ahci, but it breaks indeed when using the default IDE interface. But applying the oneliner: It is the same as 2.1+dfsg-1~bpo70+2 but with a one-line patch added: diff --git a/hw/ide/core.c b/hw/ide/core.c index db191a6..7256592 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -688,7 +688,8 @@ void ide_dma_cb(void *opaque, int ret) sector_num, n, s-dma_cmd); #endif -if (!ide_sect_range_ok(s, sector_num, n)) { +if ((s-dma_cmd == IDE_DMA_READ || s-dma_cmd == IDE_DMA_WRITE) +!ide_sect_range_ok(s, sector_num, n)) { dma_buf_commit(s); ide_dma_error(s); return; fixes the prob for me. So apparently kwolf was right pointing to that commit 58ac3211. I'll upload a new version soon. Thanks, /mjt
Re: [Qemu-devel] MSI-X interrupt emulation
On 2014-08-01 08:22, Danzer, Uwe wrote: Hi there, I'm implementing an emulated PCIe Memory class device, but can't get MSI-X interrupt emulation working. So far, the card appears in the guest system and the driver for the card recognises it and the emulation of 1MB of accessible r/w registers works as desired. As the real card is connected to the outside world, it can signal events from there to the software via 5 MSI-X interrupts. Though I do not manage do get MSI-X emulation working in my implementation. The guest OS is QNX and works just fine on the real hardware. Running QNX as guest inside QEMU, the command pci -vvv (QNX equivalent of lspci on Linux) shows my card and that it says it's able to do the desired 5 MSI-X interrupts, but the QNX driver doesn't activate MSI-X for the card. I suppose the config space layouts are identical between emulated and real card? Just in case the QNX driver has hard-coded capability offsets (it shouldn't, but who knows). Do you have the source code of the driver? In my init function of the PCIe card, I try to make MSI-X available with this code: ret = msix_init_exclusive_bar (dev, 5, 1); if (ret) { printf(msix_init() failed\n); } else { int i; for (i = 0; i 5; i++) { msix_vector_use (dev, i); } msix = 1; } Can someone tell me, what is wrong or missing in my code or does somebody have a minimal example for a (pseudo)device with MSI-X? If the problem still persists and you can't share your code here, drop me an email directly, and I can have a look or suggest further instrumentations. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH][RESEND] pci: Use bus master address space for delivering MSI/MSI-X, messages
The spec says (and real HW confirms this) that, if the bus master bit is 0, the device will not generate any PCI accesses. MSI and MSI-X messages fall among these, so we should use the corresponding address space to deliver them. This will prevent delivery if bus master support is disabled. Signed-off-by: Jan Kiszka jan.kis...@siemens.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com --- hw/pci/msi.c | 2 +- hw/pci/msix.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/pci/msi.c b/hw/pci/msi.c index a4a3040..52d2313 100644 --- a/hw/pci/msi.c +++ b/hw/pci/msi.c @@ -291,7 +291,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector) notify vector 0x%x address: 0x%PRIx64 data: 0x%PRIx32\n, vector, msg.address, msg.data); -stl_le_phys(address_space_memory, msg.address, msg.data); +stl_le_phys(dev-bus_master_as, msg.address, msg.data); } /* Normally called by pci_default_write_config(). */ diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 5c49bfc..20ae476 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -439,7 +439,7 @@ void msix_notify(PCIDevice *dev, unsigned vector) msg = msix_get_message(dev, vector); -stl_le_phys(address_space_memory, msg.address, msg.data); +stl_le_phys(dev-bus_master_as, msg.address, msg.data); } void msix_reset(PCIDevice *dev) -- 1.8.1.1.298.ge7eed54
Re: [Qemu-devel] [Qemu-trivial] [PATCH] apic: Fix reported DFR content
09.08.2014 18:05, Jan Kiszka wrote: From: Jan Kiszka jan.kis...@siemens.com IA-32 SDM, Figure 10-14: Bits 27:0 are reserved as 1. Fixes Jailhouse hypervisor start with in-kernel irqchips off. Applied to -trivial, thank you! Are the other similar cases in there okay? Say, 0x0d or 0x02 which also uses shifts like this one? /mjt
Re: [Qemu-devel] [Qemu-trivial] [PATCH] memory: Update obsolete comment about AddrRange field type
Applied to -trivial, thank you! /mjt
Re: [Qemu-devel] [PATCH] qemu-options.hx: fix a typo of chardev
13.08.2014 07:20, Liming Wang wrote: Change host to port. A good one. Applied to -trivial, thank you! /mjt
Re: [Qemu-devel] [Qemu-trivial] [PATCH 0/2] trivial patches for pci-host
11.08.2014 12:10, arei.gong...@huawei.com wrote: From: Gonglei arei.gong...@huawei.com Gonglei (2): pci-host: update obsolete reference about piix_pci.c pci-host: update uncorresponding description Applied both to -trivial, thank you! /mjt
Re: [Qemu-devel] Bug#757927: [qemu-kvm] TRIM (discard=unmap) broken in 2.1
13.08.2014 10:16, Roman Mamedov wrote: Thanks for working on this! Sorry for not being able to test an updated version sooner. You're welcome. I learned something too ;) [] I was only successful in using this with the virtual IDE interface disks on Qemu/KVM 2.0, the virtio mode does not seem to support TRIM; did not try with sata/ahci. virtio-scsi support trim, and also sata/ahci. virtio-blk does not, it is a simple interface without fancy features. Thanks, /mjt
Re: [Qemu-devel] Bug#757927: [qemu-kvm] TRIM (discard=unmap) broken in 2.1
[dropping debian bugreport] 13.08.2014 10:05, Michael Tokarev wrote: [This is http://bugs.debian.org/757927 -- trim stopped working in qemu 2.1] 12.08.2014 18:46, Michael Tokarev wrote: 12.08.2014 17:35, Roman Mamedov wrote: Package: qemu-kvm Version: 2.1+dfsg-2~bpo70+2 Severity: normal Hello, I was able to successfully use the passthrough TRIM support with an IDE interface virtual disk in Qemu-KVM version 2.0. However after upgrading to 2.1 and restarting my VM, TRIM now fails in it with messages like those quoted below (dmesg from the guest). There are no messages in dmesg related to that on the host. BTW, I found a system here with an SSD which supports discard, and tried my guests against it -- everything works fine when I use sata/ahci, but it breaks indeed when using the default IDE interface. But applying the oneliner: It is the same as 2.1+dfsg-1~bpo70+2 but with a one-line patch added: diff --git a/hw/ide/core.c b/hw/ide/core.c index db191a6..7256592 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -688,7 +688,8 @@ void ide_dma_cb(void *opaque, int ret) sector_num, n, s-dma_cmd); #endif -if (!ide_sect_range_ok(s, sector_num, n)) { +if ((s-dma_cmd == IDE_DMA_READ || s-dma_cmd == IDE_DMA_WRITE) +!ide_sect_range_ok(s, sector_num, n)) { dma_buf_commit(s); ide_dma_error(s); return; fixes the prob for me. So apparently kwolf was right pointing to that commit 58ac3211. But this makes me wonder: why the issue only exists with ide, but not with ahci/sata? The two should be sufficiently similar to trigger this check the same way. Maybe we have another bug somewhere, like adding an extra sector in some path, which is triggered by 58ac3211? Maybe even in the guest kernel (but in this case, since it works with real hw, we should ignore it). Thanks, /mjt
Re: [Qemu-devel] [Qemu-trivial] [PATCH v5 0/8] don't use Yoda conditions
Applied all to -trivial. Thank you! /mjt
Re: [Qemu-devel] [Qemu-trivial] [PATCH] apic: Fix reported DFR content
On 2014-08-13 08:14, Michael Tokarev wrote: 09.08.2014 18:05, Jan Kiszka wrote: From: Jan Kiszka jan.kis...@siemens.com IA-32 SDM, Figure 10-14: Bits 27:0 are reserved as 1. Fixes Jailhouse hypervisor start with in-kernel irqchips off. Applied to -trivial, thank you! Are the other similar cases in there okay? Say, 0x0d or 0x02 which also uses shifts like this one? Nope, didn't find any. Jan signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH] spapr_pci: Fix config space corruption
When disabling MSI/MSIX via ibm,change-msi RTAS call, no check was made if MSI or MSIX is actually supported and the MSI message was reset unconditionally. If this happened on a device which does not support MSI (but does support MSIX, otherwise ibm,change-msi would not be called), this device would have PCIDevice::msi_cap field (MSI capability offset) set to zero and writing a vector would actually clear PCI status. This clears MSI message only if MSI or MSIX is present on a device. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/ppc/spapr_pci.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index d1f4c86..c0e703f 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -263,7 +263,6 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, unsigned int irq, max_irqs = 0, num = 0; sPAPRPHBState *phb = NULL; PCIDevice *pdev = NULL; -bool msix = false; spapr_pci_msi *msi; int *config_addr_key; @@ -301,7 +300,12 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, } xics_free(spapr-icp, msi-first_irq, msi-num); -spapr_msi_setmsg(pdev, 0, msix, 0, num); +if (msi_present(pdev)) { +spapr_msi_setmsg(pdev, 0, false, 0, num); +} +if (msix_present(pdev)) { +spapr_msi_setmsg(pdev, 0, true, 0, num); +} g_hash_table_remove(phb-msi, config_addr); trace_spapr_pci_msi(Released MSIs, config_addr); -- 2.0.0
[Qemu-devel] ide: only constrain read/write requests to drive size, not other types
Commit 58ac321135a introduced a check to ide dma processing which constrains all requests to drive size. However, apparently, some valid requests (like TRIM) does not fit in this constraint, and fails in 2.1. So check the range only for reads and writes. Cc: qemu-sta...@nongnu.org Signed-off-by: Michael Tokarev m...@tls.msk.ru Signed-off-by: Markus Armbruster arm...@redhat.com diff --git a/hw/ide/core.c b/hw/ide/core.c index db191a6..7256592 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -688,7 +688,8 @@ void ide_dma_cb(void *opaque, int ret) sector_num, n, s-dma_cmd); #endif -if (!ide_sect_range_ok(s, sector_num, n)) { +if ((s-dma_cmd == IDE_DMA_READ || s-dma_cmd == IDE_DMA_WRITE) +!ide_sect_range_ok(s, sector_num, n)) { dma_buf_commit(s); ide_dma_error(s); return;
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
On Mon, Aug 11, 2014 at 09:37:01PM +0200, Paolo Bonzini wrote: Il 10/08/2014 05:46, Ming Lei ha scritto: @@ -4356,6 +4353,20 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, { trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); +if (bs-drv bs-drv-bdrv_aio_readv +bs-drv-bdrv_aio_readv != bdrv_aio_readv_em +nb_sectors = 0 nb_sectors = (UINT_MAX BDRV_SECTOR_BITS) +!bdrv_check_byte_request(bs, sector_num BDRV_SECTOR_BITS, + nb_sectors BDRV_SECTOR_BITS) +!bs-copy_on_read !bs-io_limits_enabled +bs-request_alignment = BDRV_SECTOR_SIZE) { +BlockDriverAIOCB *acb = +bs-drv-bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, +cb, opaque); +assert(acb); Minor issue: block.h:bdrv_aio_readv() guarantees the return value is non-NULL but BlockDriver-bdrv_aio_readv() does not. The floppy disk (fd_open()) code path in raw-posix.c can return NULL so we would need to return a BlockDriverAIOCB and set up a BH that will complete with -EIO. Stefan pgpjpQYmymSZA.pgp Description: PGP signature
Re: [Qemu-devel] The status about vhost-net on kvm-arm?
On Tue, Aug 12, 2014 at 6:47 PM, Nikolay Nikolaev n.nikol...@virtualopensystems.com wrote: Hello, On Tue, Aug 12, 2014 at 5:41 AM, Li Liu john.li...@huawei.com wrote: Hi all, Is anyone there can tell the current status of vhost-net on kvm-arm? Half a year has passed from Isa Ansharullah asked this question: http://www.spinics.net/lists/kvm-arm/msg08152.html I have found two patches which have provided the kvm-arm support of eventfd and irqfd: 1) [RFC PATCH 0/4] ARM: KVM: Enable the ioeventfd capability of KVM on ARM http://lists.gnu.org/archive/html/qemu-devel/2014-01/msg01770.html 2) [RFC,v3] ARM: KVM: add irqfd and irq routing support https://patches.linaro.org/32261/ And there's a rough patch for qemu to support eventfd from Ying-Shiuan Pan: [Qemu-devel] [PATCH 0/4] ioeventfd support for virtio-mmio https://lists.gnu.org/archive/html/qemu-devel/2014-02/msg00715.html But there no any comments of this patch. And I can found nothing about qemu to support irqfd. Do I lost the track? If nobody try to fix it. We have a plan to complete it about virtio-mmio supporing irqfd and multiqueue. we at Virtual Open Systems did some work and tested vhost-net on ARM back in March. The setup was based on: - host kernel with our ioeventfd patches: http://www.spinics.net/lists/kvm-arm/msg08413.html - qemu with the aforementioned patches from Ying-Shiuan Pan https://lists.gnu.org/archive/html/qemu-devel/2014-02/msg00715.html The testbed was ARM Chromebook with Exynos 5250, using a 1Gbps USB3 Ethernet adapter connected to a 1Gbps switch. I can't find the actual numbers but I remember that with multiple streams the gain was clearly seen. Note that it used the minimum required ioventfd implementation and not irqfd. I guess it is feasible to think that it all can be put together and rebased + the recent irqfd work. One can achiev even better performance (because of the irqfd). Managed to replicate the setup with the old versions e used in March: Single stream from another machine to chromebook with 1Gbps USB3 Ethernet adapter. iperf -c address -P 1 -i 1 -p 5001 -f k -t 10 to HOST: 858316 Kbits/sec to GUEST: 761563 Kbits/sec 10 parallel streams iperf -c address -P 10 -i 1 -p 5001 -f k -t 10 to HOST: 842420 Kbits/sec to GUEST: 625144 Kbits/sec ___ kvmarm mailing list kvm...@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm regards, Nikolay Nikolaev Virtual Open Systems
Re: [Qemu-devel] [PATCH] block.curl: adding 'curltimeout' option
Daniel Henrique Barboza danie...@linux.vnet.ibm.com writes: The curl hardcoded timeout (5 seconds) sometimes is not long enough depending on the remote server configuration and network traffic. The user should be able to set how much long he is willing to wait for the connection. Adding a new option to set this timeout gives the user this flexibility. The previous default timeout of 5 seconds will be used if this option is not present. Signed-off-by: Daniel Henrique Barboza danie...@linux.vnet.ibm.com --- block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/block/curl.c b/block/curl.c index 79ff2f1..a9e43f1 100644 --- a/block/curl.c +++ b/block/curl.c @@ -63,6 +63,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_NUM_ACB8 #define SECTOR_SIZE 512 #define READ_AHEAD_DEFAULT (256 * 1024) +#define CURL_TIMEOUT_DEFAULT 5 #define FIND_RET_NONE 0 #define FIND_RET_OK 1 @@ -71,6 +72,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_BLOCK_OPT_URL url #define CURL_BLOCK_OPT_READAHEAD readahead #define CURL_BLOCK_OPT_SSLVERIFY sslverify +#define CURL_BLOCK_OPT_TIMEOUT curltimeout To what could this timeout apply other than Curl? If nothing, then just timeout, please. Else, curl-timeout. struct BDRVCURLState; @@ -109,6 +111,7 @@ typedef struct BDRVCURLState { char *url; size_t readahead_size; bool sslverify; +int curltimeout; bool accept_range; AioContext *aio_context; } BDRVCURLState; Likewise: either timeout, or curl_timeout. [...]
Re: [Qemu-devel] [PATCH][RESEND] pci: Use bus master address space for delivering MSI/MSI-X, messages
On Wed, Aug 13, 2014 at 08:14:30AM +0200, Jan Kiszka wrote: The spec says (and real HW confirms this) that, if the bus master bit is 0, the device will not generate any PCI accesses. MSI and MSI-X messages fall among these, so we should use the corresponding address space to deliver them. This will prevent delivery if bus master support is disabled. Signed-off-by: Jan Kiszka jan.kis...@siemens.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Thanks, I already have this queued. --- hw/pci/msi.c | 2 +- hw/pci/msix.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/pci/msi.c b/hw/pci/msi.c index a4a3040..52d2313 100644 --- a/hw/pci/msi.c +++ b/hw/pci/msi.c @@ -291,7 +291,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector) notify vector 0x%x address: 0x%PRIx64 data: 0x%PRIx32\n, vector, msg.address, msg.data); -stl_le_phys(address_space_memory, msg.address, msg.data); +stl_le_phys(dev-bus_master_as, msg.address, msg.data); } /* Normally called by pci_default_write_config(). */ diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 5c49bfc..20ae476 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -439,7 +439,7 @@ void msix_notify(PCIDevice *dev, unsigned vector) msg = msix_get_message(dev, vector); -stl_le_phys(address_space_memory, msg.address, msg.data); +stl_le_phys(dev-bus_master_as, msg.address, msg.data); } void msix_reset(PCIDevice *dev) -- 1.8.1.1.298.ge7eed54
Re: [Qemu-devel] [PATCH] pc: Get rid of pci-info leftovers
On Tue, Aug 12, 2014 at 04:40:17PM +0200, Markus Armbruster wrote: pc_fw_cfg_guest_info() never does anything, because has_pci_info is always false. Introduced in commit f8c457b pc: pass PCI hole ranges to Guests, disabled in commit 9604f70 pc: disable pci-info for 1.6, and hasn't been enabled since. Obviously a dead end. Get of it. Signed-off-by: Markus Armbruster arm...@redhat.com Applied, thanks. --- hw/i386/pc.c | 30 -- hw/i386/pc_piix.c| 4 hw/i386/pc_q35.c | 3 --- include/hw/i386/pc.h | 1 - 4 files changed, 38 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9e58982..8fa8d2f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1066,35 +1066,6 @@ typedef struct PcRomPciInfo { uint64_t w64_max; } PcRomPciInfo; -static void pc_fw_cfg_guest_info(PcGuestInfo *guest_info) -{ -PcRomPciInfo *info; -Object *pci_info; -bool ambiguous = false; - -if (!guest_info-has_pci_info || !guest_info-fw_cfg) { -return; -} -pci_info = object_resolve_path_type(, TYPE_PCI_HOST_BRIDGE, ambiguous); -g_assert(!ambiguous); -if (!pci_info) { -return; -} - -info = g_malloc(sizeof *info); -info-w32_min = cpu_to_le64(object_property_get_int(pci_info, -PCI_HOST_PROP_PCI_HOLE_START, NULL)); -info-w32_max = cpu_to_le64(object_property_get_int(pci_info, -PCI_HOST_PROP_PCI_HOLE_END, NULL)); -info-w64_min = cpu_to_le64(object_property_get_int(pci_info, -PCI_HOST_PROP_PCI_HOLE64_START, NULL)); -info-w64_max = cpu_to_le64(object_property_get_int(pci_info, -PCI_HOST_PROP_PCI_HOLE64_END, NULL)); -/* Pass PCI hole info to guest via a side channel. - * Required so guest PCI enumeration does the right thing. */ -fw_cfg_add_file(guest_info-fw_cfg, etc/pci-info, info, sizeof *info); -} - typedef struct PcGuestInfoState { PcGuestInfo info; Notifier machine_done; @@ -1106,7 +1077,6 @@ void pc_guest_info_machine_done(Notifier *notifier, void *data) PcGuestInfoState *guest_info_state = container_of(notifier, PcGuestInfoState, machine_done); -pc_fw_cfg_guest_info(guest_info_state-info); acpi_setup(guest_info_state-info); } diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 4f22be8..12d8c26 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -59,7 +59,6 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; -static bool has_pci_info; static bool has_acpi_build = true; static int legacy_acpi_table_size; static bool smbios_defaults = true; @@ -166,7 +165,6 @@ static void pc_init1(MachineState *machine, guest_info-has_acpi_build = has_acpi_build; guest_info-legacy_acpi_table_size = legacy_acpi_table_size; -guest_info-has_pci_info = has_pci_info; guest_info-isapc_ram_fw = !pci_enabled; guest_info-has_reserved_memory = has_reserved_memory; @@ -340,7 +338,6 @@ static void pc_compat_1_7(MachineState *machine) static void pc_compat_1_6(MachineState *machine) { pc_compat_1_7(machine); -has_pci_info = false; rom_file_has_mr = false; has_acpi_build = false; } @@ -422,7 +419,6 @@ static void pc_init_pci_no_kvmclock(MachineState *machine) static void pc_init_isa(MachineState *machine) { -has_pci_info = false; has_acpi_build = false; smbios_defaults = false; gigabyte_align = false; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c39ee98..3f8a465 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -49,7 +49,6 @@ /* ICH9 AHCI has 6 ports */ #define MAX_SATA_PORTS 6 -static bool has_pci_info; static bool has_acpi_build = true; static bool smbios_defaults = true; static bool smbios_legacy_mode; @@ -150,7 +149,6 @@ static void pc_q35_init(MachineState *machine) } guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size); -guest_info-has_pci_info = has_pci_info; guest_info-isapc_ram_fw = false; guest_info-has_acpi_build = has_acpi_build; guest_info-has_reserved_memory = has_reserved_memory; @@ -296,7 +294,6 @@ static void pc_compat_1_7(MachineState *machine) static void pc_compat_1_6(MachineState *machine) { pc_compat_1_7(machine); -has_pci_info = false; rom_file_has_mr = false; has_acpi_build = false; } diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 863eefb..7eb742d 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -85,7 +85,6 @@ typedef struct PcPciInfo { #define ACPI_PM_PROP_GPE0_BLK_LEN
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
Am 12.08.2014 um 21:08 hat Paolo Bonzini geschrieben: Il 12/08/2014 10:12, Ming Lei ha scritto: The below patch is basically the minimal change to bypass coroutines. Of course the block.c part is not acceptable as is (the change to refresh_total_sectors is broken, the others are just ugly), but it is a start. Please run it with your fio workloads, or write an aio-based version of a qemu-img/qemu-io *I/O* benchmark. Could you explain why the new change is introduced? It provides a fast path for bdrv_aio_readv/writev whenever there is nothing to do after the driver routine returns. In this case there is no need to wrap the AIOCB returned by the driver routine. It doesn't go all the way, and in particular it doesn't reverse completely the roles of bdrv_co_readv/writev vs. bdrv_aio_readv/writev. That's actually why I think it's an option. Remember that, like you say below, we're optimising for an extreme case here, and I certainly don't want to hurt the common case for it. I can't imagine a way of reversing the roles without multiplying the cost for the coroutine path. Or do you have a clever solution how you'd go about it without having an impact on the common case? But it is enough to provide something that is not dataplane-specific, does not break various functionality that we need to add to dataplane virtio-blk, does not mess up the semantics of the block layer, and lets you run benchmarks. I will hold it until we can align to the coroutine cost computation, because it is very important for the discussion. First of all, note that the coroutine cost is totally pointless in the discussion unless you have 100% CPU time and the dataplane thread becomes CPU bound. You haven't said if this is the case. That's probably the implicit assumption. As I said, it's an extreme case we're trying to look at. I'm not sure how realistic it is when you don't work with ramdisks... Second, if the coroutine cost is relevant, the profile is really too flat to do much about it. The only solution (and here I *think* I disagree slightly with Kevin) is to get rid of it, which is not even too hard to do. I think we just need to make the best use of coroutines. I would really love to show you numbers, but I'm having a hard time benchmarking all this stuff. When I test only the block layer with 'qemu-img bench', I clearly have working optimisations, but it doesn't translate yet into clear improvments for actual guests. I think other things in the way from the guest to qemu slow it down so that in the end the coroutine part doesn't matter much any more. By the way, I just noticed that sequential reads were significantly faster (~25%) for me without dataplane than with it. I didn't expect to gain anything with dataplane on this setup, but certainly not to lose that much. There might be more to gain there than by optimising or removing coroutines. The problem is that your patches to do touch too much code and subtly break too much stuff. The one I wrote does have a little breakage because I don't understand bs-growable 100% and I didn't really put much effort into it (my deadline being basically be done as soon as the shower is free), and it is ugly as hell, _but_ it should be compatible with the way the block layer works. Yes, your patch is definitely much more palatable than Ming's. The part that I still don't like about it is that it would be stating in the common case, we're only doing the second best thing. I'm not yet convinced that coroutines perform necessarily worse than state-passing callbacks. Kevin
Re: [Qemu-devel] Bug#757927: [qemu-kvm] TRIM (discard=unmap) broken in 2.1
Am 13.08.2014 um 08:41 hat Michael Tokarev geschrieben: [dropping debian bugreport] 13.08.2014 10:05, Michael Tokarev wrote: [This is http://bugs.debian.org/757927 -- trim stopped working in qemu 2.1] 12.08.2014 18:46, Michael Tokarev wrote: 12.08.2014 17:35, Roman Mamedov wrote: Package: qemu-kvm Version: 2.1+dfsg-2~bpo70+2 Severity: normal Hello, I was able to successfully use the passthrough TRIM support with an IDE interface virtual disk in Qemu-KVM version 2.0. However after upgrading to 2.1 and restarting my VM, TRIM now fails in it with messages like those quoted below (dmesg from the guest). There are no messages in dmesg related to that on the host. BTW, I found a system here with an SSD which supports discard, and tried my guests against it -- everything works fine when I use sata/ahci, but it breaks indeed when using the default IDE interface. But applying the oneliner: It is the same as 2.1+dfsg-1~bpo70+2 but with a one-line patch added: diff --git a/hw/ide/core.c b/hw/ide/core.c index db191a6..7256592 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -688,7 +688,8 @@ void ide_dma_cb(void *opaque, int ret) sector_num, n, s-dma_cmd); #endif -if (!ide_sect_range_ok(s, sector_num, n)) { +if ((s-dma_cmd == IDE_DMA_READ || s-dma_cmd == IDE_DMA_WRITE) +!ide_sect_range_ok(s, sector_num, n)) { dma_buf_commit(s); ide_dma_error(s); return; fixes the prob for me. So apparently kwolf was right pointing to that commit 58ac3211. But this makes me wonder: why the issue only exists with ide, but not with ahci/sata? The two should be sufficiently similar to trigger this check the same way. Maybe we have another bug somewhere, like adding an extra sector in some path, which is triggered by 58ac3211? Maybe even in the guest kernel (but in this case, since it works with real hw, we should ignore it). I can't give you a clear answer, but it all depends on the value of sector_num. This is the contents of the LBA registers and unused for TRIM (spec says it's reserved, so we shouldn't be looking at it). Whether the problematic value in the IDE case comes from a previous command or that's just how the driver sets things and the AHCI sets different things I can't say. But it certainly depends on the guest behaviour whether the bug actually triggers. Kevin
Re: [Qemu-devel] [PATCH ] test-coroutine: test cost introduced by coroutine
On Mon, Aug 11, 2014 at 7:59 PM, Ming Lei ming@canonical.com wrote: This test uses getppid() syscall to simulate single operation run inside coroutine, and compare how many operations done per second between using coroutine and not using coroutine to evalute cost introduced by running operation via coroutine. Paolo introduced 'baseline test' for computing the cost of coroutine operations, and it may be not enough since coroutine switches stack for running task and this cost won't be considered at all, and in reality most of actual corotine cases can't avoid stack use at all. So this patch uses getppid() syscall to simulte operation running from coroutine: - syscall and related stack operations can't be optimized by compiler - push to/pop from user space stack introduced by calling syscall, such as for save/restore context - also it isn't unusual to call syscall from coroutine For example, here are the results on my machine when treating 1 getppid() as one operation: - Run operation 6000 iterations(1 getppid() per operation) without using coroutine: 3.517642 s, 17056K operations/s - Run operation 6000 iterations(1 getppid() per operation) using coroutine: 11.157434 s, 5377K operations/s - Coroutine introduced cost: 68% If running 30 getppid() in one operation: - Run operation 6000 iterations(30 getppid() per operation) without using coroutine: 3.264977 s, 612K operations/s - Run operation 6000 iterations(30 getppid() per operation) using coroutine: 3.733169 s, 535K operations/s - Coroutine introduced cost: %12 So in some situations, the cost introduced by coroutine isn't too small to be ignored. Please ignore this one, and I have better and simper patch to figure out coroutine cost. Thanks,
[Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
This test runs dummy function with coroutine by using two enter and one yield since which is a common usage. So we can see the cost introduced by corouting for running one function, for example: Run operation 2000 iterations 4.841071 s, 4131K operations/s 242ns per coroutine Signed-off-by: Ming Lei ming@canonical.com --- tests/test-coroutine.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c index 6e634f4..e22fae1 100644 --- a/tests/test-coroutine.c +++ b/tests/test-coroutine.c @@ -311,6 +311,35 @@ static void perf_baseline(void) maxcycles, duration); } +static __attribute__((noinline)) void perf_cost_func(void *opaque) +{ +qemu_coroutine_yield(); +} + +static void perf_cost(void) +{ +const unsigned long maxcycles = 4000; +unsigned long i = 0; +double duration; +unsigned long ops; +Coroutine *co; + +g_test_timer_start(); +while (i++ maxcycles) { +co = qemu_coroutine_create(perf_cost_func); +qemu_coroutine_enter(co, i); +qemu_coroutine_enter(co, NULL); +} +duration = g_test_timer_elapsed(); +ops = (long)(maxcycles / (duration * 1000)); + +g_test_message(Run operation %lu iterations %f s, %luK operations/s, + %luns per coroutine, + maxcycles, + duration, ops, + (unsigned long)(10 * duration) / maxcycles); +} + int main(int argc, char **argv) { g_test_init(argc, argv, NULL); @@ -325,6 +354,7 @@ int main(int argc, char **argv) g_test_add_func(/perf/nesting, perf_nesting); g_test_add_func(/perf/yield, perf_yield); g_test_add_func(/perf/function-call, perf_baseline); +g_test_add_func(/perf/cost, perf_cost); } return g_test_run(); } -- 1.7.9.5
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
On Wed, Aug 13, 2014 at 3:08 AM, Paolo Bonzini pbonz...@redhat.com wrote: Il 12/08/2014 10:12, Ming Lei ha scritto: The below patch is basically the minimal change to bypass coroutines. Of course the block.c part is not acceptable as is (the change to refresh_total_sectors is broken, the others are just ugly), but it is a start. Please run it with your fio workloads, or write an aio-based version of a qemu-img/qemu-io *I/O* benchmark. Could you explain why the new change is introduced? It provides a fast path for bdrv_aio_readv/writev whenever there is nothing to do after the driver routine returns. In this case there is no need to wrap the AIOCB returned by the driver routine. It doesn't go all the way, and in particular it doesn't reverse completely the roles of bdrv_co_readv/writev vs. bdrv_aio_readv/writev. But it is enough to provide something that is not dataplane-specific, does not break various functionality that we need to add to dataplane virtio-blk, does not mess up the semantics of the block layer, and lets you run benchmarks. I will hold it until we can align to the coroutine cost computation, because it is very important for the discussion. First of all, note that the coroutine cost is totally pointless in the discussion unless you have 100% CPU time and the dataplane thread becomes CPU bound. You haven't said if this is the case. No, it does make sense, especially for high speed block device. In my test, the CPU is close to 100%, otherwise block throughput should not have been effected. Also it can decrease CPU utilization if it isn't 100% CPU. Also it is related with CPU speed, in one slow machine, running coroutine may introduce some load especially for high IOPS block device. Second, if the coroutine cost is relevant, the profile is really too I have wrote a patch to figure out coroutine cost which can show it clearly, and you should be in the Cc list. flat to do much about it. The only solution (and here I *think* I disagree slightly with Kevin) is to get rid of it, which is not even too hard to do. I agree. But it depends on the situation of coroutine use. If the function running by coroutine isn't called very frequently, the effect from coroutine can be ignored. For block device which can reach hundreds of kilo IOPS, as far as I thought of, the only solution is to not using coroutine for this case. That is why I wrote the bypass coroutine patch. The problem is that your patches to do touch too much code and subtly break too much stuff. The one I wrote does have a little breakage Could you give a hint about which stuff are broken? Last time, you mention virtio-scsi need to keep AIOCB live after returning, I have fixed it in V1. because I don't understand bs-growable 100% and I didn't really put much effort into it (my deadline being basically be done as soon as the shower is free), and it is ugly as hell, _but_ it should be compatible with the way the block layer works. I will take a careful look to your patch later. If coroutine is still there, I think it still can slow down performance. Thanks,
[Qemu-devel] Discrepancy representing slot IDs in query-memory-devices and query-acpi-ospm-status
Hi, QMP command 'query-memory-devices' returns DIMM slots IDs as integers, while 'query-acpi-ospm-status' returns them as strings. Why is this the case? Aren't slot IDs numeric anyway? I've looked up the ACPI specs but I can't find any specific mention of how DIMM IDs should be represented, so what's the reason for this design choice? BR, Mohammed
[Qemu-devel] [PATCH v5 07/15] target-tricore: Add instructions of SRR opcode format
Add instructions of SRR opcode format. Add helper for add/sub_ssov. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- v4 - v5: - gen_sub_d now saves result of substraction into tcg temp to handle ret = r1 cases. - gen_mul_i32s now calculates V, SV bits in bit 31. - SSOV makro now computes V, SV bits in bit 31. - Negate conditions of 16_SRR_CMOV and 16_SRR_CMOVN insns. - MOV_AA: Switch r1 and r2 arguments. target-tricore/helper.h| 4 ++ target-tricore/op_helper.c | 43 target-tricore/translate.c | 164 + 3 files changed, 211 insertions(+) diff --git a/target-tricore/helper.h b/target-tricore/helper.h index 5884240..299bd77 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -14,3 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see http://www.gnu.org/licenses/. */ + +/* Arithmetic */ +DEF_HELPER_3(add_ssov, i32, env, i32, i32) +DEF_HELPER_3(sub_ssov, i32, env, i32, i32) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 2e5981f..3c83945 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -20,6 +20,49 @@ #include exec/helper-proto.h #include exec/cpu_ldst.h +#define SSOV(env, ret, arg, len) do { \ +int64_t max_pos = INT##len ##_MAX; \ +int64_t max_neg = INT##len ##_MIN; \ +if (arg max_pos) {\ +env-PSW_USB_V = (1 31); \ +env-PSW_USB_SV = (1 31);\ +ret = (target_ulong)max_pos;\ +} else {\ +if (arg max_neg) {\ +env-PSW_USB_V = (1 31); \ +env-PSW_USB_SV = (1 31);\ +ret = (target_ulong)max_neg;\ +} else {\ +env-PSW_USB_V = 0; \ +ret = (target_ulong)arg;\ +} \ +} \ +env-PSW_USB_AV = arg ^ arg * 2u; \ +env-PSW_USB_SAV |= env-PSW_USB_AV;\ +} while (0) + +target_ulong helper_add_ssov(CPUTRICOREState *env, target_ulong r1, + target_ulong r2) +{ +target_ulong ret; +int64_t t1 = sextract64(r1, 0, 32); +int64_t t2 = sextract64(r2, 0, 32); +int64_t result = t1 + t2; +SSOV(env, ret, result, 32); +return ret; +} + +target_ulong helper_sub_ssov(CPUTRICOREState *env, target_ulong r1, + target_ulong r2) +{ +target_ulong ret; +int64_t t1 = sextract64(r1, 0, 32); +int64_t t2 = sextract64(r2, 0, 32); +int64_t result = t1 - t2; +SSOV(env, ret, result, 32); +return ret; +} + static inline void QEMU_NORETURN do_raise_exception_err(CPUTRICOREState *env, uint32_t exception, int error_code, diff --git a/target-tricore/translate.c b/target-tricore/translate.c index fbaba9e..054d08c 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -187,6 +187,53 @@ static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2, tcg_temp_free(temp); } +static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2) +{ +TCGv temp = tcg_temp_new_i32(); +TCGv result = tcg_temp_new_i32(); + +tcg_gen_sub_tl(result, r1, r2); +/* calc V bit */ +tcg_gen_xor_tl(cpu_PSW_V, result, r1); +tcg_gen_xor_tl(temp, r1, r2); +tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp); +/* calc SV bit */ +tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V); +/* Calc AV bit */ +tcg_gen_add_tl(cpu_PSW_AV, result, result); +tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV); +/* calc SAV bit */ +tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV); +/* write back result */ +tcg_gen_mov_tl(ret, result); + +tcg_temp_free(temp); +tcg_temp_free(result); +} + +static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2) +{ +TCGv high = tcg_temp_new(); +TCGv low = tcg_temp_new(); + +tcg_gen_muls2_tl(low, high, r1, r2); +tcg_gen_mov_tl(ret, low); +/* calc V bit */ +tcg_gen_sari_tl(low, low, 31); +tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low); +tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31); +/* calc SV bit */ +tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V); +/* Calc AV bit */ +tcg_gen_add_tl(cpu_PSW_AV, ret, ret); +tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV); +/* calc SAV bit */ +tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV); + +tcg_temp_free(high); +tcg_temp_free(low); +} + static void gen_shi(TCGv ret, TCGv r1, int32_t
[Qemu-devel] [PATCH v5 04/15] target-tricore: Add initialization for translation and activate target
Add tcg and cpu model initialization. Add gen_intermediate_code function. Activate target in configure and add softmmu config. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- v4 - v5: - gen_intermediate_code_internal: Move calculation of next_pc after the ifs for singlestep and long tbs. configure | 5 ++ default-configs/tricore-softmmu.mak | 3 + target-tricore/translate.c | 165 3 files changed, 173 insertions(+) create mode 100644 default-configs/tricore-softmmu.mak diff --git a/configure b/configure index f7685b5..5003e28 100755 --- a/configure +++ b/configure @@ -4965,6 +4965,9 @@ case $target_name in TARGET_BASE_ARCH=mips echo TARGET_ABI_MIPSN64=y $config_target_mak ;; + tricore) +target_phys_bits=32 + ;; moxie) ;; or32) @@ -5162,6 +5165,8 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo CONFIG_MIPS_DIS=y $config_target_mak echo CONFIG_MIPS_DIS=y config-all-disas.mak ;; + tricore*) + ;; moxie*) echo CONFIG_MOXIE_DIS=y $config_target_mak echo CONFIG_MOXIE_DIS=y config-all-disas.mak diff --git a/default-configs/tricore-softmmu.mak b/default-configs/tricore-softmmu.mak new file mode 100644 index 000..48ccd12 --- /dev/null +++ b/default-configs/tricore-softmmu.mak @@ -0,0 +1,3 @@ +include pci.mak +CONFIG_PFLASH_CFI01=y +CONFIG_SMC91C111=y diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 5bb212d..431968b 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -26,6 +26,26 @@ #include exec/helper-proto.h #include exec/helper-gen.h +/* + * TCG registers + */ +static TCGv cpu_PC; +static TCGv cpu_PCXI; +static TCGv cpu_PSW; +static TCGv cpu_ICR; +/* GPR registers */ +static TCGv cpu_gpr_a[16]; +static TCGv cpu_gpr_d[16]; +/* PSW Flag cache */ +static TCGv cpu_PSW_C; +static TCGv cpu_PSW_V; +static TCGv cpu_PSW_SV; +static TCGv cpu_PSW_AV; +static TCGv cpu_PSW_SAV; +/* CPU env */ +static TCGv_ptr cpu_env; + +#include exec/gen-icount.h static const char *regnames_a[] = { a0 , a1 , a2 , a3 , a4 , a5 , @@ -39,6 +59,25 @@ static const char *regnames_d[] = { d12 , d13 , d14 , d15, }; +typedef struct DisasContext { +struct TranslationBlock *tb; +target_ulong pc, saved_pc, next_pc; +uint32_t opcode; +int singlestep_enabled; +/* Routine used to access memory */ +int mem_idx; +uint32_t hflags, saved_hflags; +int bstate; +} DisasContext; + +enum { + +BS_NONE = 0, +BS_STOP = 1, +BS_BRANCH = 2, +BS_EXCP = 3, +}; + void tricore_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags) { @@ -62,10 +101,88 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f, } +static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) +{ +} + +static void decode_32Bit_opc(CPUTRICOREState *env, DisasContext *ctx) +{ +} + +static void decode_opc(CPUTRICOREState *env, DisasContext *ctx, int *is_branch) +{ +/* 16-Bit Instruction */ +if ((ctx-opcode 0x1) == 0) { +ctx-next_pc = ctx-pc + 2; +decode_16Bit_opc(env, ctx); +/* 32-Bit Instruction */ +} else { +ctx-next_pc = ctx-pc + 4; +decode_32Bit_opc(env, ctx); +} +} + static inline void gen_intermediate_code_internal(TRICORECPU *cpu, struct TranslationBlock *tb, int search_pc) { +CPUState *cs = CPU(cpu); +CPUTRICOREState *env = cpu-env; +DisasContext ctx; +target_ulong pc_start; +int num_insns; +uint16_t *gen_opc_end; + +if (search_pc) { +qemu_log(search pc %d\n, search_pc); +} + +num_insns = 0; +pc_start = tb-pc; +gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; +ctx.pc = pc_start; +ctx.saved_pc = -1; +ctx.tb = tb; +ctx.singlestep_enabled = cs-singlestep_enabled; +ctx.bstate = BS_NONE; +ctx.mem_idx = cpu_mmu_index(env); + +tcg_clear_temp_count(); +gen_tb_start(); +while (ctx.bstate == BS_NONE) { +ctx.opcode = cpu_ldl_code(env, ctx.pc); +decode_opc(env, ctx, 0); + +num_insns++; + +if (tcg_ctx.gen_opc_ptr = gen_opc_end) { +break; +} +if (singlestep) { +break; +} +ctx.pc = ctx.next_pc; +} + +gen_tb_end(tb, num_insns); +*tcg_ctx.gen_opc_ptr = INDEX_op_end; +if (search_pc) { +printf(done_generating search pc\n); +} else { +tb-size = ctx.pc - pc_start; +tb-icount = num_insns; +} +if (tcg_check_temp_count()) { +printf(LEAK at %08x\n, env-PC); +} + +#ifdef DEBUG_DISAS +if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { +qemu_log(IN: %s\n, lookup_symbol(pc_start)); +log_target_disas(env, pc_start, ctx.pc - pc_start, 0); +qemu_log(\n); +} +#endif } void @@ -93,8 +210,56 @@
[Qemu-devel] [PATCH v5 13/15] target-tricore: Add instructions of SC opcode format
Add instructions of SC opcode format. Add helper for begin interrupt service routine. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de Reviewed-by: Richard Henderson r...@twiddle.net --- target-tricore/helper.h| 1 + target-tricore/op_helper.c | 59 ++ target-tricore/translate.c | 48 + 3 files changed, 108 insertions(+) diff --git a/target-tricore/helper.h b/target-tricore/helper.h index adf5b26..3c73234 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -21,3 +21,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32) /* CSA */ DEF_HELPER_2(call, void, env, i32) DEF_HELPER_1(ret, void, env) +DEF_HELPER_2(bisr, void, env, i32) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index bdcb2c4..4ea94d8 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -122,6 +122,28 @@ static void save_context_upper(CPUTRICOREState *env, int ea, } +static void save_context_lower(CPUTRICOREState *env, int ea, + target_ulong *new_FCX) +{ +*new_FCX = cpu_ldl_data(env, ea); +cpu_stl_data(env, ea, env-PCXI); +cpu_stl_data(env, ea+4, env-PSW); +cpu_stl_data(env, ea+8, env-gpr_a[2]); +cpu_stl_data(env, ea+12, env-gpr_a[3]); +cpu_stl_data(env, ea+16, env-gpr_d[0]); +cpu_stl_data(env, ea+20, env-gpr_d[1]); +cpu_stl_data(env, ea+24, env-gpr_d[2]); +cpu_stl_data(env, ea+28, env-gpr_d[3]); +cpu_stl_data(env, ea+32, env-gpr_a[4]); +cpu_stl_data(env, ea+36, env-gpr_a[5]); +cpu_stl_data(env, ea+40, env-gpr_a[6]); +cpu_stl_data(env, ea+44, env-gpr_a[7]); +cpu_stl_data(env, ea+48, env-gpr_d[4]); +cpu_stl_data(env, ea+52, env-gpr_d[5]); +cpu_stl_data(env, ea+56, env-gpr_d[6]); +cpu_stl_data(env, ea+60, env-gpr_d[7]); +} + static void restore_context_upper(CPUTRICOREState *env, int ea, target_ulong *new_PCXI, target_ulong *new_PSW) { @@ -243,6 +265,43 @@ void helper_ret(CPUTRICOREState *env) } } +void helper_bisr(CPUTRICOREState *env, uint32_t const9) +{ +target_ulong tmp_FCX; +target_ulong ea; +target_ulong new_FCX; + +if (env-FCX == 0) { +/* FCU trap */ +} + +tmp_FCX = env-FCX; +ea = ((env-FCX 0xf) 12) + ((env-FCX 0x) 6); + +save_context_lower(env, ea, new_FCX); + +/* PCXI.PCPN = ICR.CCPN */ +env-PCXI = (env-PCXI 0xff) + + ((env-ICR MASK_ICR_CCPN) 24); +/* PCXI.PIE = ICR.IE */ +env-PCXI = ((env-PCXI ~MASK_PCXI_PIE) + + ((env-ICR MASK_ICR_IE) 15)); +/* PCXI.UL = 0 */ +env-PCXI = ~(MASK_PCXI_UL); +/* PCXI[19: 0] = FCX[19: 0] */ +env-PCXI = (env-PCXI 0xfff0) + (env-FCX 0xf); +/* FXC[19: 0] = new_FCX[19: 0] */ +env-FCX = (env-FCX 0xfff0) + (new_FCX 0xf); +/* ICR.IE = 1 */ +env-ICR |= MASK_ICR_IE; + +env-ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ + +if (tmp_FCX == env-LCX) { +/* FCD trap */ +} +} + static inline void QEMU_NORETURN do_raise_exception_err(CPUTRICOREState *env, uint32_t exception, int error_code, diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 8e468bd..40459b5 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -678,6 +678,42 @@ static void decode_ssr_opc(DisasContext *ctx, int op1) } } +static void decode_sc_opc(DisasContext *ctx, int op1) +{ +int32_t const16; + +const16 = MASK_OP_SC_CONST8(ctx-opcode); + +switch (op1) { +case OPC1_16_SC_AND: +tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16); +break; +case OPC1_16_SC_BISR: +gen_helper_1arg(bisr, const16 0xff); +break; +case OPC1_16_SC_LD_A: +gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL); +break; +case OPC1_16_SC_LD_W: +gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL); +break; +case OPC1_16_SC_MOV: +tcg_gen_movi_tl(cpu_gpr_d[15], const16); +break; +case OPC1_16_SC_OR: +tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16); +break; +case OPC1_16_SC_ST_A: +gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL); +break; +case OPC1_16_SC_ST_W: +gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL); +break; +case OPC1_16_SC_SUB_A: +tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16); +break; +} +} static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) { int op1; @@ -814,6 +850,18 @@ static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) address = MASK_OP_SBR_DISP4(ctx-opcode);
[Qemu-devel] [PATCH v5 05/15] target-tricore: Add masks and opcodes for decoding
Add masks and opcodes for decoding TriCore instructions. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- target-tricore/translate.c |1 + target-tricore/tricore-opcodes.h | 1406 ++ 2 files changed, 1407 insertions(+) create mode 100644 target-tricore/tricore-opcodes.h diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 431968b..ec4d80b 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -26,6 +26,7 @@ #include exec/helper-proto.h #include exec/helper-gen.h +#include tricore-opcodes.h /* * TCG registers */ diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h new file mode 100644 index 000..9c6ec01 --- /dev/null +++ b/target-tricore/tricore-opcodes.h @@ -0,0 +1,1406 @@ +/* + * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +/* + * Opcode Masks for Tricore + * Format MASK_OP_InstrFormatName_Field + */ + +/* This creates a mask with bits start .. end set to 1 and applies it to op */ +#define MASK_BITS_SHIFT(op, start, end) (extract32(op, (start), \ +(end) - (start) + 1)) +#define MASK_BITS_SHIFT_SEXT(op, start, end) (sextract32(op, (start),\ + (end) - (start) + 1)) + +/* new opcode masks */ + +#define MASK_OP_MAJOR(op) MASK_BITS_SHIFT(op, 0, 7) + +/* 16-Bit Formats */ +#define MASK_OP_SB_DISP8(op) MASK_BITS_SHIFT(op, 8, 15) +#define MASK_OP_SB_DISP8_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 8, 15) + +#define MASK_OP_SBC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SBC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15) +#define MASK_OP_SBC_DISP4(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SBR_S2(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SBR_DISP4(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SBRN_N(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SBRN_DISP4(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SC_CONST8(op) MASK_BITS_SHIFT(op, 8, 15) + +#define MASK_OP_SLR_S2(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SLR_D(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SLRO_OFF4(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SLRO_D(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SR_OP2(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SR_S1D(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SRC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SRC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15) +#define MASK_OP_SRC_S1D(op)MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SRO_S2(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SRO_OFF4(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SRR_S2(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SRR_S1D(op)MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SRRS_S2(op)MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SRRS_S1D(op) MASK_BITS_SHIFT(op, 8, 11) +#define MASK_OP_SRRS_N(op) MASK_BITS_SHIFT(op, 6, 7) + +#define MASK_OP_SSR_S2(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SSR_S1(op) MASK_BITS_SHIFT(op, 8, 11) + +#define MASK_OP_SSRO_OFF4(op) MASK_BITS_SHIFT(op, 12, 15) +#define MASK_OP_SSRO_S1(op)MASK_BITS_SHIFT(op, 8, 11) + +/* 32-Bit Formats */ + +/* ABS Format */ +#define MASK_OP_ABS_OFF18(op) (MASK_BITS_SHIFT(op, 16, 21) + \ + (MASK_BITS_SHIFT(op, 28, 31) 6) + \ + (MASK_BITS_SHIFT(op, 22, 25) 10) +\ + (MASK_BITS_SHIFT(op, 12, 15) 14)) +#define MASK_OP_ABS_OP2(op)MASK_BITS_SHIFT(op, 26, 27) +#define MASK_OP_ABS_S1D(op)MASK_BITS_SHIFT(op, 8, 11) + +/* ABSB Format */ +#define MASK_OP_ABSB_OFF18(op) MASK_OP_ABS_OFF18(op) +#define MASK_OP_ABSB_OP2(op) MASK_BITS_SHIFT(op, 26, 27) +#define MASK_OP_ABSB_B(op) MASK_BITS_SHIFT(op, 11, 11) +#define MASK_OP_ABSB_BPOS(op) MASK_BITS_SHIFT(op, 7, 10) + +/* B Format */ +#define MASK_OP_B_DISP24(op) (MASK_BITS_SHIFT(op, 16, 31) + \ + (MASK_BITS_SHIFT(op, 8, 15) 16)) +/* BIT Format */ +#define MASK_OP_BIT_D(op) MASK_BITS_SHIFT(op, 28, 31) +#define MASK_OP_BIT_POS2(op) MASK_BITS_SHIFT(op, 23, 27) +#define MASK_OP_BIT_OP2(op)
[Qemu-devel] [PATCH v5 14/15] target-tricore: Add instructions of SLR, SSRO and SRO opcode format
Add instructions of SLR, SSRO and SRO opcode format. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de Reviewed-by: Richard Henderson r...@twiddle.net --- target-tricore/translate.c | 121 + 1 file changed, 121 insertions(+) diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 40459b5..5efa022 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -714,6 +714,84 @@ static void decode_sc_opc(DisasContext *ctx, int op1) break; } } + +static void decode_slr_opc(DisasContext *ctx, int op1) +{ +int r1, r2; + +r1 = MASK_OP_SLR_D(ctx-opcode); +r2 = MASK_OP_SLR_S2(ctx-opcode); + +switch (op1) { +/* SLR-format */ +case OPC1_16_SLR_LD_A: +tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LESL); +break; +case OPC1_16_SLR_LD_A_POSTINC: +tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LESL); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4); +break; +case OPC1_16_SLR_LD_BU: +tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_UB); +break; +case OPC1_16_SLR_LD_BU_POSTINC: +tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_UB); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1); +break; +case OPC1_16_SLR_LD_H: +tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LESW); +break; +case OPC1_16_SLR_LD_H_POSTINC: +tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LESW); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2); +break; +case OPC1_16_SLR_LD_W: +tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LESW); +break; +case OPC1_16_SLR_LD_W_POSTINC: +tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LESW); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4); +break; +} +} + +static void decode_sro_opc(DisasContext *ctx, int op1) +{ +int r2; +int32_t address; + +r2 = MASK_OP_SRO_S2(ctx-opcode); +address = MASK_OP_SRO_OFF4(ctx-opcode); + +/* SRO-format */ +switch (op1) { +case OPC1_16_SRO_LD_A: +gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL); +break; +case OPC1_16_SRO_LD_BU: +gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB); +break; +case OPC1_16_SRO_LD_H: +gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_LESW); +break; +case OPC1_16_SRO_LD_W: +gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL); +break; +case OPC1_16_SRO_ST_A: +gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL); +break; +case OPC1_16_SRO_ST_B: +gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB); +break; +case OPC1_16_SRO_ST_H: +gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW); +break; +case OPC1_16_SRO_ST_W: +gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL); +break; +} +} + static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) { int op1; @@ -862,6 +940,49 @@ static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) case OPC1_16_SC_SUB_A: decode_sc_opc(ctx, op1); break; +/* SLR-format */ +case OPC1_16_SLR_LD_A: +case OPC1_16_SLR_LD_A_POSTINC: +case OPC1_16_SLR_LD_BU: +case OPC1_16_SLR_LD_BU_POSTINC: +case OPC1_16_SLR_LD_H: +case OPC1_16_SLR_LD_H_POSTINC: +case OPC1_16_SLR_LD_W: +case OPC1_16_SLR_LD_W_POSTINC: +decode_slr_opc(ctx, op1); +break; +/* SRO-format */ +case OPC1_16_SRO_LD_A: +case OPC1_16_SRO_LD_BU: +case OPC1_16_SRO_LD_H: +case OPC1_16_SRO_LD_W: +case OPC1_16_SRO_ST_A: +case OPC1_16_SRO_ST_B: +case OPC1_16_SRO_ST_H: +case OPC1_16_SRO_ST_W: +decode_sro_opc(ctx, op1); +break; +/* SSRO-format */ +case OPC1_16_SSRO_ST_A: +r1 = MASK_OP_SSRO_S1(ctx-opcode); +const16 = MASK_OP_SSRO_OFF4(ctx-opcode); +gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL); +break; +case OPC1_16_SSRO_ST_B: +r1 = MASK_OP_SSRO_S1(ctx-opcode); +const16 = MASK_OP_SSRO_OFF4(ctx-opcode); +gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB); +break; +case OPC1_16_SSRO_ST_H: +r1 = MASK_OP_SSRO_S1(ctx-opcode); +const16 = MASK_OP_SSRO_OFF4(ctx-opcode); +gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW); +break; +case OPC1_16_SSRO_ST_W: +r1 = MASK_OP_SSRO_S1(ctx-opcode); +const16 = MASK_OP_SSRO_OFF4(ctx-opcode); +gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4,
[Qemu-devel] [PATCH v5 10/15] target-tricore: Add instructions of SB opcode format
Add instructions of SB opcode format. Add helper call/ret. Add micro-op generator functions for branches. Add makro to generate helper functions. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- v4 - v5: - Change int cond to TCGCond in functions gen_branch_cond, gen_branch_condi. - gen_intermediate_code_internal: Add gen_goto_tb so qemu finds new tb on singlestep and after long tbs without branch. target-tricore/helper.h| 3 + target-tricore/op_helper.c | 180 + target-tricore/translate.c | 91 +++ 3 files changed, 274 insertions(+) diff --git a/target-tricore/helper.h b/target-tricore/helper.h index 299bd77..adf5b26 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -18,3 +18,6 @@ /* Arithmetic */ DEF_HELPER_3(add_ssov, i32, env, i32, i32) DEF_HELPER_3(sub_ssov, i32, env, i32, i32) +/* CSA */ +DEF_HELPER_2(call, void, env, i32) +DEF_HELPER_1(ret, void, env) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 3c83945..bdcb2c4 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -63,6 +63,186 @@ target_ulong helper_sub_ssov(CPUTRICOREState *env, target_ulong r1, return ret; } +/* context save area (CSA) related helpers */ + +static int cdc_increment(target_ulong *psw) +{ +if ((*psw MASK_PSW_CDC) == 0x7f) { +return 0; +} + +(*psw)++; +/* check for overflow */ +int lo = clo32((*psw MASK_PSW_CDC) (32 - 7)); +int mask = (1u (7 - lo)) - 1; +int count = *psw mask; +if (count == 0) { +(*psw)--; +return 1; +} +return 0; +} + +static int cdc_decrement(target_ulong *psw) +{ +if ((*psw MASK_PSW_CDC) == 0x7f) { +return 0; +} +/* check for underflow */ +int lo = clo32((*psw MASK_PSW_CDC) (32 - 7)); +int mask = (1u (7 - lo)) - 1; +int count = *psw mask; +if (count == 0) { +return 1; +} +(*psw)--; +return 0; +} + +static void save_context_upper(CPUTRICOREState *env, int ea, + target_ulong *new_FCX) +{ +*new_FCX = cpu_ldl_data(env, ea); +cpu_stl_data(env, ea, env-PCXI); +cpu_stl_data(env, ea+4, env-PSW); +cpu_stl_data(env, ea+8, env-gpr_a[10]); +cpu_stl_data(env, ea+12, env-gpr_a[11]); +cpu_stl_data(env, ea+16, env-gpr_d[8]); +cpu_stl_data(env, ea+20, env-gpr_d[9]); +cpu_stl_data(env, ea+24, env-gpr_d[10]); +cpu_stl_data(env, ea+28, env-gpr_d[11]); +cpu_stl_data(env, ea+32, env-gpr_a[12]); +cpu_stl_data(env, ea+36, env-gpr_a[13]); +cpu_stl_data(env, ea+40, env-gpr_a[14]); +cpu_stl_data(env, ea+44, env-gpr_a[15]); +cpu_stl_data(env, ea+48, env-gpr_d[12]); +cpu_stl_data(env, ea+52, env-gpr_d[13]); +cpu_stl_data(env, ea+56, env-gpr_d[14]); +cpu_stl_data(env, ea+60, env-gpr_d[15]); + +} + +static void restore_context_upper(CPUTRICOREState *env, int ea, + target_ulong *new_PCXI, target_ulong *new_PSW) +{ +*new_PCXI = cpu_ldl_data(env, ea); +*new_PSW = cpu_ldl_data(env, ea+4); +env-gpr_a[10] = cpu_ldl_data(env, ea+8); +env-gpr_a[11] = cpu_ldl_data(env, ea+12); +env-gpr_d[8] = cpu_ldl_data(env, ea+16); +env-gpr_d[9] = cpu_ldl_data(env, ea+20); +env-gpr_d[10] = cpu_ldl_data(env, ea+24); +env-gpr_d[11] = cpu_ldl_data(env, ea+28); +env-gpr_a[12] = cpu_ldl_data(env, ea+32); +env-gpr_a[13] = cpu_ldl_data(env, ea+36); +env-gpr_a[14] = cpu_ldl_data(env, ea+40); +env-gpr_a[15] = cpu_ldl_data(env, ea+44); +env-gpr_d[12] = cpu_ldl_data(env, ea+48); +env-gpr_d[13] = cpu_ldl_data(env, ea+52); +env-gpr_d[14] = cpu_ldl_data(env, ea+56); +env-gpr_d[15] = cpu_ldl_data(env, ea+60); +cpu_stl_data(env, ea, env-FCX); +} + +void helper_call(CPUTRICOREState *env, uint32_t next_pc) +{ +target_ulong tmp_FCX; +target_ulong ea; +target_ulong new_FCX; +target_ulong psw; + +psw = psw_read(env); +/* if (FCX == 0) trap(FCU); */ +if (env-FCX == 0) { +/* FCU trap */ +} +/* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ +if (psw MASK_PSW_CDE) { +if (cdc_increment(psw)) { +/* CDO trap */ +} +} +/* PSW.CDE = 1;*/ +psw |= MASK_PSW_CDE; +/* tmp_FCX = FCX; */ +tmp_FCX = env-FCX; +/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ +ea = ((env-FCX MASK_FCX_FCXS) 12) + + ((env-FCX MASK_FCX_FCXO) 6); +/* new_FCX = M(EA, word); + M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], + A[12], A[13], A[14], A[15], D[12], D[13], D[14], + D[15]}; */ +save_context_upper(env, ea, new_FCX); + +/* PCXI.PCPN = ICR.CCPN; */ +env-PCXI = (env-PCXI 0xff) + +((env-ICR MASK_ICR_CCPN) 24); +/* PCXI.PIE = ICR.IE; */ +env-PCXI = ((env-PCXI
[Qemu-devel] [PATCH v5 06/15] target-tricore: Add instructions of SRC opcode format
Add instructions of SRC opcode format. Add micro-op generator functions for add, conditional add/sub and shi/shai. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- v4 - v5: - gen_shaci: Change case of shift_count == 32 to shift_count == -32 and add the clear of V bit. - gen_shaci: Move creation and freeing of t_max, t_min to case shift_count 0. - gen_shaci: Add cast to int32_t to the creation of t_min. - gen_shaci: Now msk is 1 bit longer and uses a positive value of shift_count in the else case. - gen_shaci: now computes V bit in bit 31. - gen_shaci: Move computation of shift after the computation of PSW bits to handle the case of ret = r1. - gen_shaci: Add clear of V bit for cases shift_count = 0 / = -32 / 0. - gen_add_d now saves result of addition into tcg temp to handle ret = r1 cases. - gen_cond_add now sets SV, SAV bits conditionally. - gen_cond_add now writes result after PSW bit computations, to handle ret = r1 cases. - Change int cond to TCGCond on function gen_cond_add, gen_condi_add. - Switched source and destination register of SRC_ADD_A15 and SRC_ADD_15A insns. - Negate conditions of 16_SRC_CMOV and 16_SRC_CMOVN insns. - SRC_MOV_A loads const4 zero extended. (Googled alot to find a manual saying it should be sign extended, but couldn't) - RSUB now computes V bit in bit 31. target-tricore/helper.h| 16 +++ target-tricore/translate.c | 249 + 2 files changed, 265 insertions(+) diff --git a/target-tricore/helper.h b/target-tricore/helper.h index e69de29..5884240 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ diff --git a/target-tricore/translate.c b/target-tricore/translate.c index ec4d80b..fbaba9e 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -27,6 +27,7 @@ #include exec/helper-gen.h #include tricore-opcodes.h + /* * TCG registers */ @@ -102,8 +103,256 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f, } +/* + * Functions to generate micro-ops + */ + +/* Functions for arithmetic instructions */ + +static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2) +{ +TCGv t0 = tcg_temp_new_i32(); +TCGv result = tcg_temp_new_i32(); +/* Addition and set V/SV bits */ +tcg_gen_add_tl(result, r1, r2); +/* calc V bit */ +tcg_gen_xor_tl(cpu_PSW_V, result, r1); +tcg_gen_xor_tl(t0, r1, r2); +tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0); +/* Calc SV bit */ +tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V); +/* Calc AV/SAV bits */ +tcg_gen_add_tl(cpu_PSW_AV, result, result); +tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV); +/* calc SAV */ +tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV); +/* write back result */ +tcg_gen_mov_tl(ret, result); + +tcg_temp_free(result); +tcg_temp_free(t0); +} + +static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2) +{ +TCGv temp = tcg_const_i32(r2); +gen_add_d(ret, r1, temp); +tcg_temp_free(temp); +} + +static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3, +TCGv r4) +{ +TCGv temp = tcg_temp_new(); +TCGv temp2 = tcg_temp_new(); +TCGv result = tcg_temp_new(); +TCGv mask = tcg_temp_new(); +TCGv t0 = tcg_const_i32(0); + +/* create mask for sticky bits */ +tcg_gen_setcond_tl(cond, mask, r4, t0); +tcg_gen_shli_tl(mask, mask, 31); + +tcg_gen_add_tl(result, r1, r2); +/* Calc PSW_V */ +tcg_gen_xor_tl(temp, result, r1); +tcg_gen_xor_tl(temp2, r1, r2); +tcg_gen_andc_tl(temp, temp, temp2); +tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V); +/* Set PSW_SV */ +tcg_gen_and_tl(temp, temp, mask); +tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV); +/* calc AV bit */ +tcg_gen_add_tl(temp, result, result); +tcg_gen_xor_tl(temp, temp, result); +tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV); +/* calc SAV bit */ +tcg_gen_and_tl(temp, temp, mask); +tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV); +/* write back result */ +tcg_gen_movcond_tl(cond, r3, r4, t0,
[Qemu-devel] [PATCH v5 01/15] target-tricore: Add target stubs and qom-cpu
Add TriCore target stubs, and QOM cpu. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- v4 - v5: - Change documentation of S, SV bits to use bit 31. - psw_read/_write now uses only bit 31 of S, SV bits. arch_init.c | 2 + cpu-exec.c| 11 +- cpus.c| 6 + include/elf.h | 2 + include/sysemu/arch_init.h| 1 + target-tricore/Makefile.objs | 1 + target-tricore/cpu-qom.h | 71 target-tricore/cpu.c | 191 target-tricore/cpu.h | 400 ++ target-tricore/helper.c | 92 ++ target-tricore/helper.h | 0 target-tricore/op_helper.c| 27 +++ target-tricore/translate.c| 100 +++ target-tricore/tricore-defs.h | 28 +++ 14 files changed, 931 insertions(+), 1 deletion(-) create mode 100644 target-tricore/Makefile.objs create mode 100644 target-tricore/cpu-qom.h create mode 100644 target-tricore/cpu.c create mode 100644 target-tricore/cpu.h create mode 100644 target-tricore/helper.c create mode 100644 target-tricore/helper.h create mode 100644 target-tricore/op_helper.c create mode 100644 target-tricore/translate.c create mode 100644 target-tricore/tricore-defs.h diff --git a/arch_init.c b/arch_init.c index 8ddaf35..29a5821 100644 --- a/arch_init.c +++ b/arch_init.c @@ -104,6 +104,8 @@ int graphic_depth = 32; #define QEMU_ARCH QEMU_ARCH_XTENSA #elif defined(TARGET_UNICORE32) #define QEMU_ARCH QEMU_ARCH_UNICORE32 +#elif defined(TARGET_TRICORE) +#define QEMU_ARCH QEMU_ARCH_TRICORE #endif const uint32_t arch_type = QEMU_ARCH; diff --git a/cpu-exec.c b/cpu-exec.c index cbc8067..6fbf5a6 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -382,6 +382,7 @@ int cpu_exec(CPUArchState *env) #elif defined(TARGET_CRIS) #elif defined(TARGET_S390X) #elif defined(TARGET_XTENSA) +#elif defined(TARGET_TRICORE) /* X */ #else #error unsupported target CPU @@ -439,7 +440,8 @@ int cpu_exec(CPUArchState *env) } #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ -defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32) +defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || \ +defined(TARGET_UNICORE32) || defined(TARGET_TRICORE) if (interrupt_request CPU_INTERRUPT_HALT) { cpu-interrupt_request = ~CPU_INTERRUPT_HALT; cpu-halted = 1; @@ -555,6 +557,12 @@ int cpu_exec(CPUArchState *env) cc-do_interrupt(cpu); next_tb = 0; } +#elif defined(TARGET_TRICORE) +if ((interrupt_request CPU_INTERRUPT_HARD)) { +cc-do_interrupt(cpu); +next_tb = 0; +} + #elif defined(TARGET_OPENRISC) { int idx = -1; @@ -840,6 +848,7 @@ int cpu_exec(CPUArchState *env) | env-cc_dest | (env-cc_x 4); #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) +#elif defined(TARGET_TRICORE) #elif defined(TARGET_MOXIE) #elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) diff --git a/cpus.c b/cpus.c index 2b5c0bd..c740890 100644 --- a/cpus.c +++ b/cpus.c @@ -1409,6 +1409,9 @@ CpuInfoList *qmp_query_cpus(Error **errp) #elif defined(TARGET_MIPS) MIPSCPU *mips_cpu = MIPS_CPU(cpu); CPUMIPSState *env = mips_cpu-env; +#elif defined(TARGET_TRICORE) +TRICORECPU *tricore_cpu = TRICORE_CPU(cpu); +CPUTRICOREState *env = tricore_cpu-env; #endif cpu_synchronize_state(cpu); @@ -1433,6 +1436,9 @@ CpuInfoList *qmp_query_cpus(Error **errp) #elif defined(TARGET_MIPS) info-value-has_PC = true; info-value-PC = env-active_tc.PC; +#elif defined(TARGET_TRICORE) +info-value-has_PC = true; +info-value-PC = env-PC; #endif /* XXX: waiting for the qapi to support GSList */ diff --git a/include/elf.h b/include/elf.h index e88d52f..70107f0 100644 --- a/include/elf.h +++ b/include/elf.h @@ -92,6 +92,8 @@ typedef int64_t Elf64_Sxword; #define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Infineon TriCore */ + #define EM_IA_64 50 /* HP/Intel IA-64 */ #define EM_X86_64 62 /* AMD x86-64 */ diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index 182d48d..8939233 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -22,6 +22,7 @@ enum { QEMU_ARCH_OPENRISC = 8192, QEMU_ARCH_UNICORE32 = 0x4000, QEMU_ARCH_MOXIE = 0x8000, +QEMU_ARCH_TRICORE = 0x1, }; extern const uint32_t arch_type; diff --git a/target-tricore/Makefile.objs
[Qemu-devel] [PATCH v5 12/15] target-tricore: Add instructions of SBR opcode format
Add instructions of SBR opcode format. Add gen_loop micro-op generator function. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de Reviewed-by: Richard Henderson r...@twiddle.net --- target-tricore/translate.c | 66 +- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 87b5ad3..8e468bd 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -386,6 +386,18 @@ static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1, tcg_temp_free(temp); } +static void gen_loop(DisasContext *ctx, int r1, int32_t offset) +{ +int l1; +l1 = gen_new_label(); + +tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1); +tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1); +gen_goto_tb(ctx, 1, ctx-pc + offset); +gen_set_label(l1); +gen_goto_tb(ctx, 0, ctx-next_pc); +} + static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, int r2 , int32_t constant , int32_t offset) { @@ -427,8 +439,44 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset); tcg_temp_free(temp); break; +/* SBR-format jumps */ +case OPC1_16_SBR_JEQ: +gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], +offset); +break; +case OPC1_16_SBR_JNE: +gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], +offset); +break; +case OPC1_16_SBR_JNZ: +gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], 0, offset); +break; +case OPC1_16_SBR_JNZ_A: +gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset); +break; +case OPC1_16_SBR_JGEZ: +gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], 0, offset); +break; +case OPC1_16_SBR_JGTZ: +gen_branch_condi(ctx, TCG_COND_GT, cpu_gpr_d[r1], 0, offset); +break; +case OPC1_16_SBR_JLEZ: +gen_branch_condi(ctx, TCG_COND_LE, cpu_gpr_d[r1], 0, offset); +break; +case OPC1_16_SBR_JLTZ: +gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], 0, offset); +break; +case OPC1_16_SBR_JZ: +gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], 0, offset); +break; +case OPC1_16_SBR_JZ_A: +gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset); +break; +case OPC1_16_SBR_LOOP: +gen_loop(ctx, r1, offset * 2 - 32); +break; default: -printf(Branch Error at %x\n, ctx-pc); +printf(Branch Error at %x\n, ctx-pc); } ctx-bstate = BS_BRANCH; } @@ -750,6 +798,22 @@ static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) const16 = MASK_OP_SBRN_N(ctx-opcode); gen_compute_branch(ctx, op1, 0, 0, const16, address); break; +/* SBR-format */ +case OPC1_16_SBR_JEQ: +case OPC1_16_SBR_JGEZ: +case OPC1_16_SBR_JGTZ: +case OPC1_16_SBR_JLEZ: +case OPC1_16_SBR_JLTZ: +case OPC1_16_SBR_JNE: +case OPC1_16_SBR_JNZ: +case OPC1_16_SBR_JNZ_A: +case OPC1_16_SBR_JZ: +case OPC1_16_SBR_JZ_A: +case OPC1_16_SBR_LOOP: +r1 = MASK_OP_SBR_S2(ctx-opcode); +address = MASK_OP_SBR_DISP4(ctx-opcode); +gen_compute_branch(ctx, op1, r1, 0, 0, address); +break; } } -- 2.0.4
Re: [Qemu-devel] The status about vhost-net on kvm-arm?
On 2014/8/13 17:10, Nikolay Nikolaev wrote: On Tue, Aug 12, 2014 at 6:47 PM, Nikolay Nikolaev n.nikol...@virtualopensystems.com wrote: Hello, On Tue, Aug 12, 2014 at 5:41 AM, Li Liu john.li...@huawei.com wrote: Hi all, Is anyone there can tell the current status of vhost-net on kvm-arm? Half a year has passed from Isa Ansharullah asked this question: http://www.spinics.net/lists/kvm-arm/msg08152.html I have found two patches which have provided the kvm-arm support of eventfd and irqfd: 1) [RFC PATCH 0/4] ARM: KVM: Enable the ioeventfd capability of KVM on ARM http://lists.gnu.org/archive/html/qemu-devel/2014-01/msg01770.html 2) [RFC,v3] ARM: KVM: add irqfd and irq routing support https://patches.linaro.org/32261/ And there's a rough patch for qemu to support eventfd from Ying-Shiuan Pan: [Qemu-devel] [PATCH 0/4] ioeventfd support for virtio-mmio https://lists.gnu.org/archive/html/qemu-devel/2014-02/msg00715.html But there no any comments of this patch. And I can found nothing about qemu to support irqfd. Do I lost the track? If nobody try to fix it. We have a plan to complete it about virtio-mmio supporing irqfd and multiqueue. we at Virtual Open Systems did some work and tested vhost-net on ARM back in March. The setup was based on: - host kernel with our ioeventfd patches: http://www.spinics.net/lists/kvm-arm/msg08413.html - qemu with the aforementioned patches from Ying-Shiuan Pan https://lists.gnu.org/archive/html/qemu-devel/2014-02/msg00715.html The testbed was ARM Chromebook with Exynos 5250, using a 1Gbps USB3 Ethernet adapter connected to a 1Gbps switch. I can't find the actual numbers but I remember that with multiple streams the gain was clearly seen. Note that it used the minimum required ioventfd implementation and not irqfd. I guess it is feasible to think that it all can be put together and rebased + the recent irqfd work. One can achiev even better performance (because of the irqfd). Managed to replicate the setup with the old versions e used in March: Single stream from another machine to chromebook with 1Gbps USB3 Ethernet adapter. iperf -c address -P 1 -i 1 -p 5001 -f k -t 10 to HOST: 858316 Kbits/sec to GUEST: 761563 Kbits/sec 10 parallel streams iperf -c address -P 10 -i 1 -p 5001 -f k -t 10 to HOST: 842420 Kbits/sec to GUEST: 625144 Kbits/sec Appreciate your work. Is it convenient for you to test the same cases without vhost=on? Then the results will show the improvement of performance clearly only with ioeventfd. I will try to test it with a Hisilicon board which is ongoing. Best regards Li ___ kvmarm mailing list kvm...@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm regards, Nikolay Nikolaev Virtual Open Systems .
[Qemu-devel] [PATCH v5 11/15] target-tricore: Add instructions of SBC and SBRN opcode format
Add instructions of SBC and SBRN opcode format. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de Reviewed-by: Richard Henderson r...@twiddle.net --- target-tricore/translate.c | 36 1 file changed, 36 insertions(+) diff --git a/target-tricore/translate.c b/target-tricore/translate.c index b06f856..87b5ad3 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -389,6 +389,8 @@ static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1, static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, int r2 , int32_t constant , int32_t offset) { +TCGv temp; + switch (opc) { /* SB-format jumps */ case OPC1_16_SB_J: @@ -405,6 +407,26 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, case OPC1_16_SB_JNZ: gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset); break; +/* SBC-format jumps */ +case OPC1_16_SBC_JEQ: +gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset); +break; +case OPC1_16_SBC_JNE: +gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset); +break; +/* SBRN-format jumps */ +case OPC1_16_SBRN_JZ_T: +temp = tcg_temp_new(); +tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u constant); +gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset); +tcg_temp_free(temp); +break; +case OPC1_16_SBRN_JNZ_T: +temp = tcg_temp_new(); +tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u constant); +gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset); +tcg_temp_free(temp); +break; default: printf(Branch Error at %x\n, ctx-pc); } @@ -714,6 +736,20 @@ static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) address = MASK_OP_SB_DISP8_SEXT(ctx-opcode); gen_compute_branch(ctx, op1, 0, 0, 0, address); break; +/* SBC-format */ +case OPC1_16_SBC_JEQ: +case OPC1_16_SBC_JNE: +address = MASK_OP_SBC_DISP4(ctx-opcode); +const16 = MASK_OP_SBC_CONST4_SEXT(ctx-opcode); +gen_compute_branch(ctx, op1, 0, 0, const16, address); +break; +/* SBRN-format */ +case OPC1_16_SBRN_JNZ_T: +case OPC1_16_SBRN_JZ_T: +address = MASK_OP_SBRN_DISP4(ctx-opcode); +const16 = MASK_OP_SBRN_N(ctx-opcode); +gen_compute_branch(ctx, op1, 0, 0, const16, address); +break; } } -- 2.0.4
[Qemu-devel] [PATCH v5 09/15] target-tricore: Add instructions of SRRS and SLRO opcode format
Add instructions of SSRS and SLRO opcode format. Add micro-op generator functions for offset loads. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- v4 - v5: - decode_16Bit_opc: Add if to handle ADDSC.A opcode being 6 bit instead of 7 bit long target-tricore/translate.c | 59 ++ 1 file changed, 59 insertions(+) diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 674ef9c..ad30c3d 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -107,6 +107,26 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f, * Functions to generate micro-ops */ +/* Functions for load/save to/from memory */ + +static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2, + int16_t con, TCGMemOp mop) +{ +TCGv temp = tcg_temp_new(); +tcg_gen_addi_tl(temp, r2, con); +tcg_gen_qemu_ld_tl(r1, temp, ctx-mem_idx, mop); +tcg_temp_free(temp); +} + +static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2, + int16_t con, TCGMemOp mop) +{ +TCGv temp = tcg_temp_new(); +tcg_gen_addi_tl(temp, r2, con); +tcg_gen_qemu_st_tl(r1, temp, ctx-mem_idx, mop); +tcg_temp_free(temp); +} + /* Functions for arithmetic instructions */ static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2) @@ -511,9 +531,17 @@ static void decode_ssr_opc(DisasContext *ctx, int op1) static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) { int op1; +int r1, r2; +int32_t const16; +TCGv temp; op1 = MASK_OP_MAJOR(ctx-opcode); +/* handle ADDSC.A opcode only being 6 bit long */ +if (unlikely((op1 0x3f) == OPC1_16_SRRS_ADDSC_A)) { +op1 = OPC1_16_SRRS_ADDSC_A; +} + switch (op1) { case OPC1_16_SRC_ADD: case OPC1_16_SRC_ADD_A15: @@ -566,6 +594,37 @@ static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) case OPC1_16_SSR_ST_W_POSTINC: decode_ssr_opc(ctx, op1); break; +/* SRRS-format */ +case OPC1_16_SRRS_ADDSC_A: +r2 = MASK_OP_SRRS_S2(ctx-opcode); +r1 = MASK_OP_SRRS_S1D(ctx-opcode); +const16 = MASK_OP_SRRS_N(ctx-opcode); +temp = tcg_temp_new(); +tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16); +tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp); +tcg_temp_free(temp); +break; +/* SLRO-format */ +case OPC1_16_SLRO_LD_A: +r1 = MASK_OP_SLRO_D(ctx-opcode); +const16 = MASK_OP_SLRO_OFF4(ctx-opcode); +gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL); +break; +case OPC1_16_SLRO_LD_BU: +r1 = MASK_OP_SLRO_D(ctx-opcode); +const16 = MASK_OP_SLRO_OFF4(ctx-opcode); +gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB); +break; +case OPC1_16_SLRO_LD_H: +r1 = MASK_OP_SLRO_D(ctx-opcode); +const16 = MASK_OP_SLRO_OFF4(ctx-opcode); +gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW); +break; +case OPC1_16_SLRO_LD_W: +r1 = MASK_OP_SLRO_D(ctx-opcode); +const16 = MASK_OP_SLRO_OFF4(ctx-opcode); +gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL); +break; } } -- 2.0.4
[Qemu-devel] [PATCH v5 08/15] target-tricore: Add instructions of SSR opcode format
Add instructions of SSR opcode format. Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de Reviewed-by: Richard Henderson r...@twiddle.net --- target-tricore/translate.c | 50 ++ 1 file changed, 50 insertions(+) diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 054d08c..674ef9c 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -469,6 +469,45 @@ static void decode_srr_opc(DisasContext *ctx, int op1) } } +static void decode_ssr_opc(DisasContext *ctx, int op1) +{ +int r1, r2; + +r1 = MASK_OP_SSR_S1(ctx-opcode); +r2 = MASK_OP_SSR_S2(ctx-opcode); + +switch (op1) { +case OPC1_16_SSR_ST_A: +tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LEUL); +break; +case OPC1_16_SSR_ST_A_POSTINC: +tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LEUL); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4); +break; +case OPC1_16_SSR_ST_B: +tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_UB); +break; +case OPC1_16_SSR_ST_B_POSTINC: +tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_UB); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1); +break; +case OPC1_16_SSR_ST_H: +tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LEUW); +break; +case OPC1_16_SSR_ST_H_POSTINC: +tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LEUW); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2); +break; +case OPC1_16_SSR_ST_W: +tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LEUL); +break; +case OPC1_16_SSR_ST_W_POSTINC: +tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx-mem_idx, MO_LEUL); +tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4); +break; +} +} + static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) { int op1; @@ -516,6 +555,17 @@ static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) case OPC1_16_SRR_XOR: decode_srr_opc(ctx, op1); break; +/* SSR-format */ +case OPC1_16_SSR_ST_A: +case OPC1_16_SSR_ST_A_POSTINC: +case OPC1_16_SSR_ST_B: +case OPC1_16_SSR_ST_B_POSTINC: +case OPC1_16_SSR_ST_H: +case OPC1_16_SSR_ST_H_POSTINC: +case OPC1_16_SSR_ST_W: +case OPC1_16_SSR_ST_W_POSTINC: +decode_ssr_opc(ctx, op1); +break; } } -- 2.0.4
[Qemu-devel] [PATCH v5 02/15] target-tricore: Add board for systemmode
Add basic board to allow systemmode emulation Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- hw/tricore/Makefile.objs | 1 + hw/tricore/tricore_testboard.c | 129 + include/hw/tricore/tricore.h | 54 + 3 files changed, 184 insertions(+) create mode 100644 hw/tricore/Makefile.objs create mode 100644 hw/tricore/tricore_testboard.c create mode 100644 include/hw/tricore/tricore.h diff --git a/hw/tricore/Makefile.objs b/hw/tricore/Makefile.objs new file mode 100644 index 000..435e095 --- /dev/null +++ b/hw/tricore/Makefile.objs @@ -0,0 +1 @@ +obj-y += tricore_testboard.o diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c new file mode 100644 index 000..fee67b1 --- /dev/null +++ b/hw/tricore/tricore_testboard.c @@ -0,0 +1,129 @@ +/* + * TriCore Baseboard System emulation. + * + * Copyright (c) 2014 Bastian Koppelmann + * + * This code is licensed under the GPL. + */ + +#include hw/hw.h +#include hw/devices.h +#include net/net.h +#include sysemu/sysemu.h +#include hw/boards.h +#include hw/loader.h +#include sysemu/blockdev.h +#include exec/address-spaces.h +#include hw/block/flash.h +#include elf.h +#include hw/tricore/tricore.h + +#define TRICORE_FLASH_ADDR 0xa000 +#define TRICORE_FLASH_SIZE (2 * 1024 * 1024) +#define TRICORE_FLASH_SECT_SIZE (256 * 1024) + + +/* Board init. */ + +static struct tricore_boot_info tricoretb_binfo; + +static void tricore_load_kernel(CPUTRICOREState *env) +{ +int64_t entry; +long kernel_size; + +kernel_size = load_elf(tricoretb_binfo.kernel_filename, NULL, + NULL, (uint64_t *)entry, NULL, + NULL, 0, + ELF_MACHINE, 1); +if (kernel_size = 0) { +fprintf(stderr, qemu: no kernel file '%s'\n, +tricoretb_binfo.kernel_filename); +exit(1); +} +env-PC = entry; + +} + +static void tricore_testboard_init(MachineState *machine, int board_id) +{ +TRICORECPU *cpu; +CPUTRICOREState *env; + +MemoryRegion *sysmem = get_system_memory(); +MemoryRegion *ext_cram = g_new(MemoryRegion, 1); +MemoryRegion *ext_dram = g_new(MemoryRegion, 1); +MemoryRegion *int_cram = g_new(MemoryRegion, 1); +MemoryRegion *int_dram = g_new(MemoryRegion, 1); +MemoryRegion *pcp_data = g_new(MemoryRegion, 1); +MemoryRegion *pcp_text = g_new(MemoryRegion, 1); +DriveInfo *dinfo; + +if (!machine-cpu_model) { +machine-cpu_model = tc1796; +} +cpu = cpu_tricore_init(machine-cpu_model); +env = cpu-env; +if (!cpu) { +fprintf(stderr, Unable to find CPU definition\n); +exit(1); +} +memory_region_init_ram(ext_cram, NULL, powerlink_ext_c.ram, 2*1024*1024); +vmstate_register_ram_global(ext_cram); +memory_region_init_ram(ext_dram, NULL, powerlink_ext_d.ram, 4*1024*1024); +vmstate_register_ram_global(ext_dram); +memory_region_init_ram(int_cram, NULL, powerlink_int_c.ram, 48*1024); +vmstate_register_ram_global(int_cram); +memory_region_init_ram(int_dram, NULL, powerlink_int_d.ram, 48*1024); +vmstate_register_ram_global(int_dram); +memory_region_init_ram(pcp_data, NULL, powerlink_pcp_data.ram, 16*1024); +vmstate_register_ram_global(pcp_data); +memory_region_init_ram(pcp_text, NULL, powerlink_pcp_text.ram, 32*1024); +vmstate_register_ram_global(pcp_text); + +memory_region_add_subregion(sysmem, 0x8000, ext_cram); +memory_region_add_subregion(sysmem, 0xa100, ext_dram); +memory_region_add_subregion(sysmem, 0xd400, int_cram); +memory_region_add_subregion(sysmem, 0xd000, int_dram); +memory_region_add_subregion(sysmem, 0xf005, pcp_data); +memory_region_add_subregion(sysmem, 0xf006, pcp_text); + +dinfo = drive_get(IF_PFLASH, 0, 0); +if (!pflash_cfi01_register(TRICORE_FLASH_ADDR, NULL, + tricore_testboard.flash, + TRICORE_FLASH_SIZE, dinfo ? dinfo-bdrv : NULL, + TRICORE_FLASH_SECT_SIZE, + TRICORE_FLASH_SIZE / TRICORE_FLASH_SECT_SIZE, + 2, 0x00, 0x00, 0x, 0x0, 0)) { + +fprintf(stderr, qemu: Error registering flash memory.\n); +} else { +env-PC = TRICORE_FLASH_ADDR; +} + +tricoretb_binfo.ram_size = machine-ram_size; +tricoretb_binfo.kernel_filename = machine-kernel_filename; + +if (machine-kernel_filename) { +tricore_load_kernel(env); +} +} + +static void tricoreboard_init(MachineState *machine) +{ +tricore_testboard_init(machine, 0x183); +} + +static QEMUMachine ttb_machine = { +.name = TriCore testboard, +.desc = Just for testing, +.init = tricoreboard_init, +.is_default = 1, +}; + +static void tricore_testboard_machine_init(void) +{ +qemu_register_machine(ttb_machine); +} +
[Qemu-devel] [PATCH v5 15/15] target-tricore: Add instructions of SR opcode format
Add instructions of SR opcode format. Add micro-op generator functions for saturate. Add helper return from exception (rfe). Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- v4 - v5: - Switched sat_neg and arg in first movcond in function gen_saturate. - SR_NOT: Remove if checking OP2. target-tricore/helper.h| 1 + target-tricore/op_helper.c | 52 + target-tricore/translate.c | 111 + 3 files changed, 164 insertions(+) diff --git a/target-tricore/helper.h b/target-tricore/helper.h index 3c73234..7b7d74b 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -22,3 +22,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32) DEF_HELPER_2(call, void, env, i32) DEF_HELPER_1(ret, void, env) DEF_HELPER_2(bisr, void, env, i32) +DEF_HELPER_1(rfe, void, env) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 4ea94d8..4174ef9 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -99,6 +99,21 @@ static int cdc_decrement(target_ulong *psw) return 0; } +static bool cdc_zero(target_ulong *psw) +{ +int cdc = *psw MASK_PSW_CDC; +/* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == + 7'b111, otherwise returns FALSE. */ +if (cdc == 0x7f) { +return true; +} +/* find CDC.COUNT */ +int lo = clo32((*psw MASK_PSW_CDC) (32 - 7)); +int mask = (1u (7 - lo)) - 1; +int count = *psw mask; +return count == 0; +} + static void save_context_upper(CPUTRICOREState *env, int ea, target_ulong *new_FCX) { @@ -302,6 +317,43 @@ void helper_bisr(CPUTRICOREState *env, uint32_t const9) } } +void helper_rfe(CPUTRICOREState *env) +{ +target_ulong ea; +target_ulong new_PCXI; +target_ulong new_PSW; +/* if (PCXI[19: 0] == 0) then trap(CSU); */ +if ((env-PCXI 0xf) == 0) { +/* raise csu trap */ +} +/* if (PCXI.UL == 0) then trap(CTYP); */ +if ((env-PCXI MASK_PCXI_UL) == 0) { +/* raise CTYP trap */ +} +/* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ +if (!cdc_zero((env-PSW)) (env-PSW MASK_PSW_CDE)) { +/* raise MNG trap */ +} +/* ICR.IE = PCXI.PIE; */ +env-ICR = (env-ICR ~MASK_ICR_IE) + ((env-PCXI MASK_PCXI_PIE) 15); +/* ICR.CCPN = PCXI.PCPN; */ +env-ICR = (env-ICR ~MASK_ICR_CCPN) + + ((env-PCXI MASK_PCXI_PCPN) 24); +/*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ +ea = ((env-PCXI MASK_PCXI_PCXS) 12) + + ((env-PCXI MASK_PCXI_PCXO) 6); +/*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], + A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); + M(EA, word) = FCX;*/ +restore_context_upper(env, ea, new_PCXI, new_PSW); +/* FCX[19: 0] = PCXI[19: 0]; */ +env-FCX = (env-FCX 0xfff0) + (env-PCXI 0x000f); +/* PCXI = new_PCXI; */ +env-PCXI = new_PCXI; +/* write psw */ +psw_write(env, new_PSW); +} + static inline void QEMU_NORETURN do_raise_exception_err(CPUTRICOREState *env, uint32_t exception, int error_code, diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 5efa022..7466c21 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -262,6 +262,29 @@ static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2) tcg_temp_free(low); } +static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low) +{ +TCGv sat_neg = tcg_const_i32(low); +TCGv temp = tcg_const_i32(up); + +/* sat_neg = (arg low ) ? low : arg; */ +tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg); + +/* ret = (sat_neg up ) ? up : sat_neg; */ +tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg); + +tcg_temp_free(sat_neg); +tcg_temp_free(temp); +} + +static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up) +{ +TCGv temp = tcg_const_i32(up); +/* sat_neg = (arg up ) ? up : arg; */ +tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg); +tcg_temp_free(temp); +} + static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count) { if (shift_count == -32) { @@ -475,6 +498,15 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, case OPC1_16_SBR_LOOP: gen_loop(ctx, r1, offset * 2 - 32); break; +/* SR-format jumps */ +case OPC1_16_SR_JI: +tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffe); +tcg_gen_exit_tb(0); +break; +case OPC2_16_SR_RET: +gen_helper_ret(cpu_env); +tcg_gen_exit_tb(0); +break; default: printf(Branch Error at %x\n, ctx-pc); } @@ -792,6 +824,70 @@ static void decode_sro_opc(DisasContext *ctx, int op1) } } +static void
[Qemu-devel] [PATCH v5 03/15] target-tricore: Add softmmu support
Add basic softmmu support for TriCore Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de --- target-tricore/helper.c| 54 +- target-tricore/op_helper.c | 33 +++- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/target-tricore/helper.c b/target-tricore/helper.c index 7d8fc30..9176add 100644 --- a/target-tricore/helper.c +++ b/target-tricore/helper.c @@ -24,10 +24,62 @@ #include cpu.h +enum { +TLBRET_DIRTY = -4, +TLBRET_INVALID = -3, +TLBRET_NOMATCH = -2, +TLBRET_BADADDR = -1, +TLBRET_MATCH = 0 +}; + +#if defined(CONFIG_SOFTMMU) +static int get_physical_address(CPUTRICOREState *env, hwaddr *physical, +int *prot, target_ulong address, +int rw, int access_type) +{ +int ret = TLBRET_MATCH; + +*physical = address 0x; +*prot = PAGE_READ | PAGE_WRITE; + +return ret; +} +#endif + +/* TODO: Add exeption support*/ +static void raise_mmu_exception(CPUTRICOREState *env, target_ulong address, +int rw, int tlb_error) +{ +} + int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address, int rw, int mmu_idx) { -return 0; +TRICORECPU *cpu = TRICORE_CPU(cs); +CPUTRICOREState *env = cpu-env; +hwaddr physical; +int prot; +int access_type; +int ret = 0; + +rw = 1; +access_type = ACCESS_INT; +ret = get_physical_address(env, physical, prot, + address, rw, access_type); +qemu_log(%s address= TARGET_FMT_lx ret %d physical TARGET_FMT_plx + prot %d\n, __func__, address, ret, physical, prot); + +if (ret == TLBRET_MATCH) { +tlb_set_page(cs, address TARGET_PAGE_MASK, + physical TARGET_PAGE_MASK, prot | PAGE_EXEC, + mmu_idx, TARGET_PAGE_SIZE); +ret = 0; +} else if (ret 0) { +raise_mmu_exception(env, address, rw, ret); +ret = 1; +} + +return ret; } void tricore_cpu_do_interrupt(CPUState *cs) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 275790b..2e5981f 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -20,8 +20,39 @@ #include exec/helper-proto.h #include exec/cpu_ldst.h +static inline void QEMU_NORETURN do_raise_exception_err(CPUTRICOREState *env, +uint32_t exception, +int error_code, +uintptr_t pc) +{ +CPUState *cs = CPU(tricore_env_get_cpu(env)); +cs-exception_index = exception; +env-error_code = error_code; + +if (pc) { +/* now we have a real cpu fault */ +cpu_restore_state(cs, pc); +} + +cpu_loop_exit(cs); +} + +static inline void QEMU_NORETURN do_raise_exception(CPUTRICOREState *env, +uint32_t exception, +uintptr_t pc) +{ +do_raise_exception_err(env, exception, 0, pc); +} + void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { +int ret; +ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx); +if (ret) { +TRICORECPU *cpu = TRICORE_CPU(cs); +CPUTRICOREState *env = cpu-env; +do_raise_exception_err(env, cs-exception_index, + env-error_code, retaddr); +} } - -- 2.0.4
[Qemu-devel] [PATCH v5 00/15] TriCore architecture guest implementation
Hi, my aim is to add Infineon's TriCore architecture to QEMU. This series of patches adds the target stubs, a basic testboard and a softmmu for system mode emulation. Furthermore it adds all the 16 bit long instructions of the architecture grouped by opcode format. After this series of patches. Another one will follow, which adds a lot of the 32 bit long instructions. All the best Bastian v4 - v5: - Change documentation of S, SV bits to use bit 31. - psw_read/_write now uses only bit 31 of S, SV bits. - gen_intermediate_code_internal: Move calculation of next_pc after the ifs for singlestep and long tbs. - gen_shaci: Change case of shift_count == 32 to shift_count == -32 and add the clear of V bit. - gen_shaci: Move creation and freeing of t_max, t_min to case shift_count 0. - gen_shaci: Add cast to int32_t to the creation of t_min. - gen_shaci: Now msk is 1 bit longer and uses a positive value of shift_count in the else case. - gen_shaci: now computes V bit in bit 31. - gen_shaci: Move computation of shift after the computation of PSW bits to handle the case of ret = r1. - gen_shaci: Add clear of V bit for cases shift_count = 0 / = -32 / 0. - gen_add_d now saves result of addition into tcg temp to handle ret = r1 cases. - gen_cond_add now sets SV, SAV bits conditionally. - gen_cond_add now writes result after PSW bit computations, to handle ret = r1 cases. - Change int cond to TCGCond on function gen_cond_add, gen_condi_add. - Switched source and destination register of SRC_ADD_A15 and SRC_ADD_15A insns. - Negate conditions of 16_SRC_CMOV and 16_SRC_CMOVN insns. - SRC_MOV_A loads const4 zero extended. (Googled alot to find a manual saying it should be sign extended, but couldn't. 1.3 and 1.6 manual state sign extension) - RSUB now computes V bit in bit 31. - gen_sub_d now saves result of substraction into tcg temp to handle ret = r1 cases. - gen_mul_i32s now calculates V, SV bits in bit 31. - SSOV makro now computes V, SV bits in bit 31. - Negate conditions of 16_SRR_CMOV and 16_SRR_CMOVN insns. - MOV_AA: Switch r1 and r2 arguments. - decode_16Bit_opc: Add if to handle ADDSC.A opcode being 6 bit instead of 7 bit long. - Change int cond to TCGCond in functions gen_branch_cond, gen_branch_condi. - gen_intermediate_code_internal: Add gen_goto_tb so qemu finds new tb on singlestep and after long tbs without branch. - Switched sat_neg and arg in first movcond in function gen_saturate. - SR_NOT: Remove if checking OP2. Bastian Koppelmann (15): target-tricore: Add target stubs and qom-cpu target-tricore: Add board for systemmode target-tricore: Add softmmu support target-tricore: Add initialization for translation and activate target target-tricore: Add masks and opcodes for decoding target-tricore: Add instructions of SRC opcode format target-tricore: Add instructions of SRR opcode format target-tricore: Add instructions of SSR opcode format target-tricore: Add instructions of SRRS and SLRO opcode format target-tricore: Add instructions of SB opcode format target-tricore: Add instructions of SBC and SBRN opcode format target-tricore: Add instructions of SBR opcode format target-tricore: Add instructions of SC opcode format target-tricore: Add instructions of SLR, SSRO and SRO opcode format target-tricore: Add instructions of SR opcode format arch_init.c |2 + configure |5 + cpu-exec.c | 11 +- cpus.c |6 + default-configs/tricore-softmmu.mak |3 + hw/tricore/Makefile.objs|1 + hw/tricore/tricore_testboard.c | 129 include/elf.h |2 + include/hw/tricore/tricore.h| 54 ++ include/sysemu/arch_init.h |1 + target-tricore/Makefile.objs|1 + target-tricore/cpu-qom.h| 71 ++ target-tricore/cpu.c| 191 + target-tricore/cpu.h| 400 ++ target-tricore/helper.c | 144 target-tricore/helper.h | 25 + target-tricore/op_helper.c | 392 ++ target-tricore/translate.c | 1259 +++ target-tricore/tricore-defs.h | 28 + target-tricore/tricore-opcodes.h| 1406 +++ 20 files changed, 4130 insertions(+), 1 deletion(-) create mode 100644 default-configs/tricore-softmmu.mak create mode 100644 hw/tricore/Makefile.objs create mode 100644 hw/tricore/tricore_testboard.c create mode 100644 include/hw/tricore/tricore.h create mode 100644 target-tricore/Makefile.objs create mode 100644 target-tricore/cpu-qom.h create mode 100644 target-tricore/cpu.c create mode 100644 target-tricore/cpu.h create mode 100644 target-tricore/helper.c create mode 100644 target-tricore/helper.h
Re: [Qemu-devel] [PATCH] spapr: Make machine naming conventions closer to those for PC
David Gibson da...@gibson.dropbear.id.au writes: As of qemu-2.1, spapr/pseries, has a set of versioned machine classes to represent the machine type as it appeared to the guest in different qemu versions. This allows for safe migration of guests between current and future qemu versions. In PC, however, the default plain pc machine type is just an alias for the most recent versioned machine type. In sPAPR at the moment, it names the base machine class from which the versioned types are derived. The PC approach is preferable; it makes it clearer which explicit version is the current one. Additionally updating the current machine as the base class makes it even more likely than otherwise to incorrectly alter the versioned machines' behaviour when updating the current machine. Therefore this patch changes sPAPR to the PC approach - the base class becomes abstract, and plain pseries becomes an alias for the most recent versioned machine class. Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/ppc/spapr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d01978f..2785dbc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1583,7 +1583,6 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc-name = pseries; mc-desc = pSeries Logical Partition (PAPR compliant); -mc-is_default = 1; mc-init = ppc_spapr_init; mc-reset = ppc_spapr_reset; mc-block_default_type = IF_SCSI; I suspect many of these assignments are actually overwritten by the derived machine types' class init function. Without that, mc-name = pseries would clash with the mc-alias = pseries below, wouldn't i? Care to trim the redundant assignments? @@ -1598,6 +1597,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) static const TypeInfo spapr_machine_info = { .name = TYPE_SPAPR_MACHINE, .parent= TYPE_MACHINE, +.abstract = true, .instance_size = sizeof(sPAPRMachineState), .instance_init = spapr_machine_initfn, .class_init= spapr_machine_class_init, @@ -1613,7 +1613,8 @@ static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) mc-name = pseries-2.1; mc-desc = pSeries Logical Partition (PAPR compliant) v2.1; -mc-is_default = 0; +mc-alias = pseries; +mc-is_default = 1; } static const TypeInfo spapr_machine_2_1_info = {
[Qemu-devel] [PATCH] mlock: fix bug when mlockall called before mbind
If we configure qemu with realtime-mlock-on and memory-node-bind at the same time, Qemu will fail to start, and mbind() fails with message Input/output error. From man page: int mbind(void *addr, unsigned long len, int mode, unsigned long *nodemask, unsigned long maxnode, unsigned flags); The *MPOL_BIND* mode specifies a strict policy that restricts memory allocation to the nodes specified in nodemask. If *MPOL_MF_STRICT* is passed in flags and policy is not MPOL_DEFAULT(In qemu here is MPOL_BIND), then the call will fail with the error EIO if the existing pages in the memory range don't follow the policy. The memory locked ahead by mlockall can not guarantee to follow the policy above, And if that happens, it will result in an EIO error. So we should call mlock after mbind, here we adjust the place where called mlock, Move it to function pc_memory_init. Signed-off-by: xiexiangyou xiexiang...@huawei.com Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- hw/i386/pc.c| 8 include/sysemu/sysemu.h | 1 + vl.c| 10 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9e58982..08a03c2 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1321,6 +1321,14 @@ FWCfgState *pc_memory_init(MachineState *machine, for (i = 0; i nb_option_roms; i++) { rom_add_option(option_rom[i].name, option_rom[i].bootindex); } + +if (enable_mlock) { +if (os_mlock() 0) { +error_report(qemu: locking memory failed\n); +exit(EXIT_FAILURE); +} +} + guest_info-fw_cfg = fw_cfg; return fw_cfg; } diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index d8539fd..b61e78f 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -136,6 +136,7 @@ extern uint8_t qemu_extra_params_fw[2]; extern QEMUClockType rtc_clock; extern const char *mem_path; extern int mem_prealloc; +extern bool enable_mlock; #define MAX_NODES 128 diff --git a/vl.c b/vl.c index a8029d5..9a19d97 100644 --- a/vl.c +++ b/vl.c @@ -134,6 +134,7 @@ const char* keyboard_layout = NULL; ram_addr_t ram_size; const char *mem_path = NULL; int mem_prealloc = 0; /* force preallocation of physical target memory */ +bool enable_mlock = false; int nb_nics; NICInfo nd_table[MAX_NICS]; int autostart; @@ -1419,16 +1420,7 @@ static void smp_parse(QemuOpts *opts) static void configure_realtime(QemuOpts *opts) { -bool enable_mlock; - enable_mlock = qemu_opt_get_bool(opts, mlock, true); - -if (enable_mlock) { -if (os_mlock() 0) { -fprintf(stderr, qemu: locking memory failed\n); -exit(1); -} -} } -- 1.7.12.4
Re: [Qemu-devel] The status about vhost-net on kvm-arm?
On Wed, Aug 13, 2014 at 12:10 PM, Nikolay Nikolaev n.nikol...@virtualopensystems.com wrote: On Tue, Aug 12, 2014 at 6:47 PM, Nikolay Nikolaev n.nikol...@virtualopensystems.com wrote: Hello, On Tue, Aug 12, 2014 at 5:41 AM, Li Liu john.li...@huawei.com wrote: Hi all, Is anyone there can tell the current status of vhost-net on kvm-arm? Half a year has passed from Isa Ansharullah asked this question: http://www.spinics.net/lists/kvm-arm/msg08152.html I have found two patches which have provided the kvm-arm support of eventfd and irqfd: 1) [RFC PATCH 0/4] ARM: KVM: Enable the ioeventfd capability of KVM on ARM http://lists.gnu.org/archive/html/qemu-devel/2014-01/msg01770.html 2) [RFC,v3] ARM: KVM: add irqfd and irq routing support https://patches.linaro.org/32261/ And there's a rough patch for qemu to support eventfd from Ying-Shiuan Pan: [Qemu-devel] [PATCH 0/4] ioeventfd support for virtio-mmio https://lists.gnu.org/archive/html/qemu-devel/2014-02/msg00715.html But there no any comments of this patch. And I can found nothing about qemu to support irqfd. Do I lost the track? If nobody try to fix it. We have a plan to complete it about virtio-mmio supporing irqfd and multiqueue. we at Virtual Open Systems did some work and tested vhost-net on ARM back in March. The setup was based on: - host kernel with our ioeventfd patches: http://www.spinics.net/lists/kvm-arm/msg08413.html - qemu with the aforementioned patches from Ying-Shiuan Pan https://lists.gnu.org/archive/html/qemu-devel/2014-02/msg00715.html The testbed was ARM Chromebook with Exynos 5250, using a 1Gbps USB3 Ethernet adapter connected to a 1Gbps switch. I can't find the actual numbers but I remember that with multiple streams the gain was clearly seen. Note that it used the minimum required ioventfd implementation and not irqfd. I guess it is feasible to think that it all can be put together and rebased + the recent irqfd work. One can achiev even better performance (because of the irqfd). Managed to replicate the setup with the old versions e used in March: Single stream from another machine to chromebook with 1Gbps USB3 Ethernet adapter. iperf -c address -P 1 -i 1 -p 5001 -f k -t 10 to HOST: 858316 Kbits/sec to GUEST: 761563 Kbits/sec to GUEST vhost=off: 508150 Kbits/sec 10 parallel streams iperf -c address -P 10 -i 1 -p 5001 -f k -t 10 to HOST: 842420 Kbits/sec to GUEST: 625144 Kbits/sec to GUEST vhost=off: 425276 Kbits/sec ___ kvmarm mailing list kvm...@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm regards, Nikolay Nikolaev Virtual Open Systems
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
Hi Paolo, On Tue, Aug 12, 2014 at 3:37 AM, Paolo Bonzini pbonz...@redhat.com wrote: Il 10/08/2014 05:46, Ming Lei ha scritto: Hi Kevin, Paolo, Stefan and all, On Wed, 6 Aug 2014 10:48:55 +0200 Kevin Wolf kw...@redhat.com wrote: Am 06.08.2014 um 07:33 hat Ming Lei geschrieben: Anyhow, the coroutine version of your benchmark is buggy, it leaks all coroutines instead of exiting them, so it can't make any use of the coroutine pool. On my laptop, I get this (where fixed coroutine is a version that simply removes the yield at the end): | bypass| fixed coro| buggy coro +---+---+-- time| 1.09s | 1.10s | 1.62s L1-dcache-loads | 921,836,360 | 932,781,747 | 1,298,067,438 insns per cycle | 2.39 | 2.39 | 1.90 Begs the question whether you see a similar effect on a real qemu and the coroutine pool is still not big enough? With correct use of coroutines, the difference seems to be barely measurable even without any I/O involved. Now I fixes the coroutine leak bug, and previous crypt bench is a bit high loading, and cause operations per sec very low(~40K/sec), finally I write a new and simple one which can generate hundreds of kilo operations per sec and the number should match with some fast storage devices, and it does show there is not small effect from coroutine. Extremely if just getppid() syscall is run in each iteration, with using coroutine, only 3M operations/sec can be got, and without using coroutine, the number can reach 16M/sec, and there is more than 4 times difference!!! I should be on vacation, but I'm following a couple threads in the mailing list and I'm a bit tired to hear the same argument again and again... The different characteristics of asynchronous I/O vs. any synchronous workload are such that it is hard to be sure that microbenchmarks make sense. The below patch is basically the minimal change to bypass coroutines. Of course the block.c part is not acceptable as is (the change to refresh_total_sectors is broken, the others are just ugly), but it is a start. Please run it with your fio workloads, or write an aio-based version of a qemu-img/qemu-io *I/O* benchmark. I have to say this approach is much cleaver, and better than mine, and I just run a quick fio randread test in VM, and IOPS can improve 10% than bypass coroutine patch. Hope it can be merged soon, :-) Great thanks, Paolo. Thanks, Paolo diff --git a/block.c b/block.c index 3e252a2..0b6e9cf 100644 --- a/block.c +++ b/block.c @@ -704,7 +704,7 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) return 0; /* query actual device if possible, otherwise just trust the hint */ -if (drv-bdrv_getlength) { +if (!hint drv-bdrv_getlength) { int64_t length = drv-bdrv_getlength(bs); if (length 0) { return length; @@ -2651,9 +2651,6 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, if (!bdrv_is_inserted(bs)) return -ENOMEDIUM; -if (bs-growable) -return 0; - len = bdrv_getlength(bs); if (offset 0) @@ -3107,7 +3104,7 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs, if (!drv) { return -ENOMEDIUM; } -if (bdrv_check_byte_request(bs, offset, bytes)) { +if (!bs-growable bdrv_check_byte_request(bs, offset, bytes)) { return -EIO; } @@ -3347,7 +3344,7 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs, if (bs-read_only) { return -EACCES; } -if (bdrv_check_byte_request(bs, offset, bytes)) { +if (!bs-growable bdrv_check_byte_request(bs, offset, bytes)) { return -EIO; } @@ -4356,6 +4353,20 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, { trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); +if (bs-drv bs-drv-bdrv_aio_readv +bs-drv-bdrv_aio_readv != bdrv_aio_readv_em +nb_sectors = 0 nb_sectors = (UINT_MAX BDRV_SECTOR_BITS) +!bdrv_check_byte_request(bs, sector_num BDRV_SECTOR_BITS, + nb_sectors BDRV_SECTOR_BITS) +!bs-copy_on_read !bs-io_limits_enabled +bs-request_alignment = BDRV_SECTOR_SIZE) { +BlockDriverAIOCB *acb = +bs-drv-bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, +cb, opaque); +assert(acb); +return acb; +} + return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0, cb, opaque, false); } @@ -4366,6 +4377,24 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, { trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); +if (bs-drv
Re: [Qemu-devel] [PATCH] mlock: fix bug when mlockall called before mbind
On Wed, Aug 13, 2014 at 07:21:57PM +0800, zhanghailiang wrote: If we configure qemu with realtime-mlock-on and memory-node-bind at the same time, Qemu will fail to start, and mbind() fails with message Input/output error. From man page: int mbind(void *addr, unsigned long len, int mode, unsigned long *nodemask, unsigned long maxnode, unsigned flags); The *MPOL_BIND* mode specifies a strict policy that restricts memory allocation to the nodes specified in nodemask. If *MPOL_MF_STRICT* is passed in flags and policy is not MPOL_DEFAULT(In qemu here is MPOL_BIND), then the call will fail with the error EIO if the existing pages in the memory range don't follow the policy. The memory locked ahead by mlockall can not guarantee to follow the policy above, And if that happens, it will result in an EIO error. So we should call mlock after mbind, here we adjust the place where called mlock, Move it to function pc_memory_init. Signed-off-by: xiexiangyou xiexiang...@huawei.com Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com OK but won't this still fail in case of memory hotplug? We set MCL_FUTURE so the same will apply? Maybe it's enough to set MPOL_MF_MOVE? Does the following work for you? -- hostmem: set MPOL_MF_MOVE When memory is allocated on a wrong node, MPOL_MF_STRICT doesn't move it - it just fails the allocation. A simple way to reproduce the failure is with mlock=on realtime feature. The code comment actually says: ensure policy won't be ignored so setting MPOL_MF_MOVE seems like a better way to do this. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- diff --git a/backends/hostmem.c b/backends/hostmem.c index ca10c51..a9905c0 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -304,7 +304,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) /* ensure policy won't be ignored in case memory is preallocated * before mbind(). note: MPOL_MF_STRICT is ignored on hugepages so * this doesn't catch hugepage case. */ -unsigned flags = MPOL_MF_STRICT; +unsigned flags = MPOL_MF_STRICT | MPOL_MF_MOVE; /* check for invalid host-nodes and policies and give more verbose * error messages than mbind(). */ -- MST
Re: [Qemu-devel] [PATCH] Qemu: Fix eax for cpuid leaf 0x40000000
Il 12/08/2014 21:29, Eduardo Habkost ha scritto: On Tue, Aug 12, 2014 at 09:12:00PM +0200, Paolo Bonzini wrote: Il 12/08/2014 20:55, Eduardo Habkost ha scritto: This makes the CPUID data change under the guest's feet during live-migration. Adding compat code to ensure older machine-types keep the old behavior is necessary, but in this specific case it is mostly harmless because 0x0 is documented as being equivalent to 0x4001. (But I don't know how guests are supposed to behave when they see CPUID[KVM_CPUID_SIGNATURE_NEXT].EAX==0.) The only obvious thing to do would be to treat it as 0x4101. I just want to be sure the guests really do that. If we know guests won't do anything different with the CPUID change, I won't mind having no compat code for this. Considering that only two leaves are defined for KVM, and both are mandatory I don't think current guests have any reason to look at CPUID[KVM_CPUID_SIGNATURE | kvm_base].EAX at all. Paolo
Re: [Qemu-devel] [V2 PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
On Tue, Aug 12, 2014 at 01:53:40PM -0500, Tom Musta wrote: The ELF V2 ABI for PPC64 defines MINSIGSTKSZ as 4096 bytes whereas it was 2048 previously. fails to build - need to make get_ppc64_abi a properly exported function. Signed-off-by: Tom Musta tommu...@gmail.com --- V2: Define and use TARGET_MINSIGSTKSZ constants from the various linux-user/$ARCH/syscall.h files (per Peter Maydell's review). There is still a runtime check for PPC64 since the stack size changes in ELF V2. linux-user/aarch64/syscall.h|1 + linux-user/alpha/syscall.h |1 + linux-user/arm/syscall.h|2 ++ linux-user/cris/syscall.h |1 + linux-user/i386/syscall.h |1 + linux-user/m68k/syscall.h |2 ++ linux-user/microblaze/syscall.h |1 + linux-user/mips/syscall.h |1 + linux-user/mips64/syscall.h |1 + linux-user/openrisc/syscall.h |2 ++ linux-user/ppc/syscall.h|2 ++ linux-user/s390x/syscall.h |1 + linux-user/sh4/syscall.h|2 ++ linux-user/signal.c | 12 +++- linux-user/sparc/syscall.h |1 + linux-user/sparc64/syscall.h|1 + linux-user/unicore32/syscall.h |2 ++ linux-user/x86_64/syscall.h |1 + 18 files changed, 34 insertions(+), 1 deletions(-) diff --git a/linux-user/aarch64/syscall.h b/linux-user/aarch64/syscall.h index 18f44a8..d1f4823 100644 --- a/linux-user/aarch64/syscall.h +++ b/linux-user/aarch64/syscall.h @@ -8,3 +8,4 @@ struct target_pt_regs { #define UNAME_MACHINE aarch64 #define UNAME_MINIMUM_RELEASE 3.8.0 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/alpha/syscall.h b/linux-user/alpha/syscall.h index ed13d9a..3adedeb 100644 --- a/linux-user/alpha/syscall.h +++ b/linux-user/alpha/syscall.h @@ -252,3 +252,4 @@ struct target_pt_regs { #define TARGET_UAC_NOPRINT 1 #define TARGET_UAC_NOFIX 2 #define TARGET_UAC_SIGBUS4 +#define TARGET_MINSIGSTKSZ 4096 diff --git a/linux-user/arm/syscall.h b/linux-user/arm/syscall.h index e0d2cc3..cdadb0c 100644 --- a/linux-user/arm/syscall.h +++ b/linux-user/arm/syscall.h @@ -44,3 +44,5 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS + +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/cris/syscall.h b/linux-user/cris/syscall.h index f5783c0..a75bcc4 100644 --- a/linux-user/cris/syscall.h +++ b/linux-user/cris/syscall.h @@ -39,5 +39,6 @@ struct target_pt_regs { }; #define TARGET_CLONE_BACKWARDS2 +#define TARGET_MINSIGSTKSZ 2048 #endif diff --git a/linux-user/i386/syscall.h b/linux-user/i386/syscall.h index 9bfc1ad..acf6856 100644 --- a/linux-user/i386/syscall.h +++ b/linux-user/i386/syscall.h @@ -147,3 +147,4 @@ struct target_vm86plus_struct { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/m68k/syscall.h b/linux-user/m68k/syscall.h index 889eaf7..f8553f8 100644 --- a/linux-user/m68k/syscall.h +++ b/linux-user/m68k/syscall.h @@ -18,4 +18,6 @@ struct target_pt_regs { #define UNAME_MACHINE m68k #define UNAME_MINIMUM_RELEASE 2.6.32 +#define TARGET_MINSIGSTKSZ 2048 + void do_m68k_simcall(CPUM68KState *, int); diff --git a/linux-user/microblaze/syscall.h b/linux-user/microblaze/syscall.h index 5b5f6b4..2a5e160 100644 --- a/linux-user/microblaze/syscall.h +++ b/linux-user/microblaze/syscall.h @@ -49,5 +49,6 @@ struct target_pt_regs { }; #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 #endif diff --git a/linux-user/mips/syscall.h b/linux-user/mips/syscall.h index 5bc5696..0b4662c 100644 --- a/linux-user/mips/syscall.h +++ b/linux-user/mips/syscall.h @@ -228,3 +228,4 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h index a7f5a58..39b8bed 100644 --- a/linux-user/mips64/syscall.h +++ b/linux-user/mips64/syscall.h @@ -225,3 +225,4 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/openrisc/syscall.h b/linux-user/openrisc/syscall.h index c3b36da..e5e6180 100644 --- a/linux-user/openrisc/syscall.h +++ b/linux-user/openrisc/syscall.h @@ -23,3 +23,5 @@ struct target_pt_regs { #define UNAME_MACHINE openrisc #define UNAME_MINIMUM_RELEASE 2.6.32 + +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/ppc/syscall.h b/linux-user/ppc/syscall.h index db92bbe..5311cc6 100644 --- a/linux-user/ppc/syscall.h +++ b/linux-user/ppc/syscall.h @@ -69,3 +69,5 @@ struct target_revectored_struct { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS +
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
Il 13/08/2014 12:19, Ming Lei ha scritto: The problem is that your patches to do touch too much code and subtly break too much stuff. The one I wrote does have a little breakage Could you give a hint about which stuff are broken? Last time, you mention virtio-scsi need to keep AIOCB live after returning, I have fixed it in V1. They are dataplane-specific, while there's no reason not to have the same benefits elsewhere. They are file-specific, while there's no reason not to have the same benefits for e.g. iSCSI (though iSCSI now uses coroutines instead of bdrv_aio_*). They touch AioContext for no reason, and introduce a bunch of layering violations everywhere. They are simply the wrong API. because I don't understand bs-growable 100% and I didn't really put much effort into it (my deadline being basically be done as soon as the shower is free), and it is ugly as hell, _but_ it should be compatible with the way the block layer works. I will take a careful look to your patch later. If coroutine is still there, I think it still can slow down performance. No, it's not there. Please try the patch. Paolo
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
Il 13/08/2014 13:43, Ming Lei ha scritto: The below patch is basically the minimal change to bypass coroutines. Of course the block.c part is not acceptable as is (the change to refresh_total_sectors is broken, the others are just ugly), but it is a start. Please run it with your fio workloads, or write an aio-based version of a qemu-img/qemu-io *I/O* benchmark. I have to say this approach is much cleaver, and better than mine, and I just run a quick fio randread test in VM, and IOPS can improve 10% than bypass coroutine patch. Great, do you have a profile without and with the patch? Paolo
Re: [Qemu-devel] [PATCH] block.curl: adding 'curltimeout' option
On 08/13/2014 06:15 AM, Markus Armbruster wrote: Daniel Henrique Barboza danie...@linux.vnet.ibm.com writes: The curl hardcoded timeout (5 seconds) sometimes is not long enough depending on the remote server configuration and network traffic. The user should be able to set how much long he is willing to wait for the connection. Adding a new option to set this timeout gives the user this flexibility. The previous default timeout of 5 seconds will be used if this option is not present. Signed-off-by: Daniel Henrique Barboza danie...@linux.vnet.ibm.com --- block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/block/curl.c b/block/curl.c index 79ff2f1..a9e43f1 100644 --- a/block/curl.c +++ b/block/curl.c @@ -63,6 +63,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_NUM_ACB8 #define SECTOR_SIZE 512 #define READ_AHEAD_DEFAULT (256 * 1024) +#define CURL_TIMEOUT_DEFAULT 5 #define FIND_RET_NONE 0 #define FIND_RET_OK 1 @@ -71,6 +72,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_BLOCK_OPT_URL url #define CURL_BLOCK_OPT_READAHEAD readahead #define CURL_BLOCK_OPT_SSLVERIFY sslverify +#define CURL_BLOCK_OPT_TIMEOUT curltimeout To what could this timeout apply other than Curl? If nothing, then just timeout, please. Else, curl-timeout. I will investigate a little to check if there are any option called timeout used elsewhere. If not, I see no issues rename this option to timeout. Thanks! struct BDRVCURLState; @@ -109,6 +111,7 @@ typedef struct BDRVCURLState { char *url; size_t readahead_size; bool sslverify; +int curltimeout; bool accept_range; AioContext *aio_context; } BDRVCURLState; Likewise: either timeout, or curl_timeout. [...]
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
On Wed, Aug 13, 2014 at 8:35 PM, Paolo Bonzini pbonz...@redhat.com wrote: Il 13/08/2014 13:43, Ming Lei ha scritto: The below patch is basically the minimal change to bypass coroutines. Of course the block.c part is not acceptable as is (the change to refresh_total_sectors is broken, the others are just ugly), but it is a start. Please run it with your fio workloads, or write an aio-based version of a qemu-img/qemu-io *I/O* benchmark. I have to say this approach is much cleaver, and better than mine, and I just run a quick fio randread test in VM, and IOPS can improve 10% than bypass coroutine patch. Great, do you have a profile without and with the patch? Please see below link: http://pastebin.com/0VKSMKxv Ming
Re: [Qemu-devel] [PATCH] spapr: Make machine naming conventions closer to those for PC
Hi, Am 13.08.2014 03:23, schrieb David Gibson: As of qemu-2.1, spapr/pseries, has a set of versioned machine classes to represent the machine type as it appeared to the guest in different qemu versions. This allows for safe migration of guests between current and future qemu versions. In PC, however, the default plain pc machine type is just an alias for the most recent versioned machine type. In sPAPR at the moment, it names the base machine class from which the versioned types are derived. The PC approach is preferable; it makes it clearer which explicit version is the current one. Additionally updating the current machine as the base class makes it even more likely than otherwise to incorrectly alter the versioned machines' behaviour when updating the current machine. Therefore this patch changes sPAPR to the PC approach - the base class becomes abstract, and plain pseries becomes an alias for the most recent versioned machine class. Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/ppc/spapr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d01978f..2785dbc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1583,7 +1583,6 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc-name = pseries; mc-desc = pSeries Logical Partition (PAPR compliant); -mc-is_default = 1; mc-init = ppc_spapr_init; mc-reset = ppc_spapr_reset; mc-block_default_type = IF_SCSI; @@ -1598,6 +1597,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) static const TypeInfo spapr_machine_info = { .name = TYPE_SPAPR_MACHINE, .parent= TYPE_MACHINE, +.abstract = true, .instance_size = sizeof(sPAPRMachineState), .instance_init = spapr_machine_initfn, .class_init= spapr_machine_class_init, @@ -1613,7 +1613,8 @@ static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) mc-name = pseries-2.1; mc-desc = pSeries Logical Partition (PAPR compliant) v2.1; -mc-is_default = 0; +mc-alias = pseries; +mc-is_default = 1; } static const TypeInfo spapr_machine_2_1_info = { This looks wrong to me. With 2.1 released, the default should be a 2.2 machine, not 2.1. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v1 00/17] dataplane: optimization and multi virtqueue support
On Wed, Aug 13, 2014 at 9:16 PM, Paolo Bonzini pbonz...@redhat.com wrote: Il 13/08/2014 11:54, Kevin Wolf ha scritto: Am 12.08.2014 um 21:08 hat Paolo Bonzini geschrieben: Il 12/08/2014 10:12, Ming Lei ha scritto: The below patch is basically the minimal change to bypass coroutines. Of course the block.c part is not acceptable as is (the change to refresh_total_sectors is broken, the others are just ugly), but it is a start. Please run it with your fio workloads, or write an aio-based version of a qemu-img/qemu-io *I/O* benchmark. Could you explain why the new change is introduced? It provides a fast path for bdrv_aio_readv/writev whenever there is nothing to do after the driver routine returns. In this case there is no need to wrap the AIOCB returned by the driver routine. It doesn't go all the way, and in particular it doesn't reverse completely the roles of bdrv_co_readv/writev vs. bdrv_aio_readv/writev. That's actually why I think it's an option. Remember that, like you say below, we're optimising for an extreme case here, and I certainly don't want to hurt the common case for it. I can't imagine a way of reversing the roles without multiplying the cost for the coroutine path. I'm not that worried about it. Perhaps it's enough to add an !qemu_in_coroutine() to the AIO fast path, and let the driver provide optimized coroutine paths like in your patches that allocate AIOCBs on the stack. IMO, it will not be a extreme case as SSD or high performance storage becomes more popular, coroutine starts to affect performance if IOPS is more than 100K, as previous computation. Or do you have a clever solution how you'd go about it without having an impact on the common case? I don't really have any ace up my sleeve, but there are some things that bother me in the block layer's AIO API and in block.c in general. One is that block.c can do all the pre-processing it wants before issuing AIO, but nothing before calling the callback. This means that my patches break bdrv_drain_all (they cannot call tracked_request_end). Another is all the similar structs that we have (RwCo, BdrvTrackedRequest, BlockRequest, etc.). Perhaps it would help if we had a single real block request object, which is an extension of the BlockDriverAIOCB and includes enough data to subsume all these request structs. That should help commonizing stuff between the coroutine and AIO paths, for the common case where a single yield is enough. I think the single-yield case is the one that is really worth optimizing for. If done properly, I think this can simplify a lot of block.c code, but it is really difficult to get it right, and unless the design is sound the code is going to come up really ugly. :( Another thing to evaluate is the performance gap (if there is any) between aio=threads and aio=native. The only advantage of aio=native, AFAIU, is the batch submission of requests (plug/unplug). But aio=threads often ends up having better performance because the kernel folks have optimized VFS a lot. So, in the aio=threads case, we might From my test, aio=native is much better than aio=threads at least for read. For aio=thread, it may be possible to use batch submission too with readv/writev to decrease sycall. as well move the format code out of the iothread and into the worker thread, and get rid of the coroutine cost simply by making everything synchronous. Looking within QEMU, this worked out very well for migration. (We could do batch submission of requests to the thread pool if there were a variant of sem_post that can add multiple signals to the same semaphore, similar to ReleaseSemaphore on Windows). The problem is that your patches to do touch too much code and subtly break too much stuff. The one I wrote does have a little breakage because I don't understand bs-growable 100% and I didn't really put much effort into it (my deadline being basically be done as soon as the shower is free), and it is ugly as hell, _but_ it should be compatible with the way the block layer works. Yes, your patch is definitely much more palatable than Ming's. The part that I still don't like about it is that it would be stating in the common case, we're only doing the second best thing. I'm not yet convinced that coroutines perform necessarily worse than state-passing callbacks. Coroutines lump all the allocation costs together at the time you allocate the stack, but have (much) more expensive context switching. Yes, I agree. In my tests, one pair of malloc(128)/free(128) only takes 57ns, but two enter and one yield takes 240ns, not mention dcache reload miss caused by switching stack, and allocation fallback. Ming
Re: [Qemu-devel] [V2 PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
On 8/13/2014 7:31 AM, Riku Voipio wrote: On Tue, Aug 12, 2014 at 01:53:40PM -0500, Tom Musta wrote: The ELF V2 ABI for PPC64 defines MINSIGSTKSZ as 4096 bytes whereas it was 2048 previously. fails to build - need to make get_ppc64_abi a properly exported function. Riku: Sorry about this. There is already a patch in Alex's ppc-next tree (but not yet pulled into mainline) that does this: http://lists.nongnu.org/archive/html/qemu-devel/2014-06/msg07225.html I will republish V3 with this patch included. Signed-off-by: Tom Musta tommu...@gmail.com --- V2: Define and use TARGET_MINSIGSTKSZ constants from the various linux-user/$ARCH/syscall.h files (per Peter Maydell's review). There is still a runtime check for PPC64 since the stack size changes in ELF V2. linux-user/aarch64/syscall.h|1 + linux-user/alpha/syscall.h |1 + linux-user/arm/syscall.h|2 ++ linux-user/cris/syscall.h |1 + linux-user/i386/syscall.h |1 + linux-user/m68k/syscall.h |2 ++ linux-user/microblaze/syscall.h |1 + linux-user/mips/syscall.h |1 + linux-user/mips64/syscall.h |1 + linux-user/openrisc/syscall.h |2 ++ linux-user/ppc/syscall.h|2 ++ linux-user/s390x/syscall.h |1 + linux-user/sh4/syscall.h|2 ++ linux-user/signal.c | 12 +++- linux-user/sparc/syscall.h |1 + linux-user/sparc64/syscall.h|1 + linux-user/unicore32/syscall.h |2 ++ linux-user/x86_64/syscall.h |1 + 18 files changed, 34 insertions(+), 1 deletions(-) diff --git a/linux-user/aarch64/syscall.h b/linux-user/aarch64/syscall.h index 18f44a8..d1f4823 100644 --- a/linux-user/aarch64/syscall.h +++ b/linux-user/aarch64/syscall.h @@ -8,3 +8,4 @@ struct target_pt_regs { #define UNAME_MACHINE aarch64 #define UNAME_MINIMUM_RELEASE 3.8.0 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/alpha/syscall.h b/linux-user/alpha/syscall.h index ed13d9a..3adedeb 100644 --- a/linux-user/alpha/syscall.h +++ b/linux-user/alpha/syscall.h @@ -252,3 +252,4 @@ struct target_pt_regs { #define TARGET_UAC_NOPRINT 1 #define TARGET_UAC_NOFIX2 #define TARGET_UAC_SIGBUS 4 +#define TARGET_MINSIGSTKSZ 4096 diff --git a/linux-user/arm/syscall.h b/linux-user/arm/syscall.h index e0d2cc3..cdadb0c 100644 --- a/linux-user/arm/syscall.h +++ b/linux-user/arm/syscall.h @@ -44,3 +44,5 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS + +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/cris/syscall.h b/linux-user/cris/syscall.h index f5783c0..a75bcc4 100644 --- a/linux-user/cris/syscall.h +++ b/linux-user/cris/syscall.h @@ -39,5 +39,6 @@ struct target_pt_regs { }; #define TARGET_CLONE_BACKWARDS2 +#define TARGET_MINSIGSTKSZ 2048 #endif diff --git a/linux-user/i386/syscall.h b/linux-user/i386/syscall.h index 9bfc1ad..acf6856 100644 --- a/linux-user/i386/syscall.h +++ b/linux-user/i386/syscall.h @@ -147,3 +147,4 @@ struct target_vm86plus_struct { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/m68k/syscall.h b/linux-user/m68k/syscall.h index 889eaf7..f8553f8 100644 --- a/linux-user/m68k/syscall.h +++ b/linux-user/m68k/syscall.h @@ -18,4 +18,6 @@ struct target_pt_regs { #define UNAME_MACHINE m68k #define UNAME_MINIMUM_RELEASE 2.6.32 +#define TARGET_MINSIGSTKSZ 2048 + void do_m68k_simcall(CPUM68KState *, int); diff --git a/linux-user/microblaze/syscall.h b/linux-user/microblaze/syscall.h index 5b5f6b4..2a5e160 100644 --- a/linux-user/microblaze/syscall.h +++ b/linux-user/microblaze/syscall.h @@ -49,5 +49,6 @@ struct target_pt_regs { }; #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 #endif diff --git a/linux-user/mips/syscall.h b/linux-user/mips/syscall.h index 5bc5696..0b4662c 100644 --- a/linux-user/mips/syscall.h +++ b/linux-user/mips/syscall.h @@ -228,3 +228,4 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h index a7f5a58..39b8bed 100644 --- a/linux-user/mips64/syscall.h +++ b/linux-user/mips64/syscall.h @@ -225,3 +225,4 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_CLONE_BACKWARDS +#define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/openrisc/syscall.h b/linux-user/openrisc/syscall.h index c3b36da..e5e6180 100644 --- a/linux-user/openrisc/syscall.h +++ b/linux-user/openrisc/syscall.h @@ -23,3 +23,5 @@ struct target_pt_regs { #define UNAME_MACHINE openrisc #define UNAME_MINIMUM_RELEASE 2.6.32 + +#define TARGET_MINSIGSTKSZ 2048 diff --git
Re: [Qemu-devel] Microcheckpointing: Memory-VCPU / Disk State consistency
Yes... Time is a problem, and it‘s currently running out... ;-) I think the first step is to reason about possible approaches and how they can be implemented in QEMU. The implementation can follow later :-) Thank you for the hint with the drive-mirror feature. I will take a look at it and surely come back with new questions :-) I also think that disc replication ist the most pressing issue for MC. While looking to find some ideas for approaches to replicating block devices I have read the paper about the Remus implementation. I think MC can take a similar approach for local disk. Here are the main facts that I have understood: Local disk contents is viewed as internal state the primary and secondary. In the explanation they describe that for keeping disc semantics of the primary and to allow the primary to run speculatively all disc state changes are directly written to the disk. In parrallel and asynchronously send to the secondary. The secondary keeps the pending writing requests in two disk buffers. A speculation-disk-buffer and a write-out-buffer. After the reception of the next checkpoint the secondary copies the speculation buffer to the write out buffer, commits the checkpoint and applies the write out buffer to its local disk. When the primary fails the secondary must wait until write-out-buffer has been completely written to disk before before changing the execution mode to run as primary. In this case (failure of primary) the secondary discards pending disk writes in its speculation buffer. This protocol keeps the disc state consistent with the last checkpoint. Remus uses the XEN specific blktap driver. As far as I know this can’t be used with QEMU (KVM). I must see how drive-mirror can be used for this kind of protocol. Am 11.08.2014 22:15, schrieb Michael R. Hines: Excellent question: QEMU does have a feature called drive-mirror in block/mirror.c that was introduced a couple of years ago. I'm not sure what the adoption rate of the feature is, but I would start with that one. There is also a second fault tolerance implementation that works a little differently called COLO - you may have seen those emails on the list too, but their method does not require a disk replication solution, if I recall correctly. I have taken a look at COLO. They have also published a good paper about their approach. The paper is about the XEN implementation of COLO. It’s an interesting approach to use a coarse grained lockspepping combined with checkpointing. From what i have understood the possible show stopper for general application is the depency of COLO to custom changes of the tcp stack to make it more deterministic. IMHO there are two points. Custom changes of the TCP-Stack are a no-go for proprietary operating systems like Windows. It makes COLO application agnostic but not operating system agnostic. The other point is that with I/O intensive workloads COLO will tend to behave like MC. This is my point of view but i didn’t invest much time to understand everything in detail. I know the time pressure that comes during a thesis, though =), so there's no pressure to work on it - but that is the most pressing issue in the implementation today. (Lack of disk replication in micro-checkpointing.) The MC implementation also needs to be re-based against the latest master - I just haven't had a chance to do it yet because some of my hardware has been taken away from me the last few months - will see if I can find some reasonable hardware soon. - Michael On 08/12/2014 01:22 AM, Walid Nouri wrote: Hi, I will do my best to make a contribution :-) Are there alternative ways of replicating local storage other than DRBD that are possibly feasible? Some that are directly build into Qemu? Walid Am 09.08.2014 14:25, schrieb Michael R. Hines: On Sat, 2014-08-09 at 14:08 +0200, Walid Nouri wrote: Hi Michael, how is the weather in Bejing? :-) It's terrible. Lots of pollution =( May I ask you some questions to your MC implementation? Currently i'm trying to understand the general working of the MC protokoll and possible problems that can occur so that I can discuss it in my thesis. As far as i have understand MC relies on a shared disk. Output of the primary vm are directly written, network output is buffered until the corresponding checkpoint is acknowledged. One problem that comes into my mind is: What happens when the primary vm writes to the disk and crashes before sending a corresponding checkpoint? The MC implementation itself is incomplete, today. (I need help). The Xen Remus implementation uses the DRBD system to mirror all disk writes to the source and destination before completing each checkpoint. The KVM (mc) implementation needs exactly the same support, but it is missing today. Until that happens, we are *required* to use root-over-iSCSI or root-over-NFS (meaning that the guest filesystem is mounted directly inside the virtual machine without
Re: [Qemu-devel] [PATCH] block.curl: adding 'curltimeout' option
Daniel H Barboza danie...@linux.vnet.ibm.com writes: On 08/13/2014 09:39 AM, Daniel H Barboza wrote: On 08/13/2014 06:15 AM, Markus Armbruster wrote: Daniel Henrique Barboza danie...@linux.vnet.ibm.com writes: The curl hardcoded timeout (5 seconds) sometimes is not long enough depending on the remote server configuration and network traffic. The user should be able to set how much long he is willing to wait for the connection. Adding a new option to set this timeout gives the user this flexibility. The previous default timeout of 5 seconds will be used if this option is not present. Signed-off-by: Daniel Henrique Barboza danie...@linux.vnet.ibm.com --- block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/block/curl.c b/block/curl.c index 79ff2f1..a9e43f1 100644 --- a/block/curl.c +++ b/block/curl.c @@ -63,6 +63,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_NUM_ACB8 #define SECTOR_SIZE 512 #define READ_AHEAD_DEFAULT (256 * 1024) +#define CURL_TIMEOUT_DEFAULT 5 #define FIND_RET_NONE 0 #define FIND_RET_OK 1 @@ -71,6 +72,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_BLOCK_OPT_URL url #define CURL_BLOCK_OPT_READAHEAD readahead #define CURL_BLOCK_OPT_SSLVERIFY sslverify +#define CURL_BLOCK_OPT_TIMEOUT curltimeout To what could this timeout apply other than Curl? If nothing, then just timeout, please. Else, curl-timeout. I will investigate a little to check if there are any option called timeout used elsewhere. If not, I see no issues rename this option to timeout. Thanks! I've found one option that contains the string timeout: vl.c static QemuOptsList qemu_boot_opts = { .name = boot-opts, .implied_opt_name = order, (...) }, { .name = reboot-timeout, .type = QEMU_OPT_STRING, }, { (...) I think that renaming curltimeout to just timeout can be a little misleading depending on the context. However, I believe that to keep the name of the options standardized we can rename curltimeout to curl-timeout as you've suggested. Do you agree? I can't see other block driver options with names of the form DRVNAME-OPTNAME, so keeping things standardized would rather call for just timeout. Just timeout seems clear enough to me. But if you can think of concrete contexts where it would be confusing, then I don't mind curl-timeout.
Re: [Qemu-devel] [PATCH] ide: Fix segfault when flushing a device that doesn't exist
On Tue, Aug 12, 2014 at 06:29:41PM +0200, Kevin Wolf wrote: Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/ide/core.c| 4 +++- tests/ide-test.c | 14 ++ 2 files changed, 17 insertions(+), 1 deletion(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan pgp7G6N5heu0n.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH] block.curl: adding 'curltimeout' option
On 08/13/2014 11:07 AM, Markus Armbruster wrote: Daniel H Barboza danie...@linux.vnet.ibm.com writes: On 08/13/2014 09:39 AM, Daniel H Barboza wrote: On 08/13/2014 06:15 AM, Markus Armbruster wrote: Daniel Henrique Barboza danie...@linux.vnet.ibm.com writes: The curl hardcoded timeout (5 seconds) sometimes is not long enough depending on the remote server configuration and network traffic. The user should be able to set how much long he is willing to wait for the connection. Adding a new option to set this timeout gives the user this flexibility. The previous default timeout of 5 seconds will be used if this option is not present. Signed-off-by: Daniel Henrique Barboza danie...@linux.vnet.ibm.com --- block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/block/curl.c b/block/curl.c index 79ff2f1..a9e43f1 100644 --- a/block/curl.c +++ b/block/curl.c @@ -63,6 +63,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_NUM_ACB8 #define SECTOR_SIZE 512 #define READ_AHEAD_DEFAULT (256 * 1024) +#define CURL_TIMEOUT_DEFAULT 5 #define FIND_RET_NONE 0 #define FIND_RET_OK 1 @@ -71,6 +72,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_BLOCK_OPT_URL url #define CURL_BLOCK_OPT_READAHEAD readahead #define CURL_BLOCK_OPT_SSLVERIFY sslverify +#define CURL_BLOCK_OPT_TIMEOUT curltimeout To what could this timeout apply other than Curl? If nothing, then just timeout, please. Else, curl-timeout. I will investigate a little to check if there are any option called timeout used elsewhere. If not, I see no issues rename this option to timeout. Thanks! I've found one option that contains the string timeout: vl.c static QemuOptsList qemu_boot_opts = { .name = boot-opts, .implied_opt_name = order, (...) }, { .name = reboot-timeout, .type = QEMU_OPT_STRING, }, { (...) I think that renaming curltimeout to just timeout can be a little misleading depending on the context. However, I believe that to keep the name of the options standardized we can rename curltimeout to curl-timeout as you've suggested. Do you agree? I can't see other block driver options with names of the form DRVNAME-OPTNAME, so keeping things standardized would rather call for just timeout. Just timeout seems clear enough to me. But if you can think of concrete contexts where it would be confusing, then I don't mind curl-timeout. I think you have a point. Since I can't think of any concrete context where it would be confusing, I'll rename the option to timeout in v3. Thanks!
Re: [Qemu-devel] [PATCH] ide: Add resize callback to ide/core
On Tue, Aug 12, 2014 at 02:44:09PM -0400, John Snow wrote: Currently, if the block device backing the IDE drive is resized, the information about the device as cached inside of the IDEState structure is not updated, thus when a guest OS re-queries the drive, it is unable to see the expanded size. This patch adds a resize callback to correct this, and marks the identify buffer cache as being dirty to force ide_identify to regenerate this information. This callback also attempts to update the legacy CHS values, if only to maintain a sense of informational consistency. Lastly, a Linux guest as-is cannot resize a libata drive while in-use, but it can see the expanded size as part of a bus rescan event. This patch also allows guests such as Linux to see the new drive size after a soft reboot event, without having to exit the QEMU process. Signed-off-by: John Snow js...@redhat.com --- hw/ide/core.c | 29 + 1 file changed, 29 insertions(+) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan pgpjHdoxOPgfk.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH RFC] blkdebug: make the fault injection functionality callable from QMP
On 08/12/2014 10:48 PM, Hitoshi Mitake wrote: This patch makes the fault injection functionality of blkdebug callable from QMP. Motivation of this change is for testing and debugging distributed systems. Ordinal distributed systems must handle hardware faults because of its reason for existence, but testing whether the systems can hanle such faults and recover in a correct manner is really hard. {execute: set-block-fault-state, arguments: {id: ide0-hd0, state: error}} # - inject error to /dev/sda {return: {}} Sounds interesting. Now the guest OS on the VM finds the disk is broken. Of course, using QMP directly is painful for users (developers and admins of distributed systems). I'm implementing user friendly interface in vagrant-kvm [4] for blackbox testing. In addition, a testing framework for injecting faults at critical timing (which requires solid understanding of target systems) is in progress. [1] http://ucare.cs.uchicago.edu/pdf/socc13-limplock.pdf [2] http://docs.openstack.org/developer/swift/howto_installmultinode.html [3] http://www.amazon.com/dp/B00C93QFHI [4] https://github.com/adrahon/vagrant-kvm Cc: Kevin Wolf kw...@redhat.com Cc: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Hitoshi Mitake mitake.hito...@lab.ntt.co.jp --- +++ b/qapi-schema.json @@ -3481,3 +3481,42 @@ # Since: 2.1 ## { 'command': 'rtc-reset-reinjection' } + +## +# @BlockFaultState: +# +# Injected fault state for a block device. +# +# @none: no fault +# +# @error: visible error +# Needs a Since: 2.2 line, as well as the ## trailing marker. +{ 'enum': 'BlockFaultState', 'data': [ 'none', 'error' ] } + +## +# @query-block-fault-state: +# +# Return block fault state information for the given block device. +# +# @name: name of block device +# +# Returns: @BlockFaultState of a block device. +# +# Since: 1.6 s/1.6/2.2/ Personally, I think this command is overkill. Just enhance the existing query-block to output the fault state alongside everything else it already does. There's no need to add a new command that outputs a subset of the existing command. +## +{ 'command': 'query-block-fault-state', 'data': { 'id': 'str' }, + 'returns': 'BlockFaultState' } +## +# @set-block-fault-state: +# +# Set fault state for the given block device. +# +# @name: the chardev's ID, must exist and not be in use +# @state: fault state +# +# Returns: Nothing on success +# +# Since: 1.6 s/1.6/2.2/ +## +{ 'command': 'set-block-fault-state', 'data': {'id': 'str', + 'state': 'BlockFaultState' }} diff --git a/qmp-commands.hx b/qmp-commands.hx index 4be4765..96ae7e2 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3755,3 +3755,27 @@ Example: - { return: {} } EQMP +{ +.name = query-block-fault-state, +.args_type = id:s, +.mhandler.cmd_new = qmp_marshal_input_query_block_fault_state, +}, + +SQMP +query-block-fault-state +--- + +Show block fault information. + +EQMP +{ +.name = set-block-fault-state, +.args_type = id:s,state:q, +.mhandler.cmd_new = qmp_marshal_input_set_block_fault_state, +}, + +SQMP +set-block-fault-state +--- + +Set block fault information. It would be nice to include an example section for the new command(s) (well, I argue that only one new command is needed). -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
The Wednesday 13 Aug 2014 à 18:08:47 (+0800), Ming Lei wrote : This test runs dummy function with coroutine by using two enter and one yield since which is a common usage. So we can see the cost introduced by corouting for running one function, for example: Run operation 2000 iterations 4.841071 s, 4131K operations/s 242ns per coroutine Signed-off-by: Ming Lei ming@canonical.com --- tests/test-coroutine.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c index 6e634f4..e22fae1 100644 --- a/tests/test-coroutine.c +++ b/tests/test-coroutine.c @@ -311,6 +311,35 @@ static void perf_baseline(void) maxcycles, duration); } +static __attribute__((noinline)) void perf_cost_func(void *opaque) +{ +qemu_coroutine_yield(); +} + +static void perf_cost(void) +{ +const unsigned long maxcycles = 4000; +unsigned long i = 0; +double duration; +unsigned long ops; +Coroutine *co; + +g_test_timer_start(); +while (i++ maxcycles) { +co = qemu_coroutine_create(perf_cost_func); I am not sure qemu_coroutine_create is systematically used. I rather believe the code try to reuse existing coroutine. +qemu_coroutine_enter(co, i); +qemu_coroutine_enter(co, NULL); +} +duration = g_test_timer_elapsed(); +ops = (long)(maxcycles / (duration * 1000)); + +g_test_message(Run operation %lu iterations %f s, %luK operations/s, + %luns per coroutine, + maxcycles, + duration, ops, + (unsigned long)(10 * duration) / maxcycles); +} + int main(int argc, char **argv) { g_test_init(argc, argv, NULL); @@ -325,6 +354,7 @@ int main(int argc, char **argv) g_test_add_func(/perf/nesting, perf_nesting); g_test_add_func(/perf/yield, perf_yield); g_test_add_func(/perf/function-call, perf_baseline); +g_test_add_func(/perf/cost, perf_cost); } return g_test_run(); } -- 1.7.9.5
Re: [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
On 13 août 2014 16:27:29 CEST, Benoît Canet benoit.ca...@irqsave.net wrote: The Wednesday 13 Aug 2014 à 18:08:47 (+0800), Ming Lei wrote : This test runs dummy function with coroutine by using two enter and one yield since which is a common usage. So we can see the cost introduced by corouting for running one function, for example: Run operation 2000 iterations 4.841071 s, 4131K operations/s 242ns per coroutine Signed-off-by: Ming Lei ming@canonical.com --- tests/test-coroutine.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c index 6e634f4..e22fae1 100644 --- a/tests/test-coroutine.c +++ b/tests/test-coroutine.c @@ -311,6 +311,35 @@ static void perf_baseline(void) maxcycles, duration); } +static __attribute__((noinline)) void perf_cost_func(void *opaque) +{ +qemu_coroutine_yield(); +} + +static void perf_cost(void) +{ +const unsigned long maxcycles = 4000; +unsigned long i = 0; +double duration; +unsigned long ops; +Coroutine *co; + +g_test_timer_start(); +while (i++ maxcycles) { +co = qemu_coroutine_create(perf_cost_func); I am not sure qemu_coroutine_create is systematically used. I rather believe the code try to reuse existing coroutine. Isn't it what the coroutine pool is for? Is there really code duplicating it manually? +qemu_coroutine_enter(co, i); +qemu_coroutine_enter(co, NULL); +} +duration = g_test_timer_elapsed(); +ops = (long)(maxcycles / (duration * 1000)); + +g_test_message(Run operation %lu iterations %f s, %luK operations/s, + %luns per coroutine, + maxcycles, + duration, ops, + (unsigned long)(10 * duration) / maxcycles); +} + int main(int argc, char **argv) { g_test_init(argc, argv, NULL); @@ -325,6 +354,7 @@ int main(int argc, char **argv) g_test_add_func(/perf/nesting, perf_nesting); g_test_add_func(/perf/yield, perf_yield); g_test_add_func(/perf/function-call, perf_baseline); +g_test_add_func(/perf/cost, perf_cost); } return g_test_run(); } -- 1.7.9.5 -- Gabriel
Re: [Qemu-devel] [PATCH RFC] blkdebug: make the fault injection functionality callable from QMP
On Wed, Aug 13, 2014 at 01:48:41PM +0900, Hitoshi Mitake wrote: @@ -485,6 +493,10 @@ static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs, BDRVBlkdebugState *s = bs-opaque; BlkdebugRule *rule = NULL; +if (s-qmp_fault_state != BLOCK_FAULT_STATE_NONE) { +return inject_error(bs, cb, opaque, rule); +} + QSIMPLEQ_FOREACH(rule, s-active_rules, active_next) { if (rule-options.inject.sector == -1 || (rule-options.inject.sector = sector_num A QMP command is a good idea but the hardcoded s-qmp_fault_state error injection is much less powerful than the rules that blkdebug already supports. Can you make the QMP command take a list of rules instead of setting s-qmp_fault_state? For example: # Clear all rules blkdebug-set-rules drive0 [] # Return EIO on disk flush after L1 update blkdebug-set-rules drive0 [ {type: set-state, event: BLKDBG_L1_UPDATE, state: 0, new-state 1} {type: inject-error, state: 1, event: BLKDBG_FLUSH_TO_DISK, errno: EIO, once: true}, ] In other words, instead of adding a new (more limited) mechanism for triggering error injection, please make the QMP command install a list of blkdebug rules. Stefan pgpaZ1Y8ml_W1.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v2] block.curl: adding 'curltimeout' option
The Tuesday 12 Aug 2014 à 16:12:57 (-0300), Daniel Henrique Barboza wrote : The curl hardcoded timeout (5 seconds) sometimes is not long enough depending on the remote server configuration and network traffic. The user should be able to set how much long he is willing to wait for the connection. Adding a new option to set this timeout gives the user this flexibility. The previous default timeout of 5 seconds will be used if this option is not present. Signed-off-by: Daniel Henrique Barboza danie...@linux.vnet.ibm.com --- block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/block/curl.c b/block/curl.c index 79ff2f1..a9e43f1 100644 --- a/block/curl.c +++ b/block/curl.c @@ -63,6 +63,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_NUM_ACB8 #define SECTOR_SIZE 512 #define READ_AHEAD_DEFAULT (256 * 1024) +#define CURL_TIMEOUT_DEFAULT 5 #define FIND_RET_NONE 0 #define FIND_RET_OK 1 @@ -71,6 +72,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_BLOCK_OPT_URL url #define CURL_BLOCK_OPT_READAHEAD readahead #define CURL_BLOCK_OPT_SSLVERIFY sslverify +#define CURL_BLOCK_OPT_TIMEOUT curltimeout struct BDRVCURLState; @@ -109,6 +111,7 @@ typedef struct BDRVCURLState { char *url; size_t readahead_size; bool sslverify; +int curltimeout; I know the sslverify does an exception to the coding style rule but why not name the field curl_timeout like it would be in every other part of qemu code ? bool accept_range; AioContext *aio_context; } BDRVCURLState; @@ -382,7 +385,7 @@ static CURLState *curl_init_state(BDRVCURLState *s) curl_easy_setopt(state-curl, CURLOPT_URL, s-url); curl_easy_setopt(state-curl, CURLOPT_SSL_VERIFYPEER, (long) s-sslverify); -curl_easy_setopt(state-curl, CURLOPT_TIMEOUT, 5); +curl_easy_setopt(state-curl, CURLOPT_TIMEOUT, s-curltimeout); curl_easy_setopt(state-curl, CURLOPT_WRITEFUNCTION, (void *)curl_read_cb); curl_easy_setopt(state-curl, CURLOPT_WRITEDATA, (void *)state); @@ -489,6 +492,11 @@ static QemuOptsList runtime_opts = { .type = QEMU_OPT_BOOL, .help = Verify SSL certificate }, +{ +.name = CURL_BLOCK_OPT_TIMEOUT, +.type = QEMU_OPT_NUMBER, +.help = Curl timeout +}, { /* end of list */ } }, }; @@ -525,6 +533,9 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags, goto out_noclean; } +s-curltimeout = qemu_opt_get_number(opts, CURL_BLOCK_OPT_TIMEOUT, + CURL_TIMEOUT_DEFAULT); + s-sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY, true); file = qemu_opt_get(opts, CURL_BLOCK_OPT_URL); diff --git a/qemu-options.hx b/qemu-options.hx index 96516c1..0358f38 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2351,6 +2351,11 @@ multiple of 512 bytes. It defaults to 256k. @item sslverify Whether to verify the remote server's certificate when connecting over SSL. It can have the value 'on' or 'off'. It defaults to 'on'. + +@item curltimeout +Set the timeout in seconds of the CURL connection. This timeout is the time +that CURL waits for a response from the remote server to get the size of the +image to be downloaded. If not set, the default timeout of 5 seconds is used. @end table Note that when passing options to qemu explicitly, @option{driver} is the value @@ -2372,9 +2377,10 @@ qemu-system-x86_64 -drive file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-o @end example Example: boot from an image stored on a VMware vSphere server with a self-signed -certificate using a local overlay for writes and a readahead of 64k +certificate using a local overlay for writes, a readahead of 64k and a +curltimeout of 10 seconds. @example -qemu-img create -f qcow2 -o backing_file='json:@{file.driver:https,, file.url:https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=DatacenterdsName=datastore1;,, file.sslverify:off,, file.readahead:64k@}' /tmp/test.qcow2 +qemu-img create -f qcow2 -o backing_file='json:@{file.driver:https,, file.url:https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=DatacenterdsName=datastore1;,, file.sslverify:off,, file.readahead:64k,, file.curltimeout:10@}' /tmp/test.qcow2 qemu-system-x86_64 -drive file=/tmp/test.qcow2 @end example -- 1.8.3.1 Apart from the coding style issue. Reviewed-by: Benoit Canet benoit.ca...@nodalink.com
Re: [Qemu-devel] [PATCH v3 08/16] target-arm: Add SCR_EL3
Hi Edgar, I was just writing a test to verify the correct behavior of the SCR AW/FW bits and I think there is an issue. During an SCR write an initial valid mask is set from SCR_MASK which is defined to not include these bits. Then these bits are hard-coded into the write value using RES1. Last, the new value is masked against the valid bits for which these bits are masked off. I have a number of questions: - Why are we marking these bits off as reserved? Shouldn't they be RW? - Are you intending to always enable them or always disable them? - Why are we attempting to hard-code them 'on' in the value? Is it because they have no value when VIRT is enabled? If so, we should check for EL2. Thanks for any insight. Greg On 4 August 2014 10:19, Edgar E. Iglesias edgar.igles...@gmail.com wrote: On Fri, Aug 01, 2014 at 02:34:14PM +0100, Peter Maydell wrote: On 17 June 2014 09:45, Edgar E. Iglesias edgar.igles...@gmail.com wrote: From: Edgar E. Iglesias edgar.igles...@xilinx.com Signed-off-by: Edgar E. Iglesias edgar.igles...@xilinx.com --- target-arm/cpu.h| 16 +++- target-arm/helper.c | 31 ++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index fd57fb5..fa8dee0 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -172,7 +172,6 @@ typedef struct CPUARMState { uint64_t c1_sys; /* System control register. */ uint64_t c1_coproc; /* Coprocessor access register. */ uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */ -uint32_t c1_scr; /* secure config register. */ uint64_t ttbr0_el1; /* MMU translation table base 0. */ uint64_t ttbr1_el1; /* MMU translation table base 1. */ uint64_t c2_control; /* MMU translation table base control. */ @@ -185,6 +184,7 @@ typedef struct CPUARMState { uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */ uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */ uint64_t hcr_el2; /* Hypervisor configuration register */ +uint32_t scr_el3; /* Secure configuration register. */ uint32_t ifsr_el2; /* Fault status registers. */ uint64_t esr_el[4]; uint32_t c6_region[8]; /* MPU base/size registers. */ @@ -562,6 +562,20 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) #define HCR_ID(1ULL 33) #define HCR_MASK ((1ULL 34) - 1) +#define SCR_NS(1U 0) +#define SCR_IRQ (1U 1) +#define SCR_FIQ (1U 2) +#define SCR_EA(1U 3) +#define SCR_SMD (1U 7) +#define SCR_HCE (1U 8) +#define SCR_SIF (1U 9) +#define SCR_RW(1U 10) +#define SCR_ST(1U 11) +#define SCR_TWI (1U 12) +#define SCR_TWE (1U 13) +#define SCR_RES1_MASK (3U 4) +#define SCR_MASK (0x3fff ~SCR_RES1_MASK) + /* Return the current FPSCR value. */ uint32_t vfp_get_fpscr(CPUARMState *env); void vfp_set_fpscr(CPUARMState *env, uint32_t val); diff --git a/target-arm/helper.c b/target-arm/helper.c index b04fb5d..6bacc24 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -793,7 +793,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[1]), .resetvalue = 0 }, { .name = SCR, .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3), .resetvalue = 0, }, It's awkward that this is now separate from the AArch64 reginfo below, because it makes it non-obvious that they're both the same underlying state. In particular that probably means this one now needs a NO_MIGRATE marker? Yes, I've moved this into the el3 structure and added NO_MIGRATE. Thanks, Edgar { .name = CCSIDR, .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, @@ -2161,6 +2161,31 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = { REGINFO_SENTINEL }; +static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ +uint32_t valid_mask = SCR_MASK; + +if (!arm_feature(env, ARM_FEATURE_EL2)) { +valid_mask = ~SCR_HCE; + +/* On ARMv7, SMD (or SCD as it is called in v7) is only + * supported if EL2 exists. The bit is UNK/SBZP when + * EL2 is unavailable. In QEMU ARMv7, we force it to always zero + * when EL2 is unavailable. + */ +if (arm_feature(env, ARM_FEATURE_V7)) { +valid_mask = ~SCR_SMD; +} +} + +/* Set RES1 bits. */ +
Re: [Qemu-devel] [PATCH] ide: Add resize callback to ide/core
On Tue, Aug 12, 2014 at 02:44:09PM -0400, John Snow wrote: Currently, if the block device backing the IDE drive is resized, the information about the device as cached inside of the IDEState structure is not updated, thus when a guest OS re-queries the drive, it is unable to see the expanded size. This patch adds a resize callback to correct this, and marks the identify buffer cache as being dirty to force ide_identify to regenerate this information. This callback also attempts to update the legacy CHS values, if only to maintain a sense of informational consistency. Lastly, a Linux guest as-is cannot resize a libata drive while in-use, but it can see the expanded size as part of a bus rescan event. This patch also allows guests such as Linux to see the new drive size after a soft reboot event, without having to exit the QEMU process. Signed-off-by: John Snow js...@redhat.com --- hw/ide/core.c | 29 + 1 file changed, 29 insertions(+) Dropped due to comments from Markus Armbruster. I'll wait until the discussion is finished before merging it. pgp25RIQA1OUo.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH] ide: Add resize callback to ide/core
John Snow js...@redhat.com writes: Currently, if the block device backing the IDE drive is resized, the information about the device as cached inside of the IDEState structure is not updated, thus when a guest OS re-queries the drive, it is unable to see the expanded size. This patch adds a resize callback to correct this, and marks the identify buffer cache as being dirty to force ide_identify to regenerate this information. This callback also attempts to update the legacy CHS values, if only to maintain a sense of informational consistency. Lastly, a Linux guest as-is cannot resize a libata drive while in-use, but it can see the expanded size as part of a bus rescan event. This patch also allows guests such as Linux to see the new drive size after a soft reboot event, without having to exit the QEMU process. Signed-off-by: John Snow js...@redhat.com --- hw/ide/core.c | 29 + 1 file changed, 29 insertions(+) diff --git a/hw/ide/core.c b/hw/ide/core.c index db191a6..6c86e21 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2099,6 +2099,30 @@ static bool ide_cd_is_medium_locked(void *opaque) return ((IDEState *)opaque)-tray_locked; } +static void ide_resize_cb(void *opaque) +{ +IDEState *s = opaque; +IDEDevice *dev = s-unit ? s-bus-slave : s-bus-master; +uint64_t nb_sectors; + +/* Convince blkconf_geometry to re-determine geometry */ +dev-conf.cyls = 0; +dev-conf.heads = 0; +dev-conf.secs = 0; + +blkconf_geometry(dev-conf, dev-chs_trans, 65536, 16, 255); +bdrv_get_geometry(s-bs, nb_sectors); I'm afraid this overrides any geometry specified by the user. If the user doesn't specify geometry, we make one up on device initialization. Disk capacity is one of the inputs for that guesswork. Do we really want to change geometry on resize? I suspect a guest OS old enough to care for geometry is way too old to cope with dynamic disk resize... Do we want to change it even when the user specified a geometry? I'd say no, because disk capacity is normally irrelevant then, and I can't see why resize should be an exception. + +s-nb_sectors = nb_sectors; +s-cylinders = dev-conf.cyls; +s-heads = dev-conf.heads; +s-sectors = dev-conf.secs; +s-chs_trans = dev-chs_trans; + +/* Let ide_identify() know it needs to regenerate the response. */ +s-identify_set = 0; Doesn't the regeneration clobber the updates to s-identify_data made by cmd_set_features()? Apropos: what happens if cmd_set_features() runs before ide_identify(), ide_atapi_identify(), ide_cfata_identify()? +} + static const BlockDevOps ide_cd_block_ops = { .change_media_cb = ide_cd_change_cb, .eject_request_cb = ide_cd_eject_request_cb, @@ -2106,6 +2130,10 @@ static const BlockDevOps ide_cd_block_ops = { .is_medium_locked = ide_cd_is_medium_locked, }; +static const BlockDevOps ide_hd_block_ops = { +.resize_cb = ide_resize_cb, +}; + int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, const char *version, const char *serial, const char *model, uint64_t wwn, @@ -2142,6 +2170,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, error_report(Can't use a read-only drive); return -1; } +bdrv_set_dev_ops(bs, ide_hd_block_ops, s); } if (serial) { pstrcpy(s-drive_serial_str, sizeof(s-drive_serial_str), serial); This part looks good.
Re: [Qemu-devel] [PATCH v2] block.curl: adding 'curltimeout' option
On 08/13/2014 11:38 AM, Benoît Canet wrote: The Tuesday 12 Aug 2014 à 16:12:57 (-0300), Daniel Henrique Barboza wrote : The curl hardcoded timeout (5 seconds) sometimes is not long enough depending on the remote server configuration and network traffic. The user should be able to set how much long he is willing to wait for the connection. Adding a new option to set this timeout gives the user this flexibility. The previous default timeout of 5 seconds will be used if this option is not present. Signed-off-by: Daniel Henrique Barboza danie...@linux.vnet.ibm.com --- block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/block/curl.c b/block/curl.c index 79ff2f1..a9e43f1 100644 --- a/block/curl.c +++ b/block/curl.c @@ -63,6 +63,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_NUM_ACB8 #define SECTOR_SIZE 512 #define READ_AHEAD_DEFAULT (256 * 1024) +#define CURL_TIMEOUT_DEFAULT 5 #define FIND_RET_NONE 0 #define FIND_RET_OK 1 @@ -71,6 +72,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_BLOCK_OPT_URL url #define CURL_BLOCK_OPT_READAHEAD readahead #define CURL_BLOCK_OPT_SSLVERIFY sslverify +#define CURL_BLOCK_OPT_TIMEOUT curltimeout struct BDRVCURLState; @@ -109,6 +111,7 @@ typedef struct BDRVCURLState { char *url; size_t readahead_size; bool sslverify; +int curltimeout; I know the sslverify does an exception to the coding style rule but why not name the field curl_timeout like it would be in every other part of qemu code ? I'll change the name of the field to timeout in v3 as suggested by Markus Armbruster. This fixes the coding style issue you've pointed out. Thanks! bool accept_range; AioContext *aio_context; } BDRVCURLState; @@ -382,7 +385,7 @@ static CURLState *curl_init_state(BDRVCURLState *s) curl_easy_setopt(state-curl, CURLOPT_URL, s-url); curl_easy_setopt(state-curl, CURLOPT_SSL_VERIFYPEER, (long) s-sslverify); -curl_easy_setopt(state-curl, CURLOPT_TIMEOUT, 5); +curl_easy_setopt(state-curl, CURLOPT_TIMEOUT, s-curltimeout); curl_easy_setopt(state-curl, CURLOPT_WRITEFUNCTION, (void *)curl_read_cb); curl_easy_setopt(state-curl, CURLOPT_WRITEDATA, (void *)state); @@ -489,6 +492,11 @@ static QemuOptsList runtime_opts = { .type = QEMU_OPT_BOOL, .help = Verify SSL certificate }, +{ +.name = CURL_BLOCK_OPT_TIMEOUT, +.type = QEMU_OPT_NUMBER, +.help = Curl timeout +}, { /* end of list */ } }, }; @@ -525,6 +533,9 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags, goto out_noclean; } +s-curltimeout = qemu_opt_get_number(opts, CURL_BLOCK_OPT_TIMEOUT, + CURL_TIMEOUT_DEFAULT); + s-sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY, true); file = qemu_opt_get(opts, CURL_BLOCK_OPT_URL); diff --git a/qemu-options.hx b/qemu-options.hx index 96516c1..0358f38 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2351,6 +2351,11 @@ multiple of 512 bytes. It defaults to 256k. @item sslverify Whether to verify the remote server's certificate when connecting over SSL. It can have the value 'on' or 'off'. It defaults to 'on'. + +@item curltimeout +Set the timeout in seconds of the CURL connection. This timeout is the time +that CURL waits for a response from the remote server to get the size of the +image to be downloaded. If not set, the default timeout of 5 seconds is used. @end table Note that when passing options to qemu explicitly, @option{driver} is the value @@ -2372,9 +2377,10 @@ qemu-system-x86_64 -drive file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-o @end example Example: boot from an image stored on a VMware vSphere server with a self-signed -certificate using a local overlay for writes and a readahead of 64k +certificate using a local overlay for writes, a readahead of 64k and a +curltimeout of 10 seconds. @example -qemu-img create -f qcow2 -o backing_file='json:@{file.driver:https,, file.url:https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=DatacenterdsName=datastore1;,, file.sslverify:off,, file.readahead:64k@}' /tmp/test.qcow2 +qemu-img create -f qcow2 -o backing_file='json:@{file.driver:https,, file.url:https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=DatacenterdsName=datastore1;,, file.sslverify:off,, file.readahead:64k,, file.curltimeout:10@}' /tmp/test.qcow2 qemu-system-x86_64 -drive file=/tmp/test.qcow2 @end example -- 1.8.3.1 Apart from the coding style issue. Reviewed-by: Benoit Canet benoit.ca...@nodalink.com
Re: [Qemu-devel] disk image: self-organized format or raw file
Am 12.08.2014 um 17:30 hat Eric Blake geschrieben: On 08/12/2014 08:14 AM, 吴兴博 wrote: However FVD seems to have been ignored by community. Care to give a pointer to a URL describing the FVD format? http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg00398.html This thread could be the clearest message on FVD. That very message also points out WHY the community has appeared to ignore FVD: For any feature to be seriously considered for inclusion in QEMU, patches need to be posted to the mailing list against the latest git tree. That's a pre-requisite for any real discussion. It also has a paper published on USENIX conference. https://www.usenix.org/event/atc11/tech/final_files/Tang.pdf Thanks for the references. Are you interested in posting patches to revive the work on that format? Just to be clear upfront so that you don't waste your time: A new native image format is not going to be merged. You would have to prove that your format is capable of replacing qcow2 with all its features, that it's better in some respect and that qcow2 cannot be extended to provide the same. Other proposals, including FVD, have failed to provide that and I'd consider it unlikely to happen this time. (QED fell short of it and was merged anyway for political reasons; it's clear today that this was a mistake.) Kevin pgpGt7AerV2j7.pgp Description: PGP signature
[Qemu-devel] [PATCH v3] block.curl: adding 'timeout' option
The curl hardcoded timeout (5 seconds) sometimes is not long enough depending on the remote server configuration and network traffic. The user should be able to set how much long he is willing to wait for the connection. Adding a new option to set this timeout gives the user this flexibility. The previous default timeout of 5 seconds will be used if this option is not present. Reviewed-by: Fam Zheng f...@redhat.com Signed-off-by: Daniel Henrique Barboza danie...@linux.vnet.ibm.com --- block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/block/curl.c b/block/curl.c index 79ff2f1..6f45547 100644 --- a/block/curl.c +++ b/block/curl.c @@ -63,6 +63,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_NUM_ACB8 #define SECTOR_SIZE 512 #define READ_AHEAD_DEFAULT (256 * 1024) +#define CURL_TIMEOUT_DEFAULT 5 #define FIND_RET_NONE 0 #define FIND_RET_OK 1 @@ -71,6 +72,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, #define CURL_BLOCK_OPT_URL url #define CURL_BLOCK_OPT_READAHEAD readahead #define CURL_BLOCK_OPT_SSLVERIFY sslverify +#define CURL_BLOCK_OPT_TIMEOUT timeout struct BDRVCURLState; @@ -109,6 +111,7 @@ typedef struct BDRVCURLState { char *url; size_t readahead_size; bool sslverify; +int timeout; bool accept_range; AioContext *aio_context; } BDRVCURLState; @@ -382,7 +385,7 @@ static CURLState *curl_init_state(BDRVCURLState *s) curl_easy_setopt(state-curl, CURLOPT_URL, s-url); curl_easy_setopt(state-curl, CURLOPT_SSL_VERIFYPEER, (long) s-sslverify); -curl_easy_setopt(state-curl, CURLOPT_TIMEOUT, 5); +curl_easy_setopt(state-curl, CURLOPT_TIMEOUT, s-timeout); curl_easy_setopt(state-curl, CURLOPT_WRITEFUNCTION, (void *)curl_read_cb); curl_easy_setopt(state-curl, CURLOPT_WRITEDATA, (void *)state); @@ -489,6 +492,11 @@ static QemuOptsList runtime_opts = { .type = QEMU_OPT_BOOL, .help = Verify SSL certificate }, +{ +.name = CURL_BLOCK_OPT_TIMEOUT, +.type = QEMU_OPT_NUMBER, +.help = Curl timeout +}, { /* end of list */ } }, }; @@ -525,6 +533,9 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags, goto out_noclean; } +s-timeout = qemu_opt_get_number(opts, CURL_BLOCK_OPT_TIMEOUT, + CURL_TIMEOUT_DEFAULT); + s-sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY, true); file = qemu_opt_get(opts, CURL_BLOCK_OPT_URL); diff --git a/qemu-options.hx b/qemu-options.hx index 96516c1..e93a94f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2351,6 +2351,11 @@ multiple of 512 bytes. It defaults to 256k. @item sslverify Whether to verify the remote server's certificate when connecting over SSL. It can have the value 'on' or 'off'. It defaults to 'on'. + +@item timeout +Set the timeout in seconds of the CURL connection. This timeout is the time +that CURL waits for a response from the remote server to get the size of the +image to be downloaded. If not set, the default timeout of 5 seconds is used. @end table Note that when passing options to qemu explicitly, @option{driver} is the value @@ -2372,9 +2377,10 @@ qemu-system-x86_64 -drive file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-o @end example Example: boot from an image stored on a VMware vSphere server with a self-signed -certificate using a local overlay for writes and a readahead of 64k +certificate using a local overlay for writes, a readahead of 64k and a timeout +of 10 seconds. @example -qemu-img create -f qcow2 -o backing_file='json:@{file.driver:https,, file.url:https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=DatacenterdsName=datastore1;,, file.sslverify:off,, file.readahead:64k@}' /tmp/test.qcow2 +qemu-img create -f qcow2 -o backing_file='json:@{file.driver:https,, file.url:https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=DatacenterdsName=datastore1;,, file.sslverify:off,, file.readahead:64k,, file.timeout:10@}' /tmp/test.qcow2 qemu-system-x86_64 -drive file=/tmp/test.qcow2 @end example -- 1.8.3.1
[Qemu-devel] [PATCH v3] block.curl: timeout option
Changes in v3: - changed option name from 'curltimeout' to 'timeout' Changes in v2: - remove double quote from the int value in qemu-options.hx Daniel Henrique Barboza (1): block.curl: adding 'timeout' option block/curl.c| 13 - qemu-options.hx | 10 -- 2 files changed, 20 insertions(+), 3 deletions(-) -- 1.8.3.1
Re: [Qemu-devel] disk image: self-organized format or raw file
Am 12.08.2014 um 01:38 hat 吴兴博 geschrieben: Hello, The introduction in the wiki page present several advantages of qcow2 [1]. But I'm a little confused. I really appreciate if any one can give me some help on this :). (1) Currently the raw format doesn't support COW. In other words, a raw image cannot have a backing file. COW depends on the mapping table on which we it knows whether each block/cluster is present (has been modified) in the current image file. Modern file-systems like xfs/ext4/etc. provide extent/block allocation information to user-level. Like what 'filefrag' does with ioctl 'FIBMAP' and 'FIEMAP'. I guess the raw file driver (maybe block/raw-posix.c) may obtain correct 'present information about blocks. However this information may be limited to be aligned with file allocation unit size. Maybe it's just because a raw file has no space to store the backing file name? I don't think this could hinder the useful feature. (2) As most popular filesystems support delay-allocation/on-demand allocation/ holes, whatever, a raw image is also thin provisioned as other formats. It doesn't consume much disk space by storing useless zeros. However, I don't know if there is any concern on whether fragmented extents would become a burden of the host filesystem. (3) For compression and encryption, I'm not an export on these topics at all but I think these features may not be vital to a image format as both guest/ host's filesystem can also provide similar functionality. (4) I don't have too much understanding on how snapshot works but I think theoretically it would be using the techniques no more than that used in COW and backing file. After all these thoughts, I still found no reason to not using a 'raw' file image (engineering efforts in Qemu should not count as we don't ask for more features from outside world). I would be very sorry if my ignorance wasted your time. Even if it did work (that it's problematic is already discussed in other subthreads) what advantage would you get from using an extended raw driver compared to simply using qcow2, which supports all of this today? Kevin
[Qemu-devel] [PATCH] hw/intc/arm_gic: honor target mask in gic_update()
Take IRQ target mask into account when determining the highest priority pending interrupt. Signed-off-by: Sergey Fedorov serge.f...@gmail.com --- hw/intc/arm_gic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 1532ef9..a5ad7b9 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -66,7 +66,8 @@ void gic_update(GICState *s) best_prio = 0x100; best_irq = 1023; for (irq = 0; irq s-num_irq; irq++) { -if (GIC_TEST_ENABLED(irq, cm) gic_test_pending(s, irq, cm)) { +if (GIC_TEST_ENABLED(irq, cm) gic_test_pending(s, irq, cm) +(irq GIC_INTERNAL || GIC_TARGET(irq) cm)) { if (GIC_GET_PRIORITY(irq, cpu) best_prio) { best_prio = GIC_GET_PRIORITY(irq, cpu); best_irq = irq; -- 1.9.1
Re: [Qemu-devel] [PATCH v2] target-sparc64: implement Short Floating-Point Store Instructions
On 08/12/2014 10:02 AM, Artyom Tarasenko wrote: Implement Short Floating-Point Store Instructions as described in the chapter 13.5.2 of UltraSPARC-IIi User's Manual. Particularly this instructions are used by NetBSD 4.0.1+ /sparc64 Signed-off-by: Artyom Tarasenko atar4q...@gmail.com Tested-by: Mark Cave-Ayland mark.cave-ayl...@ilande.co.uk --- With this patch applied on top of cmd646 patches it's possible to install and boot NetBSD 6.1.4 /sparc64. Changes from v0: corrected the comment messages, it's store, not load. Reviewed-by: Richard Henderson r...@twiddle.net r~
Re: [Qemu-devel] disk image: self-organized format or raw file
On Wed, Aug 13, 2014 at 11:54 AM, Kevin Wolf kw...@redhat.com wrote: Am 12.08.2014 um 01:38 hat 吴兴博 geschrieben: Hello, The introduction in the wiki page present several advantages of qcow2 [1]. But I'm a little confused. I really appreciate if any one can give me some help on this :). (1) Currently the raw format doesn't support COW. In other words, a raw image cannot have a backing file. COW depends on the mapping table on which we it knows whether each block/cluster is present (has been modified) in the current image file. Modern file-systems like xfs/ext4/etc. provide extent/block allocation information to user-level. Like what 'filefrag' does with ioctl 'FIBMAP' and 'FIEMAP'. I guess the raw file driver (maybe block/raw-posix.c) may obtain correct 'present information about blocks. However this information may be limited to be aligned with file allocation unit size. Maybe it's just because a raw file has no space to store the backing file name? I don't think this could hinder the useful feature. (2) As most popular filesystems support delay-allocation/on-demand allocation/ holes, whatever, a raw image is also thin provisioned as other formats. It doesn't consume much disk space by storing useless zeros. However, I don't know if there is any concern on whether fragmented extents would become a burden of the host filesystem. (3) For compression and encryption, I'm not an export on these topics at all but I think these features may not be vital to a image format as both guest/ host's filesystem can also provide similar functionality. (4) I don't have too much understanding on how snapshot works but I think theoretically it would be using the techniques no more than that used in COW and backing file. After all these thoughts, I still found no reason to not using a 'raw' file image (engineering efforts in Qemu should not count as we don't ask for more features from outside world). I would be very sorry if my ignorance wasted your time. Even if it did work (that it's problematic is already discussed in other subthreads) what advantage would you get from using an extended raw driver compared to simply using qcow2, which supports all of this today? Kevin I read several messages from this thread: [RFC] qed: Add QEMU Enhanced Disk format. To my understanding, if the new format can be acceptable to the community: It needs to retain all the key features provided by qcow2, especially for compression, encryption, and internal snapshot, as mentioned in that thread. And, needless to say, it must run faster. Yes I agree it's at least a subset of the homework one need to do before selling the new format to the community. Thanks and another question: What's the magic that makes QED runs faster than QCOW2? In some simple parallel IO tests QED can run a magnitude faster than QCOW2. I saw differences on simple/complex metadata organization, and coroutine/aio (however bdrv_co_s finally call bdrv_aio_s via _em. If you can provide some insight on this I would be really appreciate. -- Cheers! 吴兴博 Wu, Xingbo wux...@gmail.com
Re: [Qemu-devel] [PATCH v4 03/11] libqtest: add QTEST_LOG for debugging qtest testcases
On Tue, Aug 12, 2014 at 01:41:48PM +0200, Marc Marí wrote: Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- tests/libqtest.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) Reviewed-by: Stefan Hajnoczi stefa...@redhat.com pgpP3YN3tB85y.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v4 01/11] tests: Functions bus_foreach and device_find from libqos virtio API
On Tue, Aug 12, 2014 at 01:41:46PM +0200, Marc Marí wrote: Virtio header has been changed to compile and work with a real device. Functions bus_foreach and device_find have been implemented for PCI. Virtio-blk test case now opens a fake device. Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- tests/Makefile|3 +- tests/libqos/virtio-pci.c | 75 + tests/libqos/virtio-pci.h | 24 +++ tests/libqos/virtio.h | 23 ++ tests/virtio-blk-test.c | 61 +++- 5 files changed, 177 insertions(+), 9 deletions(-) create mode 100644 tests/libqos/virtio-pci.c create mode 100644 tests/libqos/virtio-pci.h create mode 100644 tests/libqos/virtio.h Reviewed-by: Stefan Hajnoczi stefa...@redhat.com pgpRjz6P2GQA8.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v4 02/11] tests: Add virtio device initialization
On Tue, Aug 12, 2014 at 01:41:47PM +0200, Marc Marí wrote: +static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, void *addr) +{ +QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; +return qpci_io_readl(dev-pdev, addr) | qpci_io_readl(dev-pdev, addr+4); This is broken because it never shifts bits into the upper 32 bits. Which value to shift up depends on endianness. Another solution is to do byte reads into a uint64_t variable like memcpy. I suggest you simply drop 64-bit accesses for now since they are probably not used. pgpZ4N0hKlhg_.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v4 05/11] libqos: Change free function called in malloc
On Tue, Aug 12, 2014 at 01:41:50PM +0200, Marc Marí wrote: Reviewed-by: John Snow js...@redhat.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- tests/libqos/malloc.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan pgpj2JV5O4Lmw.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v4 03/11] libqtest: add QTEST_LOG for debugging qtest testcases
On Tue, Aug 12, 2014 at 01:41:48PM +0200, Marc Marí wrote: Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- tests/libqtest.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan pgpkOgr_UxUsK.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v4 06/11] virtio-blk: Correct bug in support for flexible descriptor layout
On Tue, Aug 12, 2014 at 01:41:51PM +0200, Marc Marí wrote: Without this correction, only a three descriptor layout is accepted, and requests with just two descriptors are not completed and no error message is displayed. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- hw/block/virtio-blk.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan pgp2EXNbUkGZz.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v4 04/11] libqos: Correct mask to align size to PAGE_SIZE in malloc-pc
On Tue, Aug 12, 2014 at 01:41:49PM +0200, Marc Marí wrote: Reviewed-by: John Snow js...@redhat.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- tests/libqos/malloc-pc.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan pgpLMvX0WxGD0.pgp Description: PGP signature
[Qemu-devel] [PATCHv2 3/3] qemu-nbd: fix indentation and coding style
Signed-off-by: Peter Lieven p...@kamp.de --- qemu-nbd.c | 75 +++- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/qemu-nbd.c b/qemu-nbd.c index 6ef8b10..9bc152e 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -39,10 +39,10 @@ #include libgen.h #include pthread.h -#define SOCKET_PATH /var/lock/qemu-nbd-%s -#define QEMU_NBD_OPT_CACHE 1 -#define QEMU_NBD_OPT_AIO 2 -#define QEMU_NBD_OPT_DISCARD 3 +#define SOCKET_PATH/var/lock/qemu-nbd-%s +#define QEMU_NBD_OPT_CACHE 1 +#define QEMU_NBD_OPT_AIO 2 +#define QEMU_NBD_OPT_DISCARD 3 #define QEMU_NBD_OPT_DETECT_ZEROES 4 static NBDExport *exp; @@ -60,44 +60,44 @@ static void usage(const char *name) Usage: %s [OPTIONS] FILE\n QEMU Disk Network Block Device Server\n \n - -h, --help display this help and exit\n - -V, --versionoutput version information and exit\n + -h, --helpdisplay this help and exit\n + -V, --version output version information and exit\n \n Connection properties:\n - -p, --port=PORT port to listen on (default `%d')\n - -b, --bind=IFACE interface to bind to (default `0.0.0.0')\n - -k, --socket=PATHpath to the unix socket\n - (default 'SOCKET_PATH')\n - -e, --shared=NUM device can be shared by NUM clients (default '1')\n - -t, --persistent don't exit on the last connection\n - -v, --verbosedisplay extra debugging information\n + -p, --port=PORT port to listen on (default `%d')\n + -b, --bind=IFACE interface to bind to (default `0.0.0.0')\n + -k, --socket=PATH path to the unix socket\n +(default 'SOCKET_PATH')\n + -e, --shared=NUM device can be shared by NUM clients (default '1')\n + -t, --persistent don't exit on the last connection\n + -v, --verbose display extra debugging information\n \n Exposing part of the image:\n - -o, --offset=OFFSET offset into the image\n - -P, --partition=NUM only expose partition NUM\n + -o, --offset=OFFSET offset into the image\n + -P, --partition=NUM only expose partition NUM\n \n #ifdef __linux__ Kernel NBD client support:\n - -c, --connect=DEVconnect FILE to the local NBD device DEV\n - -d, --disconnect disconnect the specified device\n + -c, --connect=DEV connect FILE to the local NBD device DEV\n + -d, --disconnect disconnect the specified device\n \n #endif \n Block device options:\n - -f, --format=FORMAT set image format (raw, qcow2, ...)\n - -r, --read-only export read-only\n - -s, --snapshot use FILE as an external snapshot, create a temporary\n - file with backing_file=FILE, redirect the write to\n - the temporary one\n + -f, --format=FORMAT set image format (raw, qcow2, ...)\n + -r, --read-only export read-only\n + -s, --snapshotuse FILE as an external snapshot, create a temporary\n +file with backing_file=FILE, redirect the write to\n +the temporary one\n -l, --load-snapshot=SNAPSHOT_PARAM\n - load an internal snapshot inside FILE and export it\n - as an read-only device, SNAPSHOT_PARAM format is\n - 'snapshot.id=[ID],snapshot.name=[NAME]', or\n - '[ID_OR_NAME]'\n - -n, --nocachedisable host cache\n - --cache=MODE set cache mode (none, writeback, ...)\n +load an internal snapshot inside FILE and export it\n +as an read-only device, SNAPSHOT_PARAM format is\n +'snapshot.id=[ID],snapshot.name=[NAME]', or\n +'[ID_OR_NAME]'\n + -n, --nocache disable host cache\n + --cache=MODE set cache mode (none, writeback, ...)\n #ifdef CONFIG_LINUX_AIO - --aio=MODE set AIO mode (native or threads)\n + --aio=MODEset AIO mode (native or threads)\n #endif --discard=MODEset discard mode (ignore, unmap)\n --detect-zeroes=MODE set detect-zeroes mode (off, on, discard)\n @@ -546,15 +546,18 @@ int main(int argc, char **argv) break; case 'P': partition = strtol(optarg, end, 0); -if (*end) +if (*end) { errx(EXIT_FAILURE, Invalid partition `%s', optarg); -if (partition 1 || partition 8) +} +if (partition 1 || partition 8) { errx(EXIT_FAILURE, Invalid partition %d, partition); +} break; case 'k': sockpath = optarg; -if (sockpath[0] != '/') +if (sockpath[0] != '/') { errx(EXIT_FAILURE, socket
[Qemu-devel] [PATCHv2 2/3] qemu-nbd: add option to set detect-zeroes mode
Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Eric Blake ebl...@redhat.com --- qemu-nbd.c | 25 + 1 file changed, 25 insertions(+) diff --git a/qemu-nbd.c b/qemu-nbd.c index 626e584..6ef8b10 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -18,11 +18,13 @@ #include qemu-common.h #include block/block.h +#include block/block_int.h #include block/nbd.h #include qemu/main-loop.h #include qemu/sockets.h #include qemu/error-report.h #include block/snapshot.h +#include qapi/util.h #include stdarg.h #include stdio.h @@ -41,6 +43,7 @@ #define QEMU_NBD_OPT_CACHE 1 #define QEMU_NBD_OPT_AIO 2 #define QEMU_NBD_OPT_DISCARD 3 +#define QEMU_NBD_OPT_DETECT_ZEROES 4 static NBDExport *exp; static int verbose; @@ -96,6 +99,8 @@ static void usage(const char *name) #ifdef CONFIG_LINUX_AIO --aio=MODE set AIO mode (native or threads)\n #endif + --discard=MODEset discard mode (ignore, unmap)\n + --detect-zeroes=MODE set detect-zeroes mode (off, on, discard)\n \n Report bugs to qemu-devel@nongnu.org\n , name, NBD_DEFAULT_PORT, DEVICE); @@ -410,6 +415,7 @@ int main(int argc, char **argv) { aio, 1, NULL, QEMU_NBD_OPT_AIO }, #endif { discard, 1, NULL, QEMU_NBD_OPT_DISCARD }, +{ detect-zeroes, 1, NULL, QEMU_NBD_OPT_DETECT_ZEROES }, { shared, 1, NULL, 'e' }, { format, 1, NULL, 'f' }, { persistent, 0, NULL, 't' }, @@ -432,6 +438,7 @@ int main(int argc, char **argv) pthread_t client_thread; const char *fmt = NULL; Error *local_err = NULL; +BlockdevDetectZeroesOptions detect_zeroes = BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF; /* The client thread uses SIGTERM to interrupt the server. A signal * handler ensures that qemu-nbd -v -c exits with a nice status code. @@ -483,6 +490,23 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, Invalid discard mode `%s', optarg); } break; +case QEMU_NBD_OPT_DETECT_ZEROES: +detect_zeroes = +qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, +optarg, +BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX, +BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, +local_err); +if (local_err) { +errx(EXIT_FAILURE, Failed to parse detect_zeroes mode: %s, + error_get_pretty(local_err)); +} +if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP +!(flags BDRV_O_UNMAP)) { +errx(EXIT_FAILURE, setting detect-zeroes to unmap is not allowed + without setting discard operation to unmap); +} +break; case 'b': bindto = optarg; break; @@ -686,6 +710,7 @@ int main(int argc, char **argv) error_get_pretty(local_err)); } +bs-detect_zeroes = detect_zeroes; fd_size = bdrv_getlength(bs); if (partition != -1) { -- 1.7.9.5
Re: [Qemu-devel] [PATCH v4 07/11] libqos: Added basic virtqueue support to virtio implementation
On Tue, Aug 12, 2014 at 01:41:52PM +0200, Marc Marí wrote: +/* Check power of 2 */ +aux = vq-size; +while ((aux 1) != 0) { +aux = aux 1; +} +g_assert_cmpint(aux, !=, 1); Power of 2 can be tested like this without a while loop: g_assert_cmpint(vq-size (vq-size - 1), ==, 0) +void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr) +{ +int i; + +vq-desc = addr; +vq-avail = vq-desc + vq-size*sizeof(QVRingDesc); +vq-used = (uint64_t)((vq-avail + sizeof(uint16_t) * (3 + vq-size) ++vq-align-1) ~(vq-align - 1)); + +for (i = 0; i vq-size-1; i++) { +/* vq-desc[i].addr */ +writew(vq-desc+(16*i), 0); +/* vq-desc[i].next */ +writew(vq-desc+(16*i)+14, i+1); +} Please use space between operators: writew(vq-desc + (16 * i) + 14, i + 1) This applies to all patches. +void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq, +uint32_t free_head) +{ +/* vq-avail-idx */ +uint16_t idx = readl(vq-avail+2); + +/* vq-avail-ring[idx % vq-size] */ +writel(vq-avail+4+(2*(idx % vq-size)), free_head); If you want to use typed pointers you can. It will make the code nicer to read, just be careful never to dereference them and only to access through writel()/readl(): typedef struct { uint16_t foo; /* Forgot what these fields are called and didn't check */ uint16_t bar; uint16_t ring[]; } VirtioAvail; writel(vq-avail.ring[idx % vq-size], free_head); Now it looks more like normal C and the compiler is doing the address calculations for us. pgpmP7XXqhrFi.pgp Description: PGP signature
[Qemu-devel] [PATCHv2 1/3] rename parse_enum_option to qapi_enum_parse and make it public
relaxing the license to LGPLv2+ is intentional. Suggested-by: Markus Armbruster arm...@redhat.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Eric Blake ebl...@redhat.com --- blockdev.c | 30 ++ include/qapi/util.h | 17 + qapi/Makefile.objs |2 +- qapi/qapi-util.c| 34 ++ 4 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 include/qapi/util.h create mode 100644 qapi/qapi-util.c diff --git a/blockdev.c b/blockdev.c index 48bd9a3..9b93cf2 100644 --- a/blockdev.c +++ b/blockdev.c @@ -39,6 +39,7 @@ #include qapi/qmp/types.h #include qapi-visit.h #include qapi/qmp-output-visitor.h +#include qapi/util.h #include sysemu/sysemu.h #include block/block_int.h #include qmp-commands.h @@ -274,25 +275,6 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp) } } -static inline int parse_enum_option(const char *lookup[], const char *buf, -int max, int def, Error **errp) -{ -int i; - -if (!buf) { -return def; -} - -for (i = 0; i max; i++) { -if (!strcmp(buf, lookup[i])) { -return i; -} -} - -error_setg(errp, invalid parameter value: %s, buf); -return def; -} - static bool check_throttle_config(ThrottleConfig *cfg, Error **errp) { if (throttle_conflicting(cfg)) { @@ -456,11 +438,11 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, } detect_zeroes = -parse_enum_option(BlockdevDetectZeroesOptions_lookup, - qemu_opt_get(opts, detect-zeroes), - BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX, - BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, - error); +qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, +qemu_opt_get(opts, detect-zeroes), +BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX, +BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, +error); if (error) { error_propagate(errp, error); goto early_err; diff --git a/include/qapi/util.h b/include/qapi/util.h new file mode 100644 index 000..de9238b --- /dev/null +++ b/include/qapi/util.h @@ -0,0 +1,17 @@ +/* + * QAPI util functions + * + * Copyright Fujitsu, Inc. 2014 + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef QAPI_UTIL_H +#define QAPI_UTIL_H + +int qapi_enum_parse(const char *lookup[], const char *buf, +int max, int def, Error **errp); + +#endif diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index d14b769..2278970 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -1,6 +1,6 @@ util-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o util-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o util-obj-y += string-input-visitor.o string-output-visitor.o - util-obj-y += opts-visitor.o util-obj-y += qmp-event.o +util-obj-y += qapi-util.o diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c new file mode 100644 index 000..1d8fb96 --- /dev/null +++ b/qapi/qapi-util.c @@ -0,0 +1,34 @@ +/* + * QAPI util functions + * + * Authors: + * Hu Tao hu...@cn.fujitsu.com + * Peter Lieven p...@kamp.de + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qemu-common.h +#include qapi/error.h +#include qapi/util.h + +int qapi_enum_parse(const char *lookup[], const char *buf, +int max, int def, Error **errp) +{ +int i; + +if (!buf) { +return def; +} + +for (i = 0; i max; i++) { +if (!strcmp(buf, lookup[i])) { +return i; +} +} + +error_setg(errp, invalid parameter value: %s, buf); +return def; +} -- 1.7.9.5
[Qemu-devel] [PATCH v2] ide: Add resize callback to ide/core
Currently, if the block device backing the IDE drive is resized, the information about the device as cached inside of the IDEState structure is not updated, thus when a guest OS re-queries the drive, it is unable to see the expanded size. This patch adds a resize callback that updates the IDENTIFY data buffer in order to correct this. Lastly, a Linux guest as-is cannot resize a libata drive while in-use, but it can see the expanded size as part of a bus rescan event. This patch also allows guests such as Linux to see the new drive size after a soft reboot event, without having to exit the QEMU process. Signed-off-by: John Snow js...@redhat.com --- V2: - Do not attempt to update geometry values, to avoid clobbering user-specified values, if they exist. - Do not regenerate the entire IDENTIFY buffer to avoid losing any settings that occurred during normal operation. hw/ide/core.c | 32 1 file changed, 32 insertions(+) diff --git a/hw/ide/core.c b/hw/ide/core.c index db191a6..ba5e3ad 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2099,6 +2099,33 @@ static bool ide_cd_is_medium_locked(void *opaque) return ((IDEState *)opaque)-tray_locked; } +static void ide_resize_cb(void *opaque) +{ +IDEState *s = opaque; +uint16_t *p = (uint16_t *)s-identify_data; +uint64_t nb_sectors; + +if (!s-identify_set) { +return; +} + +bdrv_get_geometry(s-bs, nb_sectors); +s-nb_sectors = nb_sectors; + +/* Update the identify buffer. Note, this is not called for ATAPI. */ +if (s-drive_kind != IDE_CFATA) { +put_le16(p + 60, s-nb_sectors); +put_le16(p + 61, s-nb_sectors 16); +put_le16(p + 100, s-nb_sectors); +put_le16(p + 101, s-nb_sectors 16); +put_le16(p + 102, s-nb_sectors 32); +put_le16(p + 103, s-nb_sectors 48); +} else { +put_le16(p + 7, s-nb_sectors 16); +put_le16(p + 8, s-nb_sectors); +} +} + static const BlockDevOps ide_cd_block_ops = { .change_media_cb = ide_cd_change_cb, .eject_request_cb = ide_cd_eject_request_cb, @@ -2106,6 +2133,10 @@ static const BlockDevOps ide_cd_block_ops = { .is_medium_locked = ide_cd_is_medium_locked, }; +static const BlockDevOps ide_hd_block_ops = { +.resize_cb = ide_resize_cb, +}; + int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, const char *version, const char *serial, const char *model, uint64_t wwn, @@ -2142,6 +2173,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, error_report(Can't use a read-only drive); return -1; } +bdrv_set_dev_ops(bs, ide_hd_block_ops, s); } if (serial) { pstrcpy(s-drive_serial_str, sizeof(s-drive_serial_str), serial); -- 1.9.3
[Qemu-devel] [PATCHv2 0/3] qemu-nbd: add option to set detect-zeroes mode
v1-v2: - state that relaxing the license for qapi-util.c to LGPLv2+ was intentional [Eric] - split the qemu-nbd patch into 2 pieces [Eric] Peter Lieven (3): rename parse_enum_option to qapi_enum_parse and make it public qemu-nbd: add option to set detect-zeroes mode qemu-nbd: fix indentation and coding style blockdev.c | 30 include/qapi/util.h | 17 + qapi/Makefile.objs |2 +- qapi/qapi-util.c| 34 ++ qemu-nbd.c | 100 --- 5 files changed, 122 insertions(+), 61 deletions(-) create mode 100644 include/qapi/util.h create mode 100644 qapi/qapi-util.c -- 1.7.9.5
Re: [Qemu-devel] [PATCH v4 09/11] libqos: Added test case for configuration changes in virtio-blk test
On Tue, Aug 12, 2014 at 01:41:54PM +0200, Marc Marí wrote: @@ -349,7 +359,7 @@ int main(int argc, char **argv) g_test_init(argc, argv, NULL); g_test_add_func(/virtio/blk/pci/basic, pci_basic); -g_test_add_func(/virtio/blk/pci/indirect, pci_indirect); +g_test_add_func(/virtio/blk/pci/indirect_config, pci_indirect_config); Can you make this an independent test? I think it is unrelated to indirect descriptors. Stefan pgpvv8iEGZej1.pgp Description: PGP signature
[Qemu-devel] using virtio-net multiqueues
Hello, Using qemu2.1 I'm starting a vm with this network interface: [netdev vifA.0] type = tap vhost = on ifname = vifA.0 downscript = no script = no queues = 2 [device vifA.0] driver = virtio-net-pci netdev = vifA.0 mac = 00:16:3e:1a:4e:11 mq = on vectors = 5 during qemu startup I see several queues in /sys/devices/virtual/net/vifA.0/queues and it quickly disappears; at the end I see only one rx and one tx. Am I wrong on something? What can I do to help debug this situation? Best regards, -- William
Re: [Qemu-devel] [PATCHv2 3/3] qemu-nbd: fix indentation and coding style
On 08/13/2014 11:20 AM, Peter Lieven wrote: Signed-off-by: Peter Lieven p...@kamp.de --- qemu-nbd.c | 75 +++- 1 file changed, 39 insertions(+), 36 deletions(-) Reviewed-by: Eric Blake ebl...@redhat.com Thanks for splitting the trivia from the meat in 2/3. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] disk image: self-organized format or raw file
Am 13.08.2014 um 18:38 hat Xingbo Wu geschrieben: On Wed, Aug 13, 2014 at 11:54 AM, Kevin Wolf kw...@redhat.com wrote: Am 12.08.2014 um 01:38 hat 吴兴博 geschrieben: Hello, The introduction in the wiki page present several advantages of qcow2 [1]. But I'm a little confused. I really appreciate if any one can give me some help on this :). (1) Currently the raw format doesn't support COW. In other words, a raw image cannot have a backing file. COW depends on the mapping table on which we it knows whether each block/cluster is present (has been modified) in the current image file. Modern file-systems like xfs/ext4/etc. provide extent/block allocation information to user-level. Like what 'filefrag' does with ioctl 'FIBMAP' and 'FIEMAP'. I guess the raw file driver (maybe block/raw-posix.c) may obtain correct 'present information about blocks. However this information may be limited to be aligned with file allocation unit size. Maybe it's just because a raw file has no space to store the backing file name? I don't think this could hinder the useful feature. (2) As most popular filesystems support delay-allocation/on-demand allocation/ holes, whatever, a raw image is also thin provisioned as other formats. It doesn't consume much disk space by storing useless zeros. However, I don't know if there is any concern on whether fragmented extents would become a burden of the host filesystem. (3) For compression and encryption, I'm not an export on these topics at all but I think these features may not be vital to a image format as both guest/ host's filesystem can also provide similar functionality. (4) I don't have too much understanding on how snapshot works but I think theoretically it would be using the techniques no more than that used in COW and backing file. After all these thoughts, I still found no reason to not using a 'raw' file image (engineering efforts in Qemu should not count as we don't ask for more features from outside world). I would be very sorry if my ignorance wasted your time. Even if it did work (that it's problematic is already discussed in other subthreads) what advantage would you get from using an extended raw driver compared to simply using qcow2, which supports all of this today? Kevin I read several messages from this thread: [RFC] qed: Add QEMU Enhanced Disk format. To my understanding, if the new format can be acceptable to the community: It needs to retain all the key features provided by qcow2, especially for compression, encryption, and internal snapshot, as mentioned in that thread. And, needless to say, it must run faster. Yes I agree it's at least a subset of the homework one need to do before selling the new format to the community. So your goal is improved performance? Why do you think that a raw driver with backing file support would run much faster than qcow2? It would have to solve the same problems, like doing efficient COW. Thanks and another question: What's the magic that makes QED runs faster than QCOW2? During cluster allocation (which is the real critical part), QED is a lot slower than today's qcow2. And by that I mean not just a few percent, but like half the performance. After that, when accessing already allocated data, both perform similar. Mailing list discussions of four years ago don't reflect accurately how qemu works today. The main trick of QED was to introduce a dirty flag, which allowed to call fdatasync() less often because it was okay for image metadata to become inconsistent. After a crash, you have to repair the image then. qcow2 supports the same with lazy_refcounts=on, but it's really only useful in rare cases, mostly with cache=writethrough. In some simple parallel IO tests QED can run a magnitude faster than QCOW2. I saw differences on simple/complex metadata organization, and coroutine/aio (however bdrv_co_s finally call bdrv_aio_s via _em. If you can provide some insight on this I would be really appreciate. Today, everything is internally coroutine operations, so every request goes through bdrv_co_do_preadv/pwritev. The aio_* versions are just wrappers around it for callers and block drivers that prefer a callback based interface. Kevin
Re: [Qemu-devel] using virtio-net multiqueues
On Wed, Aug 13, 2014 at 8:03 PM, William Dauchy wdau...@gmail.com wrote: Using qemu2.1 I'm starting a vm with this network interface: [netdev vifA.0] type = tap vhost = on ifname = vifA.0 downscript = no script = no queues = 2 [device vifA.0] driver = virtio-net-pci netdev = vifA.0 mac = 00:16:3e:1a:4e:11 mq = on vectors = 5 during qemu startup I see several queues in /sys/devices/virtual/net/vifA.0/queues and it quickly disappears; at the end I see only one rx and one tx. Am I wrong on something? What can I do to help debug this situation? my host is a linux3.14.X and the guest VM is running a linux3.12.X -- William
Re: [Qemu-devel] [PATCH 1/1] add loopback for virtio-net
On Wed, Aug 13, 2014 at 09:47:40PM +0800, Hengjinxiao wrote: Sometimes it is necessary to test whether virtio-net can send and receive packets normally, just as e1000 does. This patch adds loopback for virtio-net, when the command 'VIRTIO_NET_CTRL_LOOPBACK_SET' is sent from front-end driver(such as virtio-net driver in linux.git), virtio-net goes into loopback mode, and the test above can be executed, then command 'VIRTIO_NET_CTRL_LOOPBACK_UNSET' can make virtio-net go back to previous state. Signed-off-by: Hengjinxiao hjxiaoh...@gmail.com Using two commands here seems unjustified, when using one would do. Capability to handle these commands needs a feature bit. The patches have style issues. But besides all this, there are bigger questions: How is this capability useful? Your description is kind of vague. It might be useful for e1000 as a driver development tool. For virtio it seems just as easy to connect to another VM alternatively you can write a utility - external to qemu - that gets all packets and bounces them back on the same fd. In fact, won't something like netcat do this more or less for free? It's hard to judge whether it's worth the performance and maintainance costs, without this info. --- hw/net/virtio-net.c| 26 +++--- include/hw/virtio/virtio-net.h | 9 + include/hw/virtio/virtio.h | 1 + include/net/net.h | 1 + net/net.c | 7 +-- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 268eff9..ca313f4 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -778,6 +778,22 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, return VIRTIO_NET_OK; } + +static int virtio_net_handle_loopback(VirtIONet *n, uint8_t cmd, + struct iovec *iov, unsigned int iov_cnt) +{ +VirtIODevice *vdev = VIRTIO_DEVICE(n); +if (cmd == VIRTIO_NET_CTRL_LOOPBACK_SET) { +vdev-loopback = 1; +return VIRTIO_NET_OK; +} else if (cmd == VIRTIO_NET_CTRL_LOOPBACK_UNSET) { +vdev-loopback = 0; +return VIRTIO_NET_OK; +} else { +return VIRTIO_NET_ERR; +} +} + static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) { VirtIONet *n = VIRTIO_NET(vdev); @@ -813,6 +829,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt); } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) { status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt); +} else if (ctrl.class == VIRTIO_NET_CTRL_LOOPBACK) { +status = virtio_net_handle_loopback(n, ctrl.cmd, iov, iov_cnt); } s = iov_from_buf(elem.in_sg, elem.in_num, 0, status, sizeof(status)); @@ -1108,6 +1126,9 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) VirtQueueElement elem; int32_t num_packets = 0; int queue_index = vq2q(virtio_get_queue_index(q-tx_vq)); + NetClientState *sender = qemu_get_subqueue(n-nic, queue_index); + + sender-loopback = vdev-loopback; if (!(vdev-status VIRTIO_CONFIG_S_DRIVER_OK)) { return num_packets; } @@ -1156,9 +1177,8 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) } len = n-guest_hdr_len; - -ret = qemu_sendv_packet_async(qemu_get_subqueue(n-nic, queue_index), - out_sg, out_num, virtio_net_tx_complete); + + ret = qemu_sendv_packet_async(sender, out_sg, out_num, + virtio_net_tx_complete); if (ret == 0) { virtio_queue_set_notification(q-tx_vq, 0); q-async_tx.elem = elem; diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 6ceb5aa..24e56bf 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -257,6 +257,15 @@ struct virtio_net_ctrl_mq { #define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5 #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET0 + /* + * Control Loopback + * + * The command VIRTIO_NET_CTRL_LOOPBACK_SET is used to require the device + * come into loopback state. + */ +#define VIRTIO_NET_CTRL_LOOPBACK 6 + #define VIRTIO_NET_CTRL_LOOPBACK_SET0 + #define VIRTIO_NET_CTRL_LOOPBACK_UNSET1 #define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \ DEFINE_PROP_BIT(any_layout, _state, _field, VIRTIO_F_ANY_LAYOUT, true), \ DEFINE_PROP_BIT(csum, _state, _field, VIRTIO_NET_F_CSUM, true), \ diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index a60104c..219e0d2 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -128,6 +128,7 @@ struct VirtIODevice VMChangeStateEntry *vmstate;
[Qemu-devel] [V3 PATCH 00/13] target-ppc: Linux-User Mode Bug Fixes for Power
This series of patches is the result of executing the Linux Test Program (LTP) System Call bucket (https://github.com/linux-test-project/ltp) on the 64 bit big and little endian linux user mode targets for Power. Some of the changes are not technically unique to Power, but are effectively so. For example, Power may be the only runtime that uses the ipc system call as a hub for other system calls (semctl, semop, ...). The series is dependent on my previous patch series that adds signal handler support on PPC64 (http://lists.nongnu.org/archive/html/qemu-ppc/2014-06/msg00802.html). That series has gone into Alex's ppcnext branch for QEMU 2.2. V2: Addressing review comments from Peter Maydell. V3: Included linux-user: Move get_ppc64_abi so that this series applies cleanly to the current git master. Tom Musta (13): linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2 linux-user: Dereference Pointer Argument to ipc/semctl Sys Call linux-user: Properly Handle semun Structure In Cross-Endian Situations linux-user: Make ipc syscall's third argument an abi_long linux-user: Conditionally Pass Attribute Pointer to mq_open() linux-user: Detect Negative Message Sizes in msgsnd System Call linux-user: Handle NULL sched_param argument to sched_* linux-user: Detect fault in sched_rr_get_interval linux-user: Move get_ppc64_abi linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2 linux-user: clock_nanosleep errno Handling on PPC linux-user: Support target-to-host translation of mlockall argument linux-user: writev Partial Writes linux-user/aarch64/syscall.h|3 + linux-user/alpha/syscall.h |3 + linux-user/arm/syscall.h|4 ++ linux-user/cris/syscall.h |3 + linux-user/elfload.c|9 linux-user/i386/syscall.h |3 + linux-user/m68k/syscall.h |4 ++ linux-user/microblaze/syscall.h |3 + linux-user/mips/syscall.h |3 + linux-user/mips64/syscall.h |3 + linux-user/openrisc/syscall.h |4 ++ linux-user/ppc/syscall.h|4 ++ linux-user/ppc/target_cpu.h | 10 linux-user/s390x/syscall.h |3 + linux-user/sh4/syscall.h|4 ++ linux-user/signal.c | 12 - linux-user/sparc/syscall.h |3 + linux-user/sparc64/syscall.h|3 + linux-user/syscall.c| 100 +- linux-user/unicore32/syscall.h |4 ++ linux-user/x86_64/syscall.h |3 + 21 files changed, 164 insertions(+), 24 deletions(-)
[Qemu-devel] [V3 PATCH 01/13] linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2
The 64 bit PowerPC platforms eliminate the _unused1 and _unused2 elements of the semid_ds structure from sys/sem.h. So eliminate these from the target_semid_ds structure. Signed-off-by: Tom Musta tommu...@gmail.com --- linux-user/syscall.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a50229d..540001c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2419,9 +2419,13 @@ struct target_semid_ds { struct target_ipc_perm sem_perm; abi_ulong sem_otime; +#if !defined(TARGET_PPC64) abi_ulong __unused1; +#endif abi_ulong sem_ctime; +#if !defined(TARGET_PPC64) abi_ulong __unused2; +#endif abi_ulong sem_nsems; abi_ulong __unused3; abi_ulong __unused4; -- 1.7.1
[Qemu-devel] [V3 PATCH 02/13] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call
When the ipc system call is used to wrap a semctl system call, the ptr argument to ipc needs to be dereferenced prior to passing it to the semctl handler. This is because the fourth argument to semctl is a union and not a pointer to a union. Signed-off-by: Tom Musta tommu...@gmail.com --- V2: This is unchanged from V1. I *did* review the QEMU, glibc and kernel code looking for some problems but did not find anything. I also did fairly comprehesive testing of semctl on 4 targets (ppc-linux-user, ppc64-linux-user, ppc64le-linux-user, x86_64-linux-user) on 3 different host platforms (x86-64 Ubuntu, PPC64 RHEL 6 (BE) and PPC64 Ubuntu 14.04 (LE)); this provided a broad coverage of co-endian and cross endian situations. linux-user/syscall.c | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 540001c..229c482 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3135,9 +3135,15 @@ static abi_long do_ipc(unsigned int call, int first, ret = get_errno(semget(first, second, third)); break; -case IPCOP_semctl: -ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr); +case IPCOP_semctl: { +/* The semun argument to semctl is passed by value, so dereference the + * ptr argument. */ +abi_ulong atptr; +get_user_ual(atptr, (abi_ulong)ptr); +ret = do_semctl(first, second, third, +(union target_semun)(abi_ulong) atptr); break; +} case IPCOP_msgget: ret = get_errno(msgget(first, second)); -- 1.7.1
[Qemu-devel] [V3 PATCH 12/13] linux-user: Support target-to-host translation of mlockall argument
The argument to the mlockall system call is not necessarily the same on all platforms and thus may require translation prior to passing to the host. For example, PowerPC 64 bit platforms define values for MCL_CURRENT (0x2000) and MCL_FUTURE (0x4000) which are different from Intel platforms (0x1 and 0x2, respectively) Signed-off-by: Tom Musta tommu...@gmail.com --- V2: Per Peter Maydell's review, added a complete set of TARGET_MCL_* macros in the various linux-user/$ARCH/syscall.h files. linux-user/aarch64/syscall.h|2 ++ linux-user/alpha/syscall.h |2 ++ linux-user/arm/syscall.h|2 ++ linux-user/cris/syscall.h |2 ++ linux-user/i386/syscall.h |2 ++ linux-user/m68k/syscall.h |2 ++ linux-user/microblaze/syscall.h |2 ++ linux-user/mips/syscall.h |2 ++ linux-user/mips64/syscall.h |2 ++ linux-user/openrisc/syscall.h |2 ++ linux-user/ppc/syscall.h|2 ++ linux-user/s390x/syscall.h |2 ++ linux-user/sh4/syscall.h|2 ++ linux-user/sparc/syscall.h |2 ++ linux-user/sparc64/syscall.h|2 ++ linux-user/syscall.c| 17 - linux-user/unicore32/syscall.h |2 ++ linux-user/x86_64/syscall.h |2 ++ 18 files changed, 50 insertions(+), 1 deletions(-) diff --git a/linux-user/aarch64/syscall.h b/linux-user/aarch64/syscall.h index d1f4823..dc72a15 100644 --- a/linux-user/aarch64/syscall.h +++ b/linux-user/aarch64/syscall.h @@ -9,3 +9,5 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 3.8.0 #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 diff --git a/linux-user/alpha/syscall.h b/linux-user/alpha/syscall.h index 3adedeb..245cff2 100644 --- a/linux-user/alpha/syscall.h +++ b/linux-user/alpha/syscall.h @@ -253,3 +253,5 @@ struct target_pt_regs { #define TARGET_UAC_NOFIX 2 #define TARGET_UAC_SIGBUS 4 #define TARGET_MINSIGSTKSZ 4096 +#define TARGET_MLOCKALL_MCL_CURRENT 0x2000 +#define TARGET_MLOCKALL_MCL_FUTURE 0x4000 diff --git a/linux-user/arm/syscall.h b/linux-user/arm/syscall.h index cdadb0c..3844a96 100644 --- a/linux-user/arm/syscall.h +++ b/linux-user/arm/syscall.h @@ -46,3 +46,5 @@ struct target_pt_regs { #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 diff --git a/linux-user/cris/syscall.h b/linux-user/cris/syscall.h index a75bcc4..2957b0d 100644 --- a/linux-user/cris/syscall.h +++ b/linux-user/cris/syscall.h @@ -40,5 +40,7 @@ struct target_pt_regs { #define TARGET_CLONE_BACKWARDS2 #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 #endif diff --git a/linux-user/i386/syscall.h b/linux-user/i386/syscall.h index acf6856..906aaac 100644 --- a/linux-user/i386/syscall.h +++ b/linux-user/i386/syscall.h @@ -148,3 +148,5 @@ struct target_vm86plus_struct { #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 diff --git a/linux-user/m68k/syscall.h b/linux-user/m68k/syscall.h index f8553f8..9218493 100644 --- a/linux-user/m68k/syscall.h +++ b/linux-user/m68k/syscall.h @@ -19,5 +19,7 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32 #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 void do_m68k_simcall(CPUM68KState *, int); diff --git a/linux-user/microblaze/syscall.h b/linux-user/microblaze/syscall.h index 2a5e160..3c1ed27 100644 --- a/linux-user/microblaze/syscall.h +++ b/linux-user/microblaze/syscall.h @@ -50,5 +50,7 @@ struct target_pt_regs { #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 #endif diff --git a/linux-user/mips/syscall.h b/linux-user/mips/syscall.h index 0b4662c..35ca23b 100644 --- a/linux-user/mips/syscall.h +++ b/linux-user/mips/syscall.h @@ -229,3 +229,5 @@ struct target_pt_regs { #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h index 39b8bed..6733107 100644 --- a/linux-user/mips64/syscall.h +++ b/linux-user/mips64/syscall.h @@ -226,3 +226,5 @@ struct target_pt_regs { #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 diff --git a/linux-user/openrisc/syscall.h b/linux-user/openrisc/syscall.h index e5e6180..8ac0365 100644 --- a/linux-user/openrisc/syscall.h +++ b/linux-user/openrisc/syscall.h @@ -25,3 +25,5 @@ struct target_pt_regs { #define UNAME_MINIMUM_RELEASE 2.6.32