Re: [Qemu-devel] [PATCH RFC 07/11] ide: Makefile corrected due to bridge creation

2015-08-17 Thread Hannes Reinecke
On 08/18/2015 01:42 AM, Alexander Bezzubikov wrote:
> Signed-off-by: Alexander Bezzubikov 
> ---
>  hw/ide/Makefile.objs | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/ide/Makefile.objs b/hw/ide/Makefile.objs
> index 729e9bd..f54f275 100644
> --- a/hw/ide/Makefile.objs
> +++ b/hw/ide/Makefile.objs
> @@ -1,4 +1,4 @@
> -common-obj-$(CONFIG_IDE_CORE) += core.o atapi.o
> +common-obj-$(CONFIG_IDE_CORE) += core.o atapi.o bridge.o
>  common-obj-$(CONFIG_IDE_QDEV) += qdev.o
>  common-obj-$(CONFIG_IDE_PCI) += pci.o
>  common-obj-$(CONFIG_IDE_ISA) += isa.o
> 
And this should be merged with the patch which creates 'bridge.c'

Cheers,

Hannes
-- 
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)



Re: [Qemu-devel] [PATCH RFC 08/11] scsi: SCSIDiskReq declaration moved to header

2015-08-17 Thread Hannes Reinecke
On 08/18/2015 01:42 AM, Alexander Bezzubikov wrote:
> Signed-off-by: Alexander Bezzubikov 
> ---
>  hw/scsi/scsi-disk.c| 12 
>  include/hw/scsi/scsi.h | 13 +
>  2 files changed, 13 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> index f67d816..9d5f0a4 100644
> --- a/hw/scsi/scsi-disk.c
> +++ b/hw/scsi/scsi-disk.c
> @@ -53,18 +53,6 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while 
> (0)
>  
>  typedef struct SCSIDiskState SCSIDiskState;
>  
> -typedef struct SCSIDiskReq {
> -SCSIRequest req;
> -/* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
> -uint64_t sector;
> -uint32_t sector_count;
> -uint32_t buflen;
> -bool started;
> -struct iovec iov;
> -QEMUIOVector qiov;
> -BlockAcctCookie acct;
> -} SCSIDiskReq;
> -
>  #define SCSI_DISK_F_REMOVABLE 0
>  #define SCSI_DISK_F_DPOFUA1
>  #define SCSI_DISK_F_NO_REMOVABLE_DEVOPS   2
> diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
> index 881ed23..de0546e 100644
> --- a/include/hw/scsi/scsi.h
> +++ b/include/hw/scsi/scsi.h
> @@ -6,6 +6,7 @@
>  #include "hw/block/block.h"
>  #include "sysemu/sysemu.h"
>  #include "qemu/notify.h"
> +#include "block/accounting.h"
>  
>  #define MAX_SCSI_DEVS255
>  
> @@ -120,6 +121,18 @@ extern const VMStateDescription vmstate_scsi_device;
>  .offset = vmstate_offset_value(_state, _field, SCSIDevice),  \
>  }
>  
> +typedef struct SCSIDiskReq {
> +SCSIRequest req;
> +/* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
> +uint64_t sector;
> +uint32_t sector_count;
> +uint32_t buflen;
> +bool started;
> +struct iovec iov;
> +QEMUIOVector qiov;
> +BlockAcctCookie acct;
> +} SCSIDiskReq;
> +
>  /* cdrom.c */
>  int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
>  int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int 
> session_num);
> 
I'm not sure this is a good idea; the abstraction model seems to be that
scsi-disk.h contains all declarations for the SCSI disk model, and as
such the struct should remain there.

Probably it might be better to create a 'scsi-disk.h' include file, to
contain all necessary things.

But actually I'm not sure.
John? What's your opinion here?

Cheers,

Hannes
-- 
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)



Re: [Qemu-devel] [RFC PATCH] exec-all: Translate TCI return addresses backwards too

2015-08-17 Thread Richard Henderson
On 08/15/2015 11:21 PM, Peter Crosthwaite wrote:
> I'm trying to debug why TCI doesn't work for the Microblaze example at
> http://wiki.qemu.org/Testing. My debug led me to the return addresses
> for exceptions being too far forward and this adjustment looked
> related so I gave this change a shot, and it works!
> 
> I did some further-afield image testing, and it turns out that this
> patch fixes TCI for at least several arches. Here are my test results:
> 
> ARCHTCI-WITH-PATCH  TCI-WITHOUT-PATCH   HOST-TCG
> microblaze  Y   N (blank)   Y
> crisY   N (K panic) Y
> arm Y   N (halfway) Y
> aarch64 N (abort)   N (abort)   Y
> SH4 Y   N (K panic) Y
> 
> The patch gets you to a linux login prompt on MB,CRIS,ARM and SH4
> whereas before the patch various crashes occured.
> 
> AArch64 has what appears to be a separate issue with TCI. I am use this
> for testing:
> 
> http://www.bennee.com/~alex/blog/2014/05/09/running-linux-in-qemus-aarch64-system-emulation-mode/
> 
> I don't understand this TCI code fully yet, so I doubt my change is
> correct, but RFCing incase someone has some theories to help me debug,
> or justify the change.
> 
> My debug strategy is to run QEMU both with and without TCI and pass:
> 
> -d op,exec,in_asm,mmu
> 
> then filter logs with:
> 
> s/\(exit_tb\).*$/\1/
> s/^\(Trace \)[0-9a-fx]*/\1/
> 
> The two logs then give you a nice diff between to TCI and host-TCG
> run. The first diff I saw was a bad exception return address in the TCI
> case:
> 
>  IN: PC=20
>  rmsr=4300 resr=412 rear=c7fc debug=0 imm=fffc iflags=2100 fsr=0
>  btaken=1 btarget=c0291d28 mode=kernel(saved=kernel) eip=512 ie=0
>  r00= r01=c026ff90 r02=c026de90 r03=deadbeef
>  r04=c7ffe38c r05=1c74 r06=97ffe38c r07=1c74
>  r08= r09=91fe r10=0010 r11=c1c8bd94
>  r12=c1c8bdc0 r13=c027f680 r14= r15=c0291d20
> -r16= r17=c0291d3c r18=07ffe38c r19=
> +r16= r17=c0291d44 r18=07ffe38c r19=
>  r20= r21= r22=1c70 r23=c026ffac
>  r24= r25= r26= r27=
>  r28= r29=0100 r30=0380 r31=c02722f8
> 
> In Microblaze, PC=20 is the MMU fault exception vector and R17 is
> the exception return address. The faulting instruction is at
> 0xc0291d2c as shown by the host-TCG run (-) but TCI has it at
> 0xc0291d44 (+). It is a store:
> 
>  0xc0291d38:  andi  r22, r22, -4
>  0xc0291d3c:  swr3, r4, r22
>  0xc0291d40:  imm   -15928
>  0xc0291d44:  lwi   r8, r0, -10452
> 
> Signed-off-by: Peter Crosthwaite 
> ---
>  include/exec/exec-all.h | 4 
>  1 file changed, 4 deletions(-)
> 
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index a6fce04..31c2405 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -308,11 +308,7 @@ extern uintptr_t tci_tb_ptr;
> to indicate the compressed mode; subtracting two works around that.  It
> is also the case that there are no host isas that contain a call insn
> smaller than 4 bytes, so we don't worry about special-casing this.  */
> -#if defined(CONFIG_TCG_INTERPRETER)
> -# define GETPC_ADJ   0
> -#else
>  # define GETPC_ADJ   2
> -#endif
>  
>  #define GETPC()  (GETRA() - GETPC_ADJ)
>  
> 

Reviewed-by: Richard Henderson 


r~



[Qemu-devel] [PATCH v2 0/4] pc: Initialization and compat function cleanup

2015-08-17 Thread Eduardo Habkost
Changes v1 -> v2:
* Fix build error on patch 1/4

This implements some extras code cleanups in the PC code:

* Move some local variables from pc_init1() and pc_q35_init() to
  PCMachineState, so initialization functions can get that info from a
  PCMachineState* argument directly
* Move some compat global variables to PCMachineClass,
  and move compatibility code from pc_compat_*() functions
  to the corresponding *_machine_options() function

Eduardo Habkost (4):
  pc: Remove redundant arguments from xen_hvm_init()
  pc: Move compat boolean globals to PCMachineClass
  pc: Move legacy_acpi_table_size global to PCMachineClass
  pc: Move acpi_data_size global to PCMachineClass

 hw/i386/pc.c |  25 +-
 hw/i386/pc_piix.c| 130 ---
 hw/i386/pc_q35.c |  60 +++-
 include/hw/i386/pc.h |  21 -
 include/hw/xen/xen.h |   4 +-
 xen-hvm-stub.c   |   3 +-
 xen-hvm.c|  25 +-
 7 files changed, 135 insertions(+), 133 deletions(-)

-- 
2.1.0




[Qemu-devel] [PATCH v5 1/4] scripts: Include arch/powerpc/include/uapi/asm/eeh.h

2015-08-17 Thread Gavin Shan
This includes linux/arch/powerpc/include/uapi/asm/eeh.h while
updating linux header files. The specific header file, introduced
by Linux upstream commit ed3e81f ("powerpc/eeh: Move PE state
constants around"), is used by EEH on sPAPR platform.

Signed-off-by: Gavin Shan 
---
 scripts/update-linux-headers.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index f0e830c..bcfecd3 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -89,6 +89,7 @@ for arch in $ARCHLIST; do
 cp "$tmpdir/include/asm/hyperv.h" "$output/linux-headers/asm-x86"
 fi
 if [ $arch = powerpc ]; then
+cp "$tmpdir/include/asm/eeh.h" "$output/linux-headers/asm-powerpc/"
 cp "$tmpdir/include/asm/epapr_hcalls.h" 
"$output/linux-headers/asm-powerpc/"
 fi
 
-- 
2.1.0




[Qemu-devel] [PATCH v5 4/4] sPAPR: Support RTAS call ibm,errinjct

2015-08-17 Thread Gavin Shan
The patch supports RTAS call "ibm,errinjct" to allow injecting
EEH errors to VFIO PCI devices. The implementation is similiar
to EEH support for VFIO PCI devices: The RTAS request is captured
by QEMU and routed to sPAPRPHBClass::eeh_inject_error() where the
request is translated to VFIO container IOCTL command to be handled
by the host.

Signed-off-by: Gavin Shan 
---
 hw/ppc/spapr_pci.c  | 36 +
 hw/ppc/spapr_pci_vfio.c | 56 +
 hw/ppc/spapr_rtas.c | 77 +
 include/hw/pci-host/spapr.h |  2 ++
 include/hw/ppc/spapr.h  |  9 +-
 5 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 9d41060..f6223ce 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -682,6 +682,42 @@ param_error_exit:
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 }
 
+int spapr_rtas_errinjct_ioa(sPAPRMachineState *spapr,
+target_ulong param_buf,
+bool is_64bits)
+{
+sPAPRPHBState *sphb;
+sPAPRPHBClass *spc;
+uint64_t buid, addr, mask;
+uint32_t func;
+
+if (is_64bits) {
+addr = ((uint64_t)rtas_ld(param_buf, 0) << 32) | rtas_ld(param_buf, 1);
+mask = ((uint64_t)rtas_ld(param_buf, 2) << 32) | rtas_ld(param_buf, 3);
+buid = ((uint64_t)rtas_ld(param_buf, 5) << 32) | rtas_ld(param_buf, 6);
+func = rtas_ld(param_buf, 7);
+} else {
+addr = rtas_ld(param_buf, 0);
+mask = rtas_ld(param_buf, 1);
+buid = ((uint64_t)rtas_ld(param_buf, 3) << 32) | rtas_ld(param_buf, 4);
+func = rtas_ld(param_buf, 5);
+}
+
+/* Find PHB */
+sphb = spapr_pci_find_phb(spapr, buid);
+if (!sphb) {
+return RTAS_OUT_PARAM_ERROR;
+}
+
+spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+if (!spc->eeh_inject_error) {
+return RTAS_OUT_PARAM_ERROR;
+}
+
+/* Handle the request */
+return spc->eeh_inject_error(sphb, func, addr, mask, is_64bits);
+}
+
 static int pci_spapr_swizzle(int slot, int pin)
 {
 return (slot + pin) % PCI_NUM_PINS;
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index cca45ed..a3674ee 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -17,6 +17,8 @@
  *  along with this program; if not, see .
  */
 
+#include 
+
 #include "hw/ppc/spapr.h"
 #include "hw/pci-host/spapr.h"
 #include "hw/pci/msix.h"
@@ -250,6 +252,59 @@ static int spapr_phb_vfio_eeh_configure(sPAPRPHBState 
*sphb)
 return RTAS_OUT_SUCCESS;
 }
 
+static int spapr_phb_vfio_eeh_inject_error(sPAPRPHBState *sphb,
+   uint32_t func, uint64_t addr,
+   uint64_t mask, bool is_64bits)
+{
+sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
+struct vfio_eeh_pe_op op = {
+.op = VFIO_EEH_PE_INJECT_ERR,
+.argsz = sizeof(op)
+};
+int ret = RTAS_OUT_SUCCESS;
+
+op.err.type = is_64bits ? EEH_ERR_TYPE_64 : EEH_ERR_TYPE_32;
+op.err.addr = addr;
+op.err.mask = mask;
+
+switch (func) {
+case EEH_ERR_FUNC_LD_MEM_ADDR:
+case EEH_ERR_FUNC_LD_MEM_DATA:
+case EEH_ERR_FUNC_LD_IO_ADDR:
+case EEH_ERR_FUNC_LD_IO_DATA:
+case EEH_ERR_FUNC_LD_CFG_ADDR:
+case EEH_ERR_FUNC_LD_CFG_DATA:
+case EEH_ERR_FUNC_ST_MEM_ADDR:
+case EEH_ERR_FUNC_ST_MEM_DATA:
+case EEH_ERR_FUNC_ST_IO_ADDR:
+case EEH_ERR_FUNC_ST_IO_DATA:
+case EEH_ERR_FUNC_ST_CFG_ADDR:
+case EEH_ERR_FUNC_ST_CFG_DATA:
+case EEH_ERR_FUNC_DMA_RD_ADDR:
+case EEH_ERR_FUNC_DMA_RD_DATA:
+case EEH_ERR_FUNC_DMA_RD_MASTER:
+case EEH_ERR_FUNC_DMA_RD_TARGET:
+case EEH_ERR_FUNC_DMA_WR_ADDR:
+case EEH_ERR_FUNC_DMA_WR_DATA:
+case EEH_ERR_FUNC_DMA_WR_MASTER:
+op.err.func = func;
+break;
+default:
+ret = RTAS_OUT_PARAM_ERROR;
+goto out;
+}
+
+if (vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid,
+ VFIO_EEH_PE_OP, &op) < 0) {
+ret = RTAS_OUT_HW_ERROR;
+goto out;
+}
+
+ret = RTAS_OUT_SUCCESS;
+out:
+return ret;
+}
+
 static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -262,6 +317,7 @@ static void spapr_phb_vfio_class_init(ObjectClass *klass, 
void *data)
 spc->eeh_get_state = spapr_phb_vfio_eeh_get_state;
 spc->eeh_reset = spapr_phb_vfio_eeh_reset;
 spc->eeh_configure = spapr_phb_vfio_eeh_configure;
+spc->eeh_inject_error = spapr_phb_vfio_eeh_inject_error;
 }
 
 static const TypeInfo spapr_phb_vfio_info = {
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 8405056..5645f43 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -632,6 +632,54 @@ out:
 rtas_st(rets, 1, ret);
 }
 
+static void rtas_ibm_errinjct(PowerPCCPU *cpu,
+   

[Qemu-devel] [PATCH RFC 01/11] ide: ATAPI-SCSI bridge TypeInfo and init function created

2015-08-17 Thread Alexander Bezzubikov
Signed-off-by: Alexander Bezzubikov 
---
 hw/ide/bridge.h   |  9 +
 hw/ide/internal.h |  3 ++-
 hw/ide/qdev.c | 40 
 3 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 hw/ide/bridge.h

diff --git a/hw/ide/bridge.h b/hw/ide/bridge.h
new file mode 100644
index 000..dca5d73
--- /dev/null
+++ b/hw/ide/bridge.h
@@ -0,0 +1,9 @@
+#ifndef HW_IDE_BRIDGE_H
+#define HW_IDE_BRIDGE_H
+
+#include "hw/ide/internal.h"
+
+void ide_bridge_start_transfer(SCSIRequest *req, uint32_t len);
+void ide_bridge_complete(SCSIRequest *req, uint32_t status, size_t resid);
+
+#endif
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 30fdcbc..f2999ce 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -12,6 +12,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/block/block.h"
 #include "block/scsi.h"
+#include "hw/scsi/scsi.h"
 
 /* debug IDE devices */
 //#define DEBUG_IDE
@@ -317,7 +318,7 @@ typedef struct IDEDMAOps IDEDMAOps;
 #define SMART_DISABLE 0xd9
 #define SMART_STATUS  0xda
 
-typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind;
+typedef enum { IDE_HD, IDE_CD, IDE_CFATA, IDE_BRIDGE } IDEDriveKind;
 
 typedef void EndTransferFunc(IDEState *);
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 788b361..e96a6e9 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -25,6 +25,7 @@
 #include "hw/block/block.h"
 #include "sysemu/sysemu.h"
 #include "qapi/visitor.h"
+#include "hw/ide/bridge.h"
 
 /* - */
 
@@ -143,6 +144,17 @@ int ide_get_bios_chs_trans(BusState *bus, int unit)
 return DO_UPCAST(IDEBus, qbus, bus)->ifs[unit].chs_trans;
 }
 
+/* BusInfo structure for ATAPI-SCSI bridge */
+static const struct SCSIBusInfo atapi_scsi_info = {
+.tcq = true,
+.max_target = 0,
+.max_lun = 0,
+
+.transfer_data = NULL,
+.complete = NULL,
+.cancel = NULL
+};
+
 /* - */
 
 typedef struct IDEDrive {
@@ -184,6 +196,11 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind 
kind)
dev->chs_trans) < 0) {
 return -1;
 }
+if (kind == IDE_BRIDGE) {
+scsi_bus_new(&dev->scsi_bus, sizeof(dev->scsi_bus), &dev->qdev,
+ &atapi_scsi_info, NULL);
+scsi_bus_legacy_handle_cmdline(&dev->scsi_bus, NULL);
+}
 
 if (!dev->version) {
 dev->version = g_strdup(s->version);
@@ -253,6 +270,11 @@ static int ide_cd_initfn(IDEDevice *dev)
 return ide_dev_initfn(dev, IDE_CD);
 }
 
+static int ide_bridge_initfn(IDEDevice *dev)
+{
+return ide_dev_initfn(dev, IDE_BRIDGE);
+}
+
 static int ide_drive_initfn(IDEDevice *dev)
 {
 DriveInfo *dinfo = blk_legacy_dinfo(dev->conf.blk);
@@ -314,6 +336,23 @@ static const TypeInfo ide_cd_info = {
 .class_init= ide_cd_class_init,
 };
 
+static void ide_bridge_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+IDEDeviceClass *k = IDE_DEVICE_CLASS(klass);
+k->init = ide_bridge_initfn;
+dc->fw_name = "drive";
+dc->desc = "virtual ATAPI-SCSI bridge";
+dc->props = ide_cd_properties;
+}
+
+static const TypeInfo ide_bridge_info = {
+.name  = "ide-bridge",
+.parent= TYPE_IDE_DEVICE,
+.instance_size = sizeof(IDEDrive),
+.class_init= ide_bridge_class_init,
+};
+
 static Property ide_drive_properties[] = {
 DEFINE_IDE_DEV_PROPERTIES(),
 DEFINE_PROP_END_OF_LIST(),
@@ -360,6 +399,7 @@ static void ide_register_types(void)
 type_register_static(&ide_bus_info);
 type_register_static(&ide_hd_info);
 type_register_static(&ide_cd_info);
+type_register_static(&ide_bridge_info);
 type_register_static(&ide_drive_info);
 type_register_static(&ide_device_type_info);
 }
-- 
2.1.4




[Qemu-devel] [PATCH RFC 08/11] scsi: SCSIDiskReq declaration moved to header

2015-08-17 Thread Alexander Bezzubikov
Signed-off-by: Alexander Bezzubikov 
---
 hw/scsi/scsi-disk.c| 12 
 include/hw/scsi/scsi.h | 13 +
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index f67d816..9d5f0a4 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -53,18 +53,6 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 
 typedef struct SCSIDiskState SCSIDiskState;
 
-typedef struct SCSIDiskReq {
-SCSIRequest req;
-/* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
-uint64_t sector;
-uint32_t sector_count;
-uint32_t buflen;
-bool started;
-struct iovec iov;
-QEMUIOVector qiov;
-BlockAcctCookie acct;
-} SCSIDiskReq;
-
 #define SCSI_DISK_F_REMOVABLE 0
 #define SCSI_DISK_F_DPOFUA1
 #define SCSI_DISK_F_NO_REMOVABLE_DEVOPS   2
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 881ed23..de0546e 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -6,6 +6,7 @@
 #include "hw/block/block.h"
 #include "sysemu/sysemu.h"
 #include "qemu/notify.h"
+#include "block/accounting.h"
 
 #define MAX_SCSI_DEVS  255
 
@@ -120,6 +121,18 @@ extern const VMStateDescription vmstate_scsi_device;
 .offset = vmstate_offset_value(_state, _field, SCSIDevice),  \
 }
 
+typedef struct SCSIDiskReq {
+SCSIRequest req;
+/* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
+uint64_t sector;
+uint32_t sector_count;
+uint32_t buflen;
+bool started;
+struct iovec iov;
+QEMUIOVector qiov;
+BlockAcctCookie acct;
+} SCSIDiskReq;
+
 /* cdrom.c */
 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
 int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
-- 
2.1.4




Re: [Qemu-devel] [PATCH 3/3] tcg: signal-free qemu_cpu_kick

2015-08-17 Thread Richard Henderson
On 08/14/2015 06:15 AM, Paolo Bonzini wrote:
> +atomic_mb_set(¤t_cpu, cpu);
...
> +cpu_exit(atomic_rcu_read(¤t_cpu));

Mixing java and rcu style sync to the same data structure?

> + * ensure tcg_exit_req is read before exit_request
> + * or interrupt_request.
>   */
> +smp_rmb();
>  next_tb = 0;

This I don't understand, since we've just read exit_request above, and you're
putting the barrier here?

> +/* Ensure whatever caused the exit has reached the CPU threads before
> + * writing exit_request.
> + */
> +smp_wmb();
> +exit_request = 1;
> +/* Ignore the CPU argument since all CPUs run in the same thread;
> + * preempt the currently running one.  The memory barriers ensures
> + * that other CPUs will see the request if the current CPU is
> + * preempted.
> + */
> +smp_wmb();
> +cpu_exit(atomic_rcu_read(¤t_cpu));

...

> +/* Pairs with smp_wmb in qemu_cpu_kick.  */
> +atomic_mb_set(&exit_request, 0);
>  }

Bare barriers and java style sync to the same data structure?

>  cpu->exit_request = 1;
> +/* Ensure cpu_exec will see the exit request after TCG has exited.  */
> +smp_wmb();
>  cpu->tcg_exit_req = 1;
>  }

Likewise.

I find this mixing highly confusing.  I see no way to prove that it's going to
be right for non-x86.


r~



Re: [Qemu-devel] [PATCH v7 04/11] target-mips: improve exception handling

2015-08-17 Thread Aurelien Jarno
On 2015-08-13 14:12, Leon Alrae wrote:
> On 10/07/2015 10:57, Pavel Dovgalyuk wrote:
> > @@ -2364,14 +2363,12 @@ static void gen_st_cond (DisasContext *ctx, 
> > uint32_t opc, int rt,
> >  #if defined(TARGET_MIPS64)
> >  case OPC_SCD:
> >  case R6_OPC_SCD:
> > -save_cpu_state(ctx, 1);
> >  op_st_scd(t1, t0, rt, ctx);
> >  opn = "scd";
> >  break;
> >  #endif
> >  case OPC_SC:
> >  case R6_OPC_SC:
> > -save_cpu_state(ctx, 1);
> >  op_st_sc(t1, t0, rt, ctx);
> >  opn = "sc";
> >  break;
> 
> Wouldn't we be better off assuming that conditional stores in linux-user
> always take an exception (we generate fake EXCP_SC exception) and avoid
> retranslation? After applying these changes I observed significant impact on
> performance in linux-user multithreaded apps, for instance c11-atomic-exec
> test before the change took just 2 seconds to finish, whereas now more than 
> 30...

This really show the impact of retranslation and why we should avoid
it when not necessary. Coming back to the issue here, the fact that we
go through retranslation is actually due to the fact that
helper_raise_exception has been changed to go through retranslation.

Given the code path between user-mode and softmmu is quite different,
we definitely need a different code path wrt exception and retranslation
for the two cases. That said if we want deterministic code execution
(the original purpose of this patch), I don't see how we can do without
forcing retranslation. Pavel, do you have an idea for that?

Aurelien

-- 
Aurelien Jarno  GPG: 4096R/1DDD8C9B
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH] pci: Fix pci_device_iommu_address_space() bus propagation

2015-08-17 Thread Michael S. Tsirkin
On Mon, Aug 17, 2015 at 07:39:14PM +1000, Benjamin Herrenschmidt wrote:
> On Sun, 2015-07-05 at 09:19 +1000, Benjamin Herrenschmidt wrote:
> > he current code walks up the bus tree for an iommu, however it passes
> > to the iommu_fn() callback the bus/devfn of the immediate child of
> > the level where the callback was found, rather than the original
> > bus/devfn where the search started from.
> 
> Hi Michael ! Any comment on this ? I'd like to post my series for "bare
> metal" power8 support and the iommu implementation relies on this to
> work.

I've picked this up for my next pull request.
Thanks, and sorry about the delay.

> > This prevents iommu's like POWER8 (and in fact also Q35) to properly
> > provide an address space for a subset of devices that aren't 
> > immediate
> > children of the iommu.
> > 
> > PCIe carries the originator bdfn acccross to the iommu on all DMA
> > transactions, so we must be able to properly identify devices at all
> > levels.
> > 
> > This changes the function pci_device_iommu_address_space() to pass
> > the original pointers to the iommu_fn() callback instead.
> > 
> > Signed-off-by: Benjamin Herrenschmidt 
> > ---
> > 
> > With this, I can implement PHB3's (POWER8) iommu properly, I haven't
> > submitted the P8 native patch series yet but if you are curious, you
> > can look there:
> > 
> > https://github.com/ozbenh/qemu
> > 
> > And more specifically:
> > 
> > https://github.com/ozbenh/qemu/commit/67fe0460c75417908a2b54426cb54fe
> > 5a1299a13
> >  
> > For the PHB3 code.
> > 
> >  hw/pci/pci.c | 13 +
> >  1 file changed, 5 insertions(+), 8 deletions(-)
> > 
> > diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> > index 29f0b0f..8185bbc 100644
> > --- a/hw/pci/pci.c
> > +++ b/hw/pci/pci.c
> > @@ -2403,17 +2403,14 @@ static void pci_device_class_init(ObjectClass 
> > *klass, void *data)
> >  AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
> >  {
> >  PCIBus *bus = PCI_BUS(dev->bus);
> > +PCIBus *iommu_bus = bus;
> >  
> > -if (bus->iommu_fn) {
> > -return bus->iommu_fn(bus, bus->iommu_opaque, dev->devfn);
> > +while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus
> > ->parent_dev) {
> > +iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus);
> >  }
> > -
> > -if (bus->parent_dev) {
> > -/** We are ignoring the bus master DMA bit of the bridge
> > - *  as it would complicate things such as VFIO for no good 
> > reason */
> > -return pci_device_iommu_address_space(bus->parent_dev);
> > +if (iommu_bus && iommu_bus->iommu_fn) {
> > +return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev
> > ->devfn);
> >  }
> > -
> >  return &address_space_memory;
> >  }
> >  
> > 



Re: [Qemu-devel] [Consult] tilegx: About floating point instructions

2015-08-17 Thread Richard Henderson

On 08/17/2015 02:09 PM, Chen Gang wrote:

On 8/18/15 01:31, Richard Henderson wrote:

On 08/15/2015 11:16 AM, Chen Gang wrote:


But what you said is really quite valuable to me!! we can treat the flag
as a caller saved context, then can let the caller can use callee freely
(in fact, I guess, the real hardware treats it as caller context, too).

  - we have to define the flag format based on the existing format in the
related docs and tilegx.md (reserve 0-20 and 25-31 bits).

  - We can only use 21-24 for mark addsub, mul, or typecast result. If
21-24 bits are all zero, it means typecast result. For fsingle: 32-63
bits is the input integer; for fdouble: srca is the input integer.


Plausible.



  - For addsub and mul result, we use 32-63 bits for an index of resource
handler (like 'fd' returned by open). fsingle_addsub2, fsingle_mul1,
fdouble_mul_flags, fdouble_addsub allocate resource, and pack1 free.


No, that's a bad idea.  No state external to the inputs to the insns.


...


 float32 val32s[TILEGX_F_COUNT]; /* results roudup array for fsingle */
 float64 val64s[TILEGX_F_COUNT]; /* results roudup array for fdouble */


I repeat: This is an extremely bad idea.
I will certainly not sign off on any patch that includes this.


r~



[Qemu-devel] [PATCH v2 1/4] pc: Remove redundant arguments from xen_hvm_init()

2015-08-17 Thread Eduardo Habkost
Remove arguments that can be found in PCMachineState.

Signed-off-by: Eduardo Habkost 
---
Changes v1 -> v2:
* Change prototype on xen-hvm-stub.c too
---
 hw/i386/pc_piix.c|  4 +---
 hw/i386/pc_q35.c |  4 +---
 include/hw/xen/xen.h |  4 ++--
 xen-hvm-stub.c   |  3 +--
 xen-hvm.c| 25 -
 5 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 9558467..2b7afc8 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -134,9 +134,7 @@ static void pc_init1(MachineState *machine)
 pcms->below_4g_mem_size = machine->ram_size;
 }
 
-if (xen_enabled() && xen_hvm_init(&pcms->below_4g_mem_size,
-  &pcms->above_4g_mem_size,
-  &ram_memory) != 0) {
+if (xen_enabled() && xen_hvm_init(pcms, &ram_memory) != 0) {
 fprintf(stderr, "xen hardware virtual machine initialisation 
failed\n");
 exit(1);
 }
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c07d65b..36dd6a4 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -125,9 +125,7 @@ static void pc_q35_init(MachineState *machine)
 pcms->below_4g_mem_size = machine->ram_size;
 }
 
-if (xen_enabled() && xen_hvm_init(&pcms->below_4g_mem_size,
-  &pcms->above_4g_mem_size,
-  &ram_memory) != 0) {
+if (xen_enabled() && xen_hvm_init(pcms, &ram_memory) != 0) {
 fprintf(stderr, "xen hardware virtual machine initialisation 
failed\n");
 exit(1);
 }
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 4356af4..e90931a 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -10,6 +10,7 @@
 
 #include "hw/irq.h"
 #include "qemu-common.h"
+#include "qemu/typedefs.h"
 
 /* xen-machine.c */
 enum xen_mode {
@@ -38,8 +39,7 @@ qemu_irq *xen_interrupt_controller_init(void);
 void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
 
 #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
-int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size,
- MemoryRegion **ram_memory);
+int xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory);
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
struct MemoryRegion *mr);
 void xen_modified_memory(ram_addr_t start, ram_addr_t length);
diff --git a/xen-hvm-stub.c b/xen-hvm-stub.c
index 46867d8..6a39425 100644
--- a/xen-hvm-stub.c
+++ b/xen-hvm-stub.c
@@ -47,8 +47,7 @@ void xen_modified_memory(ram_addr_t start, ram_addr_t length)
 {
 }
 
-int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size,
- MemoryRegion **ram_memory)
+int xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
 {
 return 0;
 }
diff --git a/xen-hvm.c b/xen-hvm.c
index 0408462..55bce3a 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -180,8 +180,7 @@ qemu_irq *xen_interrupt_controller_init(void)
 
 /* Memory Ops */
 
-static void xen_ram_init(ram_addr_t *below_4g_mem_size,
- ram_addr_t *above_4g_mem_size,
+static void xen_ram_init(PCMachineState *pcms,
  ram_addr_t ram_size, MemoryRegion **ram_memory_p)
 {
 MemoryRegion *sysmem = get_system_memory();
@@ -198,20 +197,20 @@ static void xen_ram_init(ram_addr_t *below_4g_mem_size,
 }
 
 if (ram_size >= user_lowmem) {
-*above_4g_mem_size = ram_size - user_lowmem;
-*below_4g_mem_size = user_lowmem;
+pcms->above_4g_mem_size = ram_size - user_lowmem;
+pcms->below_4g_mem_size = user_lowmem;
 } else {
-*above_4g_mem_size = 0;
-*below_4g_mem_size = ram_size;
+pcms->above_4g_mem_size = 0;
+pcms->below_4g_mem_size = ram_size;
 }
-if (!*above_4g_mem_size) {
+if (!pcms->above_4g_mem_size) {
 block_len = ram_size;
 } else {
 /*
  * Xen does not allocate the memory continuously, it keeps a
  * hole of the size computed above or passed in.
  */
-block_len = (1ULL << 32) + *above_4g_mem_size;
+block_len = (1ULL << 32) + pcms->above_4g_mem_size;
 }
 memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len,
&error_abort);
@@ -229,12 +228,12 @@ static void xen_ram_init(ram_addr_t *below_4g_mem_size,
  */
 memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo",
  &ram_memory, 0xc,
- *below_4g_mem_size - 0xc);
+ pcms->below_4g_mem_size - 0xc);
 memory_region_add_subregion(sysmem, 0xc, &ram_lo);
-if (*above_4g_mem_size > 0) {
+if (pcms->above_4g_mem_size > 0) {
 memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi",
  &ram_memory, 0x1ULL,
- *above_4g_mem_size)

Re: [Qemu-devel] Debian 7.8.0 SPARC64 on qemu - anything i can do to speedup the emulation?

2015-08-17 Thread Aurelien Jarno
On 2015-08-17 18:25, Artyom Tarasenko wrote:
> On Mon, Aug 17, 2015 at 5:40 PM, Richard Henderson  wrote:
> > On 08/17/2015 07:19 AM, Artyom Tarasenko wrote:
> >> Well, on the other hand, every access goes via helper_check_align.
> >> There is a comment /* XXX remove alignment check */.
> >> I wonder how this can be done in a  more efficient way?
> >
> > Not ever access does so.  There are only 3 memory related calls to 
> > check_align.
> >  The other three are for indirect branches.
> 
> Yes, but I think it's the 3 most used ones.
> 
> > For the 8 byte memory operations we can just remove the checks.  There, the
> > softmmu operation checks the alignment.
> 
> This is a good news. Where does it happen?
> 
> > For usermode, we've typically ignored
> > the guest alignment (which also causes failures for a host that requires
> > alignment emulating a guest that does not).

A tiny bit of topic, but couldn't we force the use of unaligned access 
load/store instructions in user mode instead? For example in QEMU we
can use the LWL/LWR couple instead of LW. I doubt it will make any
measurable difference in speed. For the MIPS case, that doesn't work
for 16-bit load/stores though.

The best would indeed be to switch to softmmu for the user mode. I know
there are people working on that, but given that it might take time, it
could be a simple temporary solution.

-- 
Aurelien Jarno  GPG: 4096R/1DDD8C9B
aurel...@aurel32.net http://www.aurel32.net



[Qemu-devel] [PATCH 12/17] tcg: Split trunc_shr_i32 opcode into extr[lh]_i64_i32

2015-08-17 Thread Richard Henderson
Rather than allow arbitrary shift+trunc, only concern ourselves
with low and high parts.  This is all that was being used anyway.

Signed-off-by: Richard Henderson 
---
 target-tricore/translate.c | 12 ++--
 tcg/README | 14 ++
 tcg/aarch64/tcg-target.h   |  3 ++-
 tcg/i386/tcg-target.h  |  3 ++-
 tcg/ia64/tcg-target.h  |  3 ++-
 tcg/optimize.c | 22 +++---
 tcg/ppc/tcg-target.h   |  3 ++-
 tcg/s390/tcg-target.h  |  3 ++-
 tcg/sparc/tcg-target.c | 14 +++---
 tcg/sparc/tcg-target.h |  3 ++-
 tcg/tcg-op.c   | 38 +++---
 tcg/tcg-op.h   |  5 +++--
 tcg/tcg-opc.h  |  7 +--
 tcg/tcg.h  |  3 ++-
 tcg/tci/tcg-target.h   |  3 ++-
 15 files changed, 77 insertions(+), 59 deletions(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 7dc7a32..70f0930 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -457,11 +457,11 @@ gen_add64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
 tcg_gen_xor_i64(t1, result, r1);
 tcg_gen_xor_i64(t0, r1, r2);
 tcg_gen_andc_i64(t1, t1, t0);
-tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t1, 32);
+tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
 /* calc SV bit */
 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 /* calc AV/SAV bits */
-tcg_gen_trunc_shr_i64_i32(temp, result, 32);
+tcg_gen_extrh_i64_i32(temp, result);
 tcg_gen_add_tl(cpu_PSW_AV, temp, temp);
 tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV);
 /* calc SAV */
@@ -1273,7 +1273,7 @@ gen_madd64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv 
arg1_high, TCGv arg2,
 tcg_gen_xor_i64(t3, t4, t1);
 tcg_gen_xor_i64(t2, t1, t2);
 tcg_gen_andc_i64(t3, t3, t2);
-tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t3, 32);
+tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
 /* We produce an overflow on the host if the mul before was
(0x8000 * 0x8000) << 1). If this is the
case, we negate the ovf. */
@@ -1630,11 +1630,11 @@ gen_sub64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
 tcg_gen_xor_i64(t1, result, r1);
 tcg_gen_xor_i64(t0, r1, r2);
 tcg_gen_and_i64(t1, t1, t0);
-tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t1, 32);
+tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
 /* calc SV bit */
 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 /* calc AV/SAV bits */
-tcg_gen_trunc_shr_i64_i32(temp, result, 32);
+tcg_gen_extrh_i64_i32(temp, result);
 tcg_gen_add_tl(cpu_PSW_AV, temp, temp);
 tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV);
 /* calc SAV */
@@ -2126,7 +2126,7 @@ gen_msub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv 
arg1_high, TCGv arg2,
 tcg_gen_xor_i64(t3, t4, t1);
 tcg_gen_xor_i64(t2, t1, t2);
 tcg_gen_and_i64(t3, t3, t2);
-tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t3, 32);
+tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
 /* We produce an overflow on the host if the mul before was
(0x8000 * 0x8000) << 1). If this is the
case, we negate the ovf. */
diff --git a/tcg/README b/tcg/README
index a22f251..34c0775 100644
--- a/tcg/README
+++ b/tcg/README
@@ -314,11 +314,17 @@ This operation would be equivalent to
 
   dest = (t1 & ~0x0f00) | ((t2 << 8) & 0x0f00)
 
-* trunc_shr_i64_i32 t0, t1, pos
+* extrl_i64_i32 t0, t1
 
-For 64-bit hosts only, right shift the 64-bit input T1 by POS and
-truncate to 32-bit output T0.  Depending on the host, this may be
-a simple mov/shift, or may require additional canonicalization.
+For 64-bit hosts only, extract the low 32-bits of input T1 and place it
+into 32-bit output T0.  Depending on the host, this may be a simple move,
+or may require additional canonicalization.
+
+* extrh_i64_i32 t0, t1
+
+For 64-bit hosts only, extract the high 32-bits of input T1 and place it
+into 32-bit output T0.  Depending on the host, this may be a simple shift,
+or may require additional canonicalization.
 
 * Conditional moves
 
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index dfd8801..19a04a6 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -70,7 +70,8 @@ typedef enum {
 #define TCG_TARGET_HAS_muls2_i320
 #define TCG_TARGET_HAS_muluh_i320
 #define TCG_TARGET_HAS_mulsh_i320
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_extrl_i64_i320
+#define TCG_TARGET_HAS_extrh_i64_i320
 
 #define TCG_TARGET_HAS_div_i64  1
 #define TCG_TARGET_HAS_rem_i64  1
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index dae50ba..92be341 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -102,7 +102,8 @@ extern bool have_bmi1;
 #define TCG_TARGET_HAS_mulsh_i320
 
 #if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_extrl_i64_i320
+#define TCG_TARGET_HAS_extrh_i64_i320
 #define TCG_TARGET_HAS_div2_i64

[Qemu-devel] [PATCH 03/17] tcg/optimize: add temp_is_const and temp_is_copy functions

2015-08-17 Thread Richard Henderson
From: Aurelien Jarno 

Add two accessor functions temp_is_const and temp_is_copy, to make the
code more readable and make code change easier.

Cc: Richard Henderson 
Reviewed-by: Alex Bennée 
Signed-off-by: Aurelien Jarno 
---
 tcg/optimize.c | 131 ++---
 1 file changed, 60 insertions(+), 71 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 425c14b..719fee2 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -52,11 +52,21 @@ struct tcg_temp_info {
 static struct tcg_temp_info temps[TCG_MAX_TEMPS];
 static TCGTempSet temps_used;
 
+static inline bool temp_is_const(TCGArg arg)
+{
+return temps[arg].state == TCG_TEMP_CONST;
+}
+
+static inline bool temp_is_copy(TCGArg arg)
+{
+return temps[arg].state == TCG_TEMP_COPY;
+}
+
 /* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
the copy flag from the left temp.  */
 static void reset_temp(TCGArg temp)
 {
-if (temps[temp].state == TCG_TEMP_COPY) {
+if (temp_is_copy(temp)) {
 if (temps[temp].prev_copy == temps[temp].next_copy) {
 temps[temps[temp].next_copy].state = TCG_TEMP_UNDEF;
 } else {
@@ -186,8 +196,7 @@ static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
 return true;
 }
 
-if (temps[arg1].state != TCG_TEMP_COPY
-|| temps[arg2].state != TCG_TEMP_COPY) {
+if (!temp_is_copy(arg1) || !temp_is_copy(arg2)) {
 return false;
 }
 
@@ -230,7 +239,7 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, 
TCGArg *args,
 return;
 }
 
-if (temps[src].state == TCG_TEMP_CONST) {
+if (temp_is_const(src)) {
 tcg_opt_gen_movi(s, op, args, dst, temps[src].val);
 return;
 }
@@ -248,10 +257,10 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, 
TCGArg *args,
 }
 temps[dst].mask = mask;
 
-assert(temps[src].state != TCG_TEMP_CONST);
+assert(!temp_is_const(src));
 
 if (s->temps[src].type == s->temps[dst].type) {
-if (temps[src].state != TCG_TEMP_COPY) {
+if (!temp_is_copy(src)) {
 temps[src].state = TCG_TEMP_COPY;
 temps[src].next_copy = src;
 temps[src].prev_copy = src;
@@ -488,7 +497,7 @@ static bool do_constant_folding_cond_eq(TCGCond c)
 static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
TCGArg y, TCGCond c)
 {
-if (temps[x].state == TCG_TEMP_CONST && temps[y].state == TCG_TEMP_CONST) {
+if (temp_is_const(x) && temp_is_const(y)) {
 switch (op_bits(op)) {
 case 32:
 return do_constant_folding_cond_32(temps[x].val, temps[y].val, c);
@@ -499,7 +508,7 @@ static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg 
x,
 }
 } else if (temps_are_copies(x, y)) {
 return do_constant_folding_cond_eq(c);
-} else if (temps[y].state == TCG_TEMP_CONST && temps[y].val == 0) {
+} else if (temp_is_const(y) && temps[y].val == 0) {
 switch (c) {
 case TCG_COND_LTU:
 return 0;
@@ -520,12 +529,10 @@ static TCGArg do_constant_folding_cond2(TCGArg *p1, 
TCGArg *p2, TCGCond c)
 TCGArg al = p1[0], ah = p1[1];
 TCGArg bl = p2[0], bh = p2[1];
 
-if (temps[bl].state == TCG_TEMP_CONST
-&& temps[bh].state == TCG_TEMP_CONST) {
+if (temp_is_const(bl) && temp_is_const(bh)) {
 uint64_t b = ((uint64_t)temps[bh].val << 32) | (uint32_t)temps[bl].val;
 
-if (temps[al].state == TCG_TEMP_CONST
-&& temps[ah].state == TCG_TEMP_CONST) {
+if (temp_is_const(al) && temp_is_const(ah)) {
 uint64_t a;
 a = ((uint64_t)temps[ah].val << 32) | (uint32_t)temps[al].val;
 return do_constant_folding_cond_64(a, b, c);
@@ -551,8 +558,8 @@ static bool swap_commutative(TCGArg dest, TCGArg *p1, 
TCGArg *p2)
 {
 TCGArg a1 = *p1, a2 = *p2;
 int sum = 0;
-sum += temps[a1].state == TCG_TEMP_CONST;
-sum -= temps[a2].state == TCG_TEMP_CONST;
+sum += temp_is_const(a1);
+sum -= temp_is_const(a2);
 
 /* Prefer the constant in second argument, and then the form
op a, a, b, which is better handled on non-RISC hosts. */
@@ -567,10 +574,10 @@ static bool swap_commutative(TCGArg dest, TCGArg *p1, 
TCGArg *p2)
 static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
 {
 int sum = 0;
-sum += temps[p1[0]].state == TCG_TEMP_CONST;
-sum += temps[p1[1]].state == TCG_TEMP_CONST;
-sum -= temps[p2[0]].state == TCG_TEMP_CONST;
-sum -= temps[p2[1]].state == TCG_TEMP_CONST;
+sum += temp_is_const(p1[0]);
+sum += temp_is_const(p1[1]);
+sum -= temp_is_const(p2[0]);
+sum -= temp_is_const(p2[1]);
 if (sum > 0) {
 TCGArg t;
 t = p1[0], p1[0] = p2[0], p2[0] = t;
@@ -620,7 +627,7 @@ void tcg_optimize(TCGContext *s)
 
 /* Do copy propagation */
 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
-if (temps[args[i]].state =

Re: [Qemu-devel] [Consult] tilegx: About floating point instructions

2015-08-17 Thread Chen Gang
On 8/18/15 01:31, Richard Henderson wrote:
> On 08/15/2015 11:16 AM, Chen Gang wrote:
> 
>> But what you said is really quite valuable to me!! we can treat the flag
>> as a caller saved context, then can let the caller can use callee freely
>> (in fact, I guess, the real hardware treats it as caller context, too).
>>
>>  - we have to define the flag format based on the existing format in the
>>related docs and tilegx.md (reserve 0-20 and 25-31 bits).
>>
>>  - We can only use 21-24 for mark addsub, mul, or typecast result. If
>>21-24 bits are all zero, it means typecast result. For fsingle: 32-63
>>bits is the input integer; for fdouble: srca is the input integer.
> 
> Plausible.
> 
>>
>>  - For addsub and mul result, we use 32-63 bits for an index of resource
>>handler (like 'fd' returned by open). fsingle_addsub2, fsingle_mul1,
>>fdouble_mul_flags, fdouble_addsub allocate resource, and pack1 free.
> 
> No, that's a bad idea.  No state external to the inputs to the insns.
> 

We can use 21-24 bits for the state external to the inputs to the insns.
My idea is below:

/*
 * Single floaing point instructions decription.
 *
 *  - fsingle_add1, fsingle_sub1, and fsingle_pack1/2 can be used individually.
 *
 *  - when fsingle_pack1/2 is used individually, it is for type cast.
 *
 *  - the old 4Kth result is alrealy useless for caller.
 *
 * fsingle_add1; make context and calc result from rsrca and rsrcb.
 * ; save result in roundup array, and add index to context.
 * ; move context to rdst.
 *
 * fsingle_sub1; make context and calc result from rsrca and rsrcb.
 * ; save result in roundup array, and add index to context.
 * ; move context to rdst.
 *
 * fsingle_addsub2 ; skipped.
 *
 * fsingle_mul1; make context and calc result from rsrca and srcb.
 * ; save result in roundup array, and add index to context.
 * ; move context to rdst.
 *
 * fsingle_mul2; move rsrca to rdst.
 *
 * fsingle_pack1   ; skipped.
 *
 * fsingle_pack2   ; get context from rsrca (rsrca is context).
 * ; if context for add/sub/mul
 * ; get result from roundup array based on index.
 * ; move result to rdst.
 * ; else
 * ; get (u)int32_t interger from context,
 * ; (u)int32_to_float32.
 */

/*
 * Double floating point instructions' description.
 *
 *  - fdouble_add_flags, fdouble_sub_flags, and fdouble_pack1/2 can be used
 *individually.
 *
 *  - when fdouble_pack1/2 is used individually, it is for type cast.
 *
 *  - the old 4Kth result is alrealy useless for caller.
 *
 * fdouble_unpack_max: ; skipped.
 *
 * fdouble_unpack_min: ; skipped.
 *
 * fdouble_add_flags:  ; make context and calc result from rsrca and rsrcb.
 * ; save result in roundup array, and add index to context.
 * ; move context to rdst.
 *
 * fdouble_sub_flags:  ; make context and calc result from rsrca and rsrcb.
 * ; save result in roundup array, and add index to context.
 * ; move context to rdst.
 *
 * fdouble_addsub: ; skipped.
 *
 * fdouble_mul_flags:  ; make context and calc result from rsrca and rsrcb.
 * ; save result in roundup array, and add index to context.
 * ; move context to rdst.
 *
 * fdouble_pack1:  ; get context from rsrcb.
 * ; if context for add/sub/mul
 * ; get result from roundup array based on index.
 * ; move result to rdst.
 * ; else
 * ; get (u)int32_t interger from rsrca
 * ; (u)int32_to_float64.
 *
 * fdouble_pack2:  ; skipped.
 */

#define TILEGX_F_COUNT 0x1000  /* Maximized results count for fdouble */

#define TILEGX_F_DUINT 0x21b00 /* exp is for uint32_t to double */
#define TILEGX_F_DINT  0xa1b00 /* exp is for int32_t to double */
#define TILEGX_F_SUINT 0x9e/* exp is for uint32_t to single */
#define TILEGX_F_SINT  0x29e   /* exp is for int32_t to single */

#define TILEGX_F_TCAST 0   /* Result type is for typecast, MUST BE 0 */
#define TILEGX_F_TCALC 1   /* Result type is for add/sub/mul */

#pragma pack(push, 1)
typedef struct TileGXFPCtx {

/* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
uint64_t exp : 20; /* Exponent, for TILEGX_F_(D/S)(U)INT */

/* Context type, defined and used by callee */
uint64_t type : 5; /* For TILEGX_F_T(CAST/CALC) */

/* Come from TILE-Gx ISA document, Table 7-2 for floating point */
uint64_t unordered : 1;/* The two are unordered */
uint64_t lt : 1;   /* 1st is less than 2nd */
uint64_t le : 1;   /* 1st is less than or equal to

[Qemu-devel] [PATCH v2 3/4] pc: Move legacy_acpi_table_size global to PCMachineClass

2015-08-17 Thread Eduardo Habkost
This way we can set legacy_acpi_table_size on the machine_options()
functions, instead of requirng code in pc_compat_*() functions.

Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc_piix.c| 40 +++-
 include/hw/i386/pc.h |  1 +
 2 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3b80ade..ea544fa 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -60,8 +60,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 int legacy_acpi_table_size;
-
 /* PC hardware initialisation */
 static void pc_init1(MachineState *machine)
 {
@@ -149,7 +147,7 @@ static void pc_init1(MachineState *machine)
 guest_info = pc_guest_info_init(pcms);
 
 guest_info->has_acpi_build = pcmc->has_acpi_build;
-guest_info->legacy_acpi_table_size = legacy_acpi_table_size;
+guest_info->legacy_acpi_table_size = pcmc->legacy_acpi_table_size;
 
 guest_info->isapc_ram_fw = !pcmc->pci_enabled;
 guest_info->has_reserved_memory = pcmc->has_reserved_memory;
@@ -314,23 +312,6 @@ static void pc_compat_2_1(MachineState *machine)
 static void pc_compat_2_0(MachineState *machine)
 {
 pc_compat_2_1(machine);
-/* This value depends on the actual DSDT and SSDT compiled into
- * the source QEMU; unfortunately it depends on the binary and
- * not on the machine type, so we cannot make pc-i440fx-1.7 work on
- * both QEMU 1.7 and QEMU 2.0.
- *
- * Large variations cause migration to fail for more than one
- * consecutive value of the "-smp" maxcpus option.
- *
- * For small variations of the kind caused by different iasl versions,
- * the 4k rounding usually leaves slack.  However, there could be still
- * one or two values that break.  For QEMU 1.7 and QEMU 2.0 the
- * slack is only ~10 bytes before one "-smp maxcpus" value breaks!
- *
- * 6652 is valid for QEMU 2.0, the right value for pc-i440fx-1.7 on
- * QEMU 1.7 it is 6414.  For RHEL/CentOS 7.0 it is 6418.
- */
-legacy_acpi_table_size = 6652;
 pc_set_legacy_acpi_data_size();
 }
 
@@ -338,7 +319,6 @@ static void pc_compat_1_7(MachineState *machine)
 {
 pc_compat_2_0(machine);
 option_rom_has_mr = true;
-legacy_acpi_table_size = 6414;
 x86_cpu_compat_kvm_no_autoenable(FEAT_1_ECX, CPUID_EXT_X2APIC);
 }
 
@@ -479,6 +459,23 @@ static void pc_i440fx_2_0_machine_options(MachineClass *m)
 SET_MACHINE_COMPAT(m, PC_COMPAT_2_0);
 pcmc->smbios_legacy_mode = true;
 pcmc->has_reserved_memory = false;
+/* This value depends on the actual DSDT and SSDT compiled into
+ * the source QEMU; unfortunately it depends on the binary and
+ * not on the machine type, so we cannot make pc-i440fx-1.7 work on
+ * both QEMU 1.7 and QEMU 2.0.
+ *
+ * Large variations cause migration to fail for more than one
+ * consecutive value of the "-smp" maxcpus option.
+ *
+ * For small variations of the kind caused by different iasl versions,
+ * the 4k rounding usually leaves slack.  However, there could be still
+ * one or two values that break.  For QEMU 1.7 and QEMU 2.0 the
+ * slack is only ~10 bytes before one "-smp maxcpus" value breaks!
+ *
+ * 6652 is valid for QEMU 2.0, the right value for pc-i440fx-1.7 on
+ * QEMU 1.7 it is 6414.  For RHEL/CentOS 7.0 it is 6418.
+ */
+pcmc->legacy_acpi_table_size = 6652;
 }
 
 DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0,
@@ -493,6 +490,7 @@ static void pc_i440fx_1_7_machine_options(MachineClass *m)
 SET_MACHINE_COMPAT(m, PC_COMPAT_1_7);
 pcmc->smbios_defaults = false;
 pcmc->gigabyte_align = false;
+pcmc->legacy_acpi_table_size = 6414;
 }
 
 DEFINE_I440FX_MACHINE(v1_7, "pc-i440fx-1.7", pc_compat_1_7,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index b09c652..b812968 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -75,6 +75,7 @@ struct PCMachineClass {
 bool gigabyte_align;
 bool has_reserved_memory;
 bool kvmclock_enabled;
+int legacy_acpi_table_size;
 };
 
 #define TYPE_PC_MACHINE "generic-pc-machine"
-- 
2.1.0




[Qemu-devel] [PATCH 07/17] tcg: don't abuse TCG type in tcg_gen_trunc_shr_i64_i32

2015-08-17 Thread Richard Henderson
From: Aurelien Jarno 

The tcg_gen_trunc_shr_i64_i32 function takes a 64-bit argument and
returns a 32-bit value. Directly call tcg_gen_op3 with the correct
types instead of calling tcg_gen_op3i_i32 and abusing the TCG types.

Reviewed-by: Richard Henderson 
Signed-off-by: Aurelien Jarno 
---
 tcg/tcg-op.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 61b64db..0e79fd1 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -1752,8 +1752,8 @@ void tcg_gen_trunc_shr_i64_i32(TCGv_i32 ret, TCGv_i64 
arg, unsigned count)
 tcg_temp_free_i64(t);
 }
 } else if (TCG_TARGET_HAS_trunc_shr_i64_i32) {
-tcg_gen_op3i_i32(INDEX_op_trunc_shr_i64_i32, ret,
- MAKE_TCGV_I32(GET_TCGV_I64(arg)), count);
+tcg_gen_op3(&tcg_ctx, INDEX_op_trunc_shr_i64_i32,
+GET_TCGV_I32(ret), GET_TCGV_I64(arg), count);
 } else if (count == 0) {
 tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg)));
 } else {
-- 
2.4.3




[Qemu-devel] [PATCH 14/17] tcg/i386: use softmmu fast path for unaligned accesses

2015-08-17 Thread Richard Henderson
From: Aurelien Jarno 

Softmmu unaligned load/stores currently goes through through the slow
path for two reasons:
  - to support unaligned access on host with strict alignement
  - to correctly handle accesses crossing pages

x86 is only concerned by the second reason. Unaligned accesses are
avoided by compilers, but are not uncommon. We therefore would like
to see them going through the fast path, if they don't cross pages.

For that we can use the fact that two adjacent TLB entries can't contain
the same page. Therefore accessing the TLB entry corresponding to the
first byte, but comparing its content to page address of the last byte
ensures that we don't cross pages. We can do this check without adding
more instructions in the TLB code (but increasing its length by one
byte) by using the LEA instruction to combine the existing move with the
size addition.

On an x86-64 host, this gives a 3% boot time improvement for a powerpc
guest and 4% for an x86-64 guest.

[rth: Tidied calculation of the offset mask]

Signed-off-by: Aurelien Jarno 
Message-Id: <1436467197-2183-1-git-send-email-aurel...@aurel32.net>
Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 7648f7e..ff55499 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1172,7 +1172,7 @@ static void * const qemu_st_helpers[16] = {
First argument register is clobbered.  */
 
 static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg 
addrhi,
-int mem_index, TCGMemOp s_bits,
+int mem_index, TCGMemOp opc,
 tcg_insn_unit **label_ptr, int which)
 {
 const TCGReg r0 = TCG_REG_L0;
@@ -1180,6 +1180,8 @@ static inline void tcg_out_tlb_load(TCGContext *s, TCGReg 
addrlo, TCGReg addrhi,
 TCGType ttype = TCG_TYPE_I32;
 TCGType htype = TCG_TYPE_I32;
 int trexw = 0, hrexw = 0;
+int s_mask = (1 << (opc & MO_SIZE)) - 1;
+bool aligned = (opc & MO_AMASK) == MO_ALIGN || s_mask == 0;
 
 if (TCG_TARGET_REG_BITS == 64) {
 if (TARGET_LONG_BITS == 64) {
@@ -1193,13 +1195,19 @@ static inline void tcg_out_tlb_load(TCGContext *s, 
TCGReg addrlo, TCGReg addrhi,
 }
 
 tcg_out_mov(s, htype, r0, addrlo);
-tcg_out_mov(s, ttype, r1, addrlo);
+if (aligned) {
+tcg_out_mov(s, ttype, r1, addrlo);
+} else {
+/* For unaligned access check that we don't cross pages using
+   the page address of the last byte.  */
+tcg_out_modrm_offset(s, OPC_LEA + trexw, r1, addrlo, s_mask);
+}
 
 tcg_out_shifti(s, SHIFT_SHR + hrexw, r0,
TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
 
 tgen_arithi(s, ARITH_AND + trexw, r1,
-TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
+TARGET_PAGE_MASK | (aligned ? s_mask : 0), 0);
 tgen_arithi(s, ARITH_AND + hrexw, r0,
 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
 
@@ -1545,7 +1553,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is64)
 TCGMemOp opc;
 #if defined(CONFIG_SOFTMMU)
 int mem_index;
-TCGMemOp s_bits;
 tcg_insn_unit *label_ptr[2];
 #endif
 
@@ -1558,9 +1565,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is64)
 
 #if defined(CONFIG_SOFTMMU)
 mem_index = get_mmuidx(oi);
-s_bits = opc & MO_SIZE;
 
-tcg_out_tlb_load(s, addrlo, addrhi, mem_index, s_bits,
+tcg_out_tlb_load(s, addrlo, addrhi, mem_index, opc,
  label_ptr, offsetof(CPUTLBEntry, addr_read));
 
 /* TLB Hit.  */
@@ -1687,7 +1693,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is64)
 TCGMemOp opc;
 #if defined(CONFIG_SOFTMMU)
 int mem_index;
-TCGMemOp s_bits;
 tcg_insn_unit *label_ptr[2];
 #endif
 
@@ -1700,9 +1705,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is64)
 
 #if defined(CONFIG_SOFTMMU)
 mem_index = get_mmuidx(oi);
-s_bits = opc & MO_SIZE;
 
-tcg_out_tlb_load(s, addrlo, addrhi, mem_index, s_bits,
+tcg_out_tlb_load(s, addrlo, addrhi, mem_index, opc,
  label_ptr, offsetof(CPUTLBEntry, addr_write));
 
 /* TLB Hit.  */
-- 
2.4.3




[Qemu-devel] [PATCH 05/17] tcg/optimize: allow constant to have copies

2015-08-17 Thread Richard Henderson
From: Aurelien Jarno 

Now that copies and constants are tracked separately, we can allow
constant to have copies, deferring the choice to use a register or a
constant to the register allocation pass. This prevent this kind of
regular constant reloading:

-OUT: [size=338]
+OUT: [size=298]
   mov-0x4(%r14),%ebp
   test   %ebp,%ebp
   jne0x7ffbe9cb0ed6
   mov$0x40002219f8,%rbp
   mov%rbp,(%r14)
-  mov$0x40002219f8,%rbp
   mov$0x4000221a20,%rbx
   mov%rbp,(%rbx)
   mov$0x40,%rbp
   mov%rbp,(%r14)
-  mov$0x40,%rbp
   mov$0x4000221d38,%rbx
   mov%rbp,(%rbx)
   mov$0x40002221a8,%rbp
   mov%rbp,(%r14)
-  mov$0x40002221a8,%rbp
   mov$0x4000221d40,%rbx
   mov%rbp,(%rbx)
   mov$0x419170,%rbp
   mov%rbp,(%r14)
-  mov$0x419170,%rbp
   mov$0x4000221d48,%rbx
   mov%rbp,(%rbx)
   mov$0x4049ee,%rbp
   mov%rbp,0x80(%r14)
   mov%r14,%rdi
   callq  0x7ffbe99924d0
   mov$0x401680,%rbp
   mov%rbp,0x30(%r14)
   mov0x10(%r14),%rbp
   mov$0x401680,%rbp
   mov%rbp,0x30(%r14)
   mov0x10(%r14),%rbp
   shl$0x20,%rbp
   mov(%r14),%rbx
   mov%ebx,%ebx
   mov%rbx,(%r14)
   or %rbx,%rbp
   mov%rbp,0x10(%r14)
   mov%rbp,0x90(%r14)
   mov0x60(%r14),%rbx
   mov%rbx,0x38(%r14)
   mov0x28(%r14),%rbx
   mov$0x4000220e60,%r12
   mov%rbx,(%r12)
   mov$0x40002219c8,%rbx
   mov%rbp,(%rbx)
   mov0x20(%r14),%rbp
   sub$0x8,%rbp
   mov$0x404a16,%rbx
   mov%rbx,0x0(%rbp)
   mov%rbp,0x20(%r14)
   mov$0x19,%ebp
   mov%ebp,0xa8(%r14)
   mov$0x415110,%rbp
   mov%rbp,0x80(%r14)
   xor%eax,%eax
   jmpq   0x7ffbebcae426
   lea-0x5f6d72a(%rip),%rax# 0x7ffbe3d437b3
   jmpq   0x7ffbebcae426

Cc: Richard Henderson 
Signed-off-by: Aurelien Jarno 
---
 tcg/optimize.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index e69ab05..2d3c72b 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -230,11 +230,6 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, 
TCGArg *args,
 return;
 }
 
-if (temp_is_const(src)) {
-tcg_opt_gen_movi(s, op, args, dst, temps[src].val);
-return;
-}
-
 TCGOpcode new_op = op_to_mov(op->opc);
 tcg_target_ulong mask;
 
@@ -248,14 +243,13 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, 
TCGArg *args,
 }
 temps[dst].mask = mask;
 
-assert(!temp_is_const(src));
-
 if (s->temps[src].type == s->temps[dst].type) {
 temps[dst].next_copy = temps[src].next_copy;
 temps[dst].prev_copy = src;
 temps[temps[dst].next_copy].prev_copy = dst;
 temps[src].next_copy = dst;
-temps[dst].is_const = false;
+temps[dst].is_const = temps[src].is_const;
+temps[dst].val = temps[src].val;
 }
 
 args[0] = dst;
-- 
2.4.3




[Qemu-devel] [PATCH v2 4/4] pc: Move acpi_data_size global to PCMachineClass

2015-08-17 Thread Eduardo Habkost
This way we don't need code in pc_compat_*() functions to set the legacy
acpi_data_size value.

Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc.c | 17 ++---
 hw/i386/pc_piix.c|  2 +-
 hw/i386/pc_q35.c |  2 +-
 include/hw/i386/pc.h |  6 --
 4 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 430cd5c..dea41e7 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -77,15 +77,6 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables
- * (128K) and other BIOS datastructures (less than 4K reported to be used at
- * the moment, 32K should be enough for a while).  */
-static unsigned acpi_data_size = 0x2 + 0x8000;
-void pc_set_legacy_acpi_data_size(void)
-{
-acpi_data_size = 0x1;
-}
-
 #define BIOS_CFG_IOPORT 0x510
 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
 #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
@@ -840,6 +831,7 @@ static void load_linux(PCMachineState *pcms,
 FILE *f;
 char *vmode;
 MachineState *machine = MACHINE(pcms);
+PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
@@ -907,8 +899,8 @@ static void load_linux(PCMachineState *pcms,
 initrd_max = 0x37ff;
 }
 
-if (initrd_max >= pcms->below_4g_mem_size - acpi_data_size) {
-initrd_max = pcms->below_4g_mem_size - acpi_data_size - 1;
+if (initrd_max >= pcms->below_4g_mem_size - pcmc->acpi_data_size) {
+initrd_max = pcms->below_4g_mem_size - pcmc->acpi_data_size - 1;
 }
 
 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
@@ -1959,6 +1951,9 @@ static void pc_machine_class_init(ObjectClass *oc, void 
*data)
 pcmc->gigabyte_align = true;
 pcmc->has_reserved_memory = true;
 pcmc->kvmclock_enabled = true;
+/* BIOS ACPI tables: 128K. Other BIOS datastructures: less than 4K reported
+ * to be used at the moment, 32K should be enough for a while.  */
+pcmc->acpi_data_size = 0x2 + 0x8000;
 mc->get_hotplug_handler = pc_get_hotpug_handler;
 mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id;
 mc->default_boot_order = "cad";
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ea544fa..bfa0e45 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -312,7 +312,6 @@ static void pc_compat_2_1(MachineState *machine)
 static void pc_compat_2_0(MachineState *machine)
 {
 pc_compat_2_1(machine);
-pc_set_legacy_acpi_data_size();
 }
 
 static void pc_compat_1_7(MachineState *machine)
@@ -476,6 +475,7 @@ static void pc_i440fx_2_0_machine_options(MachineClass *m)
  * QEMU 1.7 it is 6414.  For RHEL/CentOS 7.0 it is 6418.
  */
 pcmc->legacy_acpi_table_size = 6652;
+pcmc->acpi_data_size = 0x1;
 }
 
 DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index b9e931c..4ee653e 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -301,7 +301,6 @@ static void pc_compat_2_1(MachineState *machine)
 static void pc_compat_2_0(MachineState *machine)
 {
 pc_compat_2_1(machine);
-pc_set_legacy_acpi_data_size();
 }
 
 static void pc_compat_1_7(MachineState *machine)
@@ -406,6 +405,7 @@ static void pc_q35_2_0_machine_options(MachineClass *m)
 SET_MACHINE_COMPAT(m, PC_COMPAT_2_0);
 pcmc->has_reserved_memory = false;
 pcmc->smbios_legacy_mode = true;
+pcmc->acpi_data_size = 0x1;
 }
 
 DEFINE_Q35_MACHINE(v2_0, "pc-q35-2.0", pc_compat_2_0,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index b812968..e3ecc21 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -76,6 +76,10 @@ struct PCMachineClass {
 bool has_reserved_memory;
 bool kvmclock_enabled;
 int legacy_acpi_table_size;
+/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables
+ * and other BIOS datastructures.
+ */
+unsigned acpi_data_size;
 };
 
 #define TYPE_PC_MACHINE "generic-pc-machine"
@@ -182,8 +186,6 @@ void pc_acpi_init(const char *default_dsdt);
 
 PcGuestInfo *pc_guest_info_init(PCMachineState *pcms);
 
-void pc_set_legacy_acpi_data_size(void);
-
 #define PCI_HOST_PROP_PCI_HOLE_START   "pci-hole-start"
 #define PCI_HOST_PROP_PCI_HOLE_END "pci-hole-end"
 #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start"
-- 
2.1.0




Re: [Qemu-devel] [PATCH for-2.5] piix: Document coreboot-specific RAM size config register

2015-08-17 Thread Eduardo Habkost
On Thu, Aug 13, 2015 at 11:30:57AM -0400, Richard Smith wrote:
> On 08/09/2015 09:48 PM, Ed Swierk wrote:
> 
> 
> >References to coreboot commits: * Original commit adding code reading
> >register offsets 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x56, 0x57 to
> >Intel 440bx code in coreboot:
> >cb8eab482ff09ec256456312ef2d6e7710123551
> 
> I have vague recollection I may have been responsible for this but it
> was so long ago.  I'm having trouble finding the commits in gitweb.
> When I put those hashes into the commit search at
> review.coreboot.org I get not found.

Those are git commits from the repository at
http://review.coreboot.org/coreboot.git

(I couldn't check if they can be seen in a browser, right now, because
the server is returning HTTP 502 errors)

-- 
Eduardo



[Qemu-devel] [PATCH 11/17] tcg: update README about size changing ops

2015-08-17 Thread Richard Henderson
From: Aurelien Jarno 

Cc: Richard Henderson 
Signed-off-by: Aurelien Jarno 
---
 tcg/README | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/tcg/README b/tcg/README
index 61b3899..a22f251 100644
--- a/tcg/README
+++ b/tcg/README
@@ -466,13 +466,25 @@ On a 32 bit target, all 64 bit operations are converted 
to 32 bits. A
 few specific operations must be implemented to allow it (see add2_i32,
 sub2_i32, brcond2_i32).
 
+On a 64 bit target, the values are transfered between 32 and 64-bit
+registers using the following ops:
+- trunc_shr_i64_i32
+- ext_i32_i64
+- extu_i32_i64
+
+They ensure that the values are correctly truncated or extended when
+moved from a 32-bit to a 64-bit register or vice-versa. Note that the
+trunc_shr_i64_i32 is an optional op. It is not necessary to implement
+it if all the following conditions are met:
+- 64-bit registers can hold 32-bit values
+- 32-bit values in a 64-bit register do not need to stay zero or
+  sign extended
+- all 32-bit TCG ops ignore the high part of 64-bit registers
+
 Floating point operations are not supported in this version. A
 previous incarnation of the code generator had full support of them,
 but it is better to concentrate on integer operations first.
 
-On a 64 bit target, no assumption is made in TCG about the storage of
-the 32 bit values in 64 bit registers.
-
 4.2) Constraints
 
 GCC like constraints are used to define the constraints of every
-- 
2.4.3




[Qemu-devel] [PATCH 16/17] tcg/s390: Use softmmu fast path for unaligned accesses

2015-08-17 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/s390/tcg-target.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 96c3d65..be51c8b 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -1504,20 +1504,36 @@ QEMU_BUILD_BUG_ON(offsetof(CPUArchState, 
tlb_table[NB_MMU_MODES - 1][1])
 static TCGReg tcg_out_tlb_read(TCGContext* s, TCGReg addr_reg, TCGMemOp opc,
int mem_index, bool is_ld)
 {
-TCGMemOp s_bits = opc & MO_SIZE;
-uint64_t tlb_mask = TARGET_PAGE_MASK | ((1 << s_bits) - 1);
-int ofs;
+int s_mask = (1 << (opc & MO_SIZE)) - 1;
+int ofs, a_off;
+uint64_t tlb_mask;
+
+/* For aligned accesses, we check the first byte and include the alignment
+   bits within the address.  For unaligned access, we check that we don't
+   cross pages using the address of the last byte of the access.  */
+if ((opc & MO_AMASK) == MO_ALIGN || s_mask == 0) {
+a_off = 0;
+tlb_mask = TARGET_PAGE_MASK | s_mask;
+} else {
+a_off = s_mask;
+tlb_mask = TARGET_PAGE_MASK;
+}
 
 if (facilities & FACILITY_GEN_INST_EXT) {
 tcg_out_risbg(s, TCG_REG_R2, addr_reg,
   64 - CPU_TLB_BITS - CPU_TLB_ENTRY_BITS,
   63 - CPU_TLB_ENTRY_BITS,
   64 + CPU_TLB_ENTRY_BITS - TARGET_PAGE_BITS, 1);
-tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
+if (a_off) {
+tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
+tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
+} else {
+tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
+}
 } else {
 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
  TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_R3, addr_reg);
+tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
 tgen_andi(s, TCG_TYPE_I64, TCG_REG_R2,
   (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
-- 
2.4.3




[Qemu-devel] [PATCH 17/17] tcg/aarch64: Use softmmu fast path for unaligned accesses

2015-08-17 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.c | 37 -
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 7f7ab7e..bc3a539 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -1051,14 +1051,29 @@ static void add_qemu_ldst_label(TCGContext *s, bool 
is_ld, TCGMemOpIdx oi,
slow path for the failure case, which will be patched later when finalizing
the slow path. Generated code returns the host addend in X1,
clobbers X0,X2,X3,TMP. */
-static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, TCGMemOp s_bits,
+static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, TCGMemOp opc,
  tcg_insn_unit **label_ptr, int mem_index,
  bool is_read)
 {
-TCGReg base = TCG_AREG0;
 int tlb_offset = is_read ?
 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
 : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
+int s_mask = (1 << (opc & MO_SIZE)) - 1;
+TCGReg base = TCG_AREG0, x3;
+uint64_t tlb_mask;
+
+/* For aligned accesses, we check the first byte and include the alignment
+   bits within the address.  For unaligned access, we check that we don't
+   cross pages using the address of the last byte of the access.  */
+if ((opc & MO_AMASK) == MO_ALIGN || s_mask == 0) {
+tlb_mask = TARGET_PAGE_MASK | s_mask;
+x3 = addr_reg;
+} else {
+tcg_out_insn(s, 3401, ADDI, TARGET_LONG_BITS == 64,
+ TCG_REG_X3, addr_reg, s_mask);
+tlb_mask = TARGET_PAGE_MASK;
+x3 = TCG_REG_X3;
+}
 
 /* Extract the TLB index from the address into X0.
X0 =
@@ -1066,11 +1081,9 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg 
addr_reg, TCGMemOp s_bits,
 tcg_out_ubfm(s, TARGET_LONG_BITS == 64, TCG_REG_X0, addr_reg,
  TARGET_PAGE_BITS, TARGET_PAGE_BITS + CPU_TLB_BITS);
 
-/* Store the page mask part of the address and the low s_bits into X3.
-   Later this allows checking for equality and alignment at the same time.
-   X3 = addr_reg & (PAGE_MASK | ((1 << s_bits) - 1)) */
-tcg_out_logicali(s, I3404_ANDI, TARGET_LONG_BITS == 64, TCG_REG_X3,
- addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
+/* Store the page mask part of the address into X3.  */
+tcg_out_logicali(s, I3404_ANDI, TARGET_LONG_BITS == 64,
+ TCG_REG_X3, x3, tlb_mask);
 
 /* Add any "high bits" from the tlb offset to the env address into X2,
to take advantage of the LSL12 form of the ADDI instruction.
@@ -1207,10 +1220,9 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg 
data_reg, TCGReg addr_reg,
 const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32;
 #ifdef CONFIG_SOFTMMU
 unsigned mem_index = get_mmuidx(oi);
-TCGMemOp s_bits = memop & MO_SIZE;
 tcg_insn_unit *label_ptr;
 
-tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 1);
+tcg_out_tlb_read(s, addr_reg, memop, &label_ptr, mem_index, 1);
 tcg_out_qemu_ld_direct(s, memop, ext, data_reg,
TCG_REG_X1, otype, addr_reg);
 add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg,
@@ -1229,14 +1241,13 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg 
data_reg, TCGReg addr_reg,
 const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32;
 #ifdef CONFIG_SOFTMMU
 unsigned mem_index = get_mmuidx(oi);
-TCGMemOp s_bits = memop & MO_SIZE;
 tcg_insn_unit *label_ptr;
 
-tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 0);
+tcg_out_tlb_read(s, addr_reg, memop, &label_ptr, mem_index, 0);
 tcg_out_qemu_st_direct(s, memop, data_reg,
TCG_REG_X1, otype, addr_reg);
-add_qemu_ldst_label(s, false, oi, s_bits == MO_64, data_reg, addr_reg,
-s->code_ptr, label_ptr);
+add_qemu_ldst_label(s, false, oi, (memop & MO_SIZE)== MO_64,
+data_reg, addr_reg, s->code_ptr, label_ptr);
 #else /* !CONFIG_SOFTMMU */
 tcg_out_qemu_st_direct(s, memop, data_reg,
GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR,
-- 
2.4.3




Re: [Qemu-devel] [PATCH for-2.5 15/18] pc: Remove redundant arguments from xen_hvm_init()

2015-08-17 Thread Eduardo Habkost
On Thu, Aug 13, 2015 at 02:06:04PM +0300, Michael S. Tsirkin wrote:
> On Fri, Aug 07, 2015 at 04:55:56PM -0300, Eduardo Habkost wrote:
[...]
> > @@ -1159,7 +1158,7 @@ static void xen_wakeup_notifier(Notifier *notifier, 
> > void *data)
> >  }
> >  
> >  /* return 0 means OK, or -1 means critical issue -- will exit(1) */
> > -int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t 
> > *above_4g_mem_size,
> > +int xen_hvm_init(PCMachineState *pcms,
> >   MemoryRegion **ram_memory)
> >  {
> >  int i, rc;
> 
> This breaks the build: you didn't update the version in xen-hvm-stub.c

Oops, sorry.

> 
> Please test on config with all options enabled.

I incorrectly assumed the changes wouldn't affect anything except PC, so
I was building it with --target-list=x86_64-softmmu --enable-xen. I
should remember to build it at least once with all targets enabled, next
time.

-- 
Eduardo



[Qemu-devel] [RESEND PATCHv2] sdhci: Pass drive parameter to sdhci-pci via qdev property

2015-08-17 Thread Kevin O'Connor
Commit 19109131 disabled the sdhci-pci support because it used
drive_get_next().  This patch reenables sdhci-pci and changes it to
pass the drive via a qdev property - for example:
 -device sdhci-pci,drive=drive0 -drive id=drive0,if=sd,file=myimage

Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Kevin O'Connor 
---

This is a resend of the patch I sent two weeks ago.  No changes (other
than adding Stefan's reviewed-by line).

v2:
- Don't call blk_detach_dev() in sdhci pci code - instead change
  sd_init() to use blk_attach_dev() instead of blk_attach_dev_nofail().

---
 hw/sd/sd.c|  4 +++-
 hw/sd/sdhci.c | 32 +++-
 hw/sd/sdhci.h |  2 ++
 3 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a1ff465..88c4fda 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -493,7 +493,9 @@ SDState *sd_init(BlockBackend *blk, bool is_spi)
 sd->blk = blk;
 sd_reset(sd);
 if (sd->blk) {
-blk_attach_dev_nofail(sd->blk, sd);
+/* Attach dev if not already attached.  (This call ignores an
+ * error return code if sd->blk is already attached.) */
+blk_attach_dev(sd->blk, sd);
 blk_set_dev_ops(sd->blk, &sd_block_ops, sd);
 }
 vmstate_register(NULL, -1, &sd_vmstate, sd);
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index e63367b..6e01de7 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1142,13 +1142,9 @@ static inline unsigned int sdhci_get_fifolen(SDHCIState 
*s)
 }
 }
 
-static void sdhci_initfn(SDHCIState *s)
+static void sdhci_initfn(SDHCIState *s, BlockBackend *blk)
 {
-DriveInfo *di;
-
-/* FIXME use a qdev drive property instead of drive_get_next() */
-di = drive_get_next(IF_SD);
-s->card = sd_init(di ? blk_by_legacy_dinfo(di) : NULL, false);
+s->card = sd_init(blk, false);
 if (s->card == NULL) {
 exit(1);
 }
@@ -1214,7 +1210,8 @@ const VMStateDescription sdhci_vmstate = {
 
 /* Capabilities registers provide information on supported features of this
  * specific host controller implementation */
-static Property sdhci_properties[] = {
+static Property sdhci_pci_properties[] = {
+DEFINE_BLOCK_PROPERTIES(SDHCIState, conf),
 DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
 SDHC_CAPAB_REG_DEFAULT),
 DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
@@ -1226,7 +1223,7 @@ static void sdhci_pci_realize(PCIDevice *dev, Error 
**errp)
 SDHCIState *s = PCI_SDHCI(dev);
 dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
 dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
-sdhci_initfn(s);
+sdhci_initfn(s, s->conf.blk);
 s->buf_maxsz = sdhci_get_fifolen(s);
 s->fifo_buffer = g_malloc0(s->buf_maxsz);
 s->irq = pci_allocate_irq(dev);
@@ -1253,9 +1250,7 @@ static void sdhci_pci_class_init(ObjectClass *klass, void 
*data)
 k->class_id = PCI_CLASS_SYSTEM_SDHCI;
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 dc->vmsd = &sdhci_vmstate;
-dc->props = sdhci_properties;
-/* Reason: realize() method uses drive_get_next() */
-dc->cannot_instantiate_with_device_add_yet = true;
+dc->props = sdhci_pci_properties;
 }
 
 static const TypeInfo sdhci_pci_info = {
@@ -1265,10 +1260,21 @@ static const TypeInfo sdhci_pci_info = {
 .class_init = sdhci_pci_class_init,
 };
 
+static Property sdhci_sysbus_properties[] = {
+DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
+SDHC_CAPAB_REG_DEFAULT),
+DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void sdhci_sysbus_init(Object *obj)
 {
 SDHCIState *s = SYSBUS_SDHCI(obj);
-sdhci_initfn(s);
+DriveInfo *di;
+
+/* FIXME use a qdev drive property instead of drive_get_next() */
+di = drive_get_next(IF_SD);
+sdhci_initfn(s, di ? blk_by_legacy_dinfo(di) : NULL);
 }
 
 static void sdhci_sysbus_finalize(Object *obj)
@@ -1295,7 +1301,7 @@ static void sdhci_sysbus_class_init(ObjectClass *klass, 
void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->vmsd = &sdhci_vmstate;
-dc->props = sdhci_properties;
+dc->props = sdhci_sysbus_properties;
 dc->realize = sdhci_sysbus_realize;
 /* Reason: instance_init() method uses drive_get_next() */
 dc->cannot_instantiate_with_device_add_yet = true;
diff --git a/hw/sd/sdhci.h b/hw/sd/sdhci.h
index 3352d23..e2de92d 100644
--- a/hw/sd/sdhci.h
+++ b/hw/sd/sdhci.h
@@ -26,6 +26,7 @@
 #define SDHCI_H
 
 #include "qemu-common.h"
+#include "hw/block/block.h"
 #include "hw/pci/pci.h"
 #include "hw/sysbus.h"
 #include "hw/sd.h"
@@ -239,6 +240,7 @@ typedef struct SDHCIState {
 };
 SDState *card;
 MemoryRegion iomem;
+BlockConf conf;
 
 QEMUTimer *insert_timer;   /* timer for 'changing' sd card. */
 QEMUTimer *transfer_timer;
-- 
1.9.3




[Qemu-devel] [PATCH 5/5] usb-audio: support more than two channels of audio

2015-08-17 Thread Kővágó, Zoltán
This commit adds support for non stereo audio playback.  This commit
adds two new properties to usb-audio:

* channels = the number of channels
* channel-config = the channel config to use.  Should be 3 for stereo,
  0x3f for 5.1 and 0x63f for 7.1 audio.  See USB Device Class Definition
  for Audio Devices for other possible values
  (http://www.usb.org/developers/docs/devclass_docs/audio10.pdf, p34)

Signed-off-by: Kővágó, Zoltán 

---

According to the spec the channel order is front left, front right,
center, lfe, surround left, surround right for 5.1 sound.  But Linux
with alsa seems to use front left, front right, surround left, surround
right, center, lfe, while Windows uses the order in the specification.

The default pulseaudio channel map currently is an ALSA compatible,
which means by default Linux guests will have correct audio while
Windows guests will have surround and center/lfe swapped.  I could
change the pulseaudio default to OSS like, but in that case Linux guest
would be wrong and Windows ok.

With alsa there is not much to do sort of writing a mini mixeng or
something like that, but you can easily add a new device to
/etc/asound.conf that swaps the channels:

pcm.swap {
type route
slave.pcm "default" # or whatever
slave.channels 6

ttable.0.0 1
ttable.1.1 1
ttable.2.4 1
ttable.3.5 1
ttable.4.2 1
ttable.5.3 1
}

and use -audiodev alsa,id=foo,out.mixeng=off,alsa-out.dev=swap,...

(due to how usb and usb-audio works, you'll probably need
alsa-out.try-poll=off and some playing with threshold)


 hw/usb/dev-audio.c | 413 +
 1 file changed, 228 insertions(+), 185 deletions(-)

diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index f916ccc..c0637a5 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -85,165 +85,190 @@ static const USBDescStrings usb_audio_stringtable = {
 /*
  * A Basic Audio Device uses these specific values
  */
-#define USBAUDIO_PACKET_SIZE 192
+#define USBAUDIO_PACKET_SIZE_BASE 96
+#define USBAUDIO_PACKET_SIZE(channels) (USBAUDIO_PACKET_SIZE_BASE * channels)
 #define USBAUDIO_SAMPLE_RATE 48000
 #define USBAUDIO_PACKET_INTERVAL 1
 
-static const USBDescIface desc_iface[] = {
-{
-.bInterfaceNumber  = 0,
-.bNumEndpoints = 0,
-.bInterfaceClass   = USB_CLASS_AUDIO,
-.bInterfaceSubClass= USB_SUBCLASS_AUDIO_CONTROL,
-.bInterfaceProtocol= 0x04,
-.iInterface= STRING_USBAUDIO_CONTROL,
-.ndesc = 4,
-.descs = (USBDescOther[]) {
-{
-/* Headphone Class-Specific AC Interface Header Descriptor */
-.data = (uint8_t[]) {
-0x09,   /*  u8  bLength */
-USB_DT_CS_INTERFACE,/*  u8  bDescriptorType */
-DST_AC_HEADER,  /*  u8  bDescriptorSubtype */
-U16(0x0100),/* u16  bcdADC */
-U16(0x2b),  /* u16  wTotalLength */
-0x01,   /*  u8  bInCollection */
-0x01,   /*  u8  baInterfaceNr */
-}
-},{
-/* Generic Stereo Input Terminal ID1 Descriptor */
-.data = (uint8_t[]) {
-0x0c,   /*  u8  bLength */
-USB_DT_CS_INTERFACE,/*  u8  bDescriptorType */
-DST_AC_INPUT_TERMINAL,  /*  u8  bDescriptorSubtype */
-0x01,   /*  u8  bTerminalID */
-U16(0x0101),/* u16  wTerminalType */
-0x00,   /*  u8  bAssocTerminal */
-0x02,   /* u16  bNrChannels */
-U16(0x0003),/* u16  wChannelConfig */
-0x00,   /*  u8  iChannelNames */
-STRING_INPUT_TERMINAL,  /*  u8  iTerminal */
-}
-},{
-/* Generic Stereo Feature Unit ID2 Descriptor */
-.data = (uint8_t[]) {
-0x0d,   /*  u8  bLength */
-USB_DT_CS_INTERFACE,/*  u8  bDescriptorType */
-DST_AC_FEATURE_UNIT,/*  u8  bDescriptorSubtype */
-0x02,   /*  u8  bUnitID */
-0x01,   /*  u8  bSourceID */
-0x02,   /*  u8  bControlSize */
-U16(0x0001),/* u16  bmaControls(0) */
-U16(0x0002),/* u16  bmaControls(1) */
-U16(0x0002),/* u16  bmaControls(2) */
-

[Qemu-devel] [PATCH 2/5] audio: basic support for multichannel audio

2015-08-17 Thread Kővágó, Zoltán
Which currently only means removing some checks.  Old code won't require
more than two channels, but new code will need it.

Signed-off-by: Kővágó, Zoltán 
---
 audio/alsaaudio.c | 7 ---
 audio/audio.c | 2 +-
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 148df13..0e3fa1a 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -499,13 +499,6 @@ static int alsa_open(bool in, struct alsa_params_req *req,
 goto err;
 }
 
-if (nchannels != 1 && nchannels != 2) {
-alsa_logerr2 (err, typ,
-  "Can not handle obtained number of channels %d\n",
-  nchannels);
-goto err;
-}
-
 if (pdo->buffer_count) {
 if (pdo->buffer_len) {
 int64_t req = pdo->buffer_len * pdo->buffer_count;
diff --git a/audio/audio.c b/audio/audio.c
index bc32312..2aaedd4 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -210,7 +210,7 @@ static int audio_validate_settings (struct audsettings *as)
 {
 int invalid;
 
-invalid = as->nchannels != 1 && as->nchannels != 2;
+invalid = as->nchannels < 1;
 invalid |= as->endianness != 0 && as->endianness != 1;
 
 switch (as->fmt) {
-- 
2.5.0




Re: [Qemu-devel] [Consult] tilegx: About floating point instructions

2015-08-17 Thread Richard Henderson
On 08/15/2015 11:16 AM, Chen Gang wrote:
> OK, thanks, but for float(uns)sisf2 and float(uns)sidf2, we can not only
> simply move.  :-(

Oh yes, I see that now.  Unfortunate.

> But what you said is really quite valuable to me!! we can treat the flag
> as a caller saved context, then can let the caller can use callee freely
> (in fact, I guess, the real hardware treats it as caller context, too).
> 
>  - we have to define the flag format based on the existing format in the
>related docs and tilegx.md (reserve 0-20 and 25-31 bits).
> 
>  - We can only use 21-24 for mark addsub, mul, or typecast result. If
>21-24 bits are all zero, it means typecast result. For fsingle: 32-63
>bits is the input integer; for fdouble: srca is the input integer.

Plausible.

> 
>  - For addsub and mul result, we use 32-63 bits for an index of resource
>handler (like 'fd' returned by open). fsingle_addsub2, fsingle_mul1,
>fdouble_mul_flags, fdouble_addsub allocate resource, and pack1 free.

No, that's a bad idea.  No state external to the inputs to the insns.

It really would be nice if we had the same documentation that was used
to implement the gcc backend.  Otherwise we have to rely on guesswork.

For single-precision it appears that the format is

  63  31  24   10  9 0
  [ mantissa with implicit and guard bits | cmp flags | ?? | s | exp ]

We are able to deduce the bias for the exponent based on the input gcc gives us
for floatunssisf: 0x9e == 2**31 when the mantissa is normalized.

So:

  fsingle_add1, fsingle_sub1: Perform the operation.  Split the result
  such that all of the fields above are filled in.

  fsingle_mul1: Perform the operation.  Split the result such that all
  of the fields above except for cmp-flags are filled in.

  fsingle_addsub2: Nop.
  fsingle_mul2: Move srca to dest.

  fsingle_pack1: Normalize and repack the above.  In the add/sub/mul case,
  no normalization will be required, so no change to the result occurs.

  In the floatunssisf2 case, the input implicit bit may not be set, and
  guard bits may be set, so real rounding and normalization must occur,
  adjusting the exponent constructed by gcc in building the flags.

For double-precision things are more complicated.  Precisely because there is
no dedicated fdouble_mul[1-4] instructions, but instead gcc is to use a normal
128-bit integer multiplication on the mantissa.

For double-precision it appears that the format is

 63   57   40
  unpack [ overflow bits? | mantissa with implicit bit | guard bits ]

 63   31  24   20  1980
  flags  [ ?? | cmp flags | ?? | s | exp | ?? ]

Similarly we can compute the bias for exp as 0x21b == 2**53.
Or is it 20 bits of exponent and 0x21b00 == 2**53?

So:

  fdouble_unpack_max, fdouble_unpack_min: Perform the operation as described,
  extracting the mantissa of the min/max absolute value.

  fdouble_add_flags, fdouble_sub_flags: Extract the signs and exponent of the
  sources, and compute the sign and exponent of the result.  Set a bit,
  presumably one of [24:21] that tell fdouble_addsub whether to perform
  addition or subtraction.  Set the comparison flags.

  fdouble_mul_flags: Extract the signs and exponent of the sources, and compute
  the sign and exponent of the result.  Note that the result of the 128-bit
  multiplication is guaranteed to be non-normalized : the 2 57-bit inputs will
  produce a 114-bit intermediate result.  Which means that bits [63:51] are
  guaranteed to be zero on entry to the pack stages.  Which means that some
  bias will need to be applied to the intermediate exponent.

  fdouble_addsub: Add or subtract the mantissas based on a bit in flags.

  fdouble_pack1: Move flags (srcb) to result (dest).
  fdouble_pack2: Take the 128-bit mantissa of srca+srcb, the flags of dest,
  and normalize and pack the result.


r~



[Qemu-devel] [PATCH 3/5] paaudio: channel-map option

2015-08-17 Thread Kővágó, Zoltán
Add an option to change the channel map used by pulseaudio.  If not
specified, falls back to an ALSA compatible channel map.

Signed-off-by: Kővágó, Zoltán 
---
 audio/paaudio.c | 18 +++---
 qapi/audio.json |  5 -
 qemu-options.hx |  9 +
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index d2267ee..10fc54f 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -336,23 +336,27 @@ static pa_stream *qpa_simple_new (
 pa_stream_direction_t dir,
 const char *dev,
 const pa_sample_spec *ss,
-const pa_channel_map *map,
+const char *map,
 const pa_buffer_attr *attr,
 int *rerror)
 {
 int r;
 pa_stream *stream;
 pa_stream_flags_t flags;
-pa_channel_map my_map;
+pa_channel_map pa_map;
 
 pa_threaded_mainloop_lock(c->mainloop);
 
+if (map && !pa_channel_map_parse(&pa_map, map)) {
+dolog("Invalid channel map specified: '%s'\n", map);
+map = NULL;
+}
 if (!map) {
-map = pa_channel_map_init_extend(&my_map, ss->channels,
- PA_CHANNEL_MAP_ALSA);
+pa_channel_map_init_extend(&pa_map, ss->channels,
+   PA_CHANNEL_MAP_ALSA);
 }
 
-stream = pa_stream_new(c->context, name, ss, map);
+stream = pa_stream_new(c->context, name, ss, &pa_map);
 if (!stream) {
 goto fail;
 }
@@ -428,7 +432,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 PA_STREAM_PLAYBACK,
 ppdo->has_name ? ppdo->name : NULL,
 &ss,
-NULL,   /* channel map */
+ppdo->has_channel_map ? ppdo->channel_map : NULL,
 &ba,/* buffering attributes */
 &error
 );
@@ -476,7 +480,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings 
*as, void *drv_opaque)
 PA_STREAM_RECORD,
 ppdo->has_name ? ppdo->name : NULL,
 &ss,
-NULL,   /* channel map */
+ppdo->has_channel_map ? ppdo->channel_map : NULL,
 NULL,   /* buffering attributes */
 &error
 );
diff --git a/qapi/audio.json b/qapi/audio.json
index 0216a10..9070ac5 100644
--- a/qapi/audio.json
+++ b/qapi/audio.json
@@ -119,11 +119,14 @@
 #
 # @name: #optional name of the sink/source to use
 #
+# @channel-map: #optional channel map to use (default: ALSA compatible map)
+#
 # Since: 2.5
 ##
 { 'struct': 'AudiodevPaPerDirectionOptions',
   'data': {
-'*name': 'str' } }
+'*name':'str',
+'*channel-map': 'str' } }
 
 ##
 # @AudiodevPaOptions
diff --git a/qemu-options.hx b/qemu-options.hx
index 8e5ab7c..382b0ab 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -365,6 +365,7 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
 "-audiodev pa,id=id[,prop[=value][,...]]\n"
 "server= PulseAudio server address\n"
 "sink|source.name= sink/source device name\n"
+"sink|source.channel-map= channel map to use\n"
 #endif
 #ifdef CONFIG_SDL
 "-audiodev sdl,id=id[,prop[=value][,...]]\n"
@@ -518,6 +519,14 @@ Sets the PulseAudio @var{server} to connect to.
 @item sink|source.name=@var{sink}
 Use the specified sink/source for playback/recording.
 
+@item sink|source.channel-map=@var{map}
+Use the specified channel map.  The default is an ALSA compatible
+channel map.  Do not forget to escape commas inside the map:
+
+@example
+-audiodev pa,id=example,sink.channel-map=front-left,,front-right
+@end example
+
 @end table
 
 @item -audiodev sdl,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-- 
2.5.0




[Qemu-devel] [PATCH 4/5] usb-audio: do not count on avail bytes actually available

2015-08-17 Thread Kővágó, Zoltán
This assumption is no longer true when mixeng is turned off.

Signed-off-by: Kővágó, Zoltán 
---
 hw/usb/dev-audio.c | 30 ++
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index 48ac992..f916ccc 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -317,27 +317,28 @@ static int streambuf_put(struct streambuf *buf, USBPacket 
*p)
 {
 uint32_t free = buf->size - (buf->prod - buf->cons);
 
-if (!free) {
+if (free < USBAUDIO_PACKET_SIZE) {
 return 0;
 }
-assert(free >= USBAUDIO_PACKET_SIZE);
+
 usb_packet_copy(p, buf->data + (buf->prod % buf->size),
 USBAUDIO_PACKET_SIZE);
 buf->prod += USBAUDIO_PACKET_SIZE;
 return USBAUDIO_PACKET_SIZE;
 }
 
-static uint8_t *streambuf_get(struct streambuf *buf)
+static uint8_t *streambuf_get(struct streambuf *buf, size_t *len)
 {
 uint32_t used = buf->prod - buf->cons;
 uint8_t *data;
 
 if (!used) {
+*len = 0;
 return NULL;
 }
-assert(used >= USBAUDIO_PACKET_SIZE);
 data = buf->data + (buf->cons % buf->size);
-buf->cons += USBAUDIO_PACKET_SIZE;
+*len = audio_MIN(buf->prod - buf->cons,
+ buf->size - (buf->cons % buf->size));
 return data;
 }
 
@@ -369,16 +370,21 @@ static void output_callback(void *opaque, int avail)
 USBAudioState *s = opaque;
 uint8_t *data;
 
-for (;;) {
-if (avail < USBAUDIO_PACKET_SIZE) {
-return;
-}
-data = streambuf_get(&s->out.buf);
+while (avail) {
+size_t written, len;
+
+data = streambuf_get(&s->out.buf, &len);
 if (!data) {
 return;
 }
-AUD_write(s->out.voice, data, USBAUDIO_PACKET_SIZE);
-avail -= USBAUDIO_PACKET_SIZE;
+
+written = AUD_write(s->out.voice, data, len);
+avail -= written;
+s->out.buf.cons += written;
+
+if (written < len) {
+return;
+}
 }
 }
 
-- 
2.5.0




[Qemu-devel] [PATCH 0/5] audio: multi channel audio support

2015-08-17 Thread Kővágó, Zoltán
This patch series adds support to more than two channels of audio (5.1,
7.1, etc.).  Currently only usb-audio frontend and alsa and pa backends
are updated.  Using more than two channels requires turning off mixeng
(-audiodev backend,id=foo,out.mixeng=off,...).

Currently you have to specify the number of channels you want to use
when creating the usb-audio device, see the last commit for details.
To do this I currently dynamically allocate the whole USBDesc structure,
which looks ugly.  If there's a better way, please let me know!

These patches requires my previous -audiodev patches:
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg00827.html

Please review.

Kővágó, Zoltán (5):
  audio: replace shift in audio_pcm_info with bytes_per_frame
  audio: basic support for multichannel audio
  paaudio: channel-map option
  usb-audio: do not count on avail bytes actually available
  usb-audio: support more than two channels of audio

 audio/alsaaudio.c   |  17 +-
 audio/audio.c   |  70 
 audio/audio_int.h   |   3 +-
 audio/coreaudio.c   |   4 +-
 audio/dsound_template.h |  10 +-
 audio/dsoundaudio.c |   4 +-
 audio/noaudio.c |   2 +-
 audio/ossaudio.c|  14 +-
 audio/paaudio.c |  18 +-
 audio/wavaudio.c|   6 +-
 hw/usb/dev-audio.c  | 441 +++-
 qapi/audio.json |   5 +-
 qemu-options.hx |   9 +
 13 files changed, 330 insertions(+), 273 deletions(-)

-- 
2.5.0




Re: [Qemu-devel] Debian 7.8.0 SPARC64 on qemu - anything i can do to speedup the emulation?

2015-08-17 Thread Artyom Tarasenko
On Mon, Aug 17, 2015 at 5:40 PM, Richard Henderson  wrote:
> On 08/17/2015 07:19 AM, Artyom Tarasenko wrote:
>> Well, on the other hand, every access goes via helper_check_align.
>> There is a comment /* XXX remove alignment check */.
>> I wonder how this can be done in a  more efficient way?
>
> Not ever access does so.  There are only 3 memory related calls to 
> check_align.
>  The other three are for indirect branches.

Yes, but I think it's the 3 most used ones.

> For the 8 byte memory operations we can just remove the checks.  There, the
> softmmu operation checks the alignment.

This is a good news. Where does it happen?

> For usermode, we've typically ignored
> the guest alignment (which also causes failures for a host that requires
> alignment emulating a guest that does not).

Good to know. But I think it's a good compromise between the
performance and accuracy.

Artyom

-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu



Re: [Qemu-devel] [PULL 5/8] tcg: Put opcodes in a linked list

2015-08-17 Thread Artyom Tarasenko
On Mon, Aug 17, 2015 at 5:44 PM, Richard Henderson  wrote:
> On 08/17/2015 04:35 AM, Artyom Tarasenko wrote:
>> Hi Richard,
>>
>> this patch seems to break a build when USE_LIVENESS_ANALYSIS is undefined.
>
> I suppose that's possible.  If so, it must be a trivial error somewhere.
> Why in the world would you want !USE_LIVENESS_ANALYSIS?
>
> Are you simply trying to see what sort of performance impact it has?  I can
> tell you it's fairly important for generating x86 code.  The two operand 
> nature
> of the ISA means that if we don't know that the source operand is dead, we
> often have to introduce an extra move to preserve it.

~ a year ago there was a report that !USE_LIVENESS_ANALYSIS brings 5%
speed improvement when running qemu-system-sparc64 . I'd like to see
how does it look today. I see tcg_liveness_analysis taking 3%-5% in a
perf top output,  on the other hand the produced code must be more
efficient, so it's interesting to see how does it sum up.

Artyom

-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu



Re: [Qemu-devel] [PULL 5/8] tcg: Put opcodes in a linked list

2015-08-17 Thread Richard Henderson
On 08/17/2015 04:35 AM, Artyom Tarasenko wrote:
> Hi Richard,
> 
> this patch seems to break a build when USE_LIVENESS_ANALYSIS is undefined.

I suppose that's possible.  If so, it must be a trivial error somewhere.
Why in the world would you want !USE_LIVENESS_ANALYSIS?

Are you simply trying to see what sort of performance impact it has?  I can
tell you it's fairly important for generating x86 code.  The two operand nature
of the ISA means that if we don't know that the source operand is dead, we
often have to introduce an extra move to preserve it.


r~



Re: [Qemu-devel] Debian 7.8.0 SPARC64 on qemu - anything i can do to speedup the emulation?

2015-08-17 Thread Richard Henderson
On 08/17/2015 07:19 AM, Artyom Tarasenko wrote:
> Well, on the other hand, every access goes via helper_check_align.
> There is a comment /* XXX remove alignment check */.
> I wonder how this can be done in a  more efficient way?

Not ever access does so.  There are only 3 memory related calls to check_align.
 The other three are for indirect branches.

For the 8 byte memory operations we can just remove the checks.  There, the
softmmu operation checks the alignment.  For usermode, we've typically ignored
the guest alignment (which also causes failures for a host that requires
alignment emulating a guest that does not).


r~



Re: [Qemu-devel] Debian 7.8.0 SPARC64 on qemu - anything i can do to speedup the emulation?

2015-08-17 Thread Artyom Tarasenko
On Thu, Jul 30, 2015 at 9:55 AM, Aurelien Jarno  wrote:
> On 2015-07-30 05:47, Dennis Luehring wrote:
>> so your aarch64 is just less todo for qemu - not EVERY >= 16bit memory
>> access needs swapping or needs check for unaligned access to emulate
>> bus-erros
>
> On recent Intel CPU, the byteswapping comes for free (MOVBE
> instruction).
>
> About the unaligned access it's actually the reverse. The fact that
> aarch64 does unaligned access means they have to go through the slow
> path (I have posted a patch to improve that). On sparc given that all
> access are aligned means there are more chances to go through the fast
> path.

Well, on the other hand, every access goes via helper_check_align.
There is a comment /* XXX remove alignment check */.
I wonder how this can be done in a  more efficient way?
Inlining the check and using a brcond instruction would require that
all TCG temps would have to be changed to locals, which in turn would
produce a performance impact. Are there other ways of doing it?

Artyom

-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu



Re: [Qemu-devel] [PATCH 5/5] target-arm: Implement AArch32 ATS1H* operations

2015-08-17 Thread Edgar E. Iglesias
On Fri, Jul 24, 2015 at 04:21:03PM +0100, Peter Maydell wrote:
> Implement the AArch32 ATS1H* operations which perform
> Hyp mode stage 1 translations.
> 
> Signed-off-by: Peter Maydell 

Reviewed-by: Edgar E. Iglesias 


> ---
>  target-arm/helper.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 67d108e..b9ce965 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1607,6 +1607,17 @@ static void ats_write(CPUARMState *env, const 
> ARMCPRegInfo *ri, uint64_t value)
>  A32_BANKED_CURRENT_REG_SET(env, par, par64);
>  }
>  
> +static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +uint64_t value)
> +{
> +int access_type = ri->opc2 & 1;
> +uint64_t par64;
> +
> +par64 = do_ats_write(env, value, access_type, ARMMMUIdx_S2NS);
> +
> +A32_BANKED_CURRENT_REG_SET(env, par, par64);
> +}
> +
>  static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo 
> *ri)
>  {
>  if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) {
> @@ -2770,6 +2781,17 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
>.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
>.access = PL2_W, .accessfn = at_s1e2_access,
>.type = ARM_CP_NO_RAW, .writefn = ats_write64 },
> +/* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
> + * if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3
> + * with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose
> + * to behave as if SCR.NS was 1.
> + */
> +{ .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
> +  .access = PL2_W,
> +  .writefn = ats1h_write, .type = ARM_CP_NO_RAW },
> +{ .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
> +  .access = PL2_W,
> +  .writefn = ats1h_write, .type = ARM_CP_NO_RAW },
>  #endif
>  REGINFO_SENTINEL
>  };
> -- 
> 1.9.1
> 



Re: [Qemu-devel] [PATCH 4/5] target-arm: Enable the AArch32 ATS12NSO ops

2015-08-17 Thread Edgar E. Iglesias
On Fri, Jul 24, 2015 at 04:21:02PM +0100, Peter Maydell wrote:
> Apply the correct conditions in the ats_access() function for
> the ATS12NSO* address translation operations:
>  * succeed at EL2 or EL3
>  * normal UNDEF trap from NS EL1
>  * trap to EL3 from S EL1 (only possible if EL3 is AArch64)
> 
> (This change means they're now available in our EL3-supporting
> CPUs when they would previously always UNDEF.)
> 
> Signed-off-by: Peter Maydell 


Reviewed-by: Edgar E. Iglesias 


> ---
>  target-arm/helper.c | 16 +++-
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 1974fa6..67d108e 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1477,12 +1477,17 @@ static void par_write(CPUARMState *env, const 
> ARMCPRegInfo *ri, uint64_t value)
>  static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>  if (ri->opc2 & 4) {
> -/* Other states are only available with TrustZone; in
> - * a non-TZ implementation these registers don't exist
> - * at all, which is an Uncategorized trap. This underdecoding
> - * is safe because the reginfo is NO_RAW.
> +/* The ATS12NSO* operations must trap to EL3 if executed in
> + * Secure EL1 (which can only happen if EL3 is AArch64).
> + * They are simply UNDEF if executed from NS EL1.
> + * They function normally from EL2 or EL3.
>   */
> -return CP_ACCESS_TRAP_UNCATEGORIZED;
> +if (arm_current_el(env) == 1) {
> +if (arm_is_secure_below_el3(env)) {
> +return CP_ACCESS_TRAP_UNCATEGORIZED_EL3;
> +}
> +return CP_ACCESS_TRAP_UNCATEGORIZED;
> +}
>  }
>  return CP_ACCESS_OK;
>  }
> @@ -1657,6 +1662,7 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
>   offsetoflow32(CPUARMState, cp15.par_ns) },
>.writefn = par_write },
>  #ifndef CONFIG_USER_ONLY
> +/* This underdecoding is safe because the reginfo is NO_RAW. */
>  { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
>.access = PL1_W, .accessfn = ats_access,
>.writefn = ats_write, .type = ARM_CP_NO_RAW },
> -- 
> 1.9.1
> 



Re: [Qemu-devel] Help debugging a regression in KVM Module

2015-08-17 Thread Peter Lieven

Am 14.08.2015 um 22:01 schrieb Alex Bennée:

Peter Lieven  writes:


Hi,

some time a go I stumbled across a regression in the KVM Module that has been 
introduced somewhere
between 3.17 and 3.19.

I have a rather old openSUSE guest with an XFS filesystem which realiably 
crashes after some live migrations.
I originally believed that the issue might be related to my setup with a 3.12 
host kernel and kvm-kmod 3.19,
but I now found that it is also still present with a 3.19 host kernel with 
included 3.19 kvm module.

My idea was to continue testing on a 3.12 host kernel and then bisect all 
commits to the kvm related parts.

Now my question is how to best bisect only kvm related changes (those
that go into kvm-kmod)?

In general I don't bother. As it is a bisection you eliminate half the
commits at a time you get their fairly quickly anyway. However you can
tell bisect which parts of the tree you car about:

   git bisect start -- arch/arm64/kvm include/linux/kvm* 
include/uapi/linux/kvm* virt/kvm/


Yes, I just have to find out how exactly that works out if I want to bisect the 
linux submodule
of the kvm-kmod repository. But thanks for the pointer on how to limit the 
directories.

Thanks,
Peter




Re: [Qemu-devel] [PULL 5/8] tcg: Put opcodes in a linked list

2015-08-17 Thread Artyom Tarasenko
Hi Richard,

this patch seems to break a build when USE_LIVENESS_ANALYSIS is undefined.

Regards,
Artyom

On Fri, Feb 13, 2015 at 6:43 AM, Richard Henderson  wrote:
> The previous setup required ops and args to be completely sequential,
> and was error prone when it came to both iteration and optimization.
>
> Reviewed-by: Bastian Koppelmann 
> Signed-off-by: Richard Henderson 
> ---
>  include/exec/gen-icount.h |  22 ++-
>  tcg/optimize.c| 286 ++-
>  tcg/tcg-op.c  | 190 ---
>  tcg/tcg.c | 376 
> +++---
>  tcg/tcg.h |  58 ---
>  5 files changed, 431 insertions(+), 501 deletions(-)
>
> diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
> index a37a61d..6e5b012 100644
> --- a/include/exec/gen-icount.h
> +++ b/include/exec/gen-icount.h
> @@ -11,8 +11,8 @@ static int exitreq_label;
>
>  static inline void gen_tb_start(TranslationBlock *tb)
>  {
> -TCGv_i32 count;
> -TCGv_i32 flag;
> +TCGv_i32 count, flag, imm;
> +int i;
>
>  exitreq_label = gen_new_label();
>  flag = tcg_temp_new_i32();
> @@ -21,16 +21,25 @@ static inline void gen_tb_start(TranslationBlock *tb)
>  tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
>  tcg_temp_free_i32(flag);
>
> -if (!(tb->cflags & CF_USE_ICOUNT))
> +if (!(tb->cflags & CF_USE_ICOUNT)) {
>  return;
> +}
>
>  icount_label = gen_new_label();
>  count = tcg_temp_local_new_i32();
>  tcg_gen_ld_i32(count, cpu_env,
> -ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
> +
> +imm = tcg_temp_new_i32();
> +tcg_gen_movi_i32(imm, 0xdeadbeef);
> +
>  /* This is a horrid hack to allow fixing up the value later.  */
> -icount_arg = tcg_ctx.gen_opparam_ptr + 1;
> -tcg_gen_subi_i32(count, count, 0xdeadbeef);
> +i = tcg_ctx.gen_last_op_idx;
> +i = tcg_ctx.gen_op_buf[i].args;
> +icount_arg = &tcg_ctx.gen_opparam_buf[i + 1];
> +
> +tcg_gen_sub_i32(count, count, imm);
> +tcg_temp_free_i32(imm);
>
>  tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
>  tcg_gen_st16_i32(count, cpu_env,
> @@ -49,7 +58,8 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns)
>  tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED);
>  }
>
> -*tcg_ctx.gen_opc_ptr = INDEX_op_end;
> +/* Terminate the linked list.  */
> +tcg_ctx.gen_op_buf[tcg_ctx.gen_last_op_idx].next = -1;
>  }
>
>  static inline void gen_io_start(void)
> diff --git a/tcg/optimize.c b/tcg/optimize.c
> index 34ae3c2..f2b8acf 100644
> --- a/tcg/optimize.c
> +++ b/tcg/optimize.c
> @@ -162,13 +162,13 @@ static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
>  return false;
>  }
>
> -static void tcg_opt_gen_mov(TCGContext *s, int op_index, TCGArg *gen_args,
> +static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, TCGArg *args,
>  TCGOpcode old_op, TCGArg dst, TCGArg src)
>  {
>  TCGOpcode new_op = op_to_mov(old_op);
>  tcg_target_ulong mask;
>
> -s->gen_opc_buf[op_index] = new_op;
> +op->opc = new_op;
>
>  reset_temp(dst);
>  mask = temps[src].mask;
> @@ -193,17 +193,17 @@ static void tcg_opt_gen_mov(TCGContext *s, int 
> op_index, TCGArg *gen_args,
>  temps[src].next_copy = dst;
>  }
>
> -gen_args[0] = dst;
> -gen_args[1] = src;
> +args[0] = dst;
> +args[1] = src;
>  }
>
> -static void tcg_opt_gen_movi(TCGContext *s, int op_index, TCGArg *gen_args,
> +static void tcg_opt_gen_movi(TCGContext *s, TCGOp *op, TCGArg *args,
>   TCGOpcode old_op, TCGArg dst, TCGArg val)
>  {
>  TCGOpcode new_op = op_to_movi(old_op);
>  tcg_target_ulong mask;
>
> -s->gen_opc_buf[op_index] = new_op;
> +op->opc = new_op;
>
>  reset_temp(dst);
>  temps[dst].state = TCG_TEMP_CONST;
> @@ -215,8 +215,8 @@ static void tcg_opt_gen_movi(TCGContext *s, int op_index, 
> TCGArg *gen_args,
>  }
>  temps[dst].mask = mask;
>
> -gen_args[0] = dst;
> -gen_args[1] = val;
> +args[0] = dst;
> +args[1] = val;
>  }
>
>  static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
> @@ -533,11 +533,9 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
>  }
>
>  /* Propagate constants and copies, fold constant expressions. */
> -static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
> -TCGArg *args, TCGOpDef *tcg_op_defs)
> +static void tcg_constant_folding(TCGContext *s)
>  {
> -int nb_ops, op_index, nb_temps, nb_globals;
> -TCGArg *gen_args;
> +int oi, oi_next, nb_temps, nb_globals;
>
>  /* Array VALS has an element for each temp.
> If this temp holds a constant then its value is kept in VALS' element.
> @@ -548,24 +546,23 @@ static TCGArg *tcg_constant_folding(TCGContext *s, 
> uint16_t *tcg_opc_ptr,
>  nb

Re: [Qemu-devel] Debian 7.8.0 SPARC64 on qemu - anything i can do to speedup the emulation?

2015-08-17 Thread Dennis Luehring

Am 31.07.2015 um 17:43 schrieb Aurelien Jarno:

> >Anyway I have extracted this code into a C file (see attached file) that
> >can more easily compiled to 32 or 64 bit using -m32 or -m64. I observe
> >the same behavior than sysbench, even with qemu-user (which is not
> >surprising as the above code doesn't really put pressure the MMU.
> >
> >Running it in I get the following time:
> >x86-64 host   0.877s
> >sparc guest -m32  1m39s
> >sparc guest -m64   3.5s
> >opensparc T1 -m32 1m59s
> >opensparc T1 -m64 1m12s


i've redone the benchmarks with Debian and NetBSD SPARC64

host: Ubuntu 15.04 x64 (latest updates) i7, 8 Cores, 8 GB RAM
  uname -a
  Linux dl-Precision-M6500 3.19.0-25-generic #26-Ubuntu SMP Fri Jul 24 
21:17:31 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux


  file /usr/bin/gcc
  /usr/bin/gcc: symbolic link to `gcc-4.9'
  file /usr/bin/gcc-4.9
  /usr/bin/gcc-4.9: ELF 64-bit LSB executable, x86-64, version 1 
(SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, 
BuildID[sha1]=f9897a3711d41df1d427f81bf3a60a60c377cd12, stripped




qemu: qemu 2.3.93 build from source

  file ~/qemu/sparc64-softmmu/qemu-system-sparc64
  /home/dl/qemu/sparc64-softmmu/qemu-system-sparc64: ELF 64-bit LSB 
shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared 
libs), for GNU/Linux 2.6.32, 
BuildID[sha1]=8cae7ad397bb9beb12d1ad670c3170a8dceef139, not stripped




guest-debian: Debian 7.8.0 SPARC64 (mixed 32/64 bit kernel/userland)

uname -a
Linux debian 3.2.0-4-sparc64 #1 Debian 3.2.68-1+deb7u2 sparc64 GNU/Linux

32bit GCC

file /usr/bin/gcc
/usr/bin/gcc: symbolic link to `gcc-4.6'
file /usr/bin/gcc-4.6
/usr/bin/gcc-4.6: ELF 32-bit MSB executable, SPARC32PLUS, V8+ Required, 
version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 
2.6.26, BuildID[sha1]=0x64ad1bef0a0bfdb8780363e811c39b7c97d567ac, stripped




guest-netsbd: NetBSD 6.1.5 SPARC64
(according to the documentation + mailing list questions its pure 64bit 
kernel and userland)


uname -a
NetBSD myhost.mydom 6.1.5 NetBSD 6.1.5 (GENERIC) sparc64

64bit GCC

file /usr/bin/gcc
/usr/bin/gcc: ELF 64-bit MSB executable, SPARC V9, relaxed memory 
ordering, (SYSV), dynamically linked (uses shared libs), for NetBSD 
6.1.5, not stripped




benchmarks:

compilation pugixml 1.6 pugixml.cpp:
g++ src/pugixml.cpp -g -Wall -Wextra -Werror -pedantic -std=c++0x -c 
-MMD -MP


host: ~3 sec
guest-debian: ~3:52.6 (32bit gcc)
guest-netbsd: ~3:27.6 (64bit gcc)

runtime Aurelien Jarnos prime.c
gcc prime.c -o prime.out -lm

host: ~2 sec
guest-debian(-m32): ~3:37.5
guest-debian(-m64): ~11 sec
guest-netbsd(only -m64): ~11 sec

Aurelien Jarnos explained the "11 sec" boost running prime.c using -m64, 
but still the NetBSD 64bit gcc needs 3:27.6 to compile pugixml.cpp - its 
just

one file, 1GB of RAM, no swapping





Re: [Qemu-devel] [PATCH v16 00/21] Deterministic replay core

2015-08-17 Thread Paolo Bonzini


On 15/08/2015 12:03, Paolo Bonzini wrote:
> 
> 
> On 15/08/2015 11:57, Pavel Dovgalyuk wrote:
>> Hi, Paolo!
>>
>> Will you apply these patches to 2.5?
> 
> Yes, I'll put them in my next pull request.

Hi Pavel,

unfortunately I do have some more review comments; that can happen when
going back to the code after a few months, and it's also a good thing
because it means that the code _is_ actually getting cleaner.

However, I am fairly sure that v17 is going to be the good one and will
be in 2.5 if I get it by mid September when I'll be back from vacation.

In particular:

* patch 3 seems to be unnecessary (for now at least)

* replay_next_event_is is modified in patch 8 ("cpu: replay instructions
sequence") after it's introduced in patch 6 ("replay: introduce icount
event").  Please fold the change in patch 6.

* replay_add_event is not used; please remove it, rename
replay_add_event_internal to replay_add_event, and add an assertion that
the rr mode is the right one (e.g. RECORD only?)

* a couple of comments say "grteater" instead of "greater"

* the replay_save_clock and replay_read_clock stubs should abort

* please inline replay_input_event into qemu_input_event_send and
replay_input_sync_event into qemu_input_event_sync, so that the
corresponding *_impl functions can be static; this also means moving the
prototypes of replay_add_input_event and replay_add_input_sync_event to
replay/replay.h (I acknowledge this might undo a request from a previous
review of mine; I don't remember)

* most stubs are unnecessary (replay_get_current_step,
replay_checkpoint, qemu_system_shutdown_request,
qemu_input_event_send_impl, qemu_input_event_sync_impl)

* please squash this in "replay: checkpoints"

diff --git a/vl.c b/vl.c
index 5a509dc..3c69563 100644
--- a/vl.c
+++ b/vl.c
@@ -1662,8 +1662,11 @@ static void qemu_kill_report(void)
 static int qemu_reset_requested(void)
 {
 int r = reset_requested;
-reset_requested = 0;
-return r;
+if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
+reset_requested = 0;
+return r;
+}
+return false;
 }

 static int qemu_suspend_requested(void)
@@ -1862,9 +1865,7 @@ static bool main_loop_should_exit(void)
 return true;
 }
 }
-if (qemu_reset_requested_get()
-&& replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
-qemu_reset_requested();
+if (qemu_reset_requested()) {
 pause_all_vcpus();
 cpu_synchronize_all_states();
 qemu_system_reset(VMRESET_REPORT);


And a few questions.  The first three are the "if the answer is yes,
please do this" kind to questions, the others can have more
open/subjective answers:

* does it make sense to call replay_check_error from
replay_finish_event, and remove the call from replay_read_next_clock?

* should qemu_clock_use_for_deadline always return false in replay mode?
The clocks are all deterministic, so it doesn't make sense to take them
into account in the poll() deadline.

* now that qemu_clock_warp has to be called in main_loop_wait, should
the icount_warp_timer have a dummy callback?  icount_warp_rt is then
only called from qemu_clock_warp.  If so, this (adding the call to
qemu_clock_warp in main_loop_wait, making the icount_warp_timer dummy,
removing the now-unnecessary argument of icount_warp_rt) should be a
separate patch before "replay: checkpoints"

* can you explain why both CHECKPOINT_INIT and CHECKPOINT_RESET are
needed?  What events are typically found in each of them?

* would it make sense to test "replay_mode != REPLAY_MODE_NONE &&
!runstate_is_running()" in replay_checkpoint, for all checkpoints, like

  if (replay_mode != REPLAY_MODE_NONE && !runstate_is_running()) {
  return false;
  }

?

* do we need an event for suspend?

Thanks,

Paolo



[Qemu-devel] [Bug 1422307] Re: qemu-nbd corrupts files

2015-08-17 Thread Robie Basak
And since Ubuntu Wily ships 2.3, I presume this is also fixed in Ubuntu
in Wily. I'll mark that Fix Released too, and add a task for Trusty.

** Changed in: qemu (Ubuntu)
   Status: New => Fix Released

** Also affects: qemu (Ubuntu Trusty)
   Importance: Undecided
   Status: New

** Changed in: qemu (Ubuntu Trusty)
   Status: New => Triaged

** Changed in: qemu (Ubuntu Trusty)
   Importance: Undecided => Medium

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1422307

Title:
  qemu-nbd corrupts files

Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Triaged

Bug description:
  Dear all,

  On Trusty, in certain situations, try to copy files over a qemu-nbd
  mounted file system leads to write errors (and thus, file corruption).

  Here is the last example I tried:
  -> virtual disk is a VDI disk
  -> It has only one partition, in FAT

  Here is my mount process:
  # modprobe nbd max_part=63
  # qemu-nbd -c /dev/nbd0 "virtual_disk.vdi"
  # partprobe /dev/nbd0
  # mount /dev/nbd0p1 /tmp/mnt/

  Partition is properly mounted at that point:
  /dev/nbd0p1 on /tmp/mnt type vfat (rw)

  Now, when I copy a file (rather big, ~28MB):
  # cp file_to_copy /tmp/mnt/ ; sync
  # md5sum /tmp/mnt/file_to_copy
  2efc9f32e4267782b11d63d2f128a363  /tmp/mnt/file_to_copy
  # umount /tmp/mnt 
  # mount /dev/nbd0p1 /tmp/mnt/
  # md5sum /tmp/mnt/file_to_copy
  42b0a3bf73f704d03ce301716d7654de  /tmp/mnt/file_to_copy

  The first hash was obviously the right one.

  On a previous attempt I did, I spotted thanks to vbindiff that parts of the 
file were just filed with 0s instead of actual data.
  It will randomly work after several attempts to write.

  Version information:
  # qemu-nbd --version
  qemu-nbd version 0.0.1
  Written by Anthony Liguori.

  Cheers,

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1422307/+subscriptions



[Qemu-devel] [Bug 1422307] Re: qemu-nbd corrupts files

2015-08-17 Thread Robie Basak
Based on Max's comment this is Fix Released upstream.

** Also affects: qemu (Ubuntu)
   Importance: Undecided
   Status: New

** Changed in: qemu
   Status: New => Fix Released

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1422307

Title:
  qemu-nbd corrupts files

Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Triaged

Bug description:
  Dear all,

  On Trusty, in certain situations, try to copy files over a qemu-nbd
  mounted file system leads to write errors (and thus, file corruption).

  Here is the last example I tried:
  -> virtual disk is a VDI disk
  -> It has only one partition, in FAT

  Here is my mount process:
  # modprobe nbd max_part=63
  # qemu-nbd -c /dev/nbd0 "virtual_disk.vdi"
  # partprobe /dev/nbd0
  # mount /dev/nbd0p1 /tmp/mnt/

  Partition is properly mounted at that point:
  /dev/nbd0p1 on /tmp/mnt type vfat (rw)

  Now, when I copy a file (rather big, ~28MB):
  # cp file_to_copy /tmp/mnt/ ; sync
  # md5sum /tmp/mnt/file_to_copy
  2efc9f32e4267782b11d63d2f128a363  /tmp/mnt/file_to_copy
  # umount /tmp/mnt 
  # mount /dev/nbd0p1 /tmp/mnt/
  # md5sum /tmp/mnt/file_to_copy
  42b0a3bf73f704d03ce301716d7654de  /tmp/mnt/file_to_copy

  The first hash was obviously the right one.

  On a previous attempt I did, I spotted thanks to vbindiff that parts of the 
file were just filed with 0s instead of actual data.
  It will randomly work after several attempts to write.

  Version information:
  # qemu-nbd --version
  qemu-nbd version 0.0.1
  Written by Anthony Liguori.

  Cheers,

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1422307/+subscriptions



[Qemu-devel] [PATCH v2] virtio: avoid leading underscores for helpers

2015-08-17 Thread Cornelia Huck
Commit ef546f1275f6563e8934dd5e338d29d9f9909ca6 ("virtio: add
feature checking helpers") introduced a helper __virtio_has_feature.
We don't want to use reserved identifiers, though, so let's
rename __virtio_has_feature to virtio_has_feature and virtio_has_feature
to virtio_vdev_has_feature.

Signed-off-by: Cornelia Huck 
---
 hw/block/virtio-blk.c |  7 ---
 hw/char/virtio-serial-bus.c   |  2 +-
 hw/net/vhost_net.c|  2 +-
 hw/net/virtio-net.c   | 31 ---
 hw/scsi/virtio-scsi.c |  8 
 hw/virtio/dataplane/vring.c   | 10 +-
 hw/virtio/vhost.c |  4 ++--
 hw/virtio/virtio-balloon.c|  2 +-
 hw/virtio/virtio.c| 14 +++---
 include/hw/virtio/virtio-access.h |  2 +-
 include/hw/virtio/virtio.h| 11 ++-
 11 files changed, 48 insertions(+), 45 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 1556c9c..f9301ae 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -731,7 +731,7 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, 
uint64_t features,
 virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
 virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
 virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
-if (__virtio_has_feature(features, VIRTIO_F_VERSION_1)) {
+if (virtio_has_feature(features, VIRTIO_F_VERSION_1)) {
 if (s->conf.scsi) {
 error_setg(errp, "Please set scsi=off for virtio-blk devices in 
order to use virtio 1.0");
 return 0;
@@ -782,10 +782,11 @@ static void virtio_blk_set_status(VirtIODevice *vdev, 
uint8_t status)
  *
  * s->blk would erroneously be placed in writethrough mode.
  */
-if (!virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) {
+if (!virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) {
 aio_context_acquire(blk_get_aio_context(s->blk));
 blk_set_enable_write_cache(s->blk,
-   virtio_has_feature(vdev, VIRTIO_BLK_F_WCE));
+   virtio_vdev_has_feature(vdev,
+   VIRTIO_BLK_F_WCE));
 aio_context_release(blk_get_aio_context(s->blk));
 }
 }
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index bc56f5d..be97058 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -76,7 +76,7 @@ static VirtIOSerialPort *find_port_by_name(char *name)
 static bool use_multiport(VirtIOSerial *vser)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(vser);
-return virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT);
+return virtio_vdev_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT);
 }
 
 static size_t write_to_port(VirtIOSerialPort *port,
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 5c1d11f..1d76b94 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -197,7 +197,7 @@ static int vhost_net_set_vnet_endian(VirtIODevice *dev, 
NetClientState *peer,
 {
 int r = 0;
 
-if (virtio_has_feature(dev, VIRTIO_F_VERSION_1) ||
+if (virtio_vdev_has_feature(dev, VIRTIO_F_VERSION_1) ||
 (virtio_legacy_is_cross_endian(dev) && !virtio_is_big_endian(dev))) {
 r = qemu_set_vnet_le(peer, set);
 if (r) {
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 8d28e45..f72eebf 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -86,8 +86,8 @@ static void virtio_net_set_config(VirtIODevice *vdev, const 
uint8_t *config)
 
 memcpy(&netcfg, config, n->config_size);
 
-if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
-!virtio_has_feature(vdev, VIRTIO_F_VERSION_1) &&
+if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
+!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1) &&
 memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
 memcpy(n->mac, netcfg.mac, ETH_ALEN);
 qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
@@ -304,7 +304,7 @@ static RxFilterInfo 
*virtio_net_query_rxfilter(NetClientState *nc)
 info->multicast_table = str_list;
 info->vlan_table = get_vlan_table(n);
 
-if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VLAN)) {
+if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VLAN)) {
 info->vlan = RX_STATE_ALL;
 } else if (!info->vlan_table) {
 info->vlan = RX_STATE_NONE;
@@ -529,13 +529,13 @@ static void virtio_net_set_features(VirtIODevice *vdev, 
uint64_t features)
 int i;
 
 virtio_net_set_multiqueue(n,
-  __virtio_has_feature(features, VIRTIO_NET_F_MQ));
+  virtio_has_feature(features, VIRTIO_NET_F_MQ));
 
 virtio_net_set_mrg_rx_bufs(n,
-   __virtio_has_feature(features,
-VIRTIO_NET_F_MRG_RXBUF),
-   

Re: [Qemu-devel] [PATCH] pci: Fix pci_device_iommu_address_space() bus propagation

2015-08-17 Thread Benjamin Herrenschmidt
On Sun, 2015-07-05 at 09:19 +1000, Benjamin Herrenschmidt wrote:
> he current code walks up the bus tree for an iommu, however it passes
> to the iommu_fn() callback the bus/devfn of the immediate child of
> the level where the callback was found, rather than the original
> bus/devfn where the search started from.

Hi Michael ! Any comment on this ? I'd like to post my series for "bare
metal" power8 support and the iommu implementation relies on this to
work.

> This prevents iommu's like POWER8 (and in fact also Q35) to properly
> provide an address space for a subset of devices that aren't 
> immediate
> children of the iommu.
> 
> PCIe carries the originator bdfn acccross to the iommu on all DMA
> transactions, so we must be able to properly identify devices at all
> levels.
> 
> This changes the function pci_device_iommu_address_space() to pass
> the original pointers to the iommu_fn() callback instead.
> 
> Signed-off-by: Benjamin Herrenschmidt 
> ---
> 
> With this, I can implement PHB3's (POWER8) iommu properly, I haven't
> submitted the P8 native patch series yet but if you are curious, you
> can look there:
> 
> https://github.com/ozbenh/qemu
> 
> And more specifically:
> 
> https://github.com/ozbenh/qemu/commit/67fe0460c75417908a2b54426cb54fe
> 5a1299a13
>  
> For the PHB3 code.
> 
>  hw/pci/pci.c | 13 +
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 29f0b0f..8185bbc 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -2403,17 +2403,14 @@ static void pci_device_class_init(ObjectClass 
> *klass, void *data)
>  AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
>  {
>  PCIBus *bus = PCI_BUS(dev->bus);
> +PCIBus *iommu_bus = bus;
>  
> -if (bus->iommu_fn) {
> -return bus->iommu_fn(bus, bus->iommu_opaque, dev->devfn);
> +while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus
> ->parent_dev) {
> +iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus);
>  }
> -
> -if (bus->parent_dev) {
> -/** We are ignoring the bus master DMA bit of the bridge
> - *  as it would complicate things such as VFIO for no good 
> reason */
> -return pci_device_iommu_address_space(bus->parent_dev);
> +if (iommu_bus && iommu_bus->iommu_fn) {
> +return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev
> ->devfn);
>  }
> -
>  return &address_space_memory;
>  }
>  
> 



[Qemu-devel] [Bug 1481272] Re: main-loop: WARNING: I/O thread spun for 1000 iterations

2015-08-17 Thread Sibiao Luo
[root@PEK112301 qemu]# git bisect log
git bisect start
# bad: [074a9925e1cfd659d5376dcaccd1436d3840e611] Merge remote-tracking branch 
'remotes/cody/tags/block-pull-request' into staging
git bisect bad 074a9925e1cfd659d5376dcaccd1436d3840e611
# good: [dfa83a6bae960e3e3a3186264d75790cfd727bce] Update version for 2.3.1 
release
git bisect good dfa83a6bae960e3e3a3186264d75790cfd727bce
# good: [e5b3a24181ea0cebf1c5b20f44d016311b7048f0] Update version for v2.3.0 
release
git bisect good e5b3a24181ea0cebf1c5b20f44d016311b7048f0
# good: [afa25c4bb5bd0732dca4aa0691fd4682d242925f] Merge remote-tracking branch 
'remotes/kraxel/tags/pull-sdl-20150611-1' into staging
git bisect good afa25c4bb5bd0732dca4aa0691fd4682d242925f
# good: [922f893e57da24bc80db3e79bea56485d1c111fa] ahci: assert is_ncq for 
process_ncq
git bisect good 922f893e57da24bc80db3e79bea56485d1c111fa
# good: [711dc6f36b74fe65a6e5a1847f1152717d887f8a] Merge remote-tracking branch 
'remotes/cody/tags/jtc-for-upstream-pull-request' into staging
git bisect good 711dc6f36b74fe65a6e5a1847f1152717d887f8a
# bad: [226d007dbd75ec8d0f12d0f9e1ce66caf55d49e4] gdbstub: Set current CPU on 
interruptions
git bisect bad 226d007dbd75ec8d0f12d0f9e1ce66caf55d49e4
# good: [b9c46307996856d03ddc1527468ff5401ac03a79] Merge remote-tracking branch 
'remotes/mdroth/tags/qga-pull-2015-07-21-tag' into staging
git bisect good b9c46307996856d03ddc1527468ff5401ac03a79
# bad: [f793d97e454a56d17e404004867985622ca1a63b] Merge remote-tracking branch 
'remotes/bonzini/tags/for-upstream' into staging
git bisect bad f793d97e454a56d17e404004867985622ca1a63b
# bad: [80adb8fcad4778376a11d394a9e01516819e2327] tcg/aarch64: use 32-bit 
offset for 32-bit softmmu emulation
git bisect bad 80adb8fcad4778376a11d394a9e01516819e2327
# bad: [dc94bd9166af5236a56bd5bb06845911915a925c] Merge remote-tracking branch 
'remotes/stefanha/tags/block-pull-request' into staging
git bisect bad dc94bd9166af5236a56bd5bb06845911915a925c
# good: [6493c975af75be5b8d9ade954239bdf5492b7911] aio-win32: reorganize 
polling loop
git bisect good 6493c975af75be5b8d9ade954239bdf5492b7911
# good: [21a03d17f2edb1e63f7137d97ba355cc6f19d79f] AioContext: fix broken 
placement of event_notifier_test_and_clear
git bisect good 21a03d17f2edb1e63f7137d97ba355cc6f19d79f
# bad: [05e514b1d4d5bd4209e2c8bbc76ff05c85a235f3] AioContext: optimize clearing 
the EventNotifier
git bisect bad 05e514b1d4d5bd4209e2c8bbc76ff05c85a235f3

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1481272

Title:
  main-loop: WARNING: I/O thread spun for 1000 iterations

Status in QEMU:
  New

Bug description:
  I compile the latest qemu to launch a VM but the monitor output the
  "main-loop: WARNING: I/O thread spun for 1000 iterations".

  # /usr/local/bin/qemu-system-x86_64 -name rhel6 -S -no-kvm -m 1024M -realtime 
mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid 
c9dd2a5c-40f2-fd3d-3c54-9cd84f8b9174 -rtc base=utc  -drive 
file=/home/samba-share/ubuntu.img,if=none,id=drive-virtio-disk0,format=qcow2,cache=none
 -device 
virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=disk,serial=425618d4-871f-4021-bc5d-bcd7f1b5ca9c,bootindex=0
 -vnc :1 -boot menu=on -monitor stdio
  QEMU 2.3.93 monitor - type 'help' for more information
  (qemu) c
  (qemu) main-loop: WARNING: I/O thread spun for 1000 iterations   
<---

  qemu]# git branch -v
  * master   e95edef Merge remote-tracking branch 
'remotes/sstabellini/tags/xen-migration-2.4-tag' into staging

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1481272/+subscriptions



Re: [Qemu-devel] [PATCH] Move RAMBlock and ram_list to ram_addr.h

2015-08-17 Thread Dr. David Alan Gilbert
* Peter Crosthwaite (crosthwaitepe...@gmail.com) wrote:
> Is there a functional reason for making this change, or pure
> organisational? Either way the patch is ok, I'm just looking for the
> motivation as this stuff did pop up in the multi-arch refactorings at
> one stage and I did think about moving it. Can we add a one-liner to
> commit message?

Purely organisational; Paolo asked for it in reply to one of my other
patches, and it was simple enough.

It also makes sense, cpu-all.h is a bit of a dumping ground.

Dave

> Regards,
> Peter
> 
> On Fri, Aug 14, 2015 at 3:25 AM, Dr. David Alan Gilbert (git)
>  wrote:
> > From: "Dr. David Alan Gilbert" 
> >
> > Signed-off-by: Dr. David Alan Gilbert 
> > ---
> >  include/exec/cpu-all.h  | 41 -
> >  include/exec/ram_addr.h | 40 
> >  2 files changed, 40 insertions(+), 41 deletions(-)
> >
> > diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> > index ea6a9a6..175f376 100644
> > --- a/include/exec/cpu-all.h
> > +++ b/include/exec/cpu-all.h
> > @@ -273,44 +273,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
> >
> >  #if !defined(CONFIG_USER_ONLY)
> >
> > -/* memory API */
> > -
> > -typedef struct RAMBlock RAMBlock;
> > -
> > -struct RAMBlock {
> > -struct rcu_head rcu;
> > -struct MemoryRegion *mr;
> > -uint8_t *host;
> > -ram_addr_t offset;
> > -ram_addr_t used_length;
> > -ram_addr_t max_length;
> > -void (*resized)(const char*, uint64_t length, void *host);
> > -uint32_t flags;
> > -/* Protected by iothread lock.  */
> > -char idstr[256];
> > -/* RCU-enabled, writes protected by the ramlist lock */
> > -QLIST_ENTRY(RAMBlock) next;
> > -int fd;
> > -};
> > -
> > -static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset)
> > -{
> > -assert(offset < block->used_length);
> > -assert(block->host);
> > -return (char *)block->host + offset;
> > -}
> > -
> > -typedef struct RAMList {
> > -QemuMutex mutex;
> > -/* Protected by the iothread lock.  */
> > -unsigned long *dirty_memory[DIRTY_MEMORY_NUM];
> > -RAMBlock *mru_block;
> > -/* RCU-enabled, writes protected by the ramlist lock. */
> > -QLIST_HEAD(, RAMBlock) blocks;
> > -uint32_t version;
> > -} RAMList;
> > -extern RAMList ram_list;
> > -
> >  /* Flags stored in the low bits of the TLB virtual address.  These are
> > defined so that fast path ram access is all zeros.  */
> >  /* Zero if TLB entry is valid.  */
> > @@ -323,9 +285,6 @@ extern RAMList ram_list;
> >
> >  void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
> >  void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
> > -ram_addr_t last_ram_offset(void);
> > -void qemu_mutex_lock_ramlist(void);
> > -void qemu_mutex_unlock_ramlist(void);
> >  #endif /* !CONFIG_USER_ONLY */
> >
> >  int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
> > diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
> > index c113f21..c400a75 100644
> > --- a/include/exec/ram_addr.h
> > +++ b/include/exec/ram_addr.h
> > @@ -22,6 +22,46 @@
> >  #ifndef CONFIG_USER_ONLY
> >  #include "hw/xen/xen.h"
> >
> > +typedef struct RAMBlock RAMBlock;
> > +
> > +struct RAMBlock {
> > +struct rcu_head rcu;
> > +struct MemoryRegion *mr;
> > +uint8_t *host;
> > +ram_addr_t offset;
> > +ram_addr_t used_length;
> > +ram_addr_t max_length;
> > +void (*resized)(const char*, uint64_t length, void *host);
> > +uint32_t flags;
> > +/* Protected by iothread lock.  */
> > +char idstr[256];
> > +/* RCU-enabled, writes protected by the ramlist lock */
> > +QLIST_ENTRY(RAMBlock) next;
> > +int fd;
> > +};
> > +
> > +static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset)
> > +{
> > +assert(offset < block->used_length);
> > +assert(block->host);
> > +return (char *)block->host + offset;
> > +}
> > +
> > +typedef struct RAMList {
> > +QemuMutex mutex;
> > +/* Protected by the iothread lock.  */
> > +unsigned long *dirty_memory[DIRTY_MEMORY_NUM];
> > +RAMBlock *mru_block;
> > +/* RCU-enabled, writes protected by the ramlist lock. */
> > +QLIST_HEAD(, RAMBlock) blocks;
> > +uint32_t version;
> > +} RAMList;
> > +extern RAMList ram_list;
> > +
> > +ram_addr_t last_ram_offset(void);
> > +void qemu_mutex_lock_ramlist(void);
> > +void qemu_mutex_unlock_ramlist(void);
> > +
> >  ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
> >  bool share, const char *mem_path,
> >  Error **errp);
> > --
> > 2.4.3
> >
> >
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH 5/5] tcg/ppc: Improve unaligned load/store handling on 64-bit backend

2015-08-17 Thread Benjamin Herrenschmidt
On Mon, 2015-08-17 at 17:34 +1000, Benjamin Herrenschmidt wrote:
> Currently, we get to the slow path for any unaligned access in the
> backend, because we effectively preserve the bottom address bits
> below the alignment requirement when comparing with the TLB entry,
> so any non-0 bit there will cause the compare to fail.

Forget about this one, it was already picked up by Richard, I forgot
about it when I did git send-email. The other 4 however are candidate
for review/merge.

Cheers.
Ben.

> For the same number of instructions, we can instead add the access
> size - 1 to the address and stick to clearing all the bottom bits.
> 
> That means that normal unaligned accesses will not fallback (the HW
> will handle them fine). Only when crossing a page boundary well we
> end up having a mismatch because we'll end up pointing to the next
> page which cannot possibly be in that same TLB entry.
> 
> Signed-off-by: Benjamin Herrenschmidt 
> ---
>  tcg/ppc/tcg-target.c | 41 +++--
>  1 file changed, 31 insertions(+), 10 deletions(-)
> 
> diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
> index 2b6eafa..ce8d546 100644
> --- a/tcg/ppc/tcg-target.c
> +++ b/tcg/ppc/tcg-target.c
> @@ -1361,7 +1361,7 @@ static void * const qemu_st_helpers[16] = {
> in CR7, loads the addend of the TLB into R3, and returns the 
> register
> containing the guest address (zero-extended into R4).  Clobbers 
> R0 and R2. */
>  
> -static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp s_bits,
> +static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp opc,
> TCGReg addrlo, TCGReg addrhi,
> int mem_index, bool is_read)
>  {
> @@ -1371,6 +1371,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, 
> TCGMemOp s_bits,
> : offsetof(CPUArchState, 
> tlb_table[mem_index][0].addr_write));
>  int add_off = offsetof(CPUArchState, 
> tlb_table[mem_index][0].addend);
>  TCGReg base = TCG_AREG0;
> +TCGMemOp s_bits = opc & MO_SIZE;
>  
>  /* Extract the page index, shifted into place for tlb index.  */
>  if (TCG_TARGET_REG_BITS == 64) {
> @@ -1422,17 +1423,37 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, 
> TCGMemOp s_bits,
> to minimize any load use delay.  */
>  tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3, add_off);
>  
> -/* Clear the non-page, non-alignment bits from the address.  */
> +/* Clear the non-page, non-alignment bits from the address */
>  if (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32) {
> +/* We don't support unaligned accesses on 32-bits, preserve
> + * the bottom bits and thus trigger a comparison failure on
> + * unaligned accesses
> + */
>  tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
>  (32 - s_bits) & 31, 31 - TARGET_PAGE_BITS);
> -} else if (!s_bits) {
> -tcg_out_rld(s, RLDICR, TCG_REG_R0, addrlo,
> -0, 63 - TARGET_PAGE_BITS);
> +} else if (s_bits) {
> +/* > byte access, we need to handle alignment */
> +if ((opc & MO_AMASK) == MO_ALIGN) {
> +/* Alignment required by the front-end, same as 32-bits 
> */
> +tcg_out_rld(s, RLDICL, TCG_REG_R0, addrlo,
> +64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - 
> s_bits);
> +tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, 
> TARGET_PAGE_BITS, 0);
> +   } else {
> +   /* We support unaligned accesses, we need to make sure we 
> fail
> +* if we cross a page boundary. The trick is to add the
> +* access_size-1 to the address before masking the low 
> bits.
> +* That will make the address overflow to the next page 
> if we
> +* cross a page boundary which will then force a mismatch 
> of
> +* the TLB compare since the next page cannot possibly be 
> in
> +* the same TLB index.
> +*/
> +tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, (1 << 
> s_bits) - 1));
> +tcg_out_rld(s, RLDICR, TCG_REG_R0, TCG_REG_R0,
> +0, 63 - TARGET_PAGE_BITS);
> +}
>  } else {
> -tcg_out_rld(s, RLDICL, TCG_REG_R0, addrlo,
> -64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - 
> s_bits);
> -tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, 
> TARGET_PAGE_BITS, 0);
> +/* Byte access, just chop off the bits below the page index 
> */
> +tcg_out_rld(s, RLDICR, TCG_REG_R0, addrlo, 0, 63 - 
> TARGET_PAGE_BITS);
>  }
>  
>  if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
> @@ -1592,7 +1613,7 @@ static void tcg_out_qemu_ld(TCGContext *s, 
> const TCGArg *args, bool is_64)
>  
>  #ifdef CONFIG_SOFTMMU
>  mem_index = get_mmuidx(oi);
> -addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, 
> true);
> +addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, 
> true)

[Qemu-devel] [PATCH 2/2] Add dynamic generation of module_block.h

2015-08-17 Thread Marc Marí
To simplify the addition of new block modules, add a script that generates
include/qemu/module_block.h automatically from the modules' source code.

This script assumes that the QEMU coding style rules are followed.

Signed-off-by: Marc Marí 
---
 .gitignore  |   1 +
 Makefile|  10 ++-
 scripts/modules/module_block.py | 132 
 3 files changed, 140 insertions(+), 3 deletions(-)
 create mode 100755 scripts/modules/module_block.py

diff --git a/.gitignore b/.gitignore
index 61bc492..8a37067 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,3 +105,4 @@ cscope.*
 tags
 TAGS
 *~
+/include/qemu/module_block.h
diff --git a/Makefile b/Makefile
index 340d9c8..47d593e 100644
--- a/Makefile
+++ b/Makefile
@@ -73,6 +73,8 @@ GENERATED_HEADERS += trace/generated-ust-provider.h
 GENERATED_SOURCES += trace/generated-ust.c
 endif
 
+GENERATED_HEADERS += include/qemu/module_block.h
+
 # Don't try to regenerate Makefile or configure
 # We don't generate any of them
 Makefile: ;
@@ -219,9 +221,6 @@ Makefile: $(version-obj-y) $(version-lobj-y)
 libqemustub.a: $(stub-obj-y)
 libqemuutil.a: $(util-obj-y)
 
-block-modules = $(foreach o,$(block-obj-m),"$(basename $(subst /,-,$o))",) NULL
-util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)'
-
 ##
 
 qemu-img.o: qemu-img-cmds.h
@@ -313,6 +312,11 @@ msi:
@echo MSI build not configured or dependency resolution failed 
(reconfigure with --enable-guest-agent-msi option)
 endif
 
+include/qemu/module_block.h: $(SRC_PATH)/scripts/modules/module_block.py
+   $(call quiet-command,$(PYTHON) 
$(SRC_PATH)/scripts/modules/module_block.py \
+   "./include/qemu/" $(patsubst %.mo,%.c,$(block-obj-m)), \
+   "  GEN   $@")
+
 clean:
 # avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h 
gen-op-arm.h
diff --git a/scripts/modules/module_block.py b/scripts/modules/module_block.py
new file mode 100755
index 000..a9a9412
--- /dev/null
+++ b/scripts/modules/module_block.py
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+#
+# Module information generator
+#
+# Copyright Red Hat, Inc. 2015
+#
+# Authors:
+#  Marc Mari 
+#
+# This work is licensed under the terms of the GNU GPL, version 2.
+# See the COPYING file in the top-level directory.
+
+import sys
+import os
+
+def get_string_struct(line):
+data = line.split()
+
+# data[0] -> struct element name
+# data[1] -> =
+# data[2] -> value
+
+return data[2].replace('"', '')[:-1]
+
+def add_module(fhader, library, format_name, protocol_name,
+probe, probe_device):
+lines = []
+lines.append('.library_name = "' + library + '",')
+if format_name != "":
+lines.append('.format_name = "' + format_name + '",')
+if protocol_name != "":
+lines.append('.protocol_name = "' + protocol_name + '",')
+if probe:
+lines.append('.has_probe = true,')
+if probe_device:
+lines.append('.has_probe_device = true,')
+
+text = '\n\t'.join(lines)
+fheader.write('\n\t{\n\t' + text + '\n\t},')
+
+def process_file(fheader, filename):
+# This parser assumes the coding style rules are being followed
+with open(filename, "r") as cfile:
+found_something = False
+found_start = False
+library, _ = os.path.splitext(os.path.basename(filename))
+for line in cfile:
+if found_start:
+line = line.replace('\n', '')
+if line.find(".format_name") != -1:
+format_name = get_string_struct(line)
+elif line.find(".protocol_name") != -1:
+protocol_name = get_string_struct(line)
+elif line.find(".bdrv_probe") != -1:
+probe = True
+elif line.find(".bdrv_probe_device") != -1:
+probe_device = True
+elif line == "};":
+add_module(fheader, library, format_name, protocol_name,
+probe, probe_device)
+found_start = False
+elif line.find("static BlockDriver") != -1:
+found_something = True
+found_start = True
+format_name = ""
+protocol_name = ""
+probe = False
+probe_device = False
+
+if not found_something:
+print("No BlockDriver struct found in " + filename + ". \
+Is this really a module?")
+sys.exit(1)
+
+def print_top(fheader):
+fheader.write('''/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+/*
+ * QEMU Block Module Infrastructure
+ *
+ * Copyright Red Hat, Inc. 2015
+ *
+ * Authors:
+ *  Marc Mari   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  Se

[Qemu-devel] [PATCH 0/2] Dynamic module support for block drivers

2015-08-17 Thread Marc Marí
The current module infrastructure has been improved to enable dynamic module
loading.

This reduces the load time for very simple guests. For the following
configuration (very loaded)

./configure --enable-sdl --enable-gtk --enable-vte --enable-curses \
--enable-vnc --enable-vnc-{jpeg,tls,sasl,png} --enable-virtfs \
--enable-brlapi --enable-curl --enable-fdt --enable-bluez \
--enable-kvm --enable-rdma --enable-uuid --enable-vde \
--enable-linux-aio --enable-cap-ng --enable-attr --enable-vhost-net \
--enable-vhost-scsi --enable-spice --enable-rbd --enable-libiscsi \
--enable-smartcard-nss --enable-guest-agent --enable-libusb \
--enable-usb-redir --enable-lzo --enable-snappy --enable-bzip2 \
--enable-seccomp --enable-coroutine-pool --enable-glusterfs \
--enable-tpm --enable-libssh2 --enable-vhdx --enable-numa \
--enable-tcmalloc --target-list=x86_64-softmmu

With modules disabled, there are 142 libraries loaded at startup. Time is
the following:
 LD time: 0.065 seconds
 QEMU time: 0.02 seconds
 Total time: 0.085 seconds

With this patch series and modules enabled, there are 128 libraries loaded
at startup. Time is the following:
 LD time: 0.02 seconds
 QEMU time: 0.02 seconds
 Total time: 0.04 seconds

Where LD time is the time between the program startup and the jump to main,
and QEMU time is the time between the start of main and the first kvm_entry.

These results are just with a few block drivers, that were already a module.
Adding more modules (block or not block) should be easy, and will reduce
the load time even more.

Marc Marí (2):
  Add dynamic module loading for block drivers
  Add dynamic generation of module_block.h

 .gitignore  |   1 +
 Makefile|  10 ++-
 block.c |  73 +-
 configure   |   2 +-
 include/qemu/module.h   |   3 +
 include/qemu/module_block.h |  89 +++
 scripts/modules/module_block.py | 132 
 util/module.c   |  38 
 8 files changed, 314 insertions(+), 34 deletions(-)
 create mode 100644 include/qemu/module_block.h
 create mode 100755 scripts/modules/module_block.py

-- 
2.4.3




[Qemu-devel] [PATCH 1/2] Add dynamic module loading for block drivers

2015-08-17 Thread Marc Marí
Extend the current module interface to allow for block drivers to be loaded
dynamically on request.

The only block drivers that can be converted into modules are the drivers
that don't perform any init operation except for registering themselves. This
is why libiscsi has been disabled as a module.

All the necessary module information is located in a new structure found in
include/qemu/module_block.h

Signed-off-by: Marc Marí 
---
 block.c | 73 +++--
 configure   |  2 +-
 include/qemu/module.h   |  3 ++
 include/qemu/module_block.h | 89 +
 util/module.c   | 38 ++-
 5 files changed, 174 insertions(+), 31 deletions(-)
 create mode 100644 include/qemu/module_block.h

diff --git a/block.c b/block.c
index d088ee0..f24a624 100644
--- a/block.c
+++ b/block.c
@@ -27,6 +27,7 @@
 #include "block/block_int.h"
 #include "block/blockjob.h"
 #include "qemu/error-report.h"
+#include "qemu/module_block.h"
 #include "qemu/module.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qjson.h"
@@ -277,11 +278,30 @@ void bdrv_add_close_notifier(BlockDriverState *bs, 
Notifier *notify)
 BlockDriver *bdrv_find_format(const char *format_name)
 {
 BlockDriver *drv1;
+int i;
+
 QLIST_FOREACH(drv1, &bdrv_drivers, list) {
 if (!strcmp(drv1->format_name, format_name)) {
 return drv1;
 }
 }
+
+for (i = 0; i < ARRAY_SIZE(block_driver_module); ++i) {
+if (!strcmp(block_driver_module[i].format_name, format_name)) {
+block_module_load_one(block_driver_module[i].library_name);
+/* Copying code is not nice, but this way the current discovery is
+ * not modified. Calling recursively could fail if the library
+ * has been deleted.
+ */
+QLIST_FOREACH(drv1, &bdrv_drivers, list) {
+if (!strcmp(drv1->format_name, format_name)) {
+return drv1;
+}
+}
+}
+}
+
+
 return NULL;
 }
 
@@ -483,9 +503,15 @@ int get_tmp_filename(char *filename, int size)
  */
 static BlockDriver *find_hdev_driver(const char *filename)
 {
-int score_max = 0, score;
+int score_max = 0, score, i;
 BlockDriver *drv = NULL, *d;
 
+for (i = 0; i < ARRAY_SIZE(block_driver_module); ++i) {
+if (block_driver_module[i].has_probe_device) {
+block_module_load_one(block_driver_module[i].library_name);
+}
+}
+
 QLIST_FOREACH(d, &bdrv_drivers, list) {
 if (d->bdrv_probe_device) {
 score = d->bdrv_probe_device(filename);
@@ -507,6 +533,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
 char protocol[128];
 int len;
 const char *p;
+int i;
 
 /* TODO Drivers without bdrv_file_open must be specified explicitly */
 
@@ -533,6 +560,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
 len = sizeof(protocol) - 1;
 memcpy(protocol, filename, len);
 protocol[len] = '\0';
+
 QLIST_FOREACH(drv1, &bdrv_drivers, list) {
 if (drv1->protocol_name &&
 !strcmp(drv1->protocol_name, protocol)) {
@@ -540,6 +568,23 @@ BlockDriver *bdrv_find_protocol(const char *filename,
 }
 }
 
+for (i = 0; i < ARRAY_SIZE(block_driver_module); ++i) {
+if (block_driver_module[i].protocol_name &&
+!strcmp(block_driver_module[i].protocol_name, protocol)) {
+block_module_load_one(block_driver_module[i].library_name);
+/* Copying code is not nice, but this way the current discovery is
+ * not modified. Calling recursively could fail if the library
+ * has been deleted.
+ */
+QLIST_FOREACH(drv1, &bdrv_drivers, list) {
+if (drv1->protocol_name &&
+!strcmp(drv1->protocol_name, protocol)) {
+return drv1;
+}
+}
+}
+}
+
 error_setg(errp, "Unknown protocol '%s'", protocol);
 return NULL;
 }
@@ -561,9 +606,15 @@ BlockDriver *bdrv_find_protocol(const char *filename,
 BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
 const char *filename)
 {
-int score_max = 0, score;
+int score_max = 0, score, i;
 BlockDriver *drv = NULL, *d;
 
+for (i = 0; i < ARRAY_SIZE(block_driver_module); ++i) {
+if (block_driver_module[i].has_probe) {
+block_module_load_one(block_driver_module[i].library_name);
+}
+}
+
 QLIST_FOREACH(d, &bdrv_drivers, list) {
 if (d->bdrv_probe) {
 score = d->bdrv_probe(buf, buf_size, filename);
@@ -2783,7 +2834,7 @@ void bdrv_iterate_format(void (*it)(void *opaque, const 
char *name),
 {
 BlockDriver *drv;
 int count = 0;
-int i;
+int i, n;
 const char **formats = NULL;
 
 QLIST_FOREACH(drv, &bdrv_dr

[Qemu-devel] [Bug 1481272] Re: main-loop: WARNING: I/O thread spun for 1000 iterations

2015-08-17 Thread Sibiao Luo
Good catch, thanks stefanha for your kindly reminds with such good tools
(git-bisect) to determine which commit caused this problem. I'm very
sorry that i did not try it as your instruction timely, mainly that i
focus on the openstack(nova&cinder) currently in the new company and
have to adapt to the new work flow & role as quickly as possible.
According to me trying that 05e514b1d4d5bd4209e2c8bbc76ff05c85a235f3 is
the first bad commit pushed by pbonzini.

My trying results as following:
master 074a992 Merge remote-tracking branch 
'remotes/cody/tags/block-pull-request' into staging <---> latest version fail
qemu-2.3-stable dfa83a6 Update version for 2.3.1 release
  <---> qemu-2.3-stable good

[root@PEK112301 qemu]# git bisect start
[root@PEK112301 qemu]# git bisect bad 074a992
[root@PEK112301 qemu]# git bisect good dfa83a6
Bisecting: a merge base must be tested
[e5b3a24181ea0cebf1c5b20f44d016311b7048f0] Update version for v2.3.0 release
<<>>

[root@PEK112301 qemu]# git bisect good
Bisecting: 1105 revisions left to test after this (roughly 10 steps)
[afa25c4bb5bd0732dca4aa0691fd4682d242925f] Merge remote-tracking branch 
'remotes/kraxel/tags/pull-sdl-20150611-1' into staging
<<>>

[root@PEK112301 qemu]# git bisect good
Bisecting: 552 revisions left to test after this (roughly 9 steps)
[922f893e57da24bc80db3e79bea56485d1c111fa] ahci: assert is_ncq for process_ncq
<<>>

[root@PEK112301 qemu]# git bisect good
Bisecting: 274 revisions left to test after this (roughly 8 steps)
[711dc6f36b74fe65a6e5a1847f1152717d887f8a] Merge remote-tracking branch 
'remotes/cody/tags/jtc-for-upstream-pull-request' into staging
<<>>

[root@PEK112301 qemu]# git bisect good
Bisecting: 138 revisions left to test after this (roughly 7 steps)
[226d007dbd75ec8d0f12d0f9e1ce66caf55d49e4] gdbstub: Set current CPU on 
interruptions
<<>>

[root@PEK112301 qemu]# git bisect bad
Bisecting: 67 revisions left to test after this (roughly 6 steps)
[b9c46307996856d03ddc1527468ff5401ac03a79] Merge remote-tracking branch 
'remotes/mdroth/tags/qga-pull-2015-07-21-tag' into staging
<<>>

[root@PEK112301 qemu]# git bisect good
Bisecting: 32 revisions left to test after this (roughly 5 steps)
[f793d97e454a56d17e404004867985622ca1a63b] Merge remote-tracking branch 
'remotes/bonzini/tags/for-upstream' into staging
<<>>

[root@PEK112301 qemu]# git bisect bad
Bisecting: 17 revisions left to test after this (roughly 4 steps)
[80adb8fcad4778376a11d394a9e01516819e2327] tcg/aarch64: use 32-bit offset for 
32-bit softmmu emulation
<<>>

[root@PEK112301 qemu]# git bisect bad
Bisecting: 8 revisions left to test after this (roughly 3 steps)
[dc94bd9166af5236a56bd5bb06845911915a925c] Merge remote-tracking branch 
'remotes/stefanha/tags/block-pull-request' into staging
<<>>

[root@PEK112301 qemu]# git bisect bad
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[6493c975af75be5b8d9ade954239bdf5492b7911] aio-win32: reorganize polling loop
<<>>

[root@PEK112301 qemu]# git bisect good
Bisecting: 1 revision left to test after this (roughly 1 step)
[21a03d17f2edb1e63f7137d97ba355cc6f19d79f] AioContext: fix broken placement of 
event_notifier_test_and_clear
<<>>

[root@PEK112301 qemu]# git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[05e514b1d4d5bd4209e2c8bbc76ff05c85a235f3] AioContext: optimize clearing the 
EventNotifier
<<>>

[root@PEK112301 qemu]# git bisect bad
05e514b1d4d5bd4209e2c8bbc76ff05c85a235f3 is the first bad commit
commit 05e514b1d4d5bd4209e2c8bbc76ff05c85a235f3
Author: Paolo Bonzini 
Date:   Tue Jul 21 16:07:53 2015 +0200

AioContext: optimize clearing the EventNotifier

It is pretty rare for aio_notify to actually set the EventNotifier.  It
can happen with worker threads such as thread-pool.c's, but otherwise it
should never be set thanks to the ctx->notify_me optimization.  The
previous patch, unfortunately, added an unconditional call to
event_notifier_test_and_clear; now add a userspace fast path that
avoids the call.

Note that it is not possible to do the same with event_notifier_set;
it would break, as proved (again) by the included formal model.

This patch survived over 3000 reboots on aarch64 KVM.

Signed-off-by: Paolo Bonzini 
Reviewed-by: Fam Zheng 
Tested-by: Richard W.M. Jones 
Message-id: 1437487673-23740-7-git-send-email-pbonz...@redhat.com
Signed-off-by: Stefan Hajnoczi 

:100644 100644 5c8b266c72b79e07f881a563da189e0267937766 
d4770336c5d5355758c3da207b8be5160f66fc5f Maio-posix.c
:100644 100644 7afc9992d682d335b4fce58182b580f7f678f503 
50a68674589aa3c6418604bfb9320e915f624796 Maio-win32.c
:100644 100644 d625e8a8035656711f156078bbc7784b4f4754b0 
9a98a74acb99bbf74c004ab2de0d09ca78eac84c Masync.c
:04 04 6f98147da6fdc258f6b7b967ee90d02686311951 
11705f58169772ff280c44f

[Qemu-devel] [PATCH 4/5] ppc: Do some batching of TCG tlb flushes

2015-08-17 Thread Benjamin Herrenschmidt
On ppc64 especially, we flush the tlb on any slbie or tlbie instruction.

However, those instructions often come in bursts of 3 or more (context
switch will favor a series of slbie's for example to an slbia if the
SLB has less than a certain number of entries in it, and tlbie's can
happen in a series, with PAPR, H_BULK_REMOVE can remove up to 4 entries
at a time.

Doing a tlb_flush() each time is a waste of time. We end up doing a memset
of the whole TLB, reloading it for the next instruction, memset'ing again,
etc...

Those instructions don't have to take effect immediately. For slbie, they
can wait for the next context synchronizing event. For tlbie, the next
tlbsync.

This implements batching by keeping a flag that indicates that we have a
TLB in need of flushing. We check it on interrupts, rfi's, isync's and
tlbsync and flush the TLB if needed.

This reduces the number of tlb_flush() on a boot to a ubuntu installer
first dialog screen from roughly 360K down to 36K.

Signed-off-by: Benjamin Herrenschmidt 
---
 hw/ppc/spapr_hcall.c | 12 +---
 target-ppc/cpu.h |  2 ++
 target-ppc/excp_helper.c |  9 +
 target-ppc/helper.h  |  1 +
 target-ppc/helper_regs.h | 13 +
 target-ppc/mmu-hash64.c  | 12 +++-
 target-ppc/mmu_helper.c  |  9 -
 target-ppc/translate.c   | 39 ---
 8 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 652ddf6..3f4e275 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -220,6 +220,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 
 switch (ret) {
 case REMOVE_SUCCESS:
+check_tlb_flush(env);
 return H_SUCCESS;
 
 case REMOVE_NOT_FOUND:
@@ -257,6 +258,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
   target_ulong opcode, target_ulong *args)
 {
 CPUPPCState *env = &cpu->env;
+target_ulong rc = H_SUCCESS;
 int i;
 
 for (i = 0; i < H_BULK_REMOVE_MAX_BATCH; i++) {
@@ -290,14 +292,18 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 break;
 
 case REMOVE_PARM:
-return H_PARAMETER;
+rc = H_PARAMETER;
+goto exit;
 
 case REMOVE_HW:
-return H_HARDWARE;
+rc = H_HARDWARE;
+goto exit;
 }
 }
+ exit:
+check_tlb_flush(env);
 
-return H_SUCCESS;
+return rc;
 }
 
 static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index fb678a0..b68d30f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1013,6 +1013,8 @@ struct CPUPPCState {
 /* PowerPC 64 SLB area */
 ppc_slb_t slb[MAX_SLB_ENTRIES];
 int32_t slb_nr;
+/* tcg TLB needs flush (deferred slb inval instruction typically) */
+uint32_t tlb_need_flush;
 #endif
 /* segment registers */
 hwaddr htab_base;
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 6f4ea28..2a5f4a2 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -671,6 +671,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 /* Reset exception state */
 cs->exception_index = POWERPC_EXCP_NONE;
 env->error_code = 0;
+
+/* Any interrupt is context synchronizing, check if TCG TLB
+ * needs a delayed flush on ppc64
+ */
+check_tlb_flush(env);
 }
 
 void ppc_cpu_do_interrupt(CPUState *cs)
@@ -692,6 +697,7 @@ static void ppc_hw_interrupt(CPUPPCState *env)
   __func__, env, env->pending_interrupts,
   cs->interrupt_request, (int)msr_me, (int)msr_ee);
 #endif
+
 /* External reset */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
@@ -896,6 +902,9 @@ static inline void do_rfi(CPUPPCState *env, target_ulong 
nip, target_ulong msr,
  * as rfi is always the last insn of a TB
  */
 cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
+
+/* Context synchronizing: check if TCG TLB needs flush */
+check_tlb_flush(env);
 }
 
 void helper_rfi(CPUPPCState *env)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 869be15..ff2d50b 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -16,6 +16,7 @@ DEF_HELPER_1(rfmci, void, env)
 DEF_HELPER_1(rfid, void, env)
 DEF_HELPER_1(hrfid, void, env)
 #endif
+DEF_HELPER_1(check_tlb_flush, void, env)
 #endif
 
 DEF_HELPER_3(lmw, void, env, tl, i32)
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index f7edd5b..57da931 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -151,4 +151,17 @@ static inline int hreg_store_msr(CPUPPCState *env, 
target_ulong value,
 return excp;
 }
 
+#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64)
+static inl

[Qemu-devel] [PATCH 2/5] tlb: Add "ifetch" argument to cpu_mmu_index()

2015-08-17 Thread Benjamin Herrenschmidt
This is set to true when the index is for an instruction fetch
translation.

The core get_page_addr_code() sets it, as do the SOFTMMU_CODE_ACCESS
acessors.

All targets ignore it for now, and all other callers pass "false".

This will allow targets who wish to split the mmu index between
instruction and data accesses to do so. A subsequent patch will
do just that for PowerPC.

Signed-off-by: Benjamin Herrenschmidt 
---
 cputlb.c  |  2 +-
 include/exec/cpu_ldst.h   |  4 ++--
 target-alpha/cpu.h|  2 +-
 target-alpha/translate.c  |  2 +-
 target-arm/cpu.h  |  4 ++--
 target-arm/helper.c   |  4 ++--
 target-cris/cpu.h |  2 +-
 target-cris/translate.c   |  6 +++---
 target-cris/translate_v10.c   |  2 +-
 target-i386/cpu.h |  2 +-
 target-i386/translate.c   |  2 +-
 target-lm32/cpu.h |  2 +-
 target-m68k/cpu.h |  2 +-
 target-microblaze/cpu.h   |  2 +-
 target-microblaze/mmu.c   |  2 +-
 target-microblaze/translate.c | 16 
 target-mips/cpu.h |  2 +-
 target-mips/op_helper.c   |  4 ++--
 target-moxie/cpu.h|  2 +-
 target-openrisc/cpu.h |  2 +-
 target-openrisc/translate.c   |  2 +-
 target-ppc/cpu.h  |  2 +-
 target-s390x/cpu.h|  2 +-
 target-s390x/mem_helper.c |  4 ++--
 target-sh4/cpu.h  |  2 +-
 target-sparc/cpu.h|  2 +-
 target-sparc/mmu_helper.c |  2 +-
 target-sparc/translate.c  |  2 +-
 target-tricore/cpu.h  |  2 +-
 target-tricore/translate.c|  2 +-
 target-unicore32/cpu.h|  2 +-
 target-xtensa/cpu.h   |  2 +-
 32 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index a506086..f7ccc1d 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -355,7 +355,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, 
target_ulong addr)
 CPUState *cpu = ENV_GET_CPU(env1);
 
 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-mmu_idx = cpu_mmu_index(env1);
+mmu_idx = cpu_mmu_index(env1, true);
 if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
  (addr & TARGET_PAGE_MASK))) {
 cpu_ldub_code(env1, addr);
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 1239c60..8a28818 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -363,7 +363,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong 
addr, int mmu_idx);
 #endif /* (NB_MMU_MODES > 12) */
 
 /* these access are slower, they must be as rare as possible */
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
+#define CPU_MMU_INDEX (cpu_mmu_index(env, false))
 #define MEMSUFFIX _data
 #define DATA_SIZE 1
 #include "exec/cpu_ldst_template.h"
@@ -379,7 +379,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong 
addr, int mmu_idx);
 #undef CPU_MMU_INDEX
 #undef MEMSUFFIX
 
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
+#define CPU_MMU_INDEX (cpu_mmu_index(env, true))
 #define MEMSUFFIX _code
 #define SOFTMMU_CODE_ACCESS
 
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 91c56d6..ba7daa5 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -376,7 +376,7 @@ enum {
 PS_USER_MODE = 8
 };
 
-static inline int cpu_mmu_index(CPUAlphaState *env)
+static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
 {
 if (env->pal_mode) {
 return MMU_KERNEL_IDX;
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 81d4ff8..5b9b554 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2813,7 +2813,7 @@ static inline void 
gen_intermediate_code_internal(AlphaCPU *cpu,
 
 ctx.tb = tb;
 ctx.pc = pc_start;
-ctx.mem_idx = cpu_mmu_index(env);
+ctx.mem_idx = cpu_mmu_index(env, false);
 ctx.implver = env->implver;
 ctx.singlestep_enabled = cs->singlestep_enabled;
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 2e680da..a4c02b7 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1674,7 +1674,7 @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
 }
 
 /* Determine the current mmu_idx to use for normal loads/stores */
-static inline int cpu_mmu_index(CPUARMState *env)
+static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
 {
 int el = arm_current_el(env);
 
@@ -1907,7 +1907,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
<< ARM_TBFLAG_XSCALE_CPAR_SHIFT);
 }
 
-*flags |= (cpu_mmu_index(env) << ARM_TBFLAG_MMUIDX_SHIFT);
+*flags |= (cpu_mmu_index(env, false) << ARM_TBFLAG_MMUIDX_SHIFT);
 /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
  * states defined in the ARM ARM for software singlestep:
  *  SS_ACTIVE   PSTATE.SS   State
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1568aa6..b1d55b6 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -6507,7 +6507,7 @@ hwaddr a

[Qemu-devel] [PATCH 5/5] tcg/ppc: Improve unaligned load/store handling on 64-bit backend

2015-08-17 Thread Benjamin Herrenschmidt
Currently, we get to the slow path for any unaligned access in the
backend, because we effectively preserve the bottom address bits
below the alignment requirement when comparing with the TLB entry,
so any non-0 bit there will cause the compare to fail.

For the same number of instructions, we can instead add the access
size - 1 to the address and stick to clearing all the bottom bits.

That means that normal unaligned accesses will not fallback (the HW
will handle them fine). Only when crossing a page boundary well we
end up having a mismatch because we'll end up pointing to the next
page which cannot possibly be in that same TLB entry.

Signed-off-by: Benjamin Herrenschmidt 
---
 tcg/ppc/tcg-target.c | 41 +++--
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 2b6eafa..ce8d546 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -1361,7 +1361,7 @@ static void * const qemu_st_helpers[16] = {
in CR7, loads the addend of the TLB into R3, and returns the register
containing the guest address (zero-extended into R4).  Clobbers R0 and R2. 
*/
 
-static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp s_bits,
+static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp opc,
TCGReg addrlo, TCGReg addrhi,
int mem_index, bool is_read)
 {
@@ -1371,6 +1371,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp 
s_bits,
: offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
 int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
 TCGReg base = TCG_AREG0;
+TCGMemOp s_bits = opc & MO_SIZE;
 
 /* Extract the page index, shifted into place for tlb index.  */
 if (TCG_TARGET_REG_BITS == 64) {
@@ -1422,17 +1423,37 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp 
s_bits,
to minimize any load use delay.  */
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3, add_off);
 
-/* Clear the non-page, non-alignment bits from the address.  */
+/* Clear the non-page, non-alignment bits from the address */
 if (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32) {
+/* We don't support unaligned accesses on 32-bits, preserve
+ * the bottom bits and thus trigger a comparison failure on
+ * unaligned accesses
+ */
 tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
 (32 - s_bits) & 31, 31 - TARGET_PAGE_BITS);
-} else if (!s_bits) {
-tcg_out_rld(s, RLDICR, TCG_REG_R0, addrlo,
-0, 63 - TARGET_PAGE_BITS);
+} else if (s_bits) {
+/* > byte access, we need to handle alignment */
+if ((opc & MO_AMASK) == MO_ALIGN) {
+/* Alignment required by the front-end, same as 32-bits */
+tcg_out_rld(s, RLDICL, TCG_REG_R0, addrlo,
+64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - s_bits);
+tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 
0);
+   } else {
+   /* We support unaligned accesses, we need to make sure we fail
+* if we cross a page boundary. The trick is to add the
+* access_size-1 to the address before masking the low bits.
+* That will make the address overflow to the next page if we
+* cross a page boundary which will then force a mismatch of
+* the TLB compare since the next page cannot possibly be in
+* the same TLB index.
+*/
+tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, (1 << s_bits) - 1));
+tcg_out_rld(s, RLDICR, TCG_REG_R0, TCG_REG_R0,
+0, 63 - TARGET_PAGE_BITS);
+}
 } else {
-tcg_out_rld(s, RLDICL, TCG_REG_R0, addrlo,
-64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - s_bits);
-tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
+/* Byte access, just chop off the bits below the page index */
+tcg_out_rld(s, RLDICR, TCG_REG_R0, addrlo, 0, 63 - TARGET_PAGE_BITS);
 }
 
 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
@@ -1592,7 +1613,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is_64)
 
 #ifdef CONFIG_SOFTMMU
 mem_index = get_mmuidx(oi);
-addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, true);
+addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, true);
 
 /* Load a pointer into the current opcode w/conditional branch-link. */
 label_ptr = s->code_ptr;
@@ -1667,7 +1688,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 
 #ifdef CONFIG_SOFTMMU
 mem_index = get_mmuidx(oi);
-addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, false);
+addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, false);
 
 /* Load a pointer into the current opcode w/conditi

[Qemu-devel] [PATCH 3/5] ppc: Use split I/D mmu modes to avoid flushes on interrupts

2015-08-17 Thread Benjamin Herrenschmidt
We rework the way the MMU indices are calculated, providing separate
indices for I and D side based on MSR:IR and MSR:DR respectively,
and thus no longer need to flush the TLB on context changes. This also
adds correct support for HV as a separate address space.

Signed-off-by: Benjamin Herrenschmidt 
---
 target-ppc/cpu.h | 11 +++---
 target-ppc/excp_helper.c | 11 --
 target-ppc/helper_regs.h | 54 +---
 target-ppc/machine.c |  4 +++-
 target-ppc/translate.c   |  7 ---
 5 files changed, 62 insertions(+), 25 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 0a0c47e..fb678a0 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -462,6 +462,8 @@ struct ppc_slb_t {
 #define MSR_EP   6  /* Exception prefix on 601   */
 #define MSR_IR   5  /* Instruction relocate  */
 #define MSR_DR   4  /* Data relocate */
+#define MSR_IS   5  /* Instruction address space (BookE) */
+#define MSR_DS   4  /* Data address space (BookE)*/
 #define MSR_PE   3  /* Protection enable on 403  */
 #define MSR_PX   2  /* Protection exclusive on 403  x*/
 #define MSR_PMM  2  /* Performance monitor mark on POWERx*/
@@ -505,6 +507,8 @@ struct ppc_slb_t {
 #define msr_ep   ((env->msr >> MSR_EP)   & 1)
 #define msr_ir   ((env->msr >> MSR_IR)   & 1)
 #define msr_dr   ((env->msr >> MSR_DR)   & 1)
+#define msr_is   ((env->msr >> MSR_IS)   & 1)
+#define msr_ds   ((env->msr >> MSR_DS)   & 1)
 #define msr_pe   ((env->msr >> MSR_PE)   & 1)
 #define msr_px   ((env->msr >> MSR_PX)   & 1)
 #define msr_pmm  ((env->msr >> MSR_PMM)  & 1)
@@ -944,7 +948,7 @@ struct ppc_segment_page_sizes {
 
 /*/
 /* The whole PowerPC CPU context */
-#define NB_MMU_MODES 3
+#define NB_MMU_MODES8
 
 #define PPC_CPU_OPCODES_LEN  0x40
 #define PPC_CPU_INDIRECT_OPCODES_LEN 0x20
@@ -1107,7 +,8 @@ struct CPUPPCState {
 /* Those resources are used only in QEMU core */
 target_ulong hflags;  /* hflags is a MSR & HFLAGS_MASK */
 target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
-int mmu_idx; /* precomputed MMU index to speed up mem accesses */
+int immu_idx; /* precomputed MMU index to speed up insn access */
+int dmmu_idx; /* precomputed MMU index to speed up data accesses */
 
 /* Power management */
 int (*check_pow)(CPUPPCState *env);
@@ -1249,7 +1254,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t 
val);
 #define MMU_USER_IDX 0
 static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
 {
-return env->mmu_idx;
+return ifetch ? env->immu_idx : env->dmmu_idx;
 }
 
 #include "exec/cpu-all.h"
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index b803475..6f4ea28 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -623,9 +623,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 
 if (env->spr[SPR_LPCR] & LPCR_AIL) {
 new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
-} else if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
-/* If we disactivated any translation, flush TLBs */
-tlb_flush(cs, 1);
 }
 
 #ifdef TARGET_PPC64
@@ -674,14 +671,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 /* Reset exception state */
 cs->exception_index = POWERPC_EXCP_NONE;
 env->error_code = 0;
-
-if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
-(env->mmu_model == POWERPC_MMU_BOOKE206)) {
-/* XXX: The BookE changes address space when switching modes,
-we should probably implement that as different MMU indexes,
-but for the moment we do it the slow way and flush all.  */
-tlb_flush(cs, 1);
-}
 }
 
 void ppc_cpu_do_interrupt(CPUState *cs)
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index 271fddf..f7edd5b 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -41,11 +41,50 @@ static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
 
 static inline void hreg_compute_mem_idx(CPUPPCState *env)
 {
-/* Precompute MMU index */
-if (msr_pr == 0 && msr_hv != 0) {
-env->mmu_idx = 2;
+/* This is our encoding for server processors
+ *
+ *   0 = Guest User space virtual mode
+ *   1 = Guest Kernel space virtual mode
+ *   2 = Guest Kernel space real mode
+ *   3 = HV User space virtual mode
+ *   4 = HV Kernel space virtual mode
+ *   5 = HV Kernel space real mode
+ *
+ * The combination PR=1 IR&DR=0 is invalid, we will treat
+ * it as IR=DR=1
+ *
+ * For BookE, we need 8 MMU modes as follow:
+ *
+ *  0 

[Qemu-devel] [PATCH 1/5] ppc: Remove MMU_MODEn_SUFFIX definitions

2015-08-17 Thread Benjamin Herrenschmidt
We don't use the resulting accessors and this gets in the way of
the split I/D TLB work.

Signed-off-by: Benjamin Herrenschmidt 
---
 target-ppc/cpu.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 6f76674..5dfd195 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1246,9 +1246,6 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t 
val);
 #define cpu_list ppc_cpu_list
 
 /* MMU modes definitions */
-#define MMU_MODE0_SUFFIX _user
-#define MMU_MODE1_SUFFIX _kernel
-#define MMU_MODE2_SUFFIX _hypv
 #define MMU_USER_IDX 0
 static inline int cpu_mmu_index (CPUPPCState *env)
 {
-- 
2.4.3