Re: [Qemu-devel] [PATCH] ide: fix ATAPI command permissions

2015-09-14 Thread Markus Armbruster
John Snow  writes:

> We're a little too lenient with what we'll let an ATAPI drive handle.
> Clamp down on the IDE command execution table to remove CD_OK permissions
> from commands that are not and have never been ATAPI commands.
>
> For ATAPI command validity, please see:
> - ATA4 Section 6.5 ("PACKET Command feature set")
> - ATA8/ACS Section 4.3 ("The PACKET feature set")
> - ACS3 Section 4.3 ("The PACKET feature set")
>
> ACS3 has a historical command validity table in Table B.4
> ("Historical Command Assignments") that can be referenced to find when
> a command was introduced, deprecated, obsoleted, etc.
>
> The only reference for ATAPI command validity is by checking that
> version's PACKET feature set section.
>
> ATAPI was introduced by T13 into ATA4, all commands retired prior to ATA4
> therefore are assumed to have never been ATAPI commands.
>
> Mandatory commands, as listed in ATA8-ACS3, are:
>
> - DEVICE RESET
> - EXECUTE DEVICE DIAGNOSTIC
> - IDENTIFY DEVICE
> - IDENTIFY PACKET DEVICE
> - NOP
> - PACKET
> - READ SECTOR(S)
> - SET FEATURES
>
> Optional commands as listed in ATA8-ACS3, are:
>
> - FLUSH CACHE
> - READ LOG DMA EXT
> - READ LOG EXT
> - WRITE LOG DMA EXT
> - WRITE LOG EXT
>
> All other commands are illegal to send to an ATAPI device and should
> be rejected by the device.

We could perhaps argue about "should be rejected by the device", but I
think the weaker "a device is free to reject it" still suffices to
support your patch.

> CD_OK removal justifications:
>
> 0x06 WIN_DSM  Defined in ACS2. Not valid for ATAPI.
> 0x21 WIN_READ_ONCERetired in ATA5. Not ATAPI in ATA4.
> 0x94 WIN_STANDBYNOW2  Retired in ATA4. Did not coexist with ATAPI.
> 0x95 WIN_IDLEIMMEDIATE2   Retired in ATA4. Did not coexist with ATAPI.
> 0x96 WIN_STANDBY2 Retired in ATA4. Did not coexist with ATAPI.
> 0x97 WIN_SETIDLE2 Retired in ATA4. Did not coexist with ATAPI.
> 0x98 WIN_CHECKPOWERMODE2  Retired in ATA4. Did not coexist with ATAPI.
> 0x99 WIN_SLEEPNOW2Retired in ATA4. Did not coexist with ATAPI.
> 0xE0 WIN_STANDBYNOW1  Not part of ATAPI in ATA4, ACS or ACS3.
> 0xE1 WIN_IDLEIMMDIATE Not part of ATAPI in ATA4, ACS or ACS3.
> 0xE2 WIN_STANDBY  Not part of ATAPI in ATA4, ACS or ACS3.
> 0xE3 WIN_SETIDLE1 Not part of ATAPI in ATA4, ACS or ACS3.
> 0xE4 WIN_CHECKPOWERMODE1  Not part of ATAPI in ATA4, ACS or ACS3.
> 0xE5 WIN_SLEEPNOW1Not part of ATAPI in ATA4, ACS or ACS3.
> 0xF8 WIN_READ_NATIVE_MAX  Obsoleted in ACS3. Not ATAPI in ATA4 or ACS.

Actual patch matches this list.

> This patch fixes a divide by zero fault that can be caused by sending
> the WIN_READ_NATIVE_MAX command to an empty ATAPI drive, which causes
> it to attempt to use zeroed CHS values to perform sector arithmetic.
>
> Reported-by: Qinghao Tang 
> Signed-off-by: John Snow 

I appreciate you going to the root of the problem instead of merely
fixing the narrow bug.

Could a similar argument be made for dropping CFA_OK from some commands?

Do we still need this conditional in cmd_read_native_max()?

/* Refuse if no sectors are addressable (e.g. medium not inserted) */
if (s->nb_sectors == 0) {
ide_abort_command(s);
return true;
}

Why does it fail at guarding the CHS use from empty ATAPI drives before
your patch?



Re: [Qemu-devel] [PATCH v4 2/4] block: support passing 'backing': '' to 'blockdev-add'

2015-09-14 Thread Alberto Garcia
On Tue 15 Sep 2015 04:27:21 AM CEST, Fam Zheng  wrote:

>> +backing = qdict_get_try_str(options, "backing");
>> +if (backing && *backing == '\0') {
>> +flags |= BDRV_O_NO_BACKING;
>> +}
>> +qdict_del(options, "backing");
>> +

> Specifying a non-empty "backing" will be a slient nop now, but it used
> to be an error before.  Should we return an error?

Ah, yes, I think it should return an error. Thanks!

--- a/block.c
+++ b/block.c
@@ -1473,8 +1473,8 @@ static int bdrv_open_inherit(BlockDriverState
**pbs, const char *filename,
 backing = qdict_get_try_str(options, "backing");
 if (backing && *backing == '\0') {
 flags |= BDRV_O_NO_BACKING;
+qdict_del(options, "backing");
 }
-qdict_del(options, "backing");

Berto



Re: [Qemu-devel] [Question] QEMU 2.3 Assertion with `existing->mr->subpage || existing->mr == &io_mem_unassigned' failed

2015-09-14 Thread Gonglei
On 2015/9/15 9:16, Gonglei wrote:
> On 2015/9/14 17:28, Paolo Bonzini wrote:
>>
>>
>> On 14/09/2015 10:01, Gonglei (Arei) wrote:
>>> [2015-09-11 13:42:44] domain is rebooting 
>>> qemu-kvm: /home/abuild/rpmbuild/BUILD/qemu-kvm-2.3.0/exec.c:1188: 
>>> register_subpage: Assertion `existing->mr->subpage || existing->mr == 
>>> &io_mem_unassigned' failed. 
>>> [2015-09-11 13:42:58]: shutting down
>>>
>>> Or
>>> qemu-kvm: 
>>> /home/abuild/rpmbuild/BUILD/qemu-kvm-2.3.0/include/qemu/int128.h:22: 
>>> int128_get64: Assertion `!a.hi' failed.
>>
>> You need to provide a backtrace.
>>
>> Paolo
>>
> Yup, I noticed that, but when I sent this email yesterday, I didn't get a 
> backtrace :(
> Fortunately,   I get a backtrace now:
> 
> #0 int128_get64 (a=...) at /home/qemu/include/qemu/int128.h:27
> #1 0x7f17ad7a7f1a in register_multipage (d=0x7f179c4f8480, 
> section=0x7f17a323c3f0) at /home/qemu/exec.c:1215
> #2 0x7f17ad7a8266 in mem_add (listener=0x7f17ae043968 
> , section=0x7f17a323c730) at /home/qemu/exec.c:1250
> #3 0x7f17ad7f843a in address_space_update_topology_pass 
> (as=0x7f17ae043920 , old_view=0x7f179c1f8b50, 
> new_view=0x7f179c523620, adding=true)
> at /home/qemu/memory.c:739
> #4 0x7f17ad7f8520 in address_space_update_topology (as=0x7f17ae043920 
> ) at /home/qemu/memory.c:754
> #5 0x7f17ad7f8660 in memory_region_transaction_commit () at 
> /home/qemu/memory.c:794
> #6 0x7f17ad9a690c in cirrus_update_memory_access (s=0x7f17b12873c0) at 
> hw/display/cirrus_vga.c:2485
> #7 0x7f17ad9a4dac in cirrus_vga_write_gr (s=0x7f17b12873c0, reg_index=9, 
> reg_value=163) at hw/display/cirrus_vga.c:1524
> #8 0x7f17ad9a6e47 in cirrus_vga_ioport_write (opaque=0x7f17b12873c0, 
> addr=975, val=163, size=1) at hw/display/cirrus_vga.c:2672
> #9 0x7f17ad7f6882 in memory_region_write_accessor (mr=0x7f17b1297d88, 
> addr=31, value=0x7f17a323c968, size=1, shift=8, mask=255) at 
> /home/qemu/memory.c:430
> #10 0x7f17ad7f698b in access_with_adjusted_size (addr=30, 
> value=0x7f17a323c968, size=2, access_size_min=1, access_size_max=1, 
> access=0x7f17ad7f67fd , mr=0x7f17b1297d88)
> at /home/qemu/memory.c:467
> #11 0x7f17ad7f9311 in memory_region_dispatch_write (mr=0x7f17b1297d88, 
> addr=30, data=41737, size=2) at /home/qemu/memory.c:1103
> #12 0x7f17ad7fc22e in io_mem_write (mr=0x7f17b1297d88, addr=30, 
> val=41737, size=2) at /home/qemu/memory.c:2003
> #13 0x7f17ad7aafe4 in address_space_rw (as=0x7f17ae043920 
> , addr=974, buf=0x7f17ad6f6000 "\t\243\320", len=2, 
> is_write=true) at /home/qemu/exec.c:2533
> #14 0x7f17ad7f3acf in kvm_handle_io (port=974, data=0x7f17ad6f6000, 
> direction=1, size=2, count=1) at /home/qemu/kvm-all.c:1707
> #15 0x7f17ad7f3fb5 in kvm_cpu_exec (cpu=0x7f17b05b7a20) at 
> /home/qemu/kvm-all.c:1864
> #16 0x7f17ad7db416 in qemu_kvm_cpu_thread_fn (arg=0x7f17b05b7a20) at 
> /home/qemu/cpus.c:972
> #17 0x7f17ac2cbdf5 in start_thread () from /lib64/libpthread.so.0
> #18 0x7f17a73e31ad in clone () from /lib64/libc.so.6
> 
> It seems that something wrong happened in vga memory updating.
> 

Another backtrace:

(gdb) bt
#0 int128_get64 (a=...) at /home/qemu/include/qemu/int128.h:27
#1 0x7f4cdefc1f6a in register_multipage (d=0x7f4cd012f1c0, 
section=0x7f4cd4a562c0) at /home/qemu/exec.c:1215
#2 0x7f4cdefc22b6 in mem_add (listener=0x7f4cdf85d968 
, section=0x7f4cd4a56600) at /home/qemu/exec.c:1250
#3 0x7f4cdf01248a in address_space_update_topology_pass (as=0x7f4cdf85d920 
, old_view=0x7f4cd0028d40, new_view=0x7f4cd015f5f0, 
adding=true)
at /home/qemu/memory.c:739
#4 0x7f4cdf012570 in address_space_update_topology (as=0x7f4cdf85d920 
) at /home/qemu/memory.c:754
#5 0x7f4cdf0126b0 in memory_region_transaction_commit () at 
/home/qemu/memory.c:794
#6 0x7f4cdf0151f0 in memory_region_del_subregion (mr=0x7f4ce01034e0, 
subregion=0x7f4ce13873a0) at /home/qemu/memory.c:1698
#7 0x7f4cdf21761d in pci_update_mappings (d=0x7f4ce1386f70) at 
hw/pci/pci.c:1120
#8 0x7f4cdf2179b0 in pci_default_write_config (d=0x7f4ce1386f70, addr=4, 
val_in=256, l=2) at hw/pci/pci.c:1180
#9 0x7f4cdf28d2d6 in virtio_write_config (pci_dev=0x7f4ce1386f70, 
address=4, val=256, len=2) at hw/virtio/virtio-pci.c:430
#10 0x7f4cdf220746 in pci_host_config_write_common (pci_dev=0x7f4ce1386f70, 
addr=4, limit=256, val=256, len=2) at hw/pci/pci_host.c:57
#11 0x7f4cdf22084a in pci_data_write (s=0x7f4ce008afc0, addr=2147489796, 
val=256, len=2) at hw/pci/pci_host.c:84
#12 0x7f4cdf22096c in pci_host_data_write (opaque=0x7f4ce00896b0, addr=0, 
val=256, len=2) at hw/pci/pci_host.c:137
#13 0x7f4cdf0108d2 in memory_region_write_accessor (mr=0x7f4ce0089ab0, 
addr=0, value=0x7f4cd4a56968, size=2, shift=0, mask=65535) at 
/home/qemu/memory.c:430
#14 0x7f4cdf0109db in access_with_adjusted_size (addr=0, 
value=0x7f4cd4a56968, size=2, access_size_min=1, access_size_max=4, 
access=0x7f4cdf01084d , mr=0x7f4ce0089ab0)
at /home/qemu/memory.c:467
#1

[Qemu-devel] [PATCH v6 12/14] iotests: 124 - transactional failure test

2015-09-14 Thread Fam Zheng
From: John Snow 

Use a transaction to request an incremental backup across two drives.
Coerce one of the jobs to fail, and then re-run the transaction.

Verify that no bitmap data was lost due to the partial transaction
failure.

To support the 'transactional-cancel' QMP argument name it's necessary
for transaction_action() to convert underscores in Python argument names
to hyphens for QMP argument names.

Signed-off-by: John Snow 
Reviewed-by: Max Reitz 
Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/124 | 130 -
 tests/qemu-iotests/124.out |   4 +-
 2 files changed, 130 insertions(+), 4 deletions(-)

diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index 9c1977e..33d00ef 100644
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -39,7 +39,7 @@ def try_remove(img):
 def transaction_action(action, **kwargs):
 return {
 'type': action,
-'data': kwargs
+'data': dict((k.replace('_', '-'), v) for k, v in kwargs.iteritems())
 }
 
 
@@ -139,9 +139,12 @@ class TestIncrementalBackup(iotests.QMPTestCase):
 def do_qmp_backup(self, error='Input/output error', **kwargs):
 res = self.vm.qmp('drive-backup', **kwargs)
 self.assert_qmp(res, 'return', {})
+return self.wait_qmp_backup(kwargs['device'], error)
 
+
+def wait_qmp_backup(self, device, error='Input/output error'):
 event = self.vm.event_wait(name="BLOCK_JOB_COMPLETED",
-   match={'data': {'device': 
kwargs['device']}})
+   match={'data': {'device': device}})
 self.assertNotEqual(event, None)
 
 try:
@@ -156,6 +159,12 @@ class TestIncrementalBackup(iotests.QMPTestCase):
 return False
 
 
+def wait_qmp_backup_cancelled(self, device):
+event = self.vm.event_wait(name='BLOCK_JOB_CANCELLED',
+   match={'data': {'device': device}})
+self.assertNotEqual(event, None)
+
+
 def create_anchor_backup(self, drive=None):
 if drive is None:
 drive = self.drives[-1]
@@ -375,6 +384,123 @@ class TestIncrementalBackup(iotests.QMPTestCase):
 self.check_backups()
 
 
+def test_transaction_failure(self):
+'''Test: Verify backups made from a transaction that partially fails.
+
+Add a second drive with its own unique pattern, and add a bitmap to 
each
+drive. Use blkdebug to interfere with the backup on just one drive and
+attempt to create a coherent incremental backup across both drives.
+
+verify a failure in one but not both, then delete the failed stubs and
+re-run the same transaction.
+
+verify that both incrementals are created successfully.
+'''
+
+# Create a second drive, with pattern:
+drive1 = self.add_node('drive1')
+self.img_create(drive1['file'], drive1['fmt'])
+io_write_patterns(drive1['file'], (('0x14', 0, 512),
+   ('0x5d', '1M', '32k'),
+   ('0xcd', '32M', '124k')))
+
+# Create a blkdebug interface to this img as 'drive1'
+result = self.vm.qmp('blockdev-add', options={
+'id': drive1['id'],
+'driver': drive1['fmt'],
+'file': {
+'driver': 'blkdebug',
+'image': {
+'driver': 'file',
+'filename': drive1['file']
+},
+'set-state': [{
+'event': 'flush_to_disk',
+'state': 1,
+'new_state': 2
+}],
+'inject-error': [{
+'event': 'read_aio',
+'errno': 5,
+'state': 2,
+'immediately': False,
+'once': True
+}],
+}
+})
+self.assert_qmp(result, 'return', {})
+
+# Create bitmaps and full backups for both drives
+drive0 = self.drives[0]
+dr0bm0 = self.add_bitmap('bitmap0', drive0)
+dr1bm0 = self.add_bitmap('bitmap0', drive1)
+self.create_anchor_backup(drive0)
+self.create_anchor_backup(drive1)
+self.assert_no_active_block_jobs()
+self.assertFalse(self.vm.get_qmp_events(wait=False))
+
+# Emulate some writes
+self.hmp_io_writes(drive0['id'], (('0xab', 0, 512),
+  ('0xfe', '16M', '256k'),
+  ('0x64', '32736k', '64k')))
+self.hmp_io_writes(drive1['id'], (('0xba', 0, 512),
+  ('0xef', '16M', '256k'),
+  ('0x46', '32736k', '64k')))
+
+# Create incremental backup targets
+target0 = self.prepare_backup(dr0bm0)
+target1 = s

Re: [Qemu-devel] virtio-gpu: cursor update not in sync with resource update

2015-09-14 Thread Gerd Hoffmann
  Hi,

> >> if (!ret) {
> >> reservation_object_add_excl_fence(qobj->tbo.resv,
> >>   &fence->f);
> >> virtio_gpu_object_wait(qobj, false);
> >> }
> >>
> >> before moving the cursor, shouldn't that suffice?
> >>
> >> Do we fail the transfer sometimes?
> >
> >
> > That's apparently not in Gerd tree.
> 
> Interesting, I'm not sure where this got lost,

Probably fallen through the cracks with the recent fence fixups.
I've added it back.

cheers,
  Gerd





Re: [Qemu-devel] [PATCH 1/2] PCI-e device multi-function hot-add support

2015-09-14 Thread Cao jin

Hi, Alex,
Thanks very much for your quick review and I am sorry for my late 
response.


On 09/10/2015 11:29 PM, Alex Williamson wrote:

On Thu, 2015-09-10 at 20:12 +0800, Cao jin wrote:

Enable PCI-e device multifunction hot, just ensure the function 0
added last, then driver will got the notification to scan all the
function in the slot.

Signed-off-by: Cao jin 
---
  hw/pci/pcie.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 6e28985..61ebefd 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -249,16 +249,20 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler 
*hotplug_dev, DeviceState *dev,
  return;
  }

-/* TODO: multifunction hot-plug.
- * Right now, only a device of function = 0 is allowed to be
- * hot plugged/unplugged.
+/* To enable multifunction hot-plug, we just ensure the function
+ * 0 added last. Until function 0 added, we set the sltsta and
+ * inform OS via event notification.
   */
-assert(PCI_FUNC(pci_dev->devfn) == 0);
-
-pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
-   PCI_EXP_SLTSTA_PDS);
-pcie_cap_slot_event(PCI_DEVICE(hotplug_dev),
-PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
+if (!(pci_dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) &&
+PCI_FUNC(pci_dev->devfn) > 0) {


The PCI spec is actually not entirely clear about whether each function
in a multifunction device needs to have the multifunction bit set or if
only function 0 needs to set it.  From a discovery perspective, a kernel
should only scan for function 0 and only scan non-zero funcions if
function 0 reports the multifunction bit set.  Therefore, it doesn't
particularly matter what non-zero functions report for the multifunction
bit.  QEMU allows either interpretation (see comment in
pci_init_multifunction), so this appears to be a new requirement that
breaks assumptions elsewhere.  Thanks,

Alex

Yes, PCI Spec does not describe it clearly. The if() here, is based on 
the condition like following:


  (qemu) device_add e1000,bus=pb1,id=net1,addr=00.1
  (qemu) device_add e1000,bus=pb1,id=net0,addr=00.0
  PCI: 0.0 indicates single function, but 0.1 is already populated.

Now, we can see the net1 via "info pci" while can`t see net1 in guest 
via "lspci -t", so I think maybe it is not good condition, but no big 
deal, so I use the if() to prevent the condition.


will remove the if() in next version.


+error_setg(errp, "single function device, function number must be 0,"
+"but got %d", PCI_FUNC(pci_dev->devfn));
+} else if (PCI_FUNC(pci_dev->devfn) == 0) {
+pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
+   PCI_EXP_SLTSTA_PDS);
+pcie_cap_slot_event(PCI_DEVICE(hotplug_dev),
+PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
+}
  }

  void pcie_cap_slot_hot_unplug_request_cb(HotplugHandler *hotplug_dev,




.



--
Yours Sincerely,

Cao Jin



[Qemu-devel] [PATCH v6 11/14] block/backup: support block job transactions

2015-09-14 Thread Fam Zheng
From: Stefan Hajnoczi 

Join the transaction when the 'transactional-cancel' QMP argument is
true.

This ensures that the sync bitmap is not thrown away if another block
job in the transaction is cancelled or fails.  This is critical so
incremental backup with multiple disks can be retried in case of
cancellation/failure.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/backup.c|  25 +++--
 blockdev.c| 132 +++---
 include/block/block_int.h |   3 +-
 qapi-schema.json  |   4 +-
 qapi/block-core.json  |  29 ++
 5 files changed, 155 insertions(+), 38 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 609b199..5880116 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -227,11 +227,29 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob 
*job, int ret)
 }
 }
 
+static void backup_commit(BlockJob *job)
+{
+BackupBlockJob *s = container_of(job, BackupBlockJob, common);
+if (s->sync_bitmap) {
+backup_cleanup_sync_bitmap(s, 0);
+}
+}
+
+static void backup_abort(BlockJob *job)
+{
+BackupBlockJob *s = container_of(job, BackupBlockJob, common);
+if (s->sync_bitmap) {
+backup_cleanup_sync_bitmap(s, -1);
+}
+}
+
 static const BlockJobDriver backup_job_driver = {
 .instance_size  = sizeof(BackupBlockJob),
 .job_type   = BLOCK_JOB_TYPE_BACKUP,
 .set_speed  = backup_set_speed,
 .iostatus_reset = backup_iostatus_reset,
+.commit = backup_commit,
+.abort  = backup_abort,
 };
 
 static BlockErrorAction backup_error_action(BackupBlockJob *job,
@@ -444,10 +462,6 @@ static void coroutine_fn backup_run(void *opaque)
 /* wait until pending backup_do_cow() calls have completed */
 qemu_co_rwlock_wrlock(&job->flush_rwlock);
 qemu_co_rwlock_unlock(&job->flush_rwlock);
-
-if (job->sync_bitmap) {
-backup_cleanup_sync_bitmap(job, ret);
-}
 hbitmap_free(job->bitmap);
 
 bdrv_iostatus_disable(target);
@@ -464,7 +478,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState 
*target,
   BlockdevOnError on_source_error,
   BlockdevOnError on_target_error,
   BlockCompletionFunc *cb, void *opaque,
-  Error **errp)
+  BlockJobTxn *txn, Error **errp)
 {
 int64_t len;
 
@@ -546,6 +560,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState 
*target,
sync_bitmap : NULL;
 job->common.len = len;
 job->common.co = qemu_coroutine_create(backup_run);
+block_job_txn_add_job(txn, &job->common);
 qemu_coroutine_enter(job->common.co, job);
 return;
 
diff --git a/blockdev.c b/blockdev.c
index 93a9eef..79207c8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1592,16 +1592,31 @@ typedef struct DriveBackupState {
 BlockJob *job;
 } DriveBackupState;
 
+static void do_drive_backup(const char *device, const char *target,
+bool has_format, const char *format,
+enum MirrorSyncMode sync,
+bool has_mode, enum NewImageMode mode,
+bool has_speed, int64_t speed,
+bool has_bitmap, const char *bitmap,
+bool has_on_source_error,
+BlockdevOnError on_source_error,
+bool has_on_target_error,
+BlockdevOnError on_target_error,
+BlockJobTxn *txn, Error **errp);
+
 static void drive_backup_prepare(BlkActionState *common, Error **errp)
 {
 DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
 BlockDriverState *bs;
 BlockBackend *blk;
+DriveBackupTxn *backup_txn;
 DriveBackup *backup;
+BlockJobTxn *txn = NULL;
 Error *local_err = NULL;
 
 assert(common->action->kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
-backup = common->action->drive_backup;
+backup_txn = common->action->drive_backup;
+backup = backup_txn->base;
 
 blk = blk_by_name(backup->device);
 if (!blk) {
@@ -1615,15 +1630,20 @@ static void drive_backup_prepare(BlkActionState 
*common, Error **errp)
 state->aio_context = bdrv_get_aio_context(bs);
 aio_context_acquire(state->aio_context);
 
-qmp_drive_backup(backup->device, backup->target,
- backup->has_format, backup->format,
- backup->sync,
- backup->has_mode, backup->mode,
- backup->has_speed, backup->speed,
- backup->has_bitmap, backup->bitmap,
- backup->has_on_source_error, backup->on_source_error,
- backup->has_on_target_error, backup->on_target_error,
- &local_err);
+if (backup_txn->has_transactional_cancel &&
+backup_txn->transactional_cancel) {
+

[Qemu-devel] [PATCH v6 09/14] block: Add block job transactions

2015-09-14 Thread Fam Zheng
Sometimes block jobs must execute as a transaction group.  Finishing
jobs wait until all other jobs are ready to complete successfully.
Failure or cancellation of one job cancels the other jobs in the group.

Signed-off-by: Stefan Hajnoczi 
[Rewrite the implementation which is now contained in block_job_completed.
--Fam]
Signed-off-by: Fam Zheng 
---
 blockjob.c   | 135 ++-
 include/block/block.h|   1 +
 include/block/blockjob.h |  38 +
 3 files changed, 172 insertions(+), 2 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 36c18e0..91e8d3c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -36,6 +36,19 @@
 #include "qemu/timer.h"
 #include "qapi-event.h"
 
+/* Transactional group of block jobs */
+struct BlockJobTxn {
+
+/* Is this txn being cancelled? */
+bool aborting;
+
+/* List of jobs */
+QLIST_HEAD(, BlockJob) jobs;
+
+/* Reference count */
+int refcnt;
+};
+
 void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
int64_t speed, BlockCompletionFunc *cb,
void *opaque, Error **errp)
@@ -90,6 +103,86 @@ void block_job_unref(BlockJob *job)
 }
 }
 
+static void block_job_completed_single(BlockJob *job)
+{
+if (!job->ret) {
+if (job->driver->commit) {
+job->driver->commit(job);
+}
+} else {
+if (job->driver->abort) {
+job->driver->abort(job);
+}
+}
+job->cb(job->opaque, job->ret);
+if (job->txn) {
+block_job_txn_unref(job->txn);
+}
+block_job_unref(job);
+}
+
+static void block_job_completed_txn_abort(BlockJob *job)
+{
+AioContext *ctx;
+BlockJobTxn *txn = job->txn;
+BlockJob *other_job, *next;
+
+if (txn->aborting) {
+/*
+ * We are cancelled by another job, which will handle everything.
+ */
+return;
+}
+txn->aborting = true;
+/* We are the first failed job. Cancel other jobs. */
+QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
+ctx = bdrv_get_aio_context(other_job->bs);
+aio_context_acquire(ctx);
+}
+QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
+if (other_job == job || other_job->completed) {
+/* Other jobs are "effectively" cancelled by us, set the status for
+ * them; this job, however, may or may not be cancelled, depending
+ * on the caller, so leave it. */
+if (other_job != job) {
+other_job->cancelled = true;
+}
+continue;
+}
+block_job_cancel_sync(other_job);
+assert(other_job->completed);
+}
+QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
+ctx = bdrv_get_aio_context(other_job->bs);
+block_job_completed_single(other_job);
+aio_context_release(ctx);
+}
+}
+
+static void block_job_completed_txn_success(BlockJob *job)
+{
+AioContext *ctx;
+BlockJobTxn *txn = job->txn;
+BlockJob *other_job, *next;
+/*
+ * Successful completion, see if there are other running jobs in this
+ * txn.
+ */
+QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
+if (!other_job->completed) {
+return;
+}
+}
+/* We are the last completed job, commit the transaction. */
+QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
+ctx = bdrv_get_aio_context(other_job->bs);
+aio_context_acquire(ctx);
+assert(other_job->ret == 0);
+block_job_completed_single(other_job);
+aio_context_release(ctx);
+}
+}
+
 void block_job_completed(BlockJob *job, int ret)
 {
 BlockDriverState *bs = job->bs;
@@ -98,8 +191,13 @@ void block_job_completed(BlockJob *job, int ret)
 assert(!job->completed);
 job->completed = true;
 job->ret = ret;
-job->cb(job->opaque, ret);
-block_job_unref(job);
+if (!job->txn) {
+block_job_completed_single(job);
+} else if (ret < 0 || block_job_is_cancelled(job)) {
+block_job_completed_txn_abort(job);
+} else {
+block_job_completed_txn_success(job);
+}
 }
 
 void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
@@ -398,3 +496,36 @@ void block_job_defer_to_main_loop(BlockJob *job,
 
 qemu_bh_schedule(data->bh);
 }
+
+BlockJobTxn *block_job_txn_new(void)
+{
+BlockJobTxn *txn = g_new0(BlockJobTxn, 1);
+QLIST_INIT(&txn->jobs);
+txn->refcnt = 1;
+return txn;
+}
+
+static void block_job_txn_ref(BlockJobTxn *txn)
+{
+txn->refcnt++;
+}
+
+void block_job_txn_unref(BlockJobTxn *txn)
+{
+if (--txn->refcnt == 0) {
+g_free(txn);
+}
+}
+
+void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
+{
+if (!txn) {
+return;
+}
+
+assert(!job->txn);
+job->txn = txn;
+
+QLIST_INSERT_HEAD(&txn->jobs, job, txn_list);
+block_job_txn_ref(txn);
+}
diff --git a/include/blo

[Qemu-devel] [PATCH v6 14/14] tests: add BlockJobTxn unit test

2015-09-14 Thread Fam Zheng
From: Stefan Hajnoczi 

The BlockJobTxn unit test verifies that both single jobs and pairs of
jobs behave as a transaction group.  Either all jobs complete
successfully or the group is cancelled.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 tests/Makefile|   3 +
 tests/test-blockjob-txn.c | 244 ++
 2 files changed, 247 insertions(+)
 create mode 100644 tests/test-blockjob-txn.c

diff --git a/tests/Makefile b/tests/Makefile
index 34c6136..89ce2f3 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -45,6 +45,8 @@ check-unit-y += tests/test-thread-pool$(EXESUF)
 gcov-files-test-thread-pool-y = thread-pool.c
 gcov-files-test-hbitmap-y = util/hbitmap.c
 check-unit-y += tests/test-hbitmap$(EXESUF)
+gcov-files-test-hbitmap-y = blockjob.c
+check-unit-y += tests/test-blockjob-txn$(EXESUF)
 check-unit-y += tests/test-x86-cpuid$(EXESUF)
 # all code tested by test-x86-cpuid is inside topology.h
 gcov-files-test-x86-cpuid-y =
@@ -294,6 +296,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o 
$(block-obj-y) libqemuutil
 tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a 
libqemustub.a
 tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o libqemuutil.a 
libqemustub.a
 tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) 
libqemuutil.a libqemustub.a
+tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(block-obj-y) 
libqemuutil.a libqemustub.a
 tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(block-obj-y) 
libqemuutil.a libqemustub.a
 tests/test-iov$(EXESUF): tests/test-iov.o libqemuutil.a
 tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o libqemuutil.a libqemustub.a
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
new file mode 100644
index 000..000f70e
--- /dev/null
+++ b/tests/test-blockjob-txn.c
@@ -0,0 +1,244 @@
+/*
+ * Blockjob transactions tests
+ *
+ * Copyright Red Hat, Inc. 2015
+ *
+ * Authors:
+ *  Stefan Hajnoczi
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include 
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "block/blockjob.h"
+
+typedef struct {
+BlockJob common;
+unsigned int iterations;
+bool use_timer;
+int rc;
+int *result;
+} TestBlockJob;
+
+static const BlockJobDriver test_block_job_driver = {
+.instance_size = sizeof(TestBlockJob),
+};
+
+static void test_block_job_complete(BlockJob *job, void *opaque)
+{
+BlockDriverState *bs = job->bs;
+int rc = (intptr_t)opaque;
+
+if (block_job_is_cancelled(job)) {
+rc = -ECANCELED;
+}
+
+block_job_completed(job, rc);
+bdrv_unref(bs);
+}
+
+static void coroutine_fn test_block_job_run(void *opaque)
+{
+TestBlockJob *s = opaque;
+BlockJob *job = &s->common;
+
+while (s->iterations--) {
+if (s->use_timer) {
+block_job_sleep_ns(job, QEMU_CLOCK_REALTIME, 0);
+} else {
+block_job_yield(job);
+}
+
+if (block_job_is_cancelled(job)) {
+break;
+}
+}
+
+block_job_defer_to_main_loop(job, test_block_job_complete,
+ (void *)(intptr_t)s->rc);
+}
+
+typedef struct {
+TestBlockJob *job;
+int *result;
+} TestBlockJobCBData;
+
+static void test_block_job_cb(void *opaque, int ret)
+{
+TestBlockJobCBData *data = opaque;
+if (!ret && block_job_is_cancelled(&data->job->common)) {
+ret = -ECANCELED;
+}
+*data->result = ret;
+g_free(data);
+}
+
+/* Create a block job that completes with a given return code after a given
+ * number of event loop iterations.  The return code is stored in the given
+ * result pointer.
+ *
+ * The event loop iterations can either be handled automatically with a 0 delay
+ * timer, or they can be stepped manually by entering the coroutine.
+ */
+static BlockJob *test_block_job_start(unsigned int iterations,
+  bool use_timer,
+  int rc, int *result)
+{
+BlockDriverState *bs;
+TestBlockJob *s;
+TestBlockJobCBData *data;
+
+data = g_new0(TestBlockJobCBData, 1);
+bs = bdrv_new();
+s = block_job_create(&test_block_job_driver, bs, 0, test_block_job_cb,
+ data, &error_abort);
+s->iterations = iterations;
+s->use_timer = use_timer;
+s->rc = rc;
+s->result = result;
+s->common.co = qemu_coroutine_create(test_block_job_run);
+data->job = s;
+data->result = result;
+qemu_coroutine_enter(s->common.co, s);
+return &s->common;
+}
+
+static void test_single_job(int expected)
+{
+BlockJob *job;
+BlockJobTxn *txn;
+int result = -EINPROGRESS;
+
+txn = block_job_txn_new();
+job = test_block_job_start(1, true, expected, &result);
+block_job_txn_add_job(txn, job);
+
+if (expec

[Qemu-devel] [PATCH v6 10/14] blockdev: make BlockJobTxn available to qmp 'transaction'

2015-09-14 Thread Fam Zheng
From: Stefan Hajnoczi 

Provide a BlockJobTxn to actions executed in a qmp 'transaction'
command.  This allows actions to make their block jobs either complete
as a group or fail/cancel together.

The next patch adds the first user.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Fam Zheng 
Reviewed-by: John Snow 
Signed-off-by: Fam Zheng 
---
 blockdev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/blockdev.c b/blockdev.c
index 4ebded8..93a9eef 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1285,6 +1285,7 @@ typedef struct BlkActionOps {
 struct BlkActionState {
 TransactionAction *action;
 const BlkActionOps *ops;
+BlockJobTxn *block_job_txn;
 QSIMPLEQ_ENTRY(BlkActionState) entry;
 };
 
@@ -1889,12 +1890,15 @@ static const BlkActionOps actions[] = {
 void qmp_transaction(TransactionActionList *dev_list, Error **errp)
 {
 TransactionActionList *dev_entry = dev_list;
+BlockJobTxn *block_job_txn;
 BlkActionState *state, *next;
 Error *local_err = NULL;
 
 QSIMPLEQ_HEAD(snap_bdrv_states, BlkActionState) snap_bdrv_states;
 QSIMPLEQ_INIT(&snap_bdrv_states);
 
+block_job_txn = block_job_txn_new();
+
 /* drain all i/o before any operations */
 bdrv_drain_all();
 
@@ -1914,6 +1918,7 @@ void qmp_transaction(TransactionActionList *dev_list, 
Error **errp)
 state = g_malloc0(ops->instance_size);
 state->ops = ops;
 state->action = dev_info;
+state->block_job_txn = block_job_txn;
 QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry);
 
 state->ops->prepare(state, &local_err);
@@ -1946,6 +1951,7 @@ exit:
 }
 g_free(state);
 }
+block_job_txn_unref(block_job_txn);
 }
 
 
-- 
2.4.3




[Qemu-devel] [PATCH v6 07/14] blockjob: Add "completed" and "ret" in BlockJob

2015-09-14 Thread Fam Zheng
They are set when block_job_completed is called.

Signed-off-by: Fam Zheng 
Reviewed-by: John Snow 
Reviewed-by: Max Reitz 
---
 blockjob.c   | 3 +++
 include/block/blockjob.h | 9 +
 2 files changed, 12 insertions(+)

diff --git a/blockjob.c b/blockjob.c
index ec12887..293b62a 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -95,6 +95,9 @@ void block_job_completed(BlockJob *job, int ret)
 BlockDriverState *bs = job->bs;
 
 assert(bs->job == job);
+assert(!job->completed);
+job->completed = true;
+job->ret = ret;
 job->cb(job->opaque, ret);
 block_job_unref(job);
 }
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index a7b497c..f6e4c86 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -143,6 +143,15 @@ struct BlockJob {
 
 /** Reference count of the block job */
 int refcnt;
+
+/* True if this job has reported completion by calling block_job_completed.
+ */
+bool completed;
+
+/* ret code passed to block_job_completed.
+ */
+int ret;
+
 };
 
 /**
-- 
2.4.3




[Qemu-devel] [PATCH v6 08/14] blockjob: Simplify block_job_finish_sync

2015-09-14 Thread Fam Zheng
With job->completed and job->ret to replace BlockFinishData.

Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 blockjob.c | 27 ++-
 1 file changed, 6 insertions(+), 21 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 293b62a..36c18e0 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -185,43 +185,28 @@ struct BlockFinishData {
 int ret;
 };
 
-static void block_job_finish_cb(void *opaque, int ret)
-{
-struct BlockFinishData *data = opaque;
-
-data->cancelled = block_job_is_cancelled(data->job);
-data->ret = ret;
-data->cb(data->opaque, ret);
-}
-
 static int block_job_finish_sync(BlockJob *job,
  void (*finish)(BlockJob *, Error **errp),
  Error **errp)
 {
-struct BlockFinishData data;
 BlockDriverState *bs = job->bs;
 Error *local_err = NULL;
+int ret;
 
 assert(bs->job == job);
 
-/* Set up our own callback to store the result and chain to
- * the original callback.
- */
-data.job = job;
-data.cb = job->cb;
-data.opaque = job->opaque;
-data.ret = -EINPROGRESS;
-job->cb = block_job_finish_cb;
-job->opaque = &data;
+block_job_ref(job);
 finish(job, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return -EBUSY;
 }
-while (data.ret == -EINPROGRESS) {
+while (!job->completed) {
 aio_poll(bdrv_get_aio_context(bs), true);
 }
-return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
+ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret;
+block_job_unref(job);
+return ret;
 }
 
 /* A wrapper around block_job_cancel() taking an Error ** parameter so it may 
be
-- 
2.4.3




[Qemu-devel] [PATCH v6 13/14] qmp-commands.hx: Update the supported 'transaction' operations

2015-09-14 Thread Fam Zheng
From: Kashyap Chamarthy 

Although the canonical source of reference for QMP commands is
qapi-schema.json, for consistency's sake, update qmp-commands.hx to
state the list of supported transactionable operations, namely:

drive-backup
blockdev-backup
blockdev-snapshot-internal-sync
abort
block-dirty-bitmap-add
block-dirty-bitmap-clear

Signed-off-by: Kashyap Chamarthy 
Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
Signed-off-by: John Snow 
Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 qmp-commands.hx | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/qmp-commands.hx b/qmp-commands.hx
index 9848fd8..4df59df 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1263,11 +1263,22 @@ SQMP
 transaction
 ---
 
-Atomically operate on one or more block devices.  The only supported operations
-for now are drive-backup, internal and external snapshotting.  A list of
-dictionaries is accepted, that contains the actions to be performed.
-If there is any failure performing any of the operations, all operations
-for the group are abandoned.
+Atomically operate on one or more block devices.  Operations that are
+currently supported:
+
+- drive-backup
+- blockdev-backup
+- blockdev-snapshot-sync
+- blockdev-snapshot-internal-sync
+- abort
+- block-dirty-bitmap-add
+- block-dirty-bitmap-clear
+
+Refer to the qemu/qapi-schema.json file for minimum required QEMU
+versions for these operations.  A list of dictionaries is accepted,
+that contains the actions to be performed.  If there is any failure
+performing any of the operations, all operations for the group are
+abandoned.
 
 For external snapshots, the dictionary contains the device, the file to use for
 the new snapshot, and the format.  The default format, if not specified, is
-- 
2.4.3




Re: [Qemu-devel] [PATCH] q35: Remove old machine versions

2015-09-14 Thread Markus Armbruster
Eduardo Habkost  writes:

> On Mon, Sep 14, 2015 at 09:09:12AM -0600, Eric Blake wrote:
>> On 09/13/2015 03:28 AM, Michael S. Tsirkin wrote:
>> > On Fri, Sep 11, 2015 at 03:44:47PM -0300, Eduardo Habkost wrote:
>> >> Ping?
>> >>
>> >> So, what's the reason we are still keeping those old machines in the
>> >> code?
>> > 
>> > Victor also wanted to clean out some very old machine types for
>> > the PIIX, too.
>> > 
>> > But if someone created a machine with libvirt, these machine types
>> > are now written in the XML. Failing to start guests isn't nice.
>> 
>> New qemu with old libvirt isn't always guaranteed to work. And new
>> libvirt can be patched to automatically update any old hard-coded
>> machine name to a newer safe alternative, _when such update is proven
>> safe_ (we've done it in the past for Fedora: if I recall correctly,
>> Fedora 13 branched its own machine type, then in Fedora 15 qemu decided
>> to quit supporting the branch, so libvirt was patched downstream in
>> Fedora 15-17 to rewrite the old name into its safe upstream counterpart.
>>  The downstream patch was dropped in Fedora 18 since F15 was EOL by then
>> so no more new machines would have been created with the old spelling,
>> and since a year was deemed long enough for people to have either run
>> their guest to pick up the automatic update, or that their guest was so
>> infrequently run that they could read the error message and act on it
>> themselves).
>> 
>> Failing to start guests isn't nice, but it also isn't the end of the
>> world, when there is no choice but to break ABI.  An explicit ABI break
>> (by making the user rewrite machine type) is better than silent change
>> in behavior with a potential for broken guests.
>
> What I get from this, is that this is an user interface and usability
> problem, and it's better to solve it at the appropriate layer (which is
> not QEMU).
>
> If QEMU can't emulate those machines anymore, QEMU's job is to just tell
> that to libvirt (so libvirt and management layers can decide what's the
> best way to help the user cope with it), instead of lying to them and
> say that we still emulate the same machine when we actually don't.

Seconded.

The story for direct use by humans is at least as convincing.



[Qemu-devel] [PATCH v6 06/14] blockjob: Add .commit and .abort block job actions

2015-09-14 Thread Fam Zheng
Reviewed-by: Max Reitz 
Signed-off-by: Fam Zheng 
---
 include/block/blockjob.h | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 3e7ad21..a7b497c 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -50,6 +50,24 @@ typedef struct BlockJobDriver {
  * manually.
  */
 void (*complete)(BlockJob *job, Error **errp);
+
+/**
+ * If the callback is not NULL, it will be invoked when all the jobs
+ * belonging to the same transaction complete; or upon this job's
+ * completion if it is not in a transaction. Skipped if NULL.
+ *
+ * Exactly one of .commit() and .abort() will be called for each job.
+ */
+void (*commit)(BlockJob *job);
+
+/**
+ * If the callback is not NULL, it will be invoked when any job in the
+ * same transaction fails; or upon this job's failure (due to error or
+ * cancellation) if it is not in a transaction. Skipped if NULL.
+ *
+ * Exactly one of .commit() and .abort() will be called for each job.
+ */
+void (*abort)(BlockJob *job);
 } BlockJobDriver;
 
 /**
-- 
2.4.3




[Qemu-devel] iotests failure of 128

2015-09-14 Thread Fam Zheng
Since commit 934659c460d46c948cf348822fda1d38556ed9a4 (iotests: Do not suppress
segfaults in bash tests), sudo in 128 complains about unknown command
"_qemu_io_wrapper", but I don't know how to fix that. Any idea?

128 - output mismatch (see 128.out.bad)
--- /home/fam/qemu/tests/qemu-iotests/128.out   2015-09-15 11:08:07.407819420 
+0800
+++ 128.out.bad 2015-09-15 13:58:56.547396610 +0800
@@ -1,5 +1,5 @@
 QA output created by 128
 
 == reading from error device ==
-read failed: Input/output error
+sudo: _qemu_io_wrapper: command not found
 *** done
Failures: 128
Failed 1 of 1 tests



[Qemu-devel] [PATCH v6 05/14] blockjob: Introduce reference count

2015-09-14 Thread Fam Zheng
So that block_job_complete_sync can be simplified.

Reviewed-by: Max Reitz 
Signed-off-by: Fam Zheng 
---
 block/mirror.c   |  2 +-
 blockjob.c   | 22 ++
 include/block/blockjob.h | 18 +++---
 3 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index a258926..3472ad4 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -736,7 +736,7 @@ static void mirror_start_job(BlockDriverState *bs, 
BlockDriverState *target,
 s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
 if (!s->dirty_bitmap) {
 g_free(s->replaces);
-block_job_release(bs);
+block_job_unref(&s->common);
 return;
 }
 bdrv_set_enable_write_cache(s->target, true);
diff --git a/blockjob.c b/blockjob.c
index 62bb906..ec12887 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -58,6 +58,7 @@ void *block_job_create(const BlockJobDriver *driver, 
BlockDriverState *bs,
 job->cb= cb;
 job->opaque= opaque;
 job->busy  = true;
+job->refcnt= 1;
 bs->job = job;
 
 /* Only set speed when necessary to avoid NotSupported error */
@@ -66,7 +67,7 @@ void *block_job_create(const BlockJobDriver *driver, 
BlockDriverState *bs,
 
 block_job_set_speed(job, speed, &local_err);
 if (local_err) {
-block_job_release(bs);
+block_job_unref(job);
 error_propagate(errp, local_err);
 return NULL;
 }
@@ -74,14 +75,19 @@ void *block_job_create(const BlockJobDriver *driver, 
BlockDriverState *bs,
 return job;
 }
 
-void block_job_release(BlockDriverState *bs)
+void block_job_ref(BlockJob *job)
 {
-BlockJob *job = bs->job;
+++job->refcnt;
+}
 
-bs->job = NULL;
-bdrv_op_unblock_all(bs, job->blocker);
-error_free(job->blocker);
-g_free(job);
+void block_job_unref(BlockJob *job)
+{
+if (--job->refcnt == 0) {
+job->bs->job = NULL;
+bdrv_op_unblock_all(job->bs, job->blocker);
+error_free(job->blocker);
+g_free(job);
+}
 }
 
 void block_job_completed(BlockJob *job, int ret)
@@ -90,7 +96,7 @@ void block_job_completed(BlockJob *job, int ret)
 
 assert(bs->job == job);
 job->cb(job->opaque, ret);
-block_job_release(bs);
+block_job_unref(job);
 }
 
 void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index dd9d5e6..3e7ad21 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -122,6 +122,9 @@ struct BlockJob {
 
 /** The opaque value that is passed to the completion function.  */
 void *opaque;
+
+/** Reference count of the block job */
+int refcnt;
 };
 
 /**
@@ -166,12 +169,21 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType 
type, int64_t ns);
 void block_job_yield(BlockJob *job);
 
 /**
- * block_job_release:
+ * block_job_ref:
  * @bs: The block device.
  *
- * Release job resources when an error occurred or job completed.
+ * Grab a reference to the block job. Should be paired with block_job_unref.
  */
-void block_job_release(BlockDriverState *bs);
+void block_job_ref(BlockJob *job);
+
+/**
+ * block_job_unref:
+ * @bs: The block device.
+ *
+ * Release reference to the block job and release resources if it is the last
+ * reference.
+ */
+void block_job_unref(BlockJob *job);
 
 /**
  * block_job_completed:
-- 
2.4.3




[Qemu-devel] [PATCH v6 03/14] block: rename BlkTransactionState and BdrvActionOps

2015-09-14 Thread Fam Zheng
From: John Snow 

These structures are misnomers, somewhat.

(1) BlockTransactionState is not state for a transaction,
but is rather state for a single transaction action.
Rename it "BlkActionState" to be more accurate.

(2) The BdrvActionOps describes operations for the BlkActionState,
above. This name might imply a 'BdrvAction' or a 'BdrvActionState',
which there isn't.
Rename this to 'BlkActionOps' to match 'BlkActionState'.

Lastly, update the surrounding in-line documentation and comments
to reflect the current nature of how Transactions operate.

This patch changes only comments and names, and should not affect
behavior in any way.

Signed-off-by: John Snow 
Reviewed-by: Max Reitz 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Fam Zheng 
Signed-off-by: Fam Zheng 
---
 blockdev.c | 116 ++---
 1 file changed, 65 insertions(+), 51 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index b1e7f2a..4ebded8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1246,43 +1246,57 @@ static BdrvDirtyBitmap *block_dirty_bitmap_lookup(const 
char *node,
 
 /* New and old BlockDriverState structs for atomic group operations */
 
-typedef struct BlkTransactionState BlkTransactionState;
+typedef struct BlkActionState BlkActionState;
 
-/* Only prepare() may fail. In a single transaction, only one of commit() or
-   abort() will be called, clean() will always be called if it present. */
-typedef struct BdrvActionOps {
-/* Size of state struct, in bytes. */
+/**
+ * BlkActionOps:
+ * Table of operations that define an Action.
+ *
+ * @instance_size: Size of state struct, in bytes.
+ * @prepare: Prepare the work, must NOT be NULL.
+ * @commit: Commit the changes, can be NULL.
+ * @abort: Abort the changes on fail, can be NULL.
+ * @clean: Clean up resources after all transaction actions have called
+ * commit() or abort(). Can be NULL.
+ *
+ * Only prepare() may fail. In a single transaction, only one of commit() or
+ * abort() will be called. clean() will always be called if it is present.
+ */
+typedef struct BlkActionOps {
 size_t instance_size;
-/* Prepare the work, must NOT be NULL. */
-void (*prepare)(BlkTransactionState *common, Error **errp);
-/* Commit the changes, can be NULL. */
-void (*commit)(BlkTransactionState *common);
-/* Abort the changes on fail, can be NULL. */
-void (*abort)(BlkTransactionState *common);
-/* Clean up resource in the end, can be NULL. */
-void (*clean)(BlkTransactionState *common);
-} BdrvActionOps;
+void (*prepare)(BlkActionState *common, Error **errp);
+void (*commit)(BlkActionState *common);
+void (*abort)(BlkActionState *common);
+void (*clean)(BlkActionState *common);
+} BlkActionOps;
 
-/*
- * This structure must be arranged as first member in child type, assuming
- * that compiler will also arrange it to the same address with parent instance.
- * Later it will be used in free().
+/**
+ * BlkActionState:
+ * Describes one Action's state within a Transaction.
+ *
+ * @action: QAPI-defined enum identifying which Action to perform.
+ * @ops: Table of ActionOps this Action can perform.
+ * @entry: List membership for all Actions in this Transaction.
+ *
+ * This structure must be arranged as first member in a subclassed type,
+ * assuming that the compiler will also arrange it to the same offsets as the
+ * base class.
  */
-struct BlkTransactionState {
+struct BlkActionState {
 TransactionAction *action;
-const BdrvActionOps *ops;
-QSIMPLEQ_ENTRY(BlkTransactionState) entry;
+const BlkActionOps *ops;
+QSIMPLEQ_ENTRY(BlkActionState) entry;
 };
 
 /* internal snapshot private data */
 typedef struct InternalSnapshotState {
-BlkTransactionState common;
+BlkActionState common;
 BlockDriverState *bs;
 AioContext *aio_context;
 QEMUSnapshotInfo sn;
 } InternalSnapshotState;
 
-static void internal_snapshot_prepare(BlkTransactionState *common,
+static void internal_snapshot_prepare(BlkActionState *common,
   Error **errp)
 {
 Error *local_err = NULL;
@@ -1378,7 +1392,7 @@ static void internal_snapshot_prepare(BlkTransactionState 
*common,
 state->bs = bs;
 }
 
-static void internal_snapshot_abort(BlkTransactionState *common)
+static void internal_snapshot_abort(BlkActionState *common)
 {
 InternalSnapshotState *state =
  DO_UPCAST(InternalSnapshotState, common, common);
@@ -1401,7 +1415,7 @@ static void internal_snapshot_abort(BlkTransactionState 
*common)
 }
 }
 
-static void internal_snapshot_clean(BlkTransactionState *common)
+static void internal_snapshot_clean(BlkActionState *common)
 {
 InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState,
  common, common);
@@ -1413,13 +1427,13 @@ static void internal_snapshot_clean(BlkTransactionState 
*common)
 
 

[Qemu-devel] [PATCH v6 02/14] iotests: add transactional incremental backup test

2015-09-14 Thread Fam Zheng
From: John Snow 

Test simple usage cases for using transactions to create
and synchronize incremental backups.

Signed-off-by: John Snow 
Reviewed-by: Max Reitz 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Fam Zheng 
Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/124 | 54 ++
 tests/qemu-iotests/124.out |  4 ++--
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index 9ccd118..9c1977e 100644
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -36,6 +36,23 @@ def try_remove(img):
 pass
 
 
+def transaction_action(action, **kwargs):
+return {
+'type': action,
+'data': kwargs
+}
+
+
+def transaction_bitmap_clear(node, name, **kwargs):
+return transaction_action('block-dirty-bitmap-clear',
+  node=node, name=name, **kwargs)
+
+
+def transaction_drive_backup(device, target, **kwargs):
+return transaction_action('drive-backup', device=device, target=target,
+  **kwargs)
+
+
 class Bitmap:
 def __init__(self, name, drive):
 self.name = name
@@ -264,6 +281,43 @@ class TestIncrementalBackup(iotests.QMPTestCase):
 return self.do_incremental_simple(granularity=131072)
 
 
+def test_incremental_transaction(self):
+'''Test: Verify backups made from transactionally created bitmaps.
+
+Create a bitmap "before" VM execution begins, then create a second
+bitmap AFTER writes have already occurred. Use transactions to create
+a full backup and synchronize both bitmaps to this backup.
+Create an incremental backup through both bitmaps and verify that
+both backups match the current drive0 image.
+'''
+
+drive0 = self.drives[0]
+bitmap0 = self.add_bitmap('bitmap0', drive0)
+self.hmp_io_writes(drive0['id'], (('0xab', 0, 512),
+  ('0xfe', '16M', '256k'),
+  ('0x64', '32736k', '64k')))
+bitmap1 = self.add_bitmap('bitmap1', drive0)
+
+result = self.vm.qmp('transaction', actions=[
+transaction_bitmap_clear(bitmap0.drive['id'], bitmap0.name),
+transaction_bitmap_clear(bitmap1.drive['id'], bitmap1.name),
+transaction_drive_backup(drive0['id'], drive0['backup'],
+ sync='full', format=drive0['fmt'])
+])
+self.assert_qmp(result, 'return', {})
+self.wait_until_completed(drive0['id'])
+self.files.append(drive0['backup'])
+
+self.hmp_io_writes(drive0['id'], (('0x9a', 0, 512),
+  ('0x55', '8M', '352k'),
+  ('0x78', '15872k', '1M')))
+# Both bitmaps should be correctly in sync.
+self.create_incremental(bitmap0)
+self.create_incremental(bitmap1)
+self.vm.shutdown()
+self.check_backups()
+
+
 def test_incremental_failure(self):
 '''Test: Verify backups made after a failure are correct.
 
diff --git a/tests/qemu-iotests/124.out b/tests/qemu-iotests/124.out
index 2f7d390..594c16f 100644
--- a/tests/qemu-iotests/124.out
+++ b/tests/qemu-iotests/124.out
@@ -1,5 +1,5 @@
-...
+
 --
-Ran 7 tests
+Ran 8 tests
 
 OK
-- 
2.4.3




Re: [Qemu-devel] [PATCH v8 0/7] sPAPR: Support EEH Error Injection

2015-09-14 Thread Thomas Huth
On 14/09/15 06:14, David Gibson wrote:
> On Mon, Sep 14, 2015 at 11:36:08AM +1000, Gavin Shan wrote:
>> The patchset depends on below Linux upstream commits:
>>
>>   commit ed3e81f ("powerpc/eeh: Move PE state constants around")
>>   commit ec33d36 ("powerpc/eeh: Introduce eeh_pe_inject_err()")
>>
>> According to PAPR specification 2.7, there're 3 RTAS calls relevent to error
>> injection: "ibm,open-errinjct", "ibm,close-errinjct", "ibm,errinjct". The
>> userland utility "errinjct" running on guest utilizes those 3 RTAS calls like
>> this way: Call "ibm,open-errinjct" that returns open-token, which is passed 
>> to
>> "ibm,errinjct" together with error specific arguments to do error injection.
>> Finally, to return the open-token by calling "ibm,close-errinject".
>>
>> "ibm,errinjct" can be used to inject various errors, not limited to EEH 
>> errors.
>> However, this patchset is going to support injecting EEH errors only for VFIO
>> PCI devices.
> 
> I'm happy to merge 6..7/7 once 1..5/7 are in - I'm not sure what tree
> they should be going through.

According to the MAINTAINERS file, there is no explicit maintainer for
the linux-headers directory ... so I think you should maybe try to get
an "Acked-by" from Jan Kiszka (for the update-linux-header script)
and/or Michael Tsirkin (for the PCI stuff) and then take this through
your tree?

 Thomas




signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v6 01/14] qapi: Add transaction support to block-dirty-bitmap operations

2015-09-14 Thread Fam Zheng
From: John Snow 

This adds two qmp commands to transactions.

block-dirty-bitmap-add allows you to create a bitmap simultaneously
alongside a new full backup to accomplish a clean synchronization
point.

block-dirty-bitmap-clear allows you to reset a bitmap back to as-if
it were new, which can also be used alongside a full backup to
accomplish a clean synchronization point.

Signed-off-by: Fam Zheng 
Signed-off-by: John Snow 
Reviewed-by: Max Reitz 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block.c   |  19 +++-
 blockdev.c| 114 +-
 docs/bitmaps.md   |   6 +--
 include/block/block.h |   1 -
 include/block/block_int.h |   3 ++
 qapi-schema.json  |   6 ++-
 6 files changed, 139 insertions(+), 10 deletions(-)

diff --git a/block.c b/block.c
index cb5d7ae..35881e3 100644
--- a/block.c
+++ b/block.c
@@ -3566,10 +3566,25 @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
 }
 
-void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap)
+void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
 {
 assert(bdrv_dirty_bitmap_enabled(bitmap));
-hbitmap_reset_all(bitmap->bitmap);
+if (!out) {
+hbitmap_reset_all(bitmap->bitmap);
+} else {
+HBitmap *backup = bitmap->bitmap;
+bitmap->bitmap = hbitmap_alloc(bitmap->size,
+   hbitmap_granularity(backup));
+*out = backup;
+}
+}
+
+void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
+{
+HBitmap *tmp = bitmap->bitmap;
+assert(bdrv_dirty_bitmap_enabled(bitmap));
+bitmap->bitmap = in;
+hbitmap_free(tmp);
 }
 
 void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
diff --git a/blockdev.c b/blockdev.c
index 6b48be6..b1e7f2a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1714,6 +1714,106 @@ static void blockdev_backup_clean(BlkTransactionState 
*common)
 }
 }
 
+typedef struct BlockDirtyBitmapState {
+BlkTransactionState common;
+BdrvDirtyBitmap *bitmap;
+BlockDriverState *bs;
+AioContext *aio_context;
+HBitmap *backup;
+bool prepared;
+} BlockDirtyBitmapState;
+
+static void block_dirty_bitmap_add_prepare(BlkTransactionState *common,
+   Error **errp)
+{
+Error *local_err = NULL;
+BlockDirtyBitmapAdd *action;
+BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
+ common, common);
+
+action = common->action->block_dirty_bitmap_add;
+/* AIO context taken and released within qmp_block_dirty_bitmap_add */
+qmp_block_dirty_bitmap_add(action->node, action->name,
+   action->has_granularity, action->granularity,
+   &local_err);
+
+if (!local_err) {
+state->prepared = true;
+} else {
+error_propagate(errp, local_err);
+}
+}
+
+static void block_dirty_bitmap_add_abort(BlkTransactionState *common)
+{
+BlockDirtyBitmapAdd *action;
+BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
+ common, common);
+
+action = common->action->block_dirty_bitmap_add;
+/* Should not be able to fail: IF the bitmap was added via .prepare(),
+ * then the node reference and bitmap name must have been valid.
+ */
+if (state->prepared) {
+qmp_block_dirty_bitmap_remove(action->node, action->name, 
&error_abort);
+}
+}
+
+static void block_dirty_bitmap_clear_prepare(BlkTransactionState *common,
+ Error **errp)
+{
+BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
+ common, common);
+BlockDirtyBitmap *action;
+
+action = common->action->block_dirty_bitmap_clear;
+state->bitmap = block_dirty_bitmap_lookup(action->node,
+  action->name,
+  &state->bs,
+  &state->aio_context,
+  errp);
+if (!state->bitmap) {
+return;
+}
+
+if (bdrv_dirty_bitmap_frozen(state->bitmap)) {
+error_setg(errp, "Cannot modify a frozen bitmap");
+return;
+} else if (!bdrv_dirty_bitmap_enabled(state->bitmap)) {
+error_setg(errp, "Cannot clear a disabled bitmap");
+return;
+}
+
+bdrv_clear_dirty_bitmap(state->bitmap, &state->backup);
+/* AioContext is released in .clean() */
+}
+
+static void block_dirty_bitmap_clear_abort(BlkTransactionState *common)
+{
+BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
+ common, common);
+
+bdrv_undo_clear_dirty_bitmap(st

[Qemu-devel] [PATCH v6 04/14] backup: Extract dirty bitmap handling as a separate function

2015-09-14 Thread Fam Zheng
This will be reused by the coming new transactional completion code.

Signed-off-by: Fam Zheng 
Reviewed-by: John Snow 
---
 block/backup.c | 27 +--
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 965654d..609b199 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -211,6 +211,22 @@ static void backup_iostatus_reset(BlockJob *job)
 bdrv_iostatus_reset(s->target);
 }
 
+static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
+{
+BdrvDirtyBitmap *bm;
+BlockDriverState *bs = job->common.bs;
+
+if (ret < 0 || block_job_is_cancelled(&job->common)) {
+/* Merge the successor back into the parent, delete nothing. */
+bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
+assert(bm);
+} else {
+/* Everything is fine, delete this bitmap and install the backup. */
+bm = bdrv_dirty_bitmap_abdicate(bs, job->sync_bitmap, NULL);
+assert(bm);
+}
+}
+
 static const BlockJobDriver backup_job_driver = {
 .instance_size  = sizeof(BackupBlockJob),
 .job_type   = BLOCK_JOB_TYPE_BACKUP,
@@ -430,16 +446,7 @@ static void coroutine_fn backup_run(void *opaque)
 qemu_co_rwlock_unlock(&job->flush_rwlock);
 
 if (job->sync_bitmap) {
-BdrvDirtyBitmap *bm;
-if (ret < 0 || block_job_is_cancelled(&job->common)) {
-/* Merge the successor back into the parent, delete nothing. */
-bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
-assert(bm);
-} else {
-/* Everything is fine, delete this bitmap and install the backup. 
*/
-bm = bdrv_dirty_bitmap_abdicate(bs, job->sync_bitmap, NULL);
-assert(bm);
-}
+backup_cleanup_sync_bitmap(job, ret);
 }
 hbitmap_free(job->bitmap);
 
-- 
2.4.3




[Qemu-devel] [PATCH v6 00/14] block: incremental backup transactions using BlockJobTxn

2015-09-14 Thread Fam Zheng
v6: Address comments from Max and Eric (many thanks for reviewing!):
Add Max's reviews.
Don't leak txn. [Max]
Unusual comment ending "**/" -> "*/". [Eric]
Fix the stale block_job_txn_prepare_to_complete comment. [Max]
Move "block_job_txn_unref" to below FOREACH block. [Max]
Split "base" and "txn" in qapi schema, so that transactional-cancel is only
visible in transaction. [Eric]

v5: Address comments from Max Reitz:
2.4 -> 2.5 in qapi docs.
Don't leak txn object.
English syntax fixes.
Really leave the "cancelled" status of failed job.
Remove a superfluous added line.

v4: Address comments from John and Stefan, including:
Rename function: backup_cleanup_sync_bitmap.
Rename and add comments for .commit and .abort.
Call .commit and .abort for both txn and non-txn.
Drop patch 9 in v3.
Improve the txn implementation. Acquire context locks as accessing them.
Add refcnt patch for BlockJob.
Adjust txn unit test code.

This is based on top of the work by Stefan Hajnoczi and John Snow.

Recap: motivation for block job transactions

If an incremental backup block job fails then we reclaim the bitmap so
the job can be retried.  The problem comes when multiple jobs are started as
part of a qmp 'transaction' command.  We need to group these jobs in a
transaction so that either all jobs complete successfully or all bitmaps are
reclaimed.

Without transactions, there is a case where some jobs complete successfully and
throw away their bitmaps, making it impossible to retry the backup by rerunning
the command if one of the jobs fails.

How does this implementation work?
--
These patches add a BlockJobTxn object with the following API:

  txn = block_job_txn_new();
  block_job_txn_add_job(txn, job1);
  block_job_txn_add_job(txn, job2);

The jobs either both complete successfully or they both fail/cancel.  If the
user cancels job1 then job2 will also be cancelled and vice versa.

Jobs objects stay alive waiting for other jobs to complete, even if the
coroutines have returned.  They can be cancelled by the user during this time.
Job blockers are still in effect and no other block job can run on this device
in the meantime (since QEMU currently only allows 1 job per device).  This is
the main drawback to this approach but reasonable since you probably don't want
to run other jobs/operations until you're sure the backup was successful (you
won't be able to retry a failed backup if there's a new job running).


Fam Zheng (6):
  backup: Extract dirty bitmap handling as a separate function
  blockjob: Introduce reference count
  blockjob: Add .commit and .abort block job actions
  blockjob: Add "completed" and "ret" in BlockJob
  blockjob: Simplify block_job_finish_sync
  block: Add block job transactions

John Snow (4):
  qapi: Add transaction support to block-dirty-bitmap operations
  iotests: add transactional incremental backup test
  block: rename BlkTransactionState and BdrvActionOps
  iotests: 124 - transactional failure test

Kashyap Chamarthy (1):
  qmp-commands.hx: Update the supported 'transaction' operations

Stefan Hajnoczi (3):
  blockdev: make BlockJobTxn available to qmp 'transaction'
  block/backup: support block job transactions
  tests: add BlockJobTxn unit test

 block.c|  19 ++-
 block/backup.c |  50 +--
 block/mirror.c |   2 +-
 blockdev.c | 354 +++--
 blockjob.c | 185 +++
 docs/bitmaps.md|   6 +-
 include/block/block.h  |   2 +-
 include/block/block_int.h  |   6 +-
 include/block/blockjob.h   |  83 ++-
 qapi-schema.json   |  10 +-
 qapi/block-core.json   |  29 
 qmp-commands.hx|  21 ++-
 tests/Makefile |   3 +
 tests/qemu-iotests/124 | 182 ++-
 tests/qemu-iotests/124.out |   4 +-
 tests/test-blockjob-txn.c  | 244 +++
 16 files changed, 1057 insertions(+), 143 deletions(-)
 create mode 100644 tests/test-blockjob-txn.c

-- 
2.4.3




[Qemu-devel] [PATCH] ppc/spapr: Allow VIRTIO_VGA

2015-09-14 Thread Benjamin Herrenschmidt
It works fine with the Linux driver out of the box

Signed-off-by: Benjamin Herrenschmidt 
---
 default-configs/ppc64-softmmu.mak | 1 +
 hw/ppc/spapr.c| 1 +
 2 files changed, 2 insertions(+)

diff --git a/default-configs/ppc64-softmmu.mak 
b/default-configs/ppc64-softmmu.mak
index a11de08..ec3cd8b 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -3,6 +3,7 @@
 include pci.mak
 include sound.mak
 include usb.mak
+CONFIG_VIRTIO_VGA=y
 CONFIG_ISA_MMIO=y
 CONFIG_ESCC=y
 CONFIG_M48T59=y
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4590c30..b47cacd 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1072,6 +1072,7 @@ static int spapr_vga_init(PCIBus *pci_bus)
 case VGA_DEVICE:
 return true;
 case VGA_STD:
+case VGA_VIRTIO:
 return pci_vga_init(pci_bus) != NULL;
 default:
 fprintf(stderr, "This vga model is not supported,"





Re: [Qemu-devel] [PATCH v5 11/14] block/backup: support block job transactions

2015-09-14 Thread Fam Zheng
On Fri, 09/11 15:26, Eric Blake wrote:
> On 09/07/2015 01:34 AM, Fam Zheng wrote:
> > From: Stefan Hajnoczi 
> > 
> > Join the transaction when the 'transactional-cancel' QMP argument is
> > true.
> > 
> > This ensures that the sync bitmap is not thrown away if another block
> > job in the transaction is cancelled or fails.  This is critical so
> > incremental backup with multiple disks can be retried in case of
> > cancellation/failure.
> > 
> > Signed-off-by: Stefan Hajnoczi 
> > Signed-off-by: Fam Zheng 
> > ---
> 
> Interface review:
> 
> > +void qmp_blockdev_backup(const char *device, const char *target,
> > + enum MirrorSyncMode sync,
> > + bool has_speed, int64_t speed,
> > + bool has_on_source_error,
> > + BlockdevOnError on_source_error,
> > + bool has_on_target_error,
> > + BlockdevOnError on_target_error,
> > + bool has_transactional_cancel,
> > + bool transactional_cancel,
> > + Error **errp)
> > +{
> > +if (has_transactional_cancel && transactional_cancel) {
> > +error_setg(errp, "Transactional cancel can only be used in the "
> > +   "'transaction' command");
> > +return;
> > +}
> 
> Hmm. It might be nicer if we had two separate qapi structs:
> 
> # used in 'blockdev-backup'
> { 'struct':'BlockdevBackup', 'data': { device ... on-target-error } }
> 
> # used in 'transaction'
> { 'struct':'BlockdevBackupTxn', 'base':'BlockdevBackup',
>   'data': { 'transactional-cancel':'bool' } }
> 
> so that the user can't abuse the boolean from the wrong context.

Very good point, will do that in v6.

Fam



Re: [Qemu-devel] [PATCH v5 09/14] block: Add block job transactions

2015-09-14 Thread Fam Zheng
On Fri, 09/11 20:52, Max Reitz wrote:
> On 07.09.2015 09:34, Fam Zheng wrote:
> > Sometimes block jobs must execute as a transaction group.  Finishing
> > jobs wait until all other jobs are ready to complete successfully.
> > Failure or cancellation of one job cancels the other jobs in the group.
> > 
> > Signed-off-by: Stefan Hajnoczi 
> > [Rewrite the implementation which is now contained in block_job_completed.
> > --Fam]
> > Signed-off-by: Fam Zheng 
> > ---
> >  blockjob.c   | 134 
> > ++-
> >  include/block/block.h|   1 +
> >  include/block/blockjob.h |  38 ++
> >  3 files changed, 171 insertions(+), 2 deletions(-)
> > 
> > diff --git a/blockjob.c b/blockjob.c
> > index 36c18e0..1b4eb20 100644
> > --- a/blockjob.c
> > +++ b/blockjob.c
> > @@ -36,6 +36,19 @@
> >  #include "qemu/timer.h"
> >  #include "qapi-event.h"
> >  
> > +/* Transactional group of block jobs */
> > +struct BlockJobTxn {
> > +
> > +/* Is this txn being cancelled? */
> > +bool aborting;
> > +
> > +/* List of jobs */
> > +QLIST_HEAD(, BlockJob) jobs;
> > +
> > +/* Reference count */
> > +int refcnt;
> > +};
> > +
> >  void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
> > int64_t speed, BlockCompletionFunc *cb,
> > void *opaque, Error **errp)
> > @@ -90,6 +103,85 @@ void block_job_unref(BlockJob *job)
> >  }
> >  }
> >  
> > +static void block_job_completed_single(BlockJob *job)
> > +{
> > +if (!job->ret) {
> > +if (job->driver->commit) {
> > +job->driver->commit(job);
> > +}
> > +} else {
> > +if (job->driver->abort) {
> > +job->driver->abort(job);
> > +}
> > +}
> > +job->cb(job->opaque, job->ret);
> > +block_job_unref(job);
> > +}
> > +
> > +static void block_job_completed_txn_abort(BlockJob *job)
> > +{
> > +AioContext *ctx;
> > +BlockJobTxn *txn = job->txn;
> > +BlockJob *other_job, *next;
> > +
> > +if (txn->aborting) {
> > +/*
> > + * We are cancelled by another job, which will handle everything.
> > + */
> 
> After having reviewed patch 11, I think we need to call
> block_job_txn_unref(txn) here.
> 
> > +return;
> > +}
> > +txn->aborting = true;
> > +/* We are the first failed job. Cancel other jobs. */
> > +QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
> > +ctx = bdrv_get_aio_context(other_job->bs);
> > +aio_context_acquire(ctx);
> > +}
> > +QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
> > +if (other_job == job || other_job->completed) {
> > +/* Other jobs are "effectively" cancelled by us, set the 
> > status for
> > + * them; this job, however, may or may not be cancelled, 
> > depending
> > + * on the caller, so leave it. */
> > +if (other_job != job) {
> > +other_job->cancelled = true;
> > +}
> > +continue;
> > +}
> > +block_job_cancel_sync(other_job);
> > +assert(other_job->completed);
> > +}
> > +QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
> > +ctx = bdrv_get_aio_context(other_job->bs);
> > +block_job_completed_single(other_job);
> > +aio_context_release(ctx);
> > +}
> > +block_job_txn_unref(txn);
> > +}
> > +
> > +static void block_job_completed_txn_success(BlockJob *job)
> > +{
> > +AioContext *ctx;
> > +BlockJobTxn *txn = job->txn;
> > +BlockJob *other_job, *next;
> > +/*
> > + * Successful completion, see if there are other running jobs in this
> > + * txn.
> > + **/
> > +QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
> > +if (!other_job->completed) {
> 
> Same here.

Yes. Will add at ...

> > +return;
> > +}
> > +}
> > +/* We are the last completed job, commit the transaction. */
> > +QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
> > +ctx = bdrv_get_aio_context(other_job->bs);
> > +aio_context_acquire(ctx);
> > +assert(other_job->ret == 0);
> > +block_job_completed_single(other_job);
> > +aio_context_release(ctx);
> > +}
> > +block_job_txn_unref(txn);
> > +}
> > +
> >  void block_job_completed(BlockJob *job, int ret)
> >  {
> >  BlockDriverState *bs = job->bs;
> > @@ -98,8 +190,13 @@ void block_job_completed(BlockJob *job, int ret)
> >  assert(!job->completed);
> >  job->completed = true;
> >  job->ret = ret;
> > -job->cb(job->opaque, ret);
> > -block_job_unref(job);
> > +if (!job->txn) {
> > +block_job_completed_single(job);
> > +} else if (ret < 0 || block_job_is_cancelled(job)) {
> > +block_job_completed_txn_abort(job);
> > +} else {
> > +block_job_completed_txn_success(job);
> > +}

Here in an "if (job->tx

Re: [Qemu-devel] [PATCH v5 04/14] backup: Extract dirty bitmap handling as a separate function

2015-09-14 Thread Fam Zheng
On Fri, 09/11 13:35, Eric Blake wrote:
> On 09/07/2015 01:34 AM, Fam Zheng wrote:
> > This will be reused by the coming new transactional completion code.
> > 
> > Signed-off-by: Fam Zheng 
> > Reviewed-by: John Snow 
> > ---
> >  block/backup.c | 26 --
> >  1 file changed, 16 insertions(+), 10 deletions(-)
> > 
> > diff --git a/block/backup.c b/block/backup.c
> > index 965654d..9776d9c 100644
> > --- a/block/backup.c
> > +++ b/block/backup.c
> > @@ -210,6 +210,21 @@ static void backup_iostatus_reset(BlockJob *job)
> >  
> >  bdrv_iostatus_reset(s->target);
> >  }
> > +static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
> 
> Blank lines between functions?
>

OK, will add one!

Fam



Re: [Qemu-devel] [PATCH v3] ppc/spapr: Implement H_RANDOM hypercall in QEMU

2015-09-14 Thread David Gibson
On Mon, Sep 14, 2015 at 08:32:36AM +0200, Thomas Huth wrote:
> On 14/09/15 04:15, David Gibson wrote:
> > On Fri, Sep 11, 2015 at 11:17:01AM +0200, Thomas Huth wrote:
> >> The PAPR interface defines a hypercall to pass high-quality
> >> hardware generated random numbers to guests. Recent kernels can
> >> already provide this hypercall to the guest if the right hardware
> >> random number generator is available. But in case the user wants
> >> to use another source like EGD, or QEMU is running with an older
> >> kernel, we should also have this call in QEMU, so that guests that
> >> do not support virtio-rng yet can get good random numbers, too.
> >>
> >> This patch now adds a new pseude-device to QEMU that either
> >> directly provides this hypercall to the guest or is able to
> >> enable the in-kernel hypercall if available. The in-kernel
> >> hypercall can be enabled with the use-kvm property, e.g.:
> >>
> >>  qemu-system-ppc64 -device spapr-rng,use-kvm=true
> >>
> >> For handling the hypercall in QEMU instead, a RngBackend is required
> >> since the hypercall should provide "good" random data instead of
> >> pseudo-random (like from a "simple" library function like rand()
> >> or g_random_int()). Since there are multiple RngBackends available,
> >> the user must select an appropriate backend via the "backend"
> >> property of the device, e.g.:
> >>
> >>  qemu-system-ppc64 -object rng-random,filename=/dev/hwrng,id=rng0 \
> >>-device spapr-rng,backend=rng0 ...
> >>
> >> See http://wiki.qemu-project.org/Features-Done/VirtIORNG for
> >> other example of specifying RngBackends.
> ...
> >> +
> >> +#include "qemu/error-report.h"
> >> +#include "sysemu/sysemu.h"
> >> +#include "sysemu/device_tree.h"
> >> +#include "sysemu/rng.h"
> >> +#include "hw/ppc/spapr.h"
> >> +#include "kvm_ppc.h"
> >> +
> >> +#define SPAPR_RNG(obj) \
> >> +OBJECT_CHECK(sPAPRRngState, (obj), TYPE_SPAPR_RNG)
> >> +
> >> +typedef struct sPAPRRngState {
> >> +/*< private >*/
> >> +DeviceState ds;
> >> +RngBackend *backend;
> >> +bool use_kvm;
> >> +} sPAPRRngState;
> >> +
> >> +typedef struct HRandomData {
> >> +QemuSemaphore sem;
> >> +union {
> >> +uint64_t v64;
> >> +uint8_t v8[8];
> >> +} val;
> >> +int received;
> >> +} HRandomData;
> >> +
> >> +/* Callback function for the RngBackend */
> >> +static void random_recv(void *dest, const void *src, size_t size)
> >> +{
> >> +HRandomData *hrdp = dest;
> >> +
> >> +if (src && size > 0) {
> >> +assert(size + hrdp->received <= sizeof(hrdp->val.v8));
> >> +memcpy(&hrdp->val.v8[hrdp->received], src, size);
> >> +hrdp->received += size;
> >> +}
> >> +
> >> +qemu_sem_post(&hrdp->sem);
> > 
> > I'm assuming qemu_sem_post() includes the necessary memory barrier to
> > make sure the requesting thread actually sees the data.
> 
> Not sure whether I fully got your point here... both callback function
> and main thread are calling an extern C-function, so the compiler should
> not assume that the memory stays the same in the main thread...?

I'm not talking about a compiler barrier: the callback will likely be
invoked on a different CPU from the vcpu thread that invoked H_RANDOM,
so on a weakly ordered arch like Power we need a real CPU memory barrier.

> Anyway, I've tested the hypercall by implementing it in SLOF and calling
> it a couple of times there to see that all bits in the result behave
> randomly, so for me this is working fine.

Right, I'd be almost certain anyway that qemu_sem_post() (actually
likely the pthreads functions it invokes) will include the necessary
barriers to stop accesses leaking outside the locked region.

> 
> >> +}
> >> +
> >> +/* Handler for the H_RANDOM hypercall */
> >> +static target_ulong h_random(PowerPCCPU *cpu, sPAPRMachineState *spapr,
> >> + target_ulong opcode, target_ulong *args)
> >> +{
> >> +sPAPRRngState *rngstate;
> >> +HRandomData hrdata;
> >> +
> >> +rngstate = SPAPR_RNG(object_resolve_path_type("", TYPE_SPAPR_RNG, 
> >> NULL));
> >> +
> >> +if (!rngstate || !rngstate->backend) {
> >> +return H_HARDWARE;
> >> +}
> >> +
> >> +qemu_sem_init(&hrdata.sem, 0);
> >> +hrdata.val.v64 = 0;
> >> +hrdata.received = 0;
> >> +
> >> +qemu_mutex_unlock_iothread();
> >> +while (hrdata.received < 8) {
> >> +rng_backend_request_entropy(rngstate->backend, 8 - 
> >> hrdata.received,
> >> +random_recv, &hrdata);
> >> +qemu_sem_wait(&hrdata.sem);
> >> +}
> >> +qemu_mutex_lock_iothread();
> >> +
> >> +qemu_sem_destroy(&hrdata.sem);
> >> +args[0] = hrdata.val.v64;
> >> +
> >> +return H_SUCCESS;
> >> +}
> >> +
> >> +static void spapr_rng_instance_init(Object *obj)
> >> +{
> >> +sPAPRRngState *rngstate = SPAPR_RNG(obj);
> >> +
> >> +if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL) != NULL) {
> >> +error_

Re: [Qemu-devel] [PATCH RFC 2/4] arm64: kvm: enable trapping of read access to regs in TID3 group

2015-09-14 Thread Shannon Zhao


On 2015/9/9 16:38, Tushar Jagad wrote:
> This patch modifies the HCR_GUEST_FLAGS to enable trapping of
> non secure read to registers under the HCR_EL2.TID3 group to EL2.
> 
> We emulate the accesses to capability registers which list the number of
> breakpoints, watchpoints, etc. These values are provided by the user when
> starting the VM. The emulated values are constructed at runtime from the
> trap handler.
> 
> Signed-off-by: Tushar Jagad 
> ---
>  Documentation/virtual/kvm/api.txt |8 +
>  arch/arm/kvm/arm.c|   50 -
>  arch/arm64/include/asm/kvm_arm.h  |2 +-
>  arch/arm64/include/asm/kvm_asm.h  |   38 +++-
>  arch/arm64/include/asm/kvm_host.h |4 +-
>  arch/arm64/include/uapi/asm/kvm.h |7 +
>  arch/arm64/kvm/sys_regs.c |  443 
> +
>  7 files changed, 503 insertions(+), 49 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt 
> b/Documentation/virtual/kvm/api.txt
> index a7926a9..b06c104 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -2561,6 +2561,14 @@ Possible features:
> Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
>   - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU.
> Depends on KVM_CAP_ARM_PSCI_0_2.
> + - KVM_ARM_VCPU_NUM_BPTS: Number of supported h/w breakpoints
> +   This is a 4-bit value which defines number of hardware
> +   breakpoints supported on guest. If this is not sepecified or
> +   set to zero then the guest sees the value as is from the host.
> + - KVM_ARM_VCPU_NUM_WPTS: Number of supported h/w watchpoints
> +   This is a 4-bit value which defines number of hardware
> +   watchpoints supported on guest. If this is not sepecified or
> +   set to zero then the guest sees the value as is from the host.
>  
>  
>  4.83 KVM_ARM_PREFERRED_TARGET
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index bc738d2..8907d37 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -696,6 +696,8 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
>  const struct kvm_vcpu_init *init)
>  {
>   unsigned int i;
> + u64 aa64dfr;
> +
>   int phys_target = kvm_target_cpu();
>  
>   if (init->target != phys_target)
> @@ -708,6 +710,8 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
>   if (vcpu->arch.target != -1 && vcpu->arch.target != init->target)
>   return -EINVAL;
>  
> + asm volatile("mrs %0, ID_AA64DFR0_EL1\n" : "=r" (aa64dfr));
> +
>   /* -ENOENT for unknown features, -EINVAL for invalid combinations. */
>   for (i = 0; i < sizeof(init->features) * 8; i++) {
>   bool set = (init->features[i / 32] & (1 << (i % 32)));
> @@ -715,6 +719,50 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
>   if (set && i >= KVM_VCPU_MAX_FEATURES)
>   return -ENOENT;
>  
> + if (i == KVM_ARM_VCPU_NUM_BPTS) {
> + int h_bpts;
> + int g_bpts;
> +
> + h_bpts = ((aa64dfr >> 12) & 0xf) + 1;
> + g_bpts = 
> (init->features[KVM_ARM_VCPU_BPTS_FEATURES_IDX] &
> + KVM_ARM_VCPU_BPTS_MASK) >> 
> KVM_ARM_VCPU_NUM_BPTS;
> +
> + /*
> +  * We ensure that the host can support the requested
> +  * number of hardware breakpoints.
> +  */
> + if (g_bpts > h_bpts)
> + return -EINVAL;
> +
This may not work. Assuming that the number of source host hardware
breakpoints is 15 and userspace set the g_bpts to 15 as well, it's ok to
create VM on the source host. But if the number of destination host
hardware breakpoints is lees than 15 (e.g. 8), this will return -EINVAL
and fail to create VM on the destination host and migrate failed.

(P.S. I'm considering the guest PMU for cross-cpu type, so I have look
at this patch)

> + vcpu->arch.bpts = g_bpts;
> +
> + i  += 3;
> +
> + continue;
> + }
> +
> + if (i == KVM_ARM_VCPU_NUM_WPTS) {
> + int h_wpts;
> + int g_wpts;
> +
> + h_wpts = ((aa64dfr >> 20) & 0xf) + 1;
> + g_wpts = 
> (init->features[KVM_ARM_VCPU_WPTS_FEATURES_IDX] &
> + KVM_ARM_VCPU_WPTS_MASK) >> 
> KVM_ARM_VCPU_NUM_WPTS;
> +
> + /*
> +  * We ensure that the host can support the requested
> +  * number of hardware watchpoints.
> +  */
> + if (g_wpts > h_wpts)
> + return -EINVAL;
> +
> + vcpu->arch.wpts = g_wpts;
> +
> + i += 3;
> +
> + continue;
> +  

Re: [Qemu-devel] [RFCv2 2/2] spapr: Don't use QOM [*] syntax for DR connectors.

2015-09-14 Thread Michael Roth
Quoting Michael Roth (2015-09-14 23:03:00)
> Quoting David Gibson (2015-09-13 20:41:53)
> > The dynamic reconfiguration (hotplug) code for the pseries machine type
> > uses a "DR connector" QOM object for each resource it will be possible
> > to hotplug.  Each of these is added to its owner using
> > object_property_add_child(owner, "dr-connector[*], ...);
> > 
> > That works ok, mostly, but it means that the property indices are
> > arbitrary, depending on the order in which the connectors are constructed.
> > When we have both memory and cpu hotplug, the connectors will be under the
> > same parent (at least in the current drafts), meaning the indices don't
> > correspond to any meaningful ID.
> > 
> > It gets worse when large amounts of hotpluggable RAM is configured.  For
> > RAM, there's a DR connector object for every 256MB of potential memory.  So
> > if maxmem=2T, for example, there are 8192 objects under the same parent.
> > 
> > The QOM interfaces aren't really designed for this.  In particular
> > object_property_add() with [*] has O(n^2) time complexity (in the number of
> > existing children): first it has a linear search through array indices to
> > find a free slot, each of which is attempted to a recursive call to
> > object_property_add() with a specific [N].  Those calls are O(n) because
> > there's a linear search through all properties to check for duplicates.
> > 
> > By using a meaningful index value, which we already know is unique we can
> > avoid the [*] special behaviour.  That lets us reduce the total time for
> > creating the DR objects from O(n^3) to O(n^2).
> > 
> > O(n^2) is still kind of crappy, but it's enough to reduce the startup time
> > of qemu with maxmem=2T from ~20 minutes to ~4 seconds.
> > 
> > Signed-off-by: David Gibson 
> > Cc: Bharata B Rao 
> 
> This is the second patch I've seen that drops use of "[*]" for
> performance reasons, but looking at the code I don't really see
> any reason that logic can't be implemented in object_property_add()
> in O(n) time. For instance I think it can be achieved by
> storing/hashing the base string to an array of auto-incremented
> indicies that we update whenever a child with the corresponding
> [n] format is added.
> 
> I wouldn't hold this real fix up for that though, and in fact the
> use of DRC indexes make for much easier debugging anyway so I'd
> probably still prefer this approach anyway.

Well, along that line, one small nit: I think
%x would be a bit easier to correlate with the DRC indexes as we
use them elsewhere. Reviewed-by still stands though.

> 
> Reviewed-by: Michael Roth 
> 
> > ---
> >  hw/ppc/spapr_drc.c | 5 -
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> > index 68e0c3e..2f95259 100644
> > --- a/hw/ppc/spapr_drc.c
> > +++ b/hw/ppc/spapr_drc.c
> > @@ -451,13 +451,16 @@ sPAPRDRConnector *spapr_dr_connector_new(Object 
> > *owner,
> >  {
> >  sPAPRDRConnector *drc =
> >  SPAPR_DR_CONNECTOR(object_new(TYPE_SPAPR_DR_CONNECTOR));
> > +char *prop_name;
> > 
> >  g_assert(type);
> > 
> >  drc->type = type;
> >  drc->id = id;
> > -object_property_add_child(owner, "dr-connector[*]", OBJECT(drc), NULL);
> > +prop_name = g_strdup_printf("dr-connector[%"PRIu32"]", get_index(drc));
> > +object_property_add_child(owner, prop_name, OBJECT(drc), NULL);
> >  object_property_set_bool(OBJECT(drc), true, "realized", NULL);
> > +g_free(prop_name);
> > 
> >  /* human-readable name for a DRC to encode into the DT
> >   * description. this is mainly only used within a guest in place
> > -- 
> > 2.4.3
> > 




Re: [Qemu-devel] [RFCv2 2/2] spapr: Don't use QOM [*] syntax for DR connectors.

2015-09-14 Thread Michael Roth
Quoting David Gibson (2015-09-13 20:41:53)
> The dynamic reconfiguration (hotplug) code for the pseries machine type
> uses a "DR connector" QOM object for each resource it will be possible
> to hotplug.  Each of these is added to its owner using
> object_property_add_child(owner, "dr-connector[*], ...);
> 
> That works ok, mostly, but it means that the property indices are
> arbitrary, depending on the order in which the connectors are constructed.
> When we have both memory and cpu hotplug, the connectors will be under the
> same parent (at least in the current drafts), meaning the indices don't
> correspond to any meaningful ID.
> 
> It gets worse when large amounts of hotpluggable RAM is configured.  For
> RAM, there's a DR connector object for every 256MB of potential memory.  So
> if maxmem=2T, for example, there are 8192 objects under the same parent.
> 
> The QOM interfaces aren't really designed for this.  In particular
> object_property_add() with [*] has O(n^2) time complexity (in the number of
> existing children): first it has a linear search through array indices to
> find a free slot, each of which is attempted to a recursive call to
> object_property_add() with a specific [N].  Those calls are O(n) because
> there's a linear search through all properties to check for duplicates.
> 
> By using a meaningful index value, which we already know is unique we can
> avoid the [*] special behaviour.  That lets us reduce the total time for
> creating the DR objects from O(n^3) to O(n^2).
> 
> O(n^2) is still kind of crappy, but it's enough to reduce the startup time
> of qemu with maxmem=2T from ~20 minutes to ~4 seconds.
> 
> Signed-off-by: David Gibson 
> Cc: Bharata B Rao 

This is the second patch I've seen that drops use of "[*]" for
performance reasons, but looking at the code I don't really see
any reason that logic can't be implemented in object_property_add()
in O(n) time. For instance I think it can be achieved by
storing/hashing the base string to an array of auto-incremented
indicies that we update whenever a child with the corresponding
[n] format is added.

I wouldn't hold this real fix up for that though, and in fact the
use of DRC indexes make for much easier debugging anyway so I'd
probably still prefer this approach anyway.

Reviewed-by: Michael Roth 

> ---
>  hw/ppc/spapr_drc.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index 68e0c3e..2f95259 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -451,13 +451,16 @@ sPAPRDRConnector *spapr_dr_connector_new(Object *owner,
>  {
>  sPAPRDRConnector *drc =
>  SPAPR_DR_CONNECTOR(object_new(TYPE_SPAPR_DR_CONNECTOR));
> +char *prop_name;
> 
>  g_assert(type);
> 
>  drc->type = type;
>  drc->id = id;
> -object_property_add_child(owner, "dr-connector[*]", OBJECT(drc), NULL);
> +prop_name = g_strdup_printf("dr-connector[%"PRIu32"]", get_index(drc));
> +object_property_add_child(owner, prop_name, OBJECT(drc), NULL);
>  object_property_set_bool(OBJECT(drc), true, "realized", NULL);
> +g_free(prop_name);
> 
>  /* human-readable name for a DRC to encode into the DT
>   * description. this is mainly only used within a guest in place
> -- 
> 2.4.3
> 




Re: [Qemu-devel] [PATCH v3 1/5] support nbd driver in blockdev-add

2015-09-14 Thread Wen Congyang
On 09/15/2015 11:46 AM, Eric Blake wrote:
> On 09/14/2015 08:27 PM, Wen Congyang wrote:
>>> Building fails:
>>>   GEN   qmp-commands.h
>>> In file included from /work/src/qemu/qapi-schema.json:9:
>>> In file included from /work/src/qemu/qapi/block.json:6:
>>> /work/src/qemu/qapi/block-core.json:1844: Flat union 'BlockdevOptionsNBD' 
>>> must have a string base field
>>> Makefile:286: recipe for target 'qmp-commands.h' failed
>>> make: *** [qmp-commands.h] Error 1
> 
> Yep, doesn't work until pending qapi patches land.

This patchset: qapi: QMP introspection?

> 
>>>
>>> What about this:
>>> { 'struct': 'BlockdevOptionsNBDBase',
>>>   'data': {  'transport': 'NBDTransport', 'export': 'str' } }
>>> { 'union': 'BlockdevOptionsNBD',
>>>   'base': 'BlockdevOptionsNBDBase',
>>>   'discriminator': 'transport',
>>>   'data': { 'unix': 'NBDUnix', 'tcp': 'NBDInet', 'udp': 'NBDInet' } }
>>
>> Another problem:
>> In file included from /work/src/qemu/qapi-schema.json:9:
>> In file included from /work/src/qemu/qapi/block.json:6:
>> /work/src/qemu/qapi/block-core.json:1866: Member 'nbd' of union 
>> 'BlockdevOptions' cannot use union type 'BlockdevOptionsNBD'
>> Makefile:286: recipe for target 'qmp-commands.h' failed
> 
> Yep. Artificial restriction; we hope to lift it soon, but don't have
> enough qapi patches in place for that one yet (I have not posted my work
> in progress to get us that far).
> 
> Possible workaround in the meantime - instead of trying to go with a
> nice flat union (where all QMP keys are in the same {} level), we can
> use nesting (structs that add another {} to include the unions).

How to include the unions to a structs? Use 'base'?

Thanks
Wen Congyang

> 




Re: [Qemu-devel] [PATCH v3 1/5] support nbd driver in blockdev-add

2015-09-14 Thread Eric Blake
On 09/14/2015 08:27 PM, Wen Congyang wrote:
>> Building fails:
>>   GEN   qmp-commands.h
>> In file included from /work/src/qemu/qapi-schema.json:9:
>> In file included from /work/src/qemu/qapi/block.json:6:
>> /work/src/qemu/qapi/block-core.json:1844: Flat union 'BlockdevOptionsNBD' 
>> must have a string base field
>> Makefile:286: recipe for target 'qmp-commands.h' failed
>> make: *** [qmp-commands.h] Error 1

Yep, doesn't work until pending qapi patches land.

>>
>> What about this:
>> { 'struct': 'BlockdevOptionsNBDBase',
>>   'data': {  'transport': 'NBDTransport', 'export': 'str' } }
>> { 'union': 'BlockdevOptionsNBD',
>>   'base': 'BlockdevOptionsNBDBase',
>>   'discriminator': 'transport',
>>   'data': { 'unix': 'NBDUnix', 'tcp': 'NBDInet', 'udp': 'NBDInet' } }
> 
> Another problem:
> In file included from /work/src/qemu/qapi-schema.json:9:
> In file included from /work/src/qemu/qapi/block.json:6:
> /work/src/qemu/qapi/block-core.json:1866: Member 'nbd' of union 
> 'BlockdevOptions' cannot use union type 'BlockdevOptionsNBD'
> Makefile:286: recipe for target 'qmp-commands.h' failed

Yep. Artificial restriction; we hope to lift it soon, but don't have
enough qapi patches in place for that one yet (I have not posted my work
in progress to get us that far).

Possible workaround in the meantime - instead of trying to go with a
nice flat union (where all QMP keys are in the same {} level), we can
use nesting (structs that add another {} to include the unions).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v3 3/3] pc: Introduce pc-*-2.5 machine classes

2015-09-14 Thread Jason Wang


On 09/15/2015 12:27 AM, Igor Mammedov wrote:
> On Mon, 14 Sep 2015 11:32:45 -0300
> Eduardo Habkost  wrote:
>
>> Introduce pc-*-2.5 machine classes, and add HW_COMPAT_2_4/PC_COMPAT_2_4
>> macros that will allow pc-*-2.4 compat properties to be added.
>>
>> Signed-off-by: Eduardo Habkost 
> Reviewed-by: Igor Mammedov 
>

Thanks, I will include this in my new version of virtio-pci fixes.




[Qemu-devel] [PATCH] linux-user/syscall.c: Fix issue for checking ptr in different address spaces in TARGET_CMSG_NXTHDR

2015-09-14 Thread gang . chen . 5i5j
From: Chen Gang 

After fix this issue, qemu can run i386 wine notepad.exe successfully.
But the initialization performance is not quite well.

Signed-off-by: Chen Gang 
---
 linux-user/syscall.c  | 30 +-
 linux-user/syscall_defs.h | 20 +---
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 973cc2f..521749c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1181,17 +1181,18 @@ static inline abi_long target_to_host_cmsg(struct 
msghdr *msgh,
 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
 abi_long msg_controllen;
 abi_ulong target_cmsg_addr;
-struct target_cmsghdr *target_cmsg;
+struct target_cmsghdr *target_cmsg, *base;
 socklen_t space = 0;
 
 msg_controllen = tswapal(target_msgh->msg_controllen);
 if (msg_controllen < sizeof (struct target_cmsghdr)) 
 goto the_end;
 target_cmsg_addr = tswapal(target_msgh->msg_control);
-target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
-if (!target_cmsg)
+base = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
+if (!base) {
 return -TARGET_EFAULT;
-
+}
+target_cmsg = base;
 while (cmsg && target_cmsg) {
 void *data = CMSG_DATA(cmsg);
 void *target_data = TARGET_CMSG_DATA(target_cmsg);
@@ -1247,7 +1248,7 @@ static inline abi_long target_to_host_cmsg(struct msghdr 
*msgh,
 }
 
 cmsg = CMSG_NXTHDR(msgh, cmsg);
-target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
+target_cmsg = TARGET_CMSG_NXTHDR(base, msg_controllen, target_cmsg);
 }
 unlock_user(target_cmsg, target_cmsg_addr, 0);
  the_end:
@@ -1259,19 +1260,22 @@ static inline abi_long host_to_target_cmsg(struct 
target_msghdr *target_msgh,
struct msghdr *msgh)
 {
 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
-abi_long msg_controllen;
+abi_long msg_controllen, size;
 abi_ulong target_cmsg_addr;
-struct target_cmsghdr *target_cmsg;
+struct target_cmsghdr *target_cmsg, *base;
 socklen_t space = 0;
 
-msg_controllen = tswapal(target_msgh->msg_controllen);
-if (msg_controllen < sizeof (struct target_cmsghdr)) 
+size = tswapal(target_msgh->msg_controllen);
+if (size < sizeof(struct target_cmsghdr)) {
 goto the_end;
+}
 target_cmsg_addr = tswapal(target_msgh->msg_control);
-target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
-if (!target_cmsg)
+base = lock_user(VERIFY_WRITE, target_cmsg_addr, size, 0);
+if (!base) {
 return -TARGET_EFAULT;
-
+}
+msg_controllen = size;
+target_cmsg = base;
 while (cmsg && target_cmsg) {
 void *data = CMSG_DATA(cmsg);
 void *target_data = TARGET_CMSG_DATA(target_cmsg);
@@ -1389,7 +1393,7 @@ static inline abi_long host_to_target_cmsg(struct 
target_msghdr *target_msgh,
 msg_controllen -= tgt_space;
 space += tgt_space;
 cmsg = CMSG_NXTHDR(msgh, cmsg);
-target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
+target_cmsg = TARGET_CMSG_NXTHDR(base, size, target_cmsg);
 }
 unlock_user(target_cmsg, target_cmsg_addr, space);
  the_end:
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 5256fe5..aec2f23 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -234,7 +234,8 @@ struct target_cmsghdr {
 };
 
 #define TARGET_CMSG_DATA(cmsg) ((unsigned char *) ((struct target_cmsghdr *) 
(cmsg) + 1))
-#define TARGET_CMSG_NXTHDR(mhdr, cmsg) __target_cmsg_nxthdr (mhdr, cmsg)
+#define TARGET_CMSG_NXTHDR(base, size, cmsg) __target_cmsg_nxthdr(base, size, \
+  cmsg)
 #define TARGET_CMSG_ALIGN(len) (((len) + sizeof (abi_long) - 1) \
& (size_t) ~(sizeof (abi_long) - 1))
 #define TARGET_CMSG_SPACE(len) (TARGET_CMSG_ALIGN (len) \
@@ -242,17 +243,14 @@ struct target_cmsghdr {
 #define TARGET_CMSG_LEN(len)   (TARGET_CMSG_ALIGN (sizeof (struct 
target_cmsghdr)) + (len))
 
 static __inline__ struct target_cmsghdr *
-__target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct target_cmsghdr 
*__cmsg)
+__target_cmsg_nxthdr(void *base, abi_long size, struct target_cmsghdr *msg)
 {
-  struct target_cmsghdr *__ptr;
-
-  __ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg
-+ TARGET_CMSG_ALIGN 
(tswapal(__cmsg->cmsg_len)));
-  if ((unsigned long)((char *)(__ptr+1) - (char 
*)(size_t)tswapal(__mhdr->msg_control))
-  > tswapal(__mhdr->msg_controllen))
-/* No more entries.  */
-return (struct target_cmsghdr *)0;
-  return __cmsg;
+msg = (struct target_cmsghdr *)((unsigned char *)msg +
+TARGET_CMSG_ALIGN(tswapal(msg->cmsg_len)));
+if ((unsigned long)((char *)(msg + 1)

Re: [Qemu-devel] [PATCH v3 4/5] qmp: add monitor command to add/remove a child

2015-09-14 Thread Wen Congyang
On 09/14/2015 10:36 PM, Markus Armbruster wrote:
> Wen Congyang  writes:
> 
>> Signed-off-by: Wen Congyang 
>> Signed-off-by: zhanghailiang 
>> Signed-off-by: Gonglei 
>> ---
>>  blockdev.c   | 47 ++
>>  qapi/block-core.json | 34 +
>>  qmp-commands.hx  | 53 
>> 
>>  3 files changed, 134 insertions(+)
>>
>> diff --git a/blockdev.c b/blockdev.c
>> index bd47756..0a40607 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -3413,6 +3413,53 @@ fail:
>>  qmp_output_visitor_cleanup(ov);
>>  }
>>  
>> +void qmp_x_child_add(const char *parent, const char *child,
>> + Error **errp)
>> +{
>> +BlockDriverState *parent_bs, *child_bs;
>> +Error *local_err = NULL;
>> +
>> +parent_bs = bdrv_lookup_bs(parent, parent, &local_err);
>> +if (!parent_bs) {
>> +error_propagate(errp, local_err);
>> +return;
>> +}
>> +
>> +child_bs = bdrv_find_node(child);
>> +if (!child_bs) {
>> +error_setg(errp, "Node '%s' not found", child);
>> +return;
>> +}
>> +
>> +bdrv_add_child(parent_bs, child_bs, &local_err);
>> +if (local_err) {
>> +error_propagate(errp, local_err);
>> +}
>> +}
>> +
>> +void qmp_child_del(const char *parent, const char *child, Error **errp)
>> +{
>> +BlockDriverState *parent_bs, *child_bs;
>> +Error *local_err = NULL;
>> +
>> +parent_bs = bdrv_lookup_bs(parent, parent, &local_err);
>> +if (!parent_bs) {
>> +error_propagate(errp, local_err);
>> +return;
>> +}
>> +
>> +child_bs = bdrv_find_node(child);
>> +if (!child_bs) {
>> +error_setg(errp, "Node '%s' not found", child);
>> +return;
>> +}
>> +
>> +bdrv_del_child(parent_bs, child_bs, &local_err);
>> +if (local_err) {
>> +error_propagate(errp, local_err);
>> +}
>> +}
>> +
>>  BlockJobInfoList *qmp_query_block_jobs(Error **errp)
>>  {
>>  BlockJobInfoList *head = NULL, **p_next = &head;
>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>> index e68a59f..b959577 100644
>> --- a/qapi/block-core.json
>> +++ b/qapi/block-core.json
>> @@ -2272,3 +2272,37 @@
>>  ##
>>  { 'command': 'block-set-write-threshold',
>>'data': { 'node-name': 'str', 'write-threshold': 'uint64' } }
>> +
>> +##
>> +# @x-child-add
>> +#
>> +# Add a new child to the parent BDS. Currently only the Quorum driver
>> +# implements this feature. This is useful to fix a broken quorum child.
>> +#
>> +# @parent: graph node name or id which the child will be added to.
>> +#
>> +# @child: graph node name that will be added.
>> +#
>> +# Note: this command is experimental, and not a stable API.
>> +#
>> +# Since: 2.5
>> +##
>> +{ 'command': 'x-child-add',
>> +  'data' : { 'parent': 'str', 'child': 'str' } }
>> +
>> +##
>> +# @child-del
>> +#
>> +# Remove a child from the parent BDS. Currently only the Quorum driver
>> +# implements this feature. This is useful to fix a broken quorum child.
>> +# Note, you can't remove a child if it would bring the quorum below its
>> +# threshold.
>> +#
>> +# @parent: graph node name or id from which the child will removed.
>> +#
>> +# @child: graph node name that will be removed.
>> +#
>> +# Since: 2.5
>> +##
>> +{ 'command': 'child-del',
>> +  'data' : { 'parent': 'str', 'child': 'str' } }
> 
> Why is x-child-add experimental, but child-del isn't?  Please explain
> both in the schema and in the commit message.

No special reason. Should I put child-del in experimental namespace?

> 
>> diff --git a/qmp-commands.hx b/qmp-commands.hx
>> index 495670b..139a23b 100644
>> --- a/qmp-commands.hx
>> +++ b/qmp-commands.hx
>> @@ -4053,6 +4053,59 @@ Example:
>>  EQMP
>>  
>>  {
>> +.name   = "x-child-add",
>> +.args_type  = "parent:B,child:B",
>> +.mhandler.cmd_new = qmp_marshal_input_x_child_add,
>> +},
>> +
>> +SQMP
>> +x-child-add
>> +
>> +
>> +Add a child to a quorum node.
>> +
>> +Arguments:
>> +
>> +- "parent": the quorum's id or node name
>> +- "child": the child node-name which will be added
> 
> Node name parameters are usually named node-name or, if there's more
> than one, FOO-node-name.  Unless we want to abandon that convention,
> this should therefore be node-name and child-node-name, or parent-node
> name and child-node-name.

parent can be top BDS, so it can be id. node-name is a very common name,
and I think child or child-node-name is better.

> 
>> +
>> +Note: this command is experimental, and not a stable API.
>> +
>> +Example:
>> +
>> +-> { "execute": "x-child-add",
>> +"arguments": { "parent": "disk1", "child": "new_node" } }
>> +<- { "return": {} }
>> +
>> +EQMP
>> +
>> +{
>> +.name= "child-del",
> 
> Documentation and schema have x-child-add, actual command is child-add.
> Oops.

Here is child-del

> 
>> +.args_type   = "parent:B,child:B",
>>

Re: [Qemu-devel] [PATCH v3 4/5] qmp: add monitor command to add/remove a child

2015-09-14 Thread Wen Congyang
On 09/14/2015 11:37 PM, Kevin Wolf wrote:
> Am 10.09.2015 um 11:55 hat Wen Congyang geschrieben:
>> +##
>> +# @x-child-add
>> +#
>> +# Add a new child to the parent BDS. Currently only the Quorum driver
>> +# implements this feature. This is useful to fix a broken quorum child.
>> +#
>> +# @parent: graph node name or id which the child will be added to.
>> +#
>> +# @child: graph node name that will be added.
>> +#
>> +# Note: this command is experimental, and not a stable API.
>> +#
>> +# Since: 2.5
>> +##
>> +{ 'command': 'x-child-add',
>> +  'data' : { 'parent': 'str', 'child': 'str' } }
> 
> This is probably not future-proof and only made for the special case of
> quorum. Specifically, one thing I'm missing is some way to specfiy what
> kind of child the new node is when a node can take different types of
> children (e.g. bs->file and bs->backing_hd).

Currently, we only add/remove quorum's child. We can add a new parameter
to specify the type in the furture to support more things.

Thanks
Wen Congyang

> 
> Kevin
> .
> 




Re: [Qemu-devel] [PATCH] block/ssh: remove dead code

2015-09-14 Thread Fam Zheng
On Mon, 09/14 13:12, Paolo Bonzini wrote:
> The "err" label cannot be reached with qp != NULL.  Remove the free-ing
> of qp and avoid future regressions by removing the initializer.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  block/ssh.c | 5 +
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/block/ssh.c b/block/ssh.c
> index 8d06739..d35b51f 100644
> --- a/block/ssh.c
> +++ b/block/ssh.c
> @@ -193,7 +193,7 @@ sftp_error_report(BDRVSSHState *s, const char *fs, ...)
>  static int parse_uri(const char *filename, QDict *options, Error **errp)
>  {
>  URI *uri = NULL;
> -QueryParams *qp = NULL;
> +QueryParams *qp;
>  int i;
>  
>  uri = uri_parse(filename);
> @@ -249,9 +249,6 @@ static int parse_uri(const char *filename, QDict 
> *options, Error **errp)
>  return 0;
>  
>   err:
> -if (qp) {
> -  query_params_free(qp);
> -}
>  if (uri) {
>uri_free(uri);
>  }
> -- 
> 2.5.0
> 
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH v3 1/5] support nbd driver in blockdev-add

2015-09-14 Thread Wen Congyang
On 09/15/2015 10:20 AM, Wen Congyang wrote:
> On 09/14/2015 11:47 PM, Eric Blake wrote:
>> On 09/14/2015 08:27 AM, Markus Armbruster wrote:
>>> Wen Congyang  writes:
>>>
 The NBD driver needs: filename, path or (host, port, exportname).
 It checks which key exists and decides use unix or inet socket.
 It doesn't recognize the key type, so we can't use union, and
 can't reuse InetSocketAddress.

 Signed-off-by: Wen Congyang 
 Signed-off-by: zhanghailiang 
 Signed-off-by: Gonglei 
 ---
  qapi/block-core.json | 42 --
  1 file changed, 40 insertions(+), 2 deletions(-)

>>
  ##
 +# @BlockdevOptionsNBD
 +#
 +# Driver specific block device options for NBD
 +#
 +# @filename: #optional unix or inet path. The format is:
 +#unix: nbd+unix:///export?socket=path or
 +#  nbd:unix:path:exportname=export
 +#inet: nbd[+tcp]://host[:port]/export or
 +#  nbd:host[:port]:exportname=export
>>
>> Yuck. You are passing structured data through a single 'str', when you
>> SHOULD be passing it through structured JSON.  Just because we have a
>> filename shorthand for convenience does NOT mean that we want to expose
>> that convenience in QMP.  Instead, we really want the breakdown of the
>> pieces (here, using abbreviated syntax of an inline base, since there
>> are pending qapi patches that will allow it):
>>
>> { 'enum': 'NBDTransport', 'data': ['unix', 'tcp', 'udp'] }
>> { 'union': 'BlockdevOptionsNBD',
>>   'base': { 'transport': 'NBDTransport', 'export': 'str' },
>>   'discriminator': 'transport',
>>   'data': { 'unix': 'NBDUnix', 'tcp': 'NBDInet', 'udp': 'NBDInet' } }
> 
> Building fails:
>   GEN   qmp-commands.h
> In file included from /work/src/qemu/qapi-schema.json:9:
> In file included from /work/src/qemu/qapi/block.json:6:
> /work/src/qemu/qapi/block-core.json:1844: Flat union 'BlockdevOptionsNBD' 
> must have a string base field
> Makefile:286: recipe for target 'qmp-commands.h' failed
> make: *** [qmp-commands.h] Error 1
> 
> What about this:
> { 'struct': 'BlockdevOptionsNBDBase',
>   'data': {  'transport': 'NBDTransport', 'export': 'str' } }
> { 'union': 'BlockdevOptionsNBD',
>   'base': 'BlockdevOptionsNBDBase',
>   'discriminator': 'transport',
>   'data': { 'unix': 'NBDUnix', 'tcp': 'NBDInet', 'udp': 'NBDInet' } }

Another problem:
In file included from /work/src/qemu/qapi-schema.json:9:
In file included from /work/src/qemu/qapi/block.json:6:
/work/src/qemu/qapi/block-core.json:1866: Member 'nbd' of union 
'BlockdevOptions' cannot use union type 'BlockdevOptionsNBD'
Makefile:286: recipe for target 'qmp-commands.h' failed

Thanks
Wen Congyang

> 
> Thanks
> Wen Congyang
> 
>> { 'struct': 'NBDUnix', 'data': { 'socket': 'str' } }
>> { 'struct': 'NBDInet', 'data': { 'host': 'str', '*port': 'int',
>>  '*ipv4': 'bool', '*ipv6': 'bool' } }
>>
>>
>>> I'm afraid this doesn't address Eric's review of your v2.
>>
>> Agreed; we still don't have the right interface.
>>
>>
>>> Eric further observed that support for the nbd+unix transport was
>>> missing, and suggested to have a union type combining the various
>>> transports.
>>
>> And I just spelled out above what that should look like.
>>
>>>
>>> If we decide separate types for single port and port ranges aren't
>>> worthwhile, you can simply use SocketAddress where your v2 used
>>> InetSocketAddress.
>>
>> I'm not sure if my 'NBDInet' above makes any more sense than reusing
>> 'SocketAddress' (and if we do reuse 'SocketAddress', we have the further
>> question of whether to split out socket ranges as a separate type so
>> that SocketAddress becomes a single-port identity).
>>
>>>
>>> Eric, how strongly do you feel about separating the two?
>>
>> I'm more worried about properly using a union type to represent unix vs.
>> tcp, and less worried about SocketAddress vs. range types vs creating a
>> new type (although in the long run, fixing ranges to be in a properly
>> named type rather than re-inventing the struct across multiple
>> transports is a good goal).  But you are quite correct that I do not
>> like the v3 proposal, because it encodes far too much information into a
>> single '*filename':'str', which is not the qapi way.
>>
> 
> 
> .
> 




Re: [Qemu-devel] [PATCH v4 2/4] block: support passing 'backing': '' to 'blockdev-add'

2015-09-14 Thread Fam Zheng
On Mon, 09/14 19:01, Alberto Garcia wrote:
> Passing an empty string allows opening an image but not its backing
> file. This was already described in the API documentation, only the
> implementation was missing.
> 
> This is useful for creating snapshots using images opened with
> blockdev-add, since they are not supposed to have a backing image
> before the operation.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/block.c b/block.c
> index 22d3b0e..ad1792d 100644
> --- a/block.c
> +++ b/block.c
> @@ -1402,6 +1402,7 @@ static int bdrv_open_inherit(BlockDriverState **pbs, 
> const char *filename,
>  BlockDriverState *file = NULL, *bs;
>  BlockDriver *drv = NULL;
>  const char *drvname;
> +const char *backing;
>  Error *local_err = NULL;
>  int snapshot_flags = 0;
>  
> @@ -1469,6 +1470,12 @@ static int bdrv_open_inherit(BlockDriverState **pbs, 
> const char *filename,
>  
>  assert(drvname || !(flags & BDRV_O_PROTOCOL));
>  
> +backing = qdict_get_try_str(options, "backing");
> +if (backing && *backing == '\0') {
> +flags |= BDRV_O_NO_BACKING;
> +}
> +qdict_del(options, "backing");
> +
>  bs->open_flags = flags;
>  bs->options = options;
>  options = qdict_clone_shallow(options);
> -- 
> 2.5.1
> 
> 

Specifying a non-empty "backing" will be a slient nop now, but it used to be an
error before.  Should we return an error?

Fam




Re: [Qemu-devel] [PATCH v3 1/5] support nbd driver in blockdev-add

2015-09-14 Thread Wen Congyang
On 09/14/2015 11:47 PM, Eric Blake wrote:
> On 09/14/2015 08:27 AM, Markus Armbruster wrote:
>> Wen Congyang  writes:
>>
>>> The NBD driver needs: filename, path or (host, port, exportname).
>>> It checks which key exists and decides use unix or inet socket.
>>> It doesn't recognize the key type, so we can't use union, and
>>> can't reuse InetSocketAddress.
>>>
>>> Signed-off-by: Wen Congyang 
>>> Signed-off-by: zhanghailiang 
>>> Signed-off-by: Gonglei 
>>> ---
>>>  qapi/block-core.json | 42 --
>>>  1 file changed, 40 insertions(+), 2 deletions(-)
>>>
> 
>>>  ##
>>> +# @BlockdevOptionsNBD
>>> +#
>>> +# Driver specific block device options for NBD
>>> +#
>>> +# @filename: #optional unix or inet path. The format is:
>>> +#unix: nbd+unix:///export?socket=path or
>>> +#  nbd:unix:path:exportname=export
>>> +#inet: nbd[+tcp]://host[:port]/export or
>>> +#  nbd:host[:port]:exportname=export
> 
> Yuck. You are passing structured data through a single 'str', when you
> SHOULD be passing it through structured JSON.  Just because we have a
> filename shorthand for convenience does NOT mean that we want to expose
> that convenience in QMP.  Instead, we really want the breakdown of the
> pieces (here, using abbreviated syntax of an inline base, since there
> are pending qapi patches that will allow it):
> 
> { 'enum': 'NBDTransport', 'data': ['unix', 'tcp', 'udp'] }
> { 'union': 'BlockdevOptionsNBD',
>   'base': { 'transport': 'NBDTransport', 'export': 'str' },
>   'discriminator': 'transport',
>   'data': { 'unix': 'NBDUnix', 'tcp': 'NBDInet', 'udp': 'NBDInet' } }

Building fails:
  GEN   qmp-commands.h
In file included from /work/src/qemu/qapi-schema.json:9:
In file included from /work/src/qemu/qapi/block.json:6:
/work/src/qemu/qapi/block-core.json:1844: Flat union 'BlockdevOptionsNBD' must 
have a string base field
Makefile:286: recipe for target 'qmp-commands.h' failed
make: *** [qmp-commands.h] Error 1

What about this:
{ 'struct': 'BlockdevOptionsNBDBase',
  'data': {  'transport': 'NBDTransport', 'export': 'str' } }
{ 'union': 'BlockdevOptionsNBD',
  'base': 'BlockdevOptionsNBDBase',
  'discriminator': 'transport',
  'data': { 'unix': 'NBDUnix', 'tcp': 'NBDInet', 'udp': 'NBDInet' } }

Thanks
Wen Congyang

> { 'struct': 'NBDUnix', 'data': { 'socket': 'str' } }
> { 'struct': 'NBDInet', 'data': { 'host': 'str', '*port': 'int',
>  '*ipv4': 'bool', '*ipv6': 'bool' } }
> 
> 
>> I'm afraid this doesn't address Eric's review of your v2.
> 
> Agreed; we still don't have the right interface.
> 
> 
>> Eric further observed that support for the nbd+unix transport was
>> missing, and suggested to have a union type combining the various
>> transports.
> 
> And I just spelled out above what that should look like.
> 
>>
>> If we decide separate types for single port and port ranges aren't
>> worthwhile, you can simply use SocketAddress where your v2 used
>> InetSocketAddress.
> 
> I'm not sure if my 'NBDInet' above makes any more sense than reusing
> 'SocketAddress' (and if we do reuse 'SocketAddress', we have the further
> question of whether to split out socket ranges as a separate type so
> that SocketAddress becomes a single-port identity).
> 
>>
>> Eric, how strongly do you feel about separating the two?
> 
> I'm more worried about properly using a union type to represent unix vs.
> tcp, and less worried about SocketAddress vs. range types vs creating a
> new type (although in the long run, fixing ranges to be in a properly
> named type rather than re-inventing the struct across multiple
> transports is a good goal).  But you are quite correct that I do not
> like the v3 proposal, because it encodes far too much information into a
> single '*filename':'str', which is not the qapi way.
> 




Re: [Qemu-devel] [RFT PATCH v1 3/3] net: smc91c111: flush packets on RCR register changes

2015-09-14 Thread Fam Zheng
On Thu, 09/10 21:24, Peter Crosthwaite wrote:
> The SOFT_RST or RXEN in the control register can be used as a condition
> to unblock the net layer via can_receive(). So check for possible
> flushes on RCR changes. This will drop all pending packets on soft
> reset or disable which is the functional intent of the can_receive()
> logic.
> 
> Signed-off-by: Peter Crosthwaite 
> ---
> 
>  hw/net/smc91c111.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
> index 8fc3deb..c19cdd1 100644
> --- a/hw/net/smc91c111.c
> +++ b/hw/net/smc91c111.c
> @@ -331,6 +331,7 @@ static void smc91c111_writeb(void *opaque, hwaddr offset,
>  if (s->rcr & RCR_SOFT_RST) {
>  smc91c111_reset(DEVICE(s));
>  }
> +smc91c111_flush_queued_packets(s);
>  return;
>  case 10: case 11: /* RPCR */
>  /* Ignored */
> -- 
> 1.9.1
> 
> 

Reviewed-by: Fam Zheng 

This should be useful for other NICs too.

Fam



Re: [Qemu-devel] [PATCH v2 4/5] acpi: arm: add fw_cfg device node to dsdt

2015-09-14 Thread Shannon Zhao


On 2015/9/14 22:57, Gabriel L. Somlo wrote:
> Add a fw_cfg device node to the ACPI DSDT. This is mostly
> informational, as the authoritative fw_cfg MMIO region(s)
> are listed in the Device Tree. However, since we are building
> ACPI tables, we might as well be thorough while at it...
> 
> Signed-off-by: Gabriel Somlo 
> ---
>  hw/arm/virt-acpi-build.c | 13 +
>  1 file changed, 13 insertions(+)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 9088248..dcf9752 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -110,6 +110,18 @@ static void acpi_dsdt_add_rtc(Aml *scope, const 
> MemMapEntry *rtc_memmap,
>  aml_append(scope, dev);
>  }
>  
> +static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry 
> *fw_cfg_memmap)
> +{
> +Aml *dev = aml_device("FWCF");
> +aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
> +
> +Aml *crs = aml_resource_template();
> +aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
> +   fw_cfg_memmap->size, AML_READ_WRITE));
> +aml_append(dev, aml_name_decl("_CRS", crs));
> +aml_append(scope, dev);
> +}
> +
>  static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
>  {
>  Aml *dev, *crs;
> @@ -519,6 +531,7 @@ build_dsdt(GArray *table_data, GArray *linker, 
> VirtGuestInfo *guest_info)
> (irqmap[VIRT_UART] + ARM_SPI_BASE));
>  acpi_dsdt_add_rtc(scope, &memmap[VIRT_RTC],
>(irqmap[VIRT_RTC] + ARM_SPI_BASE));
> +acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
>  acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
>  acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
>  (irqmap[VIRT_MMIO] + ARM_SPI_BASE), 
> NUM_VIRTIO_TRANSPORTS);
> 

This looks fine to me. But from what you said, the kernel driver is not
in upstream kernel yet, so this would be applied after the kernel patch
applied in case of unexpected change.

Thanks,
-- 
Shannon




Re: [Qemu-devel] [PATCH 6/7] vhost-user: add multiple queue support

2015-09-14 Thread Yuanhan Liu
On Mon, Sep 14, 2015 at 06:00:41PM +0800, Jason Wang wrote:
> 
> 
> On 09/08/2015 03:38 PM, Yuanhan Liu wrote:
> > From: Ouyang Changchun 
> >
> > This patch is initially based a patch from Nikolay Nikolaev.
> >
> > Here is the latest version for adding vhost-user multiple queue support,
> > by creating a nc and vhost_net pair for each queue.
> >
> > What differs from last version is that this patch addresses two major
> > concerns from Michael, and fixes one hidden bug.
> >
> > - Concern #1: no feedback when the backend can't support # of
> >   requested queues(by providing queues=# option).
> >
> >   Here we address this issue by querying VHOST_USER_PROTOCOL_F_MQ
> >   protocol features first, if not set, it means the backend don't
> >   support mq feature, and let max_queues be 1. Otherwise, we send
> >   another message, VHOST_USER_GET_QUEUE_NUM, for getting the max_queues
> >   the backend supports.
> >
> >   At vhost-user initiation stage(net_vhost_user_start), we then initiate
> >   one queue first, which, in the meantime, also gets the max_queues.
> >   We then do a simple compare: if requested_queues > max_queues, we
> >   exit(I guess it's safe to exit here, as the vm is not running yet).
> >
> > - Concern #2: some messages are sent more times than necessary.
> >
> >   We came an agreement with Michael that we could categorize vhost
> >   user messages to 2 types: none-vring specific messages, which should
> >   be sent only once, and vring specific messages, which should be sent
> >   per queue.
> >
> >   Here I introduced a helper function vhost_user_one_time_request(),
> >   which lists following messages as none-vring specific messages:
> >
> > VHOST_USER_GET_FEATURES
> > VHOST_USER_SET_FEATURES
> > VHOST_USER_GET_PROTOCOL_FEATURES
> > VHOST_USER_SET_PROTOCOL_FEATURES
> > VHOST_USER_SET_OWNER
> > VHOST_USER_RESET_DEVICE
> > VHOST_USER_SET_MEM_TABLE
> > VHOST_USER_GET_QUEUE_NUM
> >
> >   For above messages, we simply ignore them when they are not sent the first
> >   time.
> >
> > I also observed a hidden bug from last version. We register the char dev
> > event handler N times, which is not necessary, as well as buggy: A later
> > register overwrites the former one, as qemu_chr_add_handlers() will not
> > chain those handlers, but instead overwrites the old one. So, in theory,
> > invoking qemu_chr_add_handlers N times will not end up with calling the
> > handler N times.
> >
> > However, the reason the handler is invoked N times is because we start
> > the backend(the connection server) first, and hence when 
> > net_vhost_user_init()
> > is executed, the connection is already established, and 
> > qemu_chr_add_handlers()
> > then invoke the handler immediately, which just looks like we invoke the
> > handler(net_vhost_user_event) directly from net_vhost_user_init().
> >
> > The solution I came up with is to make VhostUserState as an upper level
> > structure, making it includes N nc and vhost_net pairs:
> >
> >struct VhostUserNetPeer {
> >NetClientState *nc;
> >VHostNetState  *vhost_net;
> >};
> >
> >typedef struct VhostUserState {
> >CharDriverState *chr;
> >bool running;
> >int queues;
> >struct VhostUserNetPeer peers[];
> >} VhostUserState;
> 
> Haven't looked at previous versions but alternatively, can you do this by:
> 
> - keep current VhostUserState
> - allocate multiple VhostUserState
> - register the char handler only on VhostUserState[0]
> - enumerate all others in handler by qemu_find_net_clients_except() ?

That does sound work and much better! I will give it a try soon. Thanks!

> 
> >
> > Signed-off-by: Nikolay Nikolaev 
> > Signed-off-by: Changchun Ouyang 
> > Signed-off-by: Yuanhan Liu 
> > ---
...
> >  case VHOST_USER_GET_VRING_BASE:
> >  memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
> > +msg.addr.index += dev->vq_index;
> 
> Let's don't do this silently here. Since we've done a minus in
> vhost_virtqueue_start(), I think we could introduce a new callback and
> do correct calculation there.

Good point, I will try it as well.

> > -s->vhost_net = vhost_net_init(&options);
> > +options.net_backend = s->peers[i].nc;
> > +vhost_net = s->peers[i++].vhost_net = vhost_net_init(&options);
> > +
> > +max_queues = vhost_net_get_max_queues(vhost_net);
> > +if (s->queues >= max_queues) {
> > +error_report("you are asking more queues than supported: %d\n",
> > + max_queues);
> > +return -1;
> 
> Memory leak here?

Yeah, it is. But Does it matter? Since we will call exit() soon, which will
reclaim everything in the end. Or, even though, it's still needed?

Either way, I can do that.

> 
> > +}
> > +
> > +for (; i < s->queues; i++) {
> > +options.net_backend = s->peers[i].nc;
> > +
> > +s->peers[i].vhost_net = vhost_net_init(&options);
> > +if

Re: [Qemu-devel] [RFT PATCH v1 2/3] net: smc91c111: gate can_receive() on rx FIFO having a slot

2015-09-14 Thread Fam Zheng
On Thu, 09/10 21:23, Peter Crosthwaite wrote:
> Return false from can_receive() when the FIFO doesn't have a free RX
> slot. This fixes a bug in the current code where the allocated buffer
> is freed before the fifo pop, triggering a premature flush of queued RX
> packets. It also will handle a corner case, where the guest manually
> frees the allocated buffer before popping the rx FIFO (hence it is not
> enough to just delay the flush_queued_packets()).
> 
> Reported-by: Richard Purdie 
> Signed-off-by: Peter Crosthwaite 
> ---
> 
>  hw/net/smc91c111.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
> index 5774eff..8fc3deb 100644
> --- a/hw/net/smc91c111.c
> +++ b/hw/net/smc91c111.c
> @@ -129,7 +129,8 @@ static int smc91c111_can_receive(smc91c111_state *s)
>  if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) {
>  return 1;
>  }
> -if (s->allocated == (1 << NUM_PACKETS) - 1) {
> +if (s->allocated == (1 << NUM_PACKETS) - 1 ||
> +s->rx_fifo_len == NUM_PACKETS) {
>  return 0;
>  }
>  return 1;
> @@ -182,6 +183,7 @@ static void smc91c111_pop_rx_fifo(smc91c111_state *s)
>  } else {
>  s->int_level &= ~INT_RCV;
>  }
> +smc91c111_flush_queued_packets(s);
>  smc91c111_update(s);
>  }
>  
> -- 
> 1.9.1
> 
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [RFT PATCH v1 1/3] net: smc91c111: guard flush_queued_packets() on can_rx()

2015-09-14 Thread Fam Zheng
On Thu, 09/10 21:23, Peter Crosthwaite wrote:
> Check that the core can once again receive packets before asking the
> net layer to do a flush. This will make it more convenient to flush
> packets when adding new conditions to can_receive.
> 
> Add missing if braces while moving the can_receive() core code.
> 
> Signed-off-by: Peter Crosthwaite 
> ---
> 
>  hw/net/smc91c111.c | 30 ++
>  1 file changed, 22 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
> index 74e06e6..5774eff 100644
> --- a/hw/net/smc91c111.c
> +++ b/hw/net/smc91c111.c
> @@ -124,6 +124,24 @@ static void smc91c111_update(smc91c111_state *s)
>  qemu_set_irq(s->irq, level);
>  }
>  
> +static int smc91c111_can_receive(smc91c111_state *s)
> +{
> +if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) {
> +return 1;
> +}
> +if (s->allocated == (1 << NUM_PACKETS) - 1) {
> +return 0;
> +}
> +return 1;
> +}
> +
> +static inline void smc91c111_flush_queued_packets(smc91c111_state *s)
> +{
> +if (smc91c111_can_receive(s)) {
> +qemu_flush_queued_packets(qemu_get_queue(s->nic));
> +}
> +}
> +
>  /* Try to allocate a packet.  Returns 0x80 on failure.  */
>  static int smc91c111_allocate_packet(smc91c111_state *s)
>  {
> @@ -185,7 +203,7 @@ static void smc91c111_release_packet(smc91c111_state *s, 
> int packet)
>  s->allocated &= ~(1 << packet);
>  if (s->tx_alloc == 0x80)
>  smc91c111_tx_alloc(s);
> -qemu_flush_queued_packets(qemu_get_queue(s->nic));
> +smc91c111_flush_queued_packets(s);
>  }
>  
>  /* Flush the TX FIFO.  */
> @@ -636,15 +654,11 @@ static uint32_t smc91c111_readl(void *opaque, hwaddr 
> offset)
>  return val;
>  }
>  
> -static int smc91c111_can_receive(NetClientState *nc)
> +static int smc91c111_can_receive_nc(NetClientState *nc)
>  {
>  smc91c111_state *s = qemu_get_nic_opaque(nc);
>  
> -if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
> -return 1;
> -if (s->allocated == (1 << NUM_PACKETS) - 1)
> -return 0;
> -return 1;
> +return smc91c111_can_receive(s);
>  }
>  
>  static ssize_t smc91c111_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> @@ -739,7 +753,7 @@ static const MemoryRegionOps smc91c111_mem_ops = {
>  static NetClientInfo net_smc91c111_info = {
>  .type = NET_CLIENT_OPTIONS_KIND_NIC,
>  .size = sizeof(NICState),
> -.can_receive = smc91c111_can_receive,
> +.can_receive = smc91c111_can_receive_nc,
>  .receive = smc91c111_receive,
>  };
>  
> -- 
> 1.9.1
> 
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH v3 1/5] support nbd driver in blockdev-add

2015-09-14 Thread Wen Congyang
On 09/14/2015 11:47 PM, Eric Blake wrote:
> On 09/14/2015 08:27 AM, Markus Armbruster wrote:
>> Wen Congyang  writes:
>>
>>> The NBD driver needs: filename, path or (host, port, exportname).
>>> It checks which key exists and decides use unix or inet socket.
>>> It doesn't recognize the key type, so we can't use union, and
>>> can't reuse InetSocketAddress.
>>>
>>> Signed-off-by: Wen Congyang 
>>> Signed-off-by: zhanghailiang 
>>> Signed-off-by: Gonglei 
>>> ---
>>>  qapi/block-core.json | 42 --
>>>  1 file changed, 40 insertions(+), 2 deletions(-)
>>>
> 
>>>  ##
>>> +# @BlockdevOptionsNBD
>>> +#
>>> +# Driver specific block device options for NBD
>>> +#
>>> +# @filename: #optional unix or inet path. The format is:
>>> +#unix: nbd+unix:///export?socket=path or
>>> +#  nbd:unix:path:exportname=export
>>> +#inet: nbd[+tcp]://host[:port]/export or
>>> +#  nbd:host[:port]:exportname=export
> 
> Yuck. You are passing structured data through a single 'str', when you
> SHOULD be passing it through structured JSON.  Just because we have a
> filename shorthand for convenience does NOT mean that we want to expose
> that convenience in QMP.  Instead, we really want the breakdown of the
> pieces (here, using abbreviated syntax of an inline base, since there
> are pending qapi patches that will allow it):

Do you mean that: there is no need to support filename?

> 
> { 'enum': 'NBDTransport', 'data': ['unix', 'tcp', 'udp'] }

NBD only uses tcp, it doesn't support udp.

> { 'union': 'BlockdevOptionsNBD',
>   'base': { 'transport': 'NBDTransport', 'export': 'str' },
>   'discriminator': 'transport',
>   'data': { 'unix': 'NBDUnix', 'tcp': 'NBDInet', 'udp': 'NBDInet' } }
> { 'struct': 'NBDUnix', 'data': { 'socket': 'str' } }

unix socket needs a path, and I think we can use UnixSocketAddress here.

> { 'struct': 'NBDInet', 'data': { 'host': 'str', '*port': 'int',
>  '*ipv4': 'bool', '*ipv6': 'bool' } }

Thanks for the above, and I will try it.

> 
> 
>> I'm afraid this doesn't address Eric's review of your v2.
> 
> Agreed; we still don't have the right interface.
> 
> 
>> Eric further observed that support for the nbd+unix transport was
>> missing, and suggested to have a union type combining the various
>> transports.
> 
> And I just spelled out above what that should look like.
> 
>>
>> If we decide separate types for single port and port ranges aren't
>> worthwhile, you can simply use SocketAddress where your v2 used
>> InetSocketAddress.
> 
> I'm not sure if my 'NBDInet' above makes any more sense than reusing
> 'SocketAddress' (and if we do reuse 'SocketAddress', we have the further
> question of whether to split out socket ranges as a separate type so
> that SocketAddress becomes a single-port identity).
> 
>>
>> Eric, how strongly do you feel about separating the two?
> 
> I'm more worried about properly using a union type to represent unix vs.
> tcp, and less worried about SocketAddress vs. range types vs creating a
> new type (although in the long run, fixing ranges to be in a properly
> named type rather than re-inventing the struct across multiple
> transports is a good goal).  But you are quite correct that I do not
> like the v3 proposal, because it encodes far too much information into a
> single '*filename':'str', which is not the qapi way.
> 




Re: [Qemu-devel] [PATCH v2 2/2] hw/arm/virt-acpi-build: Add DBG2 table

2015-09-14 Thread Shannon Zhao


On 2015/9/15 0:35, Andrew Jones wrote:
> On Sun, Sep 13, 2015 at 04:06:33PM +0100, Leif Lindholm wrote:
>> Add a DBG2 table, describing the pl011 UART.
>>
>> Signed-off-by: Leif Lindholm 
>> ---
>>  hw/arm/virt-acpi-build.c | 60 
>> +++-
>>  1 file changed, 59 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 9088248..0ea7023 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -352,6 +352,61 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned 
>> rsdt)
>>  }
>>  
>>  static void
>> +build_dbg2(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
>> +{
>> +AcpiDebugPort2Header *dbg2;
>> +AcpiDebugPort2Device *dev;
>> +struct AcpiGenericAddress *addr;
>> +uint32_t *addr_size;
>> +char *name;
>> +const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART];
>> +int table_size, dev_size, namepath_length;
>> +const char namepath[] = ".";
>> +
>> +namepath_length = strlen(namepath) + 1;
>> +dev_size = sizeof(*dev) + sizeof(*addr) * 1 + sizeof(uint32_t) * 1 +
>> +namepath_length;
>> +table_size = dev_size + sizeof(AcpiDebugPort2Header);
>> +
>> +dbg2 = acpi_data_push(table_data, table_size);
>> +dev = (void *)dbg2 + sizeof(*dbg2);
>> +addr = (void *)dev + sizeof(*dev);
>> +addr_size = (void *)addr + sizeof(*addr);
>> +name = (void *)addr_size + sizeof(*addr_size);
>> +

This looks hard to read.

>> +dbg2->devices_offset = sizeof(*dbg2);
>> +dbg2->devices_count = 1;
>> +
>> +/* First (only) debug device */
>> +dev->revision = 0;
>> +dev->length = cpu_to_le16(dev_size);
>> +dev->address_count = 1;
>> +dev->namepath_length = cpu_to_le16(namepath_length);
>> +dev->namepath_offset = cpu_to_le16((void *)name - (void *)dev);
>> +dev->oem_data_length = 0;
>> +dev->oem_data_offset = 0;
>> +dev->port_type = cpu_to_le16(0x8000);/* Serial */
>> +dev->port_subtype = cpu_to_le16(0x3);/* ARM PL011 UART */
>> +dev->base_address_offset = cpu_to_le16((void *)addr - (void *)dev);
>> +dev->address_size_offset = cpu_to_le16((void *)addr_size - (void *)dev);
>> +
>> +/* First (only) address */
>> +addr->space_id = AML_SYSTEM_MEMORY;
>> +addr->bit_width = 8;
>> +addr->bit_offset = 0;
>> +addr->access_width = 1;
>> +addr->address = cpu_to_le64(uart_memmap->base);
>> +
>> +/* Size of first (only) address */
>> +*addr_size = cpu_to_le32(sizeof(*addr));
>> +
>> +/* Namespace String for first (only) device */
>> +strcpy(name, namepath);
>> +
>> +build_header(linker, table_data, (void *)dbg2, "DBG2", table_size, 0);
>> +}
>> +
>> +static void
>>  build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
>>  {
>>  AcpiSerialPortConsoleRedirection *spcr;
>> @@ -577,7 +632,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
>> AcpiBuildTables *tables)
>>  dsdt = tables_blob->len;
>>  build_dsdt(tables_blob, tables->linker, guest_info);
>>  
>> -/* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
>> +/* FADT MADT GTDT MCFG DBG2 SPCR pointed to by RSDT */
>>  acpi_add_table(table_offsets, tables_blob);
>>  build_fadt(tables_blob, tables->linker, dsdt);
>>  
>> @@ -591,6 +646,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
>> AcpiBuildTables *tables)
>>  build_mcfg(tables_blob, tables->linker, guest_info);
>>  
>>  acpi_add_table(table_offsets, tables_blob);
>> +build_dbg2(tables_blob, tables->linker, guest_info);
>> +
>> +acpi_add_table(table_offsets, tables_blob);
>>  build_spcr(tables_blob, tables->linker, guest_info);
>>  
>>  /* RSDT is pointed to by RSDP */
>> -- 
>> 2.1.4
>>
>>
> 
> This looks good to me, since it's pretty unlikely we'll ever want
> more than one device, so
> 
> Reviewed-by: Andrew Jones 
> 
> But, when I read that the table generation had become dynamic, I was sort
> of expecting something like
> 

Leif, you can have a look at build_madt.

-- 
Shannon



Re: [Qemu-devel] [Question] QEMU 2.3 Assertion with `existing->mr->subpage || existing->mr == &io_mem_unassigned' failed

2015-09-14 Thread Gonglei
On 2015/9/14 17:28, Paolo Bonzini wrote:
> 
> 
> On 14/09/2015 10:01, Gonglei (Arei) wrote:
>> [2015-09-11 13:42:44] domain is rebooting 
>> qemu-kvm: /home/abuild/rpmbuild/BUILD/qemu-kvm-2.3.0/exec.c:1188: 
>> register_subpage: Assertion `existing->mr->subpage || existing->mr == 
>> &io_mem_unassigned' failed. 
>> [2015-09-11 13:42:58]: shutting down
>>
>> Or
>> qemu-kvm: 
>> /home/abuild/rpmbuild/BUILD/qemu-kvm-2.3.0/include/qemu/int128.h:22: 
>> int128_get64: Assertion `!a.hi' failed.
> 
> You need to provide a backtrace.
> 
> Paolo
> 
Yup, I noticed that, but when I sent this email yesterday, I didn't get a 
backtrace :(
Fortunately,   I get a backtrace now:

#0 int128_get64 (a=...) at /home/qemu/include/qemu/int128.h:27
#1 0x7f17ad7a7f1a in register_multipage (d=0x7f179c4f8480, 
section=0x7f17a323c3f0) at /home/qemu/exec.c:1215
#2 0x7f17ad7a8266 in mem_add (listener=0x7f17ae043968 
, section=0x7f17a323c730) at /home/qemu/exec.c:1250
#3 0x7f17ad7f843a in address_space_update_topology_pass (as=0x7f17ae043920 
, old_view=0x7f179c1f8b50, new_view=0x7f179c523620, 
adding=true)
at /home/qemu/memory.c:739
#4 0x7f17ad7f8520 in address_space_update_topology (as=0x7f17ae043920 
) at /home/qemu/memory.c:754
#5 0x7f17ad7f8660 in memory_region_transaction_commit () at 
/home/qemu/memory.c:794
#6 0x7f17ad9a690c in cirrus_update_memory_access (s=0x7f17b12873c0) at 
hw/display/cirrus_vga.c:2485
#7 0x7f17ad9a4dac in cirrus_vga_write_gr (s=0x7f17b12873c0, reg_index=9, 
reg_value=163) at hw/display/cirrus_vga.c:1524
#8 0x7f17ad9a6e47 in cirrus_vga_ioport_write (opaque=0x7f17b12873c0, 
addr=975, val=163, size=1) at hw/display/cirrus_vga.c:2672
#9 0x7f17ad7f6882 in memory_region_write_accessor (mr=0x7f17b1297d88, 
addr=31, value=0x7f17a323c968, size=1, shift=8, mask=255) at 
/home/qemu/memory.c:430
#10 0x7f17ad7f698b in access_with_adjusted_size (addr=30, 
value=0x7f17a323c968, size=2, access_size_min=1, access_size_max=1, 
access=0x7f17ad7f67fd , mr=0x7f17b1297d88)
at /home/qemu/memory.c:467
#11 0x7f17ad7f9311 in memory_region_dispatch_write (mr=0x7f17b1297d88, 
addr=30, data=41737, size=2) at /home/qemu/memory.c:1103
#12 0x7f17ad7fc22e in io_mem_write (mr=0x7f17b1297d88, addr=30, val=41737, 
size=2) at /home/qemu/memory.c:2003
#13 0x7f17ad7aafe4 in address_space_rw (as=0x7f17ae043920 
, addr=974, buf=0x7f17ad6f6000 "\t\243\320", len=2, 
is_write=true) at /home/qemu/exec.c:2533
#14 0x7f17ad7f3acf in kvm_handle_io (port=974, data=0x7f17ad6f6000, 
direction=1, size=2, count=1) at /home/qemu/kvm-all.c:1707
#15 0x7f17ad7f3fb5 in kvm_cpu_exec (cpu=0x7f17b05b7a20) at 
/home/qemu/kvm-all.c:1864
#16 0x7f17ad7db416 in qemu_kvm_cpu_thread_fn (arg=0x7f17b05b7a20) at 
/home/qemu/cpus.c:972
#17 0x7f17ac2cbdf5 in start_thread () from /lib64/libpthread.so.0
#18 0x7f17a73e31ad in clone () from /lib64/libc.so.6

It seems that something wrong happened in vga memory updating.

Regards,
-Gonglei




Re: [Qemu-devel] [PATCH] migration: Use g_new() & friends where that makes obvious sense

2015-09-14 Thread zhanghailiang

Reviewed-by: zhanghailiang 

On 2015/9/14 19:51, Markus Armbruster wrote:

g_new(T, n) is neater than g_malloc(sizeof(T) * n).  It's also safer,
for two reasons.  One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.

This commit only touches allocations with size arguments of the form
sizeof(T).  Same Coccinelle semantic patch as in commit b45c03f.

Signed-off-by: Markus Armbruster 
---
  migration/migration.c   |  2 +-
  migration/qemu-file-buf.c   |  2 +-
  migration/qemu-file-stdio.c |  4 ++--
  migration/qemu-file-unix.c  |  4 ++--
  migration/qemu-file.c   |  2 +-
  migration/rdma.c| 17 -
  migration/savevm.c  | 12 ++--
  7 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 662e77e..e0ce401 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -86,7 +86,7 @@ MigrationIncomingState *migration_incoming_get_current(void)

  MigrationIncomingState *migration_incoming_state_new(QEMUFile* f)
  {
-mis_current = g_malloc0(sizeof(MigrationIncomingState));
+mis_current = g_new0(MigrationIncomingState, 1);
  mis_current->file = f;
  QLIST_INIT(&mis_current->loadvm_handlers);

diff --git a/migration/qemu-file-buf.c b/migration/qemu-file-buf.c
index 2de9330..7adec46 100644
--- a/migration/qemu-file-buf.c
+++ b/migration/qemu-file-buf.c
@@ -439,7 +439,7 @@ QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer 
*input)
  return NULL;
  }

-s = g_malloc0(sizeof(QEMUBuffer));
+s = g_new0(QEMUBuffer, 1);
  s->qsb = input;

  if (s->qsb == NULL) {
diff --git a/migration/qemu-file-stdio.c b/migration/qemu-file-stdio.c
index 285068b..079caee 100644
--- a/migration/qemu-file-stdio.c
+++ b/migration/qemu-file-stdio.c
@@ -143,7 +143,7 @@ QEMUFile *qemu_popen_cmd(const char *command, const char 
*mode)
  return NULL;
  }

-s = g_malloc0(sizeof(QEMUFileStdio));
+s = g_new0(QEMUFileStdio, 1);

  s->stdio_file = stdio_file;

@@ -175,7 +175,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode)
  return NULL;
  }

-s = g_malloc0(sizeof(QEMUFileStdio));
+s = g_new0(QEMUFileStdio, 1);

  s->stdio_file = fopen(filename, mode);
  if (!s->stdio_file) {
diff --git a/migration/qemu-file-unix.c b/migration/qemu-file-unix.c
index bfbc086..7d80a54 100644
--- a/migration/qemu-file-unix.c
+++ b/migration/qemu-file-unix.c
@@ -192,7 +192,7 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
  return NULL;
  }

-s = g_malloc0(sizeof(QEMUFileSocket));
+s = g_new0(QEMUFileSocket, 1);
  s->fd = fd;

  if (mode[0] == 'r') {
@@ -226,7 +226,7 @@ QEMUFile *qemu_fopen_socket(int fd, const char *mode)
  return NULL;
  }

-s = g_malloc0(sizeof(QEMUFileSocket));
+s = g_new0(QEMUFileSocket, 1);
  s->fd = fd;
  if (mode[0] == 'w') {
  qemu_set_block(s->fd);
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 6bb3dc1..6162e7e 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -60,7 +60,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
  {
  QEMUFile *f;

-f = g_malloc0(sizeof(QEMUFile));
+f = g_new0(QEMUFile, 1);

  f->opaque = opaque;
  f->ops = ops;
diff --git a/migration/rdma.c b/migration/rdma.c
index 9424834..8886fa2 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -541,7 +541,7 @@ static int rdma_add_block(RDMAContext *rdma, const char 
*block_name,
  RDMALocalBlock *block;
  RDMALocalBlock *old = local->block;

-local->block = g_malloc0(sizeof(RDMALocalBlock) * (local->nb_blocks + 1));
+local->block = g_new0(RDMALocalBlock, local->nb_blocks + 1);

  if (local->nb_blocks) {
  int x;
@@ -572,7 +572,7 @@ static int rdma_add_block(RDMAContext *rdma, const char 
*block_name,
  bitmap_clear(block->transit_bitmap, 0, block->nb_chunks);
  block->unregister_bitmap = bitmap_new(block->nb_chunks);
  bitmap_clear(block->unregister_bitmap, 0, block->nb_chunks);
-block->remote_keys = g_malloc0(block->nb_chunks * sizeof(uint32_t));
+block->remote_keys = g_new0(uint32_t, block->nb_chunks);

  block->is_ram_block = local->init ? false : true;

@@ -617,8 +617,8 @@ static int qemu_rdma_init_ram_blocks(RDMAContext *rdma)
  memset(local, 0, sizeof *local);
  qemu_ram_foreach_block(qemu_rdma_init_one_block, rdma);
  trace_qemu_rdma_init_ram_blocks(local->nb_blocks);
-rdma->dest_blocks = (RDMADestBlock *) g_malloc0(sizeof(RDMADestBlock) *
-rdma->local_ram_blocks.nb_blocks);
+rdma->dest_blocks = g_new0(RDMADestBlock,
+   rdma->local_ram_blocks.nb_blocks);
  local->init = true;
  return 0;
  }
@@ -677,8 +677,7 @@ static int rdma_delete_block(RDMAContext *rdma, 
RDMALocalBlock *block)

  if 

Re: [Qemu-devel] [PATCH v11 4/5] cpu/apic: drop icc bus/bridge

2015-09-14 Thread Zhu Guihua


On 09/14/2015 09:18 PM, Igor Mammedov wrote:

On Wed, 2 Sep 2015 17:36:21 +0800
Zhu Guihua  wrote:


From: Chen Fan 

After CPU hotplug has been converted to BUS-less hot-plug infrastructure,
the only function ICC bus performs is to propagate reset to LAPICs. However
LAPIC could be reset by registering its reset handler after all device are
initialized.
Do so and drop ~200LOC of not needed anymore ICCBus related code.

this patch drops about 30LOCs only ...


PS:
Doesn't apply to current master, please rebase.


This patch rebased on my another patch
'[PATCH v3] i386: keep cpu_model field in MachineState uptodate'
https://lists.nongnu.org/archive/html/qemu-devel/2015-08/msg03375.html

The patch has been reviewed by Eduardo, but not been merged.

Should I only rebase on current master?

Thanks,
Zhu


Signed-off-by: Chen Fan 
Signed-off-by: Zhu Guihua 
---
  hw/i386/pc.c| 19 ---
  hw/i386/pc_piix.c   |  9 +
  hw/i386/pc_q35.c|  9 +
  hw/intc/apic_common.c   |  5 ++---
  include/hw/i386/apic_internal.h |  7 ---
  include/hw/i386/pc.h|  2 +-
  target-i386/cpu.c   |  9 +
  7 files changed, 14 insertions(+), 46 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4b4a7f3..4c1d68a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -59,7 +59,6 @@
  #include "qemu/error-report.h"
  #include "hw/acpi/acpi.h"
  #include "hw/acpi/cpu_hotplug.h"
-#include "hw/cpu/icc_bus.h"
  #include "hw/boards.h"
  #include "hw/pci/pci_host.h"
  #include "acpi-build.h"
@@ -1052,23 +1051,16 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int 
level)
  }
  
  static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,

-  DeviceState *icc_bridge, Error **errp)
+  Error **errp)
  {
  X86CPU *cpu = NULL;
  Error *local_err = NULL;
  
-if (icc_bridge == NULL) {

-error_setg(&local_err, "Invalid icc-bridge value");
-goto out;
-}
-
  cpu = cpu_x86_create(cpu_model, &local_err);
  if (local_err != NULL) {
  goto out;
  }
  
-qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));

-
  object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
  object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
  
@@ -1083,7 +1075,6 @@ out:
  
  void pc_hot_add_cpu(const int64_t id, Error **errp)

  {
-DeviceState *icc_bridge;
  MachineState *machine = MACHINE(qdev_get_machine());
  X86CPU *cpu;
  int64_t apic_id = x86_cpu_apic_id_from_index(id);
@@ -1113,9 +1104,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
  return;
  }
  
-icc_bridge = DEVICE(object_resolve_path_type("icc-bridge",

- TYPE_ICC_BRIDGE, NULL));
-cpu = pc_new_cpu(machine->cpu_model, apic_id, icc_bridge, &local_err);
+cpu = pc_new_cpu(machine->cpu_model, apic_id, &local_err);
  if (local_err) {
  error_propagate(errp, local_err);
  return;
@@ -1123,7 +1112,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
  object_unref(OBJECT(cpu));
  }
  
-void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge)

+void pc_cpus_init(PCMachineState *pcms)
  {
  int i;
  X86CPU *cpu = NULL;
@@ -1149,7 +1138,7 @@ void pc_cpus_init(PCMachineState *pcms, DeviceState 
*icc_bridge)
  
  for (i = 0; i < smp_cpus; i++) {

  cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i),
- icc_bridge, &error);
+ &error);
  if (error) {
  error_report_err(error);
  exit(1);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index fd6130d..3a97826 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -39,7 +39,6 @@
  #include "hw/kvm/clock.h"
  #include "sysemu/sysemu.h"
  #include "hw/sysbus.h"
-#include "hw/cpu/icc_bus.h"
  #include "sysemu/arch_init.h"
  #include "sysemu/block-backend.h"
  #include "hw/i2c/smbus.h"
@@ -96,7 +95,6 @@ static void pc_init1(MachineState *machine)
  MemoryRegion *ram_memory;
  MemoryRegion *pci_memory;
  MemoryRegion *rom_memory;
-DeviceState *icc_bridge;
  PcGuestInfo *guest_info;
  ram_addr_t lowmem;
  
@@ -141,11 +139,7 @@ static void pc_init1(MachineState *machine)

  exit(1);
  }
  
-icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);

-object_property_add_child(qdev_get_machine(), "icc-bridge",
-  OBJECT(icc_bridge), NULL);
-
-pc_cpus_init(pcms, icc_bridge);
+pc_cpus_init(pcms);
  
  if (kvm_enabled() && kvmclock_enabled) {

  kvmclock_create();
@@ -223,7 +217,6 @@ static void pc_init1(MachineState *machine)
  if (pci_enabled) {
  ioapic_init_gsi(gsi_state, "i440fx");
  }
-qdev_init_nofail(icc_bridge);
  
  pc_register_ferr_irq(gsi[13]);

Re: [Qemu-devel] [RFCv2 1/2] spapr: Remove unnecessary owner field from sPAPRDRConnector

2015-09-14 Thread David Gibson
On Mon, Sep 14, 2015 at 02:11:53PM +0200, Paolo Bonzini wrote:
> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA256
> 
> 
> 
> On 14/09/2015 13:45, David Gibson wrote:
> >>> 
> >>> === * There is no way for a child to determine what its parent
> >>> is.  It is not * a bidirectional relationship.  This is by
> >>> design. ===
> >>> 
> >>> This part always confused me as there is "Object *parent" in
> >>> the "struct Object". So there is way to determine but it must
> >>> not be used? Is it debug only?
> >>> 
> >>> Anyway, all members of the Object class are under /*< private
> >>> >*/ so they should not be accesses in sPAPR code, I believe.
> > Ah, good point, I missed that.  I guess we have to keep the owner 
> > field, redundant though it seems.  Blech.
> 
> I think the comment is wrong or at least inaccurate; it only applies
> to the external QOM interface.  The patch is a good idea, even though
> OBJECT(x)->y traditionally is not used (instead you assign OBJECT(x) to
> a different Object* variable).

Ok.. so are you prepared to give a Reviewed-by, or do I need to ask
someone else (Andreas?) to approve this as QOMishly correct?

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


pgp68n07rtC1V.pgp
Description: PGP signature


Re: [Qemu-devel] [RFCv2 1/2] spapr: Remove unnecessary owner field from sPAPRDRConnector

2015-09-14 Thread David Gibson
On Tue, Sep 15, 2015 at 12:06:49AM +1000, Alexey Kardashevskiy wrote:
> On 09/14/2015 10:11 PM, Paolo Bonzini wrote:
> >-BEGIN PGP SIGNED MESSAGE-
> >Hash: SHA256
> >
> >
> >
> >On 14/09/2015 13:45, David Gibson wrote:
> 
> === * There is no way for a child to determine what its parent
> is.  It is not * a bidirectional relationship.  This is by
> design. ===
> 
> This part always confused me as there is "Object *parent" in
> the "struct Object". So there is way to determine but it must
> not be used? Is it debug only?
> 
> Anyway, all members of the Object class are under /*< private
> >*/ so they should not be accesses in sPAPR code, I believe.
> >>Ah, good point, I missed that.  I guess we have to keep the owner
> >>field, redundant though it seems.  Blech.
> >
> >I think the comment is wrong or at least inaccurate; it only applies
> >to the external QOM interface.
> 
> 
> Is this case external?

I'm assyming by "external" Paolo means outside qemu - i.e. access via
the qapi monitor.

> Originally I was looking for a object_get_parent() but it is not there so I
> decided that the comment is correct or I just fail to understand it :)
> 
> 
> >The patch is a good idea, even though
> >OBJECT(x)->y traditionally is not used (instead you assign OBJECT(x) to
> >a different Object* variable).
> 
> 
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


pgpgKB3RamJzS.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH 1/2] target-ppc: remove hreg_compute_mem_idx() from cpu_post_load

2015-09-14 Thread Alexey Kardashevskiy

On 09/15/2015 05:30 AM, Mark Cave-Ayland wrote:

hreg_compute_mem_idx() has already been called previously by ppc_store_msr()
via hreg_store_msr() and hreg_compute_hflags(). Drop the duplicate function
call as it is no longer needed.

Signed-off-by: Mark Cave-Ayland 


Reviewed-by: Alexey Kardashevskiy 


---
  target-ppc/machine.c |2 --
  1 file changed, 2 deletions(-)

diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index f4ac761..bd99844 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -197,8 +197,6 @@ static int cpu_post_load(void *opaque, int version_id)
  env->msr ^= ~((1ULL << MSR_TGPR) | MSR_HVB);
  ppc_store_msr(env, msr);

-hreg_compute_mem_idx(env);
-
  return 0;
  }





--
Alexey



Re: [Qemu-devel] [RFC PATCH 2/2] target-ppc: add CPU IRQ state to PPC VMStateDescription

2015-09-14 Thread Alexey Kardashevskiy

On 09/15/2015 05:30 AM, Mark Cave-Ayland wrote:

Commit a90db15 "target-ppc: Convert ppc cpu savevm to VMStateDescription"
appears to drop the internal CPU IRQ state from the migration stream. Whilst
testing migration on g3beige/mac99 machines, test images would randomly fail to
resume unless a key was pressed on the VGA console.

Further investigation suggests that internal CPU IRQ state isn't being
preserved and so interrupts asserted at the time of migration are lost. Adding
the pending_interrupts and irq_input_state fields back into the migration
stream appears to fix the problem here during local tests.



On spapr, interrupt state migrates with XICS interrupt controller and it 
resets the CPU bits you are adding to the migration descriptor. I'd expect 
openpic (this one is used for mac99?) to do the same.




Signed-off-by: Mark Cave-Ayland 
---
  target-ppc/machine.c |2 ++
  1 file changed, 2 insertions(+)

diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index bd99844..968a7d6 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -528,6 +528,8 @@ const VMStateDescription vmstate_ppc_cpu = {

  /* Internal state */
  VMSTATE_UINTTL(env.hflags_nmsr, PowerPCCPU),
+VMSTATE_UINT32(env.pending_interrupts, PowerPCCPU),
+VMSTATE_UINT32(env.irq_input_state, PowerPCCPU),


This update requires a "version" increment for vmstate_ppc_cpu and
VMSTATE_UINT32_V instead of VMSTATE_UINT32.



  /* FIXME: access_type? */

  /* Sanity checking */




--
Alexey



[Qemu-devel] [PATCH v16 32/35] target-tilegx: Handle atomic instructions

2015-09-14 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/main.c | 166 ++
 target-tilegx/cpu.h   |   4 +-
 target-tilegx/translate.c |  80 +-
 3 files changed, 248 insertions(+), 2 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 57c1942..388caec 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3436,6 +3436,148 @@ static void gen_sigill_reg(CPUTLGState *env)
 queue_signal(env, info.si_signo, &info);
 }
 
+static void set_regval(CPUTLGState *env, uint8_t reg, uint64_t val)
+{
+if (unlikely(reg >= TILEGX_R_COUNT)) {
+switch (reg) {
+case TILEGX_R_SN:
+case TILEGX_R_ZERO:
+return;
+case TILEGX_R_IDN0:
+case TILEGX_R_IDN1:
+case TILEGX_R_UDN0:
+case TILEGX_R_UDN1:
+case TILEGX_R_UDN2:
+case TILEGX_R_UDN3:
+gen_sigill_reg(env);
+return;
+default:
+g_assert_not_reached();
+}
+}
+env->regs[reg] = val;
+}
+
+/*
+ * Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
+ * memory at the address held in the first source register. If the values are
+ * not equal, then no memory operation is performed. If the values are equal,
+ * the 8-byte quantity from the second source register is written into memory
+ * at the address held in the first source register. In either case, the result
+ * of the instruction is the value read from memory. The compare and write to
+ * memory are atomic and thus can be used for synchronization purposes. This
+ * instruction only operates for addresses aligned to a 8-byte boundary.
+ * Unaligned memory access causes an Unaligned Data Reference interrupt.
+ *
+ * Functional Description (64-bit)
+ *   uint64_t memVal = memoryReadDoubleWord (rf[SrcA]);
+ *   rf[Dest] = memVal;
+ *   if (memVal == SPR[CmpValueSPR])
+ *   memoryWriteDoubleWord (rf[SrcA], rf[SrcB]);
+ *
+ * Functional Description (32-bit)
+ *   uint64_t memVal = signExtend32 (memoryReadWord (rf[SrcA]));
+ *   rf[Dest] = memVal;
+ *   if (memVal == signExtend32 (SPR[CmpValueSPR]))
+ *   memoryWriteWord (rf[SrcA], rf[SrcB]);
+ *
+ *
+ * This function also processes exch and exch4 which need not process SPR.
+ */
+static void do_exch(CPUTLGState *env, bool quad, bool cmp)
+{
+target_ulong addr;
+target_long val, sprval;
+
+start_exclusive();
+
+addr = env->atomic_srca;
+if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
+goto sigsegv_mapper;
+}
+
+if (cmp) {
+if (quad) {
+sprval = env->spregs[TILEGX_SPR_CMPEXCH];
+} else {
+sprval = sextract64(env->spregs[TILEGX_SPR_CMPEXCH], 0, 32);
+}
+}
+
+if (!cmp || val == sprval) {
+target_long valb = env->atomic_srcb;
+if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
+goto sigsegv_mapper;
+}
+}
+
+set_regval(env, env->atomic_dstr, val);
+end_exclusive();
+return;
+
+ sigsegv_mapper:
+end_exclusive();
+gen_sigsegv_mapper(env, addr);
+}
+
+static void do_fetch(CPUTLGState *env, int trapnr, bool quad)
+{
+int8_t write = 1;
+target_ulong addr;
+target_long val, valb;
+
+start_exclusive();
+
+addr = env->atomic_srca;
+valb = env->atomic_srcb;
+if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
+goto sigsegv_mapper;
+}
+
+switch (trapnr) {
+case TILEGX_EXCP_OPCODE_FETCHADD:
+case TILEGX_EXCP_OPCODE_FETCHADD4:
+valb += val;
+break;
+case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
+valb += val;
+if (valb < 0) {
+write = 0;
+}
+break;
+case TILEGX_EXCP_OPCODE_FETCHADDGEZ4:
+valb += val;
+if ((int32_t)valb < 0) {
+write = 0;
+}
+break;
+case TILEGX_EXCP_OPCODE_FETCHAND:
+case TILEGX_EXCP_OPCODE_FETCHAND4:
+valb &= val;
+break;
+case TILEGX_EXCP_OPCODE_FETCHOR:
+case TILEGX_EXCP_OPCODE_FETCHOR4:
+valb |= val;
+break;
+default:
+g_assert_not_reached();
+}
+
+if (write) {
+if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
+goto sigsegv_mapper;
+}
+}
+
+set_regval(env, env->atomic_dstr, val);
+end_exclusive();
+return;
+
+ sigsegv_mapper:
+end_exclusive();
+gen_sigsegv_mapper(env, addr);
+}
+
 void cpu_loop(CPUTLGState *env)
 {
 CPUState *cs = CPU(tilegx_env_get_cpu(env));
@@ -3456,6 +3598,30 @@ void cpu_loop(CPUTLGState *env)
   ? - 
env->regs[TILEGX_R_RE]
   : 0;
 break;
+case TILEGX_EXCP_OPCODE_EXCH:
+do_exch(env, true, false);
+break;
+case TILEGX_EXCP_OPCODE_EXCH4

[Qemu-devel] [PATCH v16 30/35] target-tilegx: Handle v1cmpeq, v1cmpne

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 38f9389..b5ae3f6 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -93,6 +93,8 @@ typedef struct {
 #define OE_IM(E,XY)OE(IMM8_OPCODE_##XY, E##_IMM8_OPCODE_##XY, XY)
 #define OE_SH(E,XY)OE(SHIFT_OPCODE_##XY, E##_SHIFT_OPCODE_##XY, XY)
 
+#define V1_IMM(X)  (((X) & 0xff) * 0x0101010101010101ull)
+
 
 static void gen_exception(DisasContext *dc, TileExcp num)
 {
@@ -245,6 +247,41 @@ static void gen_mul_half(TCGv tdest, TCGv tsrca, TCGv 
tsrcb,
 tcg_temp_free(t);
 }
 
+/* Equality comparison with zero can be done quickly and efficiently.  */
+static void gen_v1cmpeq0(TCGv v)
+{
+TCGv m = tcg_const_tl(V1_IMM(0x7f));
+TCGv c = tcg_temp_new();
+
+/* ~(((v & m) + m) | m | v).  Sets the msb for each byte == 0.  */
+tcg_gen_and_tl(c, v, m);
+tcg_gen_add_tl(c, c, m);
+tcg_gen_or_tl(c, c, m);
+tcg_gen_nor_tl(c, c, v);
+tcg_temp_free(m);
+
+/* Shift the msb down to form the lsb boolean result.  */
+tcg_gen_shri_tl(v, c, 7);
+tcg_temp_free(c);
+}
+
+static void gen_v1cmpne0(TCGv v)
+{
+TCGv m = tcg_const_tl(V1_IMM(0x7f));
+TCGv c = tcg_temp_new();
+
+/* (((v & m) + m) | v) & ~m.  Sets the msb for each byte != 0.  */
+tcg_gen_and_tl(c, v, m);
+tcg_gen_add_tl(c, c, m);
+tcg_gen_or_tl(c, c, v);
+tcg_gen_andc_tl(c, c, m);
+tcg_temp_free(m);
+
+/* Shift the msb down to form the lsb boolean result.  */
+tcg_gen_shri_tl(v, c, 7);
+tcg_temp_free(c);
+}
+
 static TileExcp gen_st_opcode(DisasContext *dc, unsigned dest, unsigned srca,
   unsigned srcb, TCGMemOp memop, const char *name)
 {
@@ -915,8 +952,13 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(V1ADD, 0, X1):
 case OE_RRR(V1ADIFFU, 0, X0):
 case OE_RRR(V1AVGU, 0, X0):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(V1CMPEQ, 0, X0):
 case OE_RRR(V1CMPEQ, 0, X1):
+tcg_gen_xor_tl(tdest, tsrca, tsrcb);
+gen_v1cmpeq0(tdest);
+mnemonic = "v1cmpeq";
+break;
 case OE_RRR(V1CMPLES, 0, X0):
 case OE_RRR(V1CMPLES, 0, X1):
 case OE_RRR(V1CMPLEU, 0, X0):
@@ -925,8 +967,13 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(V1CMPLTS, 0, X1):
 case OE_RRR(V1CMPLTU, 0, X0):
 case OE_RRR(V1CMPLTU, 0, X1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(V1CMPNE, 0, X0):
 case OE_RRR(V1CMPNE, 0, X1):
+tcg_gen_xor_tl(tdest, tsrca, tsrcb);
+gen_v1cmpne0(tdest);
+mnemonic = "v1cmpne";
+break;
 case OE_RRR(V1DDOTPUA, 0, X0):
 case OE_RRR(V1DDOTPUSA, 0, X0):
 case OE_RRR(V1DDOTPUS, 0, X0):
@@ -1187,6 +1234,10 @@ static TileExcp gen_rri_opcode(DisasContext *dc, 
unsigned opext,
 case OE_IM(V1ADDI, X1):
 case OE_IM(V1CMPEQI, X0):
 case OE_IM(V1CMPEQI, X1):
+tcg_gen_xori_tl(tdest, tsrca, V1_IMM(imm));
+gen_v1cmpeq0(tdest);
+mnemonic = "v1cmpeqi";
+break;
 case OE_IM(V1CMPLTSI, X0):
 case OE_IM(V1CMPLTSI, X1):
 case OE_IM(V1CMPLTUI, X0):
-- 
2.4.3




[Qemu-devel] [PATCH v16 33/35] target-tilegx: Handle v4int_l/h

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 8895d72..2fcb17d 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -1148,10 +1148,18 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, 
unsigned opext,
 case OE_RRR(V4ADDSC, 0, X1):
 case OE_RRR(V4ADD, 0, X0):
 case OE_RRR(V4ADD, 0, X1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(V4INT_H, 0, X0):
 case OE_RRR(V4INT_H, 0, X1):
+tcg_gen_shri_tl(tdest, tsrcb, 32);
+tcg_gen_deposit_tl(tdest, tsrca, tdest, 0, 32);
+mnemonic = "v4int_h";
+break;
 case OE_RRR(V4INT_L, 0, X0):
 case OE_RRR(V4INT_L, 0, X1):
+tcg_gen_deposit_tl(tdest, tsrcb, tsrca, 32, 32);
+mnemonic = "v4int_l";
+break;
 case OE_RRR(V4PACKSC, 0, X0):
 case OE_RRR(V4PACKSC, 0, X1):
 case OE_RRR(V4SHLSC, 0, X0):
-- 
2.4.3




[Qemu-devel] [PATCH v16 28/35] target-tilegx: Handle scalar multiply instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 112 ++
 1 file changed, 112 insertions(+)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index a9018f0..943b8a2 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -213,6 +213,38 @@ static void gen_dblaligni(TCGv tdest, TCGv tsrca, TCGv 
tsrcb, int shr)
 tcg_temp_free(t0);
 }
 
+typedef enum {
+LU, LS, HU, HS
+} MulHalf;
+
+static void gen_ext_half(TCGv d, TCGv s, MulHalf h)
+{
+switch (h) {
+case LU:
+tcg_gen_ext32u_tl(d, s);
+break;
+case LS:
+tcg_gen_ext32s_tl(d, s);
+break;
+case HU:
+tcg_gen_shri_tl(d, s, 32);
+break;
+case HS:
+tcg_gen_sari_tl(d, s, 32);
+break;
+}
+}
+
+static void gen_mul_half(TCGv tdest, TCGv tsrca, TCGv tsrcb,
+ MulHalf ha, MulHalf hb)
+{
+TCGv t = tcg_temp_new();
+gen_ext_half(t, tsrca, ha);
+gen_ext_half(tdest, tsrcb, hb);
+tcg_gen_mul_tl(tdest, tdest, t);
+tcg_temp_free(t);
+}
+
 static TileExcp gen_st_opcode(DisasContext *dc, unsigned dest, unsigned srca,
   unsigned srcb, TCGMemOp memop, const char *name)
 {
@@ -615,38 +647,118 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, 
unsigned opext,
 case OE_RRR(MNZ, 0, X1):
 case OE_RRR(MNZ, 4, Y0):
 case OE_RRR(MNZ, 4, Y1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(MULAX, 0, X0):
 case OE_RRR(MULAX, 3, Y0):
+tcg_gen_mul_tl(tdest, tsrca, tsrcb);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "mulax";
+break;
 case OE_RRR(MULA_HS_HS, 0, X0):
 case OE_RRR(MULA_HS_HS, 9, Y0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, HS);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_hs_hs";
+break;
 case OE_RRR(MULA_HS_HU, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, HU);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_hs_hu";
+break;
 case OE_RRR(MULA_HS_LS, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, LS);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_hs_ls";
+break;
 case OE_RRR(MULA_HS_LU, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, LU);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_hs_lu";
+break;
 case OE_RRR(MULA_HU_HU, 0, X0):
 case OE_RRR(MULA_HU_HU, 9, Y0):
+gen_mul_half(tdest, tsrca, tsrcb, HU, HU);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_hu_hu";
+break;
 case OE_RRR(MULA_HU_LS, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HU, LS);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_hu_ls";
+break;
 case OE_RRR(MULA_HU_LU, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HU, LU);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_hu_lu";
+break;
 case OE_RRR(MULA_LS_LS, 0, X0):
 case OE_RRR(MULA_LS_LS, 9, Y0):
+gen_mul_half(tdest, tsrca, tsrcb, LS, LS);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_ls_ls";
+break;
 case OE_RRR(MULA_LS_LU, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, LS, LU);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_ls_lu";
+break;
 case OE_RRR(MULA_LU_LU, 0, X0):
 case OE_RRR(MULA_LU_LU, 9, Y0):
+gen_mul_half(tdest, tsrca, tsrcb, LU, LU);
+tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
+mnemonic = "mula_lu_lu";
+break;
 case OE_RRR(MULX, 0, X0):
 case OE_RRR(MULX, 3, Y0):
+tcg_gen_mul_tl(tdest, tsrca, tsrcb);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "mulx";
+break;
 case OE_RRR(MUL_HS_HS, 0, X0):
 case OE_RRR(MUL_HS_HS, 8, Y0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, HS);
+mnemonic = "mul_hs_hs";
+break;
 case OE_RRR(MUL_HS_HU, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, HU);
+mnemonic = "mul_hs_hu";
+break;
 case OE_RRR(MUL_HS_LS, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, LS);
+mnemonic = "mul_hs_ls";
+break;
 case OE_RRR(MUL_HS_LU, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HS, LU);
+mnemonic = "mul_hs_lu";
+break;
 case OE_RRR(MUL_HU_HU, 0, X0):
 case OE_RRR(MUL_HU_HU, 8, Y0):
+gen_mul_half(tdest, tsrca, tsrcb, HU, HU);
+mnemonic = "mul_hu_hu";
+break;
 case OE_RRR(MUL_HU_LS, 0, X0):
+gen_mul_half(tdest, tsrca, tsrcb, HU, LS);
+mnemonic = "mul_hu_ls";
+break;
 

[Qemu-devel] [PATCH v16 35/35] target-tilegx: Handle v1shl, v1shru, v1shrs

2015-09-14 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-tilegx/Makefile.objs |  2 +-
 target-tilegx/helper.h  |  4 
 target-tilegx/simd_helper.c | 55 +
 target-tilegx/translate.c   | 17 +-
 4 files changed, 76 insertions(+), 2 deletions(-)
 create mode 100644 target-tilegx/simd_helper.c

diff --git a/target-tilegx/Makefile.objs b/target-tilegx/Makefile.objs
index 8b3dc76..0db778f 100644
--- a/target-tilegx/Makefile.objs
+++ b/target-tilegx/Makefile.objs
@@ -1 +1 @@
-obj-y += cpu.o translate.o helper.o
+obj-y += cpu.o translate.o helper.o simd_helper.o
diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h
index 644d313..766f5f2 100644
--- a/target-tilegx/helper.h
+++ b/target-tilegx/helper.h
@@ -4,3 +4,7 @@ DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64)
 DEF_HELPER_FLAGS_1(pcnt, TCG_CALL_NO_RWG_SE, i64, i64)
 DEF_HELPER_FLAGS_1(revbits, TCG_CALL_NO_RWG_SE, i64, i64)
 DEF_HELPER_FLAGS_3(shufflebytes, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
+
+DEF_HELPER_FLAGS_2(v1shl, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(v1shru, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(v1shrs, TCG_CALL_NO_RWG_SE, i64, i64, i64)
diff --git a/target-tilegx/simd_helper.c b/target-tilegx/simd_helper.c
new file mode 100644
index 000..b931929
--- /dev/null
+++ b/target-tilegx/simd_helper.c
@@ -0,0 +1,55 @@
+/*
+ * QEMU TILE-Gx helpers
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "exec/helper-proto.h"
+
+
+uint64_t helper_v1shl(uint64_t a, uint64_t b)
+{
+uint64_t m;
+
+b &= 7;
+m = 0x0101010101010101ULL * (0xff >> b);
+return (a & m) << b;
+}
+
+uint64_t helper_v1shru(uint64_t a, uint64_t b)
+{
+uint64_t m;
+
+b &= 7;
+m = 0x0101010101010101ULL * ((0xff << b) & 0xff);
+return (a & m) >> b;
+}
+
+uint64_t helper_v1shrs(uint64_t a, uint64_t b)
+{
+uint64_t r = 0;
+int i;
+
+b &= 7;
+for (i = 0; i < 64; i += 8) {
+int64_t ae = (int8_t)(a >> i);
+r |= ((ae >> b) & 0xff) << i;
+}
+return r;
+}
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 8c25282..3447c6d 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -1077,12 +1077,22 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, 
unsigned opext,
 case OE_RRR(V1MZ, 0, X1):
 case OE_RRR(V1SADAU, 0, X0):
 case OE_RRR(V1SADU, 0, X0):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(V1SHL, 0, X0):
 case OE_RRR(V1SHL, 0, X1):
+gen_helper_v1shl(tdest, tsrca, tsrcb);
+mnemonic = "v1shl";
+break;
 case OE_RRR(V1SHRS, 0, X0):
 case OE_RRR(V1SHRS, 0, X1):
+gen_helper_v1shrs(tdest, tsrca, tsrcb);
+mnemonic = "v1shrs";
+break;
 case OE_RRR(V1SHRU, 0, X0):
 case OE_RRR(V1SHRU, 0, X1):
+gen_helper_v1shru(tdest, tsrca, tsrcb);
+mnemonic = "v1shru";
+break;
 case OE_RRR(V1SUBUC, 0, X0):
 case OE_RRR(V1SUBUC, 0, X1):
 case OE_RRR(V1SUB, 0, X0):
@@ -1199,6 +1209,7 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned 
opext,
 const char *mnemonic;
 TCGMemOp memop;
 int i2, i3;
+TCGv t0;
 
 switch (opext) {
 case OE(ADDI_OPCODE_Y0, 0, Y0):
@@ -1401,7 +1412,11 @@ static TileExcp gen_rri_opcode(DisasContext *dc, 
unsigned opext,
 break;
 case OE_SH(V1SHRSI, X0):
 case OE_SH(V1SHRSI, X1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+t0 = tcg_const_tl(imm & 7);
+gen_helper_v1shrs(tdest, tsrca, t0);
+tcg_temp_free(t0);
+mnemonic = "v1shrsi";
+break;
 case OE_SH(V1SHRUI, X0):
 case OE_SH(V1SHRUI, X1):
 i2 = imm & 7;
-- 
2.4.3




Re: [Qemu-devel] [PATCH v7 00/11] Fix exceptions handling for MIPS, PowerPC, and i386

2015-09-14 Thread Richard Henderson

On 07/10/2015 02:56 AM, Pavel Dovgalyuk wrote:

Pavel Dovgalyuk (11):
   softmmu: add helper function to pass through retaddr
   softmmu: remove now unused functions
   cpu-exec: introduce loop exit with restore function


These first three have been merged now.


   target-mips: improve exception handling
   target-i386: introduce new raise_exception functions
   target-i386: exception handling for FPU instructions
   target-i386: exception handling for div instructions
   target-i386: exception handling for memory helpers
   target-i386: exception handling for seg_helper functions
   target-i386: exception handling for other helper functions
   target-ppc: exceptions handling in icount mode


And I've applied the target-i386 patches to my tgt-i386-next branch.  They'll 
be merged soon.  That leaves the mips and ppc patches; I hope that Leon and 
Alex will review these.



r~



[Qemu-devel] [PATCH v16 34/35] target-tilegx: Handle v1shli, v1shrui

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 2fcb17d..8c25282 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -1198,6 +1198,7 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned 
opext,
 TCGv tsrca = load_gr(dc, srca);
 const char *mnemonic;
 TCGMemOp memop;
+int i2, i3;
 
 switch (opext) {
 case OE(ADDI_OPCODE_Y0, 0, Y0):
@@ -1392,10 +1393,23 @@ static TileExcp gen_rri_opcode(DisasContext *dc, 
unsigned opext,
 break;
 case OE_SH(V1SHLI, X0):
 case OE_SH(V1SHLI, X1):
+i2 = imm & 7;
+i3 = 0xff >> i2;
+tcg_gen_andi_tl(tdest, tsrca, V1_IMM(i3));
+tcg_gen_shli_tl(tdest, tdest, i2);
+mnemonic = "v1shli";
+break;
 case OE_SH(V1SHRSI, X0):
 case OE_SH(V1SHRSI, X1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_SH(V1SHRUI, X0):
 case OE_SH(V1SHRUI, X1):
+i2 = imm & 7;
+i3 = (0xff << i2) & 0xff;
+tcg_gen_andi_tl(tdest, tsrca, V1_IMM(i3));
+tcg_gen_shri_tl(tdest, tdest, i2);
+mnemonic = "v1shrui";
+break;
 case OE_SH(V2SHLI, X0):
 case OE_SH(V2SHLI, X1):
 case OE_SH(V2SHRSI, X0):
-- 
2.4.3




[Qemu-devel] [PATCH v16 21/35] target-tilegx: Handle unconditional jump instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 58 +--
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index bbea252..81033bb 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -249,7 +249,7 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 const char *mnemonic;
 TCGMemOp memop;
 
-/* Eliminate nops before doing anything else.  */
+/* Eliminate nops and jumps before doing anything else.  */
 switch (opext) {
 case OE_RR_Y0(NOP):
 case OE_RR_Y1(NOP):
@@ -268,6 +268,31 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 }
 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
 return TILEGX_EXCP_NONE;
+
+case OE_RR_X1(JRP):
+case OE_RR_Y1(JRP):
+mnemonic = "jrp";
+goto do_jr;
+case OE_RR_X1(JR):
+case OE_RR_Y1(JR):
+mnemonic = "jr";
+goto do_jr;
+case OE_RR_X1(JALRP):
+case OE_RR_Y1(JALRP):
+mnemonic = "jalrp";
+goto do_jalr;
+case OE_RR_X1(JALR):
+case OE_RR_Y1(JALR):
+mnemonic = "jalr";
+do_jalr:
+tcg_gen_movi_tl(dest_gr(dc, TILEGX_R_LR),
+dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
+do_jr:
+dc->jmp.cond = TCG_COND_ALWAYS;
+dc->jmp.dest = tcg_temp_new();
+tcg_gen_andi_tl(dc->jmp.dest, load_gr(dc, srca), ~7);
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s", mnemonic, reg_names[srca]);
+return TILEGX_EXCP_NONE;
 }
 
 tdest = dest_gr(dc, dest);
@@ -296,14 +321,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RR_Y1(ILL):
 case OE_RR_X1(INV):
 case OE_RR_X1(IRET):
-case OE_RR_X1(JALRP):
-case OE_RR_Y1(JALRP):
-case OE_RR_X1(JALR):
-case OE_RR_Y1(JALR):
-case OE_RR_X1(JRP):
-case OE_RR_Y1(JRP):
-case OE_RR_X1(JR):
-case OE_RR_Y1(JR):
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RR_X1(LD1S):
 memop = MO_SB;
@@ -370,6 +387,12 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 break;
 case OE_RR_X1(LNK):
 case OE_RR_Y1(LNK):
+if (srca) {
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+}
+tcg_gen_movi_tl(tdest, dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
+mnemonic = "lnk";
+break;
 case OE_RR_X1(MF):
 case OE_RR_X1(NAP):
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
@@ -1094,18 +1117,19 @@ static TileExcp gen_branch_opcode_x1(DisasContext *dc, 
unsigned ext,
 return TILEGX_EXCP_NONE;
 }
 
-static TileExcp gen_jump_opcode_x1(DisasContext *dc, unsigned ext,
-   int off)
+static TileExcp gen_jump_opcode_x1(DisasContext *dc, unsigned ext, int off)
 {
 target_ulong tgt = dc->pc + off * TILEGX_BUNDLE_SIZE_IN_BYTES;
-const char *mnemonic;
+const char *mnemonic = "j";
 
-switch (ext) {
-case JAL_JUMP_OPCODE_X1:
-case J_JUMP_OPCODE_X1:
-default:
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+/* The extension field is 1 bit, therefore we only have JAL and J.  */
+if (ext == JAL_JUMP_OPCODE_X1) {
+tcg_gen_movi_tl(dest_gr(dc, TILEGX_R_LR),
+dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
+mnemonic = "jal";
 }
+dc->jmp.cond = TCG_COND_ALWAYS;
+dc->jmp.dest = tcg_const_tl(tgt);
 
 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 qemu_log("%s " TARGET_FMT_lx " <%s>",
-- 
2.4.3




[Qemu-devel] [PATCH v16 31/35] target-tilegx: Handle mtspr, mfspr

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 76 +--
 1 file changed, 73 insertions(+), 3 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index b5ae3f6..1e678ec 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -24,6 +24,7 @@
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 #include "opcode_tilegx.h"
+#include "spr_def_64.h"
 
 #define FMT64X  "%016" PRIx64
 
@@ -1222,9 +1223,6 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned 
opext,
 tcg_gen_addi_tl(dest_gr(dc, srca), tsrca, imm);
 mnemonic = "ldna_add";
 break;
-case OE_IM(MFSPR, X1):
-case OE_IM(MTSPR, X1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_IM(ORI, X0):
 case OE_IM(ORI, X1):
 tcg_gen_ori_tl(tdest, tsrca, imm);
@@ -1524,6 +1522,74 @@ static TileExcp gen_jump_opcode_x1(DisasContext *dc, 
unsigned ext, int off)
 return TILEGX_EXCP_NONE;
 }
 
+typedef struct {
+const char *name;
+intptr_t offset;
+void (*get)(TCGv, TCGv_ptr);
+void (*put)(TCGv_ptr, TCGv);
+} TileSPR;
+
+static const TileSPR *find_spr(unsigned spr)
+{
+/* Allow the compiler to construct the binary search tree.  */
+#define D(N, O, G, P) \
+case SPR_##N: { static const TileSPR x = { #N, O, G, P }; return &x; }
+
+switch (spr) {
+D(CMPEXCH_VALUE,
+  offsetof(CPUTLGState, spregs[TILEGX_SPR_CMPEXCH]), 0, 0)
+D(INTERRUPT_CRITICAL_SECTION,
+  offsetof(CPUTLGState, spregs[TILEGX_SPR_CRITICAL_SEC]), 0, 0)
+D(SIM_CONTROL,
+  offsetof(CPUTLGState, spregs[TILEGX_SPR_SIM_CONTROL]), 0, 0)
+}
+
+#undef D
+
+qemu_log_mask(LOG_UNIMP, "UNIMP SPR %u\n", spr);
+return NULL;
+}
+
+static TileExcp gen_mtspr_x1(DisasContext *dc, unsigned spr, unsigned srca)
+{
+const TileSPR *def = find_spr(spr);
+TCGv tsrca;
+
+if (def == NULL) {
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "mtspr spr[%u], %s", spr, 
reg_names[srca]);
+return TILEGX_EXCP_OPCODE_UNKNOWN;
+}
+
+tsrca = load_gr(dc, srca);
+if (def->put) {
+def->put(cpu_env, tsrca);
+} else {
+tcg_gen_st_tl(tsrca, cpu_env, def->offset);
+}
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "mtspr %s, %s", def->name, 
reg_names[srca]);
+return TILEGX_EXCP_NONE;
+}
+
+static TileExcp gen_mfspr_x1(DisasContext *dc, unsigned dest, unsigned spr)
+{
+const TileSPR *def = find_spr(spr);
+TCGv tdest;
+
+if (def == NULL) {
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "mtspr %s, spr[%u]", reg_names[dest], 
spr);
+return TILEGX_EXCP_OPCODE_UNKNOWN;
+}
+
+tdest = dest_gr(dc, dest);
+if (def->get) {
+def->get(tdest, cpu_env);
+} else {
+tcg_gen_ld_tl(tdest, cpu_env, def->offset);
+}
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "mfspr %s, %s", reg_names[dest], 
def->name);
+return TILEGX_EXCP_NONE;
+}
+
 static TileExcp decode_y0(DisasContext *dc, tilegx_bundle_bits bundle)
 {
 unsigned opc = get_Opcode_Y0(bundle);
@@ -1778,6 +1844,10 @@ static TileExcp decode_x1(DisasContext *dc, 
tilegx_bundle_bits bundle)
 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEQ, "stnt_add");
 case ST_ADD_IMM8_OPCODE_X1:
 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEQ, "st_add");
+case MFSPR_IMM8_OPCODE_X1:
+return gen_mfspr_x1(dc, dest, get_MF_Imm14_X1(bundle));
+case MTSPR_IMM8_OPCODE_X1:
+return gen_mtspr_x1(dc, get_MT_Imm14_X1(bundle), srca);
 }
 imm = (int8_t)get_Imm8_X1(bundle);
 return gen_rri_opcode(dc, OE(opc, ext, X1), dest, srca, imm);
-- 
2.4.3




[Qemu-devel] [PATCH v16 25/35] target-tilegx: Handle bitfield instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 74 +++
 1 file changed, 74 insertions(+)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index cb21c14..9604320 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -1125,13 +1125,87 @@ static TileExcp gen_bf_opcode_x0(DisasContext *dc, 
unsigned ext,
  unsigned dest, unsigned srca,
  unsigned bfs, unsigned bfe)
 {
+TCGv tdest = dest_gr(dc, dest);
+TCGv tsrca = load_gr(dc, srca);
+TCGv tsrcd;
+int len;
 const char *mnemonic;
 
+/* The bitfield is either between E and S inclusive,
+   or up from S and down from E inclusive.  */
+if (bfs <= bfe) {
+len = bfe - bfs + 1;
+} else {
+len = (64 - bfs) + (bfe + 1);
+}
+
 switch (ext) {
 case BFEXTU_BF_OPCODE_X0:
+if (bfs == 0 && bfe == 7) {
+tcg_gen_ext8u_tl(tdest, tsrca);
+} else if (bfs == 0 && bfe == 15) {
+tcg_gen_ext16u_tl(tdest, tsrca);
+} else if (bfs == 0 && bfe == 31) {
+tcg_gen_ext32u_tl(tdest, tsrca);
+} else {
+int rol = 63 - bfe;
+if (bfs <= bfe) {
+tcg_gen_shli_tl(tdest, tsrca, rol);
+} else {
+tcg_gen_rotli_tl(tdest, tsrca, rol);
+}
+tcg_gen_shri_tl(tdest, tdest, (bfs + rol) & 63);
+}
+mnemonic = "bfextu";
+break;
+
 case BFEXTS_BF_OPCODE_X0:
+if (bfs == 0 && bfe == 7) {
+tcg_gen_ext8s_tl(tdest, tsrca);
+} else if (bfs == 0 && bfe == 15) {
+tcg_gen_ext16s_tl(tdest, tsrca);
+} else if (bfs == 0 && bfe == 31) {
+tcg_gen_ext32s_tl(tdest, tsrca);
+} else {
+int rol = 63 - bfe;
+if (bfs <= bfe) {
+tcg_gen_shli_tl(tdest, tsrca, rol);
+} else {
+tcg_gen_rotli_tl(tdest, tsrca, rol);
+}
+tcg_gen_sari_tl(tdest, tdest, (bfs + rol) & 63);
+}
+mnemonic = "bfexts";
+break;
+
 case BFINS_BF_OPCODE_X0:
+tsrcd = load_gr(dc, dest);
+if (bfs <= bfe) {
+tcg_gen_deposit_tl(tdest, tsrcd, tsrca, bfs, len);
+} else {
+tcg_gen_rotri_tl(tdest, tsrcd, bfs);
+tcg_gen_deposit_tl(tdest, tdest, tsrca, 0, len);
+tcg_gen_rotli_tl(tdest, tdest, bfs);
+}
+mnemonic = "bfins";
+break;
+
 case MM_BF_OPCODE_X0:
+tsrcd = load_gr(dc, dest);
+if (bfs == 0) {
+tcg_gen_deposit_tl(tdest, tsrca, tsrcd, 0, len);
+} else {
+uint64_t mask = len == 64 ? -1 : rol64((1ULL << len) - 1, bfs);
+TCGv tmp = tcg_const_tl(mask);
+
+tcg_gen_and_tl(tdest, tsrcd, tmp);
+tcg_gen_andc_tl(tmp, tsrca, tmp);
+tcg_gen_or_tl(tdest, tdest, tmp);
+tcg_temp_free(tmp);
+}
+mnemonic = "mm";
+break;
+
 default:
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 }
-- 
2.4.3




[Qemu-devel] [PATCH v16 23/35] target-tilegx: Handle comparison instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 39 +--
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 5d7aefa..0fbd11b 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -473,32 +473,52 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(CMOVEQZ, 4, Y0):
 case OE_RRR(CMOVNEZ, 0, X0):
 case OE_RRR(CMOVNEZ, 4, Y0):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(CMPEQ, 0, X0):
 case OE_RRR(CMPEQ, 0, X1):
 case OE_RRR(CMPEQ, 3, Y0):
 case OE_RRR(CMPEQ, 3, Y1):
+tcg_gen_setcond_tl(TCG_COND_EQ, tdest, tsrca, tsrcb);
+mnemonic = "cmpeq";
+break;
 case OE_RRR(CMPEXCH4, 0, X1):
 case OE_RRR(CMPEXCH, 0, X1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(CMPLES, 0, X0):
 case OE_RRR(CMPLES, 0, X1):
 case OE_RRR(CMPLES, 2, Y0):
 case OE_RRR(CMPLES, 2, Y1):
+tcg_gen_setcond_tl(TCG_COND_LE, tdest, tsrca, tsrcb);
+mnemonic = "cmples";
+break;
 case OE_RRR(CMPLEU, 0, X0):
 case OE_RRR(CMPLEU, 0, X1):
 case OE_RRR(CMPLEU, 2, Y0):
 case OE_RRR(CMPLEU, 2, Y1):
+tcg_gen_setcond_tl(TCG_COND_LEU, tdest, tsrca, tsrcb);
+mnemonic = "cmpleu";
+break;
 case OE_RRR(CMPLTS, 0, X0):
 case OE_RRR(CMPLTS, 0, X1):
 case OE_RRR(CMPLTS, 2, Y0):
 case OE_RRR(CMPLTS, 2, Y1):
+tcg_gen_setcond_tl(TCG_COND_LT, tdest, tsrca, tsrcb);
+mnemonic = "cmplts";
+break;
 case OE_RRR(CMPLTU, 0, X0):
 case OE_RRR(CMPLTU, 0, X1):
 case OE_RRR(CMPLTU, 2, Y0):
 case OE_RRR(CMPLTU, 2, Y1):
+tcg_gen_setcond_tl(TCG_COND_LTU, tdest, tsrca, tsrcb);
+mnemonic = "cmpltu";
+break;
 case OE_RRR(CMPNE, 0, X0):
 case OE_RRR(CMPNE, 0, X1):
 case OE_RRR(CMPNE, 3, Y0):
 case OE_RRR(CMPNE, 3, Y1):
+tcg_gen_setcond_tl(TCG_COND_NE, tdest, tsrca, tsrcb);
+mnemonic = "cmpne";
+break;
 case OE_RRR(CMULAF, 0, X0):
 case OE_RRR(CMULA, 0, X0):
 case OE_RRR(CMULFR, 0, X0):
@@ -886,13 +906,25 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned 
opext,
 tcg_gen_andi_tl(tdest, tsrca, imm);
 mnemonic = "andi";
 break;
+case OE(CMPEQI_OPCODE_Y0, 0, Y0):
+case OE(CMPEQI_OPCODE_Y1, 0, Y1):
 case OE_IM(CMPEQI, X0):
 case OE_IM(CMPEQI, X1):
+tcg_gen_setcondi_tl(TCG_COND_EQ, tdest, tsrca, imm);
+mnemonic = "cmpeqi";
+break;
+case OE(CMPLTSI_OPCODE_Y0, 0, Y0):
+case OE(CMPLTSI_OPCODE_Y1, 0, Y1):
 case OE_IM(CMPLTSI, X0):
 case OE_IM(CMPLTSI, X1):
+tcg_gen_setcondi_tl(TCG_COND_LT, tdest, tsrca, imm);
+mnemonic = "cmpltsi";
+break;
 case OE_IM(CMPLTUI, X0):
 case OE_IM(CMPLTUI, X1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+tcg_gen_setcondi_tl(TCG_COND_LTU, tdest, tsrca, imm);
+mnemonic = "cmpltui";
+break;
 case OE_IM(LD1S_ADD, X1):
 memop = MO_SB;
 mnemonic = "ld1s_add";
@@ -1042,11 +1074,6 @@ static TileExcp gen_rri_opcode(DisasContext *dc, 
unsigned opext,
 tcg_gen_ext32s_tl(tdest, tdest);
 mnemonic = "addxli";
 break;
-case OE(CMPEQI_OPCODE_Y0, 0, Y0):
-case OE(CMPEQI_OPCODE_Y1, 0, Y1):
-case OE(CMPLTSI_OPCODE_Y0, 0, Y0):
-case OE(CMPLTSI_OPCODE_Y1, 0, Y1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE(SHL16INSLI_OPCODE_X0, 0, X0):
 case OE(SHL16INSLI_OPCODE_X1, 0, X1):
 tcg_gen_shli_tl(tdest, tsrca, 16);
-- 
2.4.3




[Qemu-devel] [PATCH v16 24/35] target-tilegx: Implement system and memory management instructions

2015-09-14 Thread Richard Henderson
Most of which are either nops or exceptions.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 77 +--
 1 file changed, 54 insertions(+), 23 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 0fbd11b..cb21c14 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -248,27 +248,71 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 TCGv tdest, tsrca;
 const char *mnemonic;
 TCGMemOp memop;
+TileExcp ret = TILEGX_EXCP_NONE;
 
-/* Eliminate nops and jumps before doing anything else.  */
+/* Eliminate instructions with no output before doing anything else.  */
 switch (opext) {
 case OE_RR_Y0(NOP):
 case OE_RR_Y1(NOP):
 case OE_RR_X0(NOP):
 case OE_RR_X1(NOP):
 mnemonic = "nop";
-goto do_nop;
+goto done0;
 case OE_RR_Y0(FNOP):
 case OE_RR_Y1(FNOP):
 case OE_RR_X0(FNOP):
 case OE_RR_X1(FNOP):
 mnemonic = "fnop";
-do_nop:
+goto done0;
+case OE_RR_X1(DRAIN):
+mnemonic = "drain";
+goto done0;
+case OE_RR_X1(FLUSHWB):
+mnemonic = "flushwb";
+goto done0;
+case OE_RR_X1(ILL):
+case OE_RR_Y1(ILL):
+mnemonic = (dest == 0x1c && srca == 0x25 ? "bpt" : "ill");
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
+return TILEGX_EXCP_OPCODE_UNKNOWN;
+case OE_RR_X1(MF):
+mnemonic = "mf";
+goto done0;
+case OE_RR_X1(NAP):
+/* ??? This should yield, especially in system mode.  */
+mnemonic = "nap";
+goto done0;
+case OE_RR_X1(SWINT0):
+case OE_RR_X1(SWINT2):
+case OE_RR_X1(SWINT3):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+case OE_RR_X1(SWINT1):
+ret = TILEGX_EXCP_SYSCALL;
+mnemonic = "swint1";
+done0:
 if (srca || dest) {
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 }
 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
-return TILEGX_EXCP_NONE;
+return ret;
 
+case OE_RR_X1(DTLBPR):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+case OE_RR_X1(FINV):
+mnemonic = "finv";
+goto done1;
+case OE_RR_X1(FLUSH):
+mnemonic = "flush";
+goto done1;
+case OE_RR_X1(ICOH):
+mnemonic = "icoh";
+goto done1;
+case OE_RR_X1(INV):
+mnemonic = "inv";
+goto done1;
+case OE_RR_X1(WH64):
+mnemonic = "wh64";
+goto done1;
 case OE_RR_X1(JRP):
 case OE_RR_Y1(JRP):
 mnemonic = "jrp";
@@ -291,8 +335,12 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 dc->jmp.cond = TCG_COND_ALWAYS;
 dc->jmp.dest = tcg_temp_new();
 tcg_gen_andi_tl(dc->jmp.dest, load_gr(dc, srca), ~7);
+done1:
+if (dest) {
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+}
 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s", mnemonic, reg_names[srca]);
-return TILEGX_EXCP_NONE;
+return ret;
 }
 
 tdest = dest_gr(dc, dest);
@@ -309,17 +357,8 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 gen_helper_cnttz(tdest, tsrca);
 mnemonic = "cnttz";
 break;
-case OE_RR_X1(DRAIN):
-case OE_RR_X1(DTLBPR):
-case OE_RR_X1(FINV):
-case OE_RR_X1(FLUSHWB):
-case OE_RR_X1(FLUSH):
 case OE_RR_X0(FSINGLE_PACK1):
 case OE_RR_Y0(FSINGLE_PACK1):
-case OE_RR_X1(ICOH):
-case OE_RR_X1(ILL):
-case OE_RR_Y1(ILL):
-case OE_RR_X1(INV):
 case OE_RR_X1(IRET):
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RR_X1(LD1S):
@@ -393,9 +432,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 tcg_gen_movi_tl(tdest, dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
 mnemonic = "lnk";
 break;
-case OE_RR_X1(MF):
-case OE_RR_X1(NAP):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RR_X0(PCNT):
 case OE_RR_Y0(PCNT):
 gen_helper_pcnt(tdest, tsrca);
@@ -411,10 +447,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 tcg_gen_bswap64_tl(tdest, tsrca);
 mnemonic = "revbytes";
 break;
-case OE_RR_X1(SWINT0):
-case OE_RR_X1(SWINT1):
-case OE_RR_X1(SWINT2):
-case OE_RR_X1(SWINT3):
 case OE_RR_X0(TBLIDXB0):
 case OE_RR_Y0(TBLIDXB0):
 case OE_RR_X0(TBLIDXB1):
@@ -423,14 +455,13 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RR_Y0(TBLIDXB2):
 case OE_RR_X0(TBLIDXB3):
 case OE_RR_Y0(TBLIDXB3):
-case OE_RR_X1(WH64):
 default:
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 }
 
 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
   reg_names[dest], reg_names[srca]);
-return TILEGX_EXCP_NONE;
+return ret;
 }
 
 static TileExcp gen_rrr_opc

[Qemu-devel] [PATCH v16 29/35] target-tilegx: Handle mask instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 943b8a2..38f9389 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -643,11 +643,15 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(FSINGLE_MUL2, 0, X0):
 case OE_RRR(FSINGLE_PACK2, 0, X0):
 case OE_RRR(FSINGLE_SUB1, 0, X0):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(MNZ, 0, X0):
 case OE_RRR(MNZ, 0, X1):
 case OE_RRR(MNZ, 4, Y0):
 case OE_RRR(MNZ, 4, Y1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+t0 = load_zero(dc);
+tcg_gen_movcond_tl(TCG_COND_NE, tdest, tsrca, t0, tsrcb, t0);
+mnemonic = "mnz";
+break;
 case OE_RRR(MULAX, 0, X0):
 case OE_RRR(MULAX, 3, Y0):
 tcg_gen_mul_tl(tdest, tsrca, tsrcb);
@@ -763,7 +767,10 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(MZ, 0, X1):
 case OE_RRR(MZ, 4, Y0):
 case OE_RRR(MZ, 4, Y1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+t0 = load_zero(dc);
+tcg_gen_movcond_tl(TCG_COND_EQ, tdest, tsrca, t0, tsrcb, t0);
+mnemonic = "mz";
+break;
 case OE_RRR(NOR, 0, X0):
 case OE_RRR(NOR, 0, X1):
 case OE_RRR(NOR, 5, Y0):
-- 
2.4.3




[Qemu-devel] [PATCH v16 19/35] target-tilegx: Handle basic load and store instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 130 --
 1 file changed, 115 insertions(+), 15 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index c2f38f1..d3b4eae 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -213,12 +213,27 @@ static void gen_dblaligni(TCGv tdest, TCGv tsrca, TCGv 
tsrcb, int shr)
 tcg_temp_free(t0);
 }
 
+static TileExcp gen_st_opcode(DisasContext *dc, unsigned dest, unsigned srca,
+  unsigned srcb, TCGMemOp memop, const char *name)
+{
+if (dest) {
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+}
+
+tcg_gen_qemu_st_tl(load_gr(dc, srcb), load_gr(dc, srca),
+  dc->mmuidx, memop);
+
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", name,
+  reg_names[srca], reg_names[srcb]);
+return TILEGX_EXCP_NONE;
+}
 
 static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
   unsigned dest, unsigned srca)
 {
 TCGv tdest, tsrca;
 const char *mnemonic;
+TCGMemOp memop;
 
 /* Eliminate nops before doing anything else.  */
 switch (opext) {
@@ -275,21 +290,70 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RR_Y1(JRP):
 case OE_RR_X1(JR):
 case OE_RR_Y1(JR):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RR_X1(LD1S):
+memop = MO_SB;
+mnemonic = "ld1s";
+goto do_load;
 case OE_RR_X1(LD1U):
+memop = MO_UB;
+mnemonic = "ld1u";
+goto do_load;
 case OE_RR_X1(LD2S):
+memop = MO_TESW;
+mnemonic = "ld2s";
+goto do_load;
 case OE_RR_X1(LD2U):
+memop = MO_TEUW;
+mnemonic = "ld2u";
+goto do_load;
 case OE_RR_X1(LD4S):
+memop = MO_TESL;
+mnemonic = "ld4s";
+goto do_load;
 case OE_RR_X1(LD4U):
-case OE_RR_X1(LDNA):
+memop = MO_TEUL;
+mnemonic = "ld4u";
+goto do_load;
 case OE_RR_X1(LDNT1S):
+memop = MO_SB;
+mnemonic = "ldnt1s";
+goto do_load;
 case OE_RR_X1(LDNT1U):
+memop = MO_UB;
+mnemonic = "ldnt1u";
+goto do_load;
 case OE_RR_X1(LDNT2S):
+memop = MO_TESW;
+mnemonic = "ldnt2s";
+goto do_load;
 case OE_RR_X1(LDNT2U):
+memop = MO_TEUW;
+mnemonic = "ldnt2u";
+goto do_load;
 case OE_RR_X1(LDNT4S):
+memop = MO_TESL;
+mnemonic = "ldnt4s";
+goto do_load;
 case OE_RR_X1(LDNT4U):
+memop = MO_TEUL;
+mnemonic = "ldnt4u";
+goto do_load;
 case OE_RR_X1(LDNT):
+memop = MO_TEQ;
+mnemonic = "ldnt";
+goto do_load;
 case OE_RR_X1(LD):
+memop = MO_TEQ;
+mnemonic = "ld";
+do_load:
+tcg_gen_qemu_ld_tl(tdest, tsrca, dc->mmuidx, memop);
+break;
+case OE_RR_X1(LDNA):
+tcg_gen_andi_tl(tdest, tsrca, ~7);
+tcg_gen_qemu_ld_tl(tdest, tdest, dc->mmuidx, MO_TEQ);
+mnemonic = "ldna";
+break;
 case OE_RR_X1(LNK):
 case OE_RR_Y1(LNK):
 case OE_RR_X1(MF):
@@ -583,15 +647,6 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 gen_helper_shufflebytes(tdest, load_gr(dc, dest), tsrca, tsrca);
 mnemonic = "shufflebytes";
 break;
-case OE_RRR(ST1, 0, X1):
-case OE_RRR(ST2, 0, X1):
-case OE_RRR(ST4, 0, X1):
-case OE_RRR(STNT1, 0, X1):
-case OE_RRR(STNT2, 0, X1):
-case OE_RRR(STNT4, 0, X1):
-case OE_RRR(STNT, 0, X1):
-case OE_RRR(ST, 0, X1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(SUBXSC, 0, X0):
 case OE_RRR(SUBXSC, 0, X1):
 gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_sub_tl);
@@ -1098,27 +1153,55 @@ static TileExcp decode_y2(DisasContext *dc, 
tilegx_bundle_bits bundle)
 unsigned srca = get_SrcA_Y2(bundle);
 unsigned srcbdest = get_SrcBDest_Y2(bundle);
 const char *mnemonic;
+TCGMemOp memop;
 
 switch (OEY2(opc, mode)) {
 case OEY2(LD1S_OPCODE_Y2, MODE_OPCODE_YA2):
+memop = MO_SB;
+mnemonic = "ld1s";
+goto do_load;
 case OEY2(LD1U_OPCODE_Y2, MODE_OPCODE_YA2):
+memop = MO_UB;
+mnemonic = "ld1u";
+goto do_load;
 case OEY2(LD2S_OPCODE_Y2, MODE_OPCODE_YA2):
+memop = MO_TESW;
+mnemonic = "ld2s";
+goto do_load;
 case OEY2(LD2U_OPCODE_Y2, MODE_OPCODE_YA2):
+memop = MO_TEUW;
+mnemonic = "ld2u";
+goto do_load;
 case OEY2(LD4S_OPCODE_Y2, MODE_OPCODE_YB2):
+memop = MO_TESL;
+mnemonic = "ld4s";
+goto do_load;
 case OEY2(LD4U_OPCODE_Y2, MODE_OPCODE_YB2):
+memop = MO_TEUL;
+mnemonic = "ld4u";
+goto do_load;
 case OEY2(LD_OPCODE_Y2, MODE_OPCODE_YB2):
+memop = MO_TEQ;
+

[Qemu-devel] [PATCH v16 11/35] target-tilegx: Framework for decoding bundles

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 1145 +
 1 file changed, 1145 insertions(+)
 create mode 100644 target-tilegx/translate.c

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
new file mode 100644
index 000..58289b7
--- /dev/null
+++ b/target-tilegx/translate.c
@@ -0,0 +1,1145 @@
+/*
+ * QEMU TILE-Gx CPU
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "cpu.h"
+#include "qemu/log.h"
+#include "disas/disas.h"
+#include "tcg-op.h"
+#include "exec/cpu_ldst.h"
+#include "opcode_tilegx.h"
+
+#define FMT64X  "%016" PRIx64
+
+static TCGv_ptr cpu_env;
+static TCGv cpu_pc;
+static TCGv cpu_regs[TILEGX_R_COUNT];
+
+static const char * const reg_names[64] = {
+ "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+ "r8",  "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+"r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+"r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+"r48", "r49", "r50", "r51",  "bp",  "tp",  "sp",  "lr",
+"sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn2", "zero"
+};
+
+/* Modified registers are cached in temporaries until the end of the bundle. */
+typedef struct {
+unsigned reg;
+TCGv val;
+} DisasContextTemp;
+
+#define MAX_WRITEBACK 4
+
+/* This is the state at translation time.  */
+typedef struct {
+uint64_t pc;   /* Current pc */
+
+TCGv zero;  /* For zero register */
+
+DisasContextTemp wb[MAX_WRITEBACK];
+int num_wb;
+int mmuidx;
+bool exit_tb;
+
+struct {
+TCGCond cond;/* branch condition */
+TCGv dest;   /* branch destination */
+TCGv val1;   /* value to be compared against zero, for cond */
+} jmp;   /* Jump object, only once in each TB block */
+} DisasContext;
+
+#include "exec/gen-icount.h"
+
+/* Differentiate the various pipe encodings.  */
+#define TY_X0  0
+#define TY_X1  1
+#define TY_Y0  2
+#define TY_Y1  3
+
+/* Remerge the base opcode and extension fields for switching.
+   The X opcode fields are 3 bits; Y0/Y1 opcode fields are 4 bits;
+   Y2 opcode field is 2 bits.  */
+#define OE(OP, EXT, XY) (TY_##XY + OP * 4 + EXT * 64)
+
+/* Similar, but for Y2 only.  */
+#define OEY2(OP, MODE) (OP + MODE * 4)
+
+/* Similar, but make sure opcode names match up.  */
+#define OE_RR_X0(E)OE(RRR_0_OPCODE_X0, E##_UNARY_OPCODE_X0, X0)
+#define OE_RR_X1(E)OE(RRR_0_OPCODE_X1, E##_UNARY_OPCODE_X1, X1)
+#define OE_RR_Y0(E)OE(RRR_1_OPCODE_Y0, E##_UNARY_OPCODE_Y0, Y0)
+#define OE_RR_Y1(E)OE(RRR_1_OPCODE_Y1, E##_UNARY_OPCODE_Y1, Y1)
+#define OE_RRR(E,N,XY) OE(RRR_##N##_OPCODE_##XY, E##_RRR_##N##_OPCODE_##XY, XY)
+#define OE_IM(E,XY)OE(IMM8_OPCODE_##XY, E##_IMM8_OPCODE_##XY, XY)
+#define OE_SH(E,XY)OE(SHIFT_OPCODE_##XY, E##_SHIFT_OPCODE_##XY, XY)
+
+
+static void gen_exception(DisasContext *dc, TileExcp num)
+{
+TCGv_i32 tmp;
+
+tcg_gen_movi_tl(cpu_pc, dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
+
+tmp = tcg_const_i32(num);
+gen_helper_exception(cpu_env, tmp);
+tcg_temp_free_i32(tmp);
+dc->exit_tb = true;
+}
+
+static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
+  unsigned dest, unsigned srca)
+{
+const char *mnemonic;
+
+/* Eliminate nops before doing anything else.  */
+switch (opext) {
+case OE_RR_Y0(NOP):
+case OE_RR_Y1(NOP):
+case OE_RR_X0(NOP):
+case OE_RR_X1(NOP):
+mnemonic = "nop";
+goto do_nop;
+case OE_RR_Y0(FNOP):
+case OE_RR_Y1(FNOP):
+case OE_RR_X0(FNOP):
+case OE_RR_X1(FNOP):
+mnemonic = "fnop";
+do_nop:
+if (srca || dest) {
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+}
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
+return TILEGX_EXCP_NONE;
+}
+
+switch (opext) {
+case OE_RR_X0(CNTLZ):
+case OE_RR_Y0(CNTLZ):
+case OE_RR_X0(CNTTZ):
+case OE_RR_Y0(CNTTZ):
+case OE_RR_X1(DRAIN):
+case OE_RR_X1(DTLBPR):
+case OE_RR_X1(FINV):
+case OE_RR_X1(

[Qemu-devel] [PATCH v16 27/35] target-tilegx: Handle conditional move instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index c18e60c..a9018f0 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -503,9 +503,16 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 break;
 case OE_RRR(CMOVEQZ, 0, X0):
 case OE_RRR(CMOVEQZ, 4, Y0):
+tcg_gen_movcond_tl(TCG_COND_EQ, tdest, tsrca, load_zero(dc),
+   tsrcb, load_gr(dc, dest));
+mnemonic = "cmoveqz";
+break;
 case OE_RRR(CMOVNEZ, 0, X0):
 case OE_RRR(CMOVNEZ, 4, Y0):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+tcg_gen_movcond_tl(TCG_COND_NE, tdest, tsrca, load_zero(dc),
+   tsrcb, load_gr(dc, dest));
+mnemonic = "cmovnez";
+break;
 case OE_RRR(CMPEQ, 0, X0):
 case OE_RRR(CMPEQ, 0, X1):
 case OE_RRR(CMPEQ, 3, Y0):
-- 
2.4.3




[Qemu-devel] [PATCH v16 17/35] target-arm: Use new revbit functions

2015-09-14 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-arm/helper-a64.c | 15 +--
 target-arm/helper.c | 12 +---
 2 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 2c7a645..deb8dbe 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -70,20 +70,7 @@ uint32_t HELPER(clz32)(uint32_t x)
 
 uint64_t HELPER(rbit64)(uint64_t x)
 {
-/* assign the correct byte position */
-x = bswap64(x);
-
-/* assign the correct nibble position */
-x = ((x & 0xf0f0f0f0f0f0f0f0ULL) >> 4)
-| ((x & 0x0f0f0f0f0f0f0f0fULL) << 4);
-
-/* assign the correct bit position */
-x = ((x & 0xULL) >> 3)
-| ((x & 0xULL) >> 1)
-| ((x & 0xULL) << 1)
-| ((x & 0xULL) << 3);
-
-return x;
+return revbit64(x);
 }
 
 /* Convert a softfloat float_relation_ (as returned by
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 65b9ff5..12ea88f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5044,17 +5044,7 @@ uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
 
 uint32_t HELPER(rbit)(uint32_t x)
 {
-x =  ((x & 0xff00) >> 24)
-   | ((x & 0x00ff) >> 8)
-   | ((x & 0xff00) << 8)
-   | ((x & 0x00ff) << 24);
-x =  ((x & 0xf0f0f0f0) >> 4)
-   | ((x & 0x0f0f0f0f) << 4);
-x =  ((x & 0x) >> 3)
-   | ((x & 0x) >> 1)
-   | ((x & 0x) << 1)
-   | ((x & 0x) << 3);
-return x;
+return revbit32(x);
 }
 
 #if defined(CONFIG_USER_ONLY)
-- 
2.4.3




[Qemu-devel] [PATCH v16 18/35] target-tilegx: Handle most bit manipulation instructions

2015-09-14 Thread Richard Henderson
The crc instructions are omitted from this set.

Signed-off-by: Richard Henderson 
---
 target-tilegx/helper.c| 10 +++
 target-tilegx/helper.h|  2 ++
 target-tilegx/translate.c | 68 ++-
 3 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/target-tilegx/helper.c b/target-tilegx/helper.c
index 5b37a8c..a01bb8d 100644
--- a/target-tilegx/helper.c
+++ b/target-tilegx/helper.c
@@ -40,6 +40,16 @@ uint64_t helper_cnttz(uint64_t arg)
 return ctz64(arg);
 }
 
+uint64_t helper_pcnt(uint64_t arg)
+{
+return ctpop64(arg);
+}
+
+uint64_t helper_revbits(uint64_t arg)
+{
+return revbit64(arg);
+}
+
 /*
  * Functional Description
  * uint64_t a = rf[SrcA];
diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h
index fd5517e..644d313 100644
--- a/target-tilegx/helper.h
+++ b/target-tilegx/helper.h
@@ -1,4 +1,6 @@
 DEF_HELPER_2(exception, noreturn, env, i32)
 DEF_HELPER_FLAGS_1(cntlz, TCG_CALL_NO_RWG_SE, i64, i64)
 DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64)
+DEF_HELPER_FLAGS_1(pcnt, TCG_CALL_NO_RWG_SE, i64, i64)
+DEF_HELPER_FLAGS_1(revbits, TCG_CALL_NO_RWG_SE, i64, i64)
 DEF_HELPER_FLAGS_3(shufflebytes, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 6b5de55..c2f38f1 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -177,6 +177,43 @@ static void gen_saturate_op(TCGv tdest, TCGv tsrca, TCGv 
tsrcb,
 tcg_temp_free(t0);
 }
 
+/* Shift the 128-bit value TSRCA:TSRCD riht by the number of bytes
+   specified by the bottom 3 bits of TSRCB, and set TDEST to the
+   low 64 bits of the resulting value.  */
+static void gen_dblalign(TCGv tdest, TCGv tsrcd, TCGv tsrca, TCGv tsrcb)
+{
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_andi_tl(t0, tsrcb, 7);
+tcg_gen_shli_tl(t0, t0, 3);
+tcg_gen_shr_tl(tdest, tsrcd, t0);
+
+/* We want to do "t0 = tsrca << (64 - t0)".  Two's complement
+   arithmetic on a 6-bit field tells us that 64 - t0 is equal
+   to (t0 ^ 63) + 1.  So we can do the shift in two parts,
+   neither of which will be an invalid shift by 64.  */
+tcg_gen_xori_tl(t0, t0, 63);
+tcg_gen_shl_tl(t0, tsrca, t0);
+tcg_gen_shli_tl(t0, t0, 1);
+tcg_gen_or_tl(tdest, tdest, t0);
+
+tcg_temp_free(t0);
+}
+
+/* Similarly, except that the 128-bit value is TSRCA:TSRCB, and the
+   right shift is an immediate.  */
+static void gen_dblaligni(TCGv tdest, TCGv tsrca, TCGv tsrcb, int shr)
+{
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_shri_tl(t0, tsrcb, shr);
+tcg_gen_shli_tl(tdest, tsrca, 64 - shr);
+tcg_gen_or_tl(tdest, tdest, t0);
+
+tcg_temp_free(t0);
+}
+
+
 static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
   unsigned dest, unsigned srca)
 {
@@ -210,8 +247,14 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 switch (opext) {
 case OE_RR_X0(CNTLZ):
 case OE_RR_Y0(CNTLZ):
+gen_helper_cntlz(tdest, tsrca);
+mnemonic = "cntlz";
+break;
 case OE_RR_X0(CNTTZ):
 case OE_RR_Y0(CNTTZ):
+gen_helper_cnttz(tdest, tsrca);
+mnemonic = "cnttz";
+break;
 case OE_RR_X1(DRAIN):
 case OE_RR_X1(DTLBPR):
 case OE_RR_X1(FINV):
@@ -251,11 +294,17 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RR_Y1(LNK):
 case OE_RR_X1(MF):
 case OE_RR_X1(NAP):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RR_X0(PCNT):
 case OE_RR_Y0(PCNT):
+gen_helper_pcnt(tdest, tsrca);
+mnemonic = "pcnt";
+break;
 case OE_RR_X0(REVBITS):
 case OE_RR_Y0(REVBITS):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+gen_helper_revbits(tdest, tsrca);
+mnemonic = "revbits";
+break;
 case OE_RR_X0(REVBYTES):
 case OE_RR_Y0(REVBYTES):
 tcg_gen_bswap64_tl(tdest, tsrca);
@@ -358,13 +407,26 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(CMUL, 0, X0):
 case OE_RRR(CRC32_32, 0, X0):
 case OE_RRR(CRC32_8, 0, X0):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(DBLALIGN2, 0, X0):
 case OE_RRR(DBLALIGN2, 0, X1):
+gen_dblaligni(tdest, tsrca, tsrcb, 16);
+mnemonic = "dblalign2";
+break;
 case OE_RRR(DBLALIGN4, 0, X0):
 case OE_RRR(DBLALIGN4, 0, X1):
+gen_dblaligni(tdest, tsrca, tsrcb, 32);
+mnemonic = "dblalign4";
+break;
 case OE_RRR(DBLALIGN6, 0, X0):
 case OE_RRR(DBLALIGN6, 0, X1):
+gen_dblaligni(tdest, tsrca, tsrcb, 48);
+mnemonic = "dblalign6";
+break;
 case OE_RRR(DBLALIGN, 0, X0):
+gen_dblalign(tdest, load_gr(dc, dest), tsrca, tsrcb);
+mnemonic = "dblalign";
+break;
 case OE_RRR(EXCH4, 0, X1):
 case OE_RRR(EXCH, 0, X1):
 case OE_RRR(FDOUBLE_ADDSUB, 0, X0):
@@ -516,7 +578,11 @@ static TileExcp

[Qemu-devel] [PATCH v16 15/35] target-tilegx: Handle arithmetic instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 96 ---
 1 file changed, 90 insertions(+), 6 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 68c7db2..6b5de55 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -160,6 +160,23 @@ static TCGv dest_gr(DisasContext *dc, unsigned reg)
 return dc->wb[n].val = tcg_temp_new_i64();
 }
 
+static void gen_saturate_op(TCGv tdest, TCGv tsrca, TCGv tsrcb,
+void (*operate)(TCGv, TCGv, TCGv))
+{
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_ext32s_tl(tdest, tsrca);
+tcg_gen_ext32s_tl(t0, tsrcb);
+operate(tdest, tdest, t0);
+
+tcg_gen_movi_tl(t0, 0x7fff);
+tcg_gen_movcond_tl(TCG_COND_GT, tdest, tdest, t0, t0, tdest);
+tcg_gen_movi_tl(t0, -0x8000LL);
+tcg_gen_movcond_tl(TCG_COND_LT, tdest, tdest, t0, t0, tdest);
+
+tcg_temp_free(t0);
+}
+
 static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
   unsigned dest, unsigned srca)
 {
@@ -277,15 +294,24 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 switch (opext) {
 case OE_RRR(ADDXSC, 0, X0):
 case OE_RRR(ADDXSC, 0, X1):
+gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_add_tl);
+mnemonic = "addxsc";
+break;
 case OE_RRR(ADDX, 0, X0):
 case OE_RRR(ADDX, 0, X1):
 case OE_RRR(ADDX, 0, Y0):
 case OE_RRR(ADDX, 0, Y1):
+tcg_gen_add_tl(tdest, tsrca, tsrcb);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "addx";
+break;
 case OE_RRR(ADD, 0, X0):
 case OE_RRR(ADD, 0, X1):
 case OE_RRR(ADD, 0, Y0):
 case OE_RRR(ADD, 0, Y1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+tcg_gen_add_tl(tdest, tsrca, tsrcb);
+mnemonic = "add";
+break;
 case OE_RRR(AND, 0, X0):
 case OE_RRR(AND, 0, X1):
 case OE_RRR(AND, 5, Y0):
@@ -422,30 +448,58 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(ROTL, 0, X1):
 case OE_RRR(ROTL, 6, Y0):
 case OE_RRR(ROTL, 6, Y1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(SHL1ADDX, 0, X0):
 case OE_RRR(SHL1ADDX, 0, X1):
 case OE_RRR(SHL1ADDX, 7, Y0):
 case OE_RRR(SHL1ADDX, 7, Y1):
+tcg_gen_shli_tl(tdest, tsrca, 1);
+tcg_gen_add_tl(tdest, tdest, tsrcb);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "shl1addx";
+break;
 case OE_RRR(SHL1ADD, 0, X0):
 case OE_RRR(SHL1ADD, 0, X1):
 case OE_RRR(SHL1ADD, 1, Y0):
 case OE_RRR(SHL1ADD, 1, Y1):
+tcg_gen_shli_tl(tdest, tsrca, 1);
+tcg_gen_add_tl(tdest, tdest, tsrcb);
+mnemonic = "shl1add";
+break;
 case OE_RRR(SHL2ADDX, 0, X0):
 case OE_RRR(SHL2ADDX, 0, X1):
 case OE_RRR(SHL2ADDX, 7, Y0):
 case OE_RRR(SHL2ADDX, 7, Y1):
+tcg_gen_shli_tl(tdest, tsrca, 2);
+tcg_gen_add_tl(tdest, tdest, tsrcb);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "shl2addx";
+break;
 case OE_RRR(SHL2ADD, 0, X0):
 case OE_RRR(SHL2ADD, 0, X1):
 case OE_RRR(SHL2ADD, 1, Y0):
 case OE_RRR(SHL2ADD, 1, Y1):
+tcg_gen_shli_tl(tdest, tsrca, 2);
+tcg_gen_add_tl(tdest, tdest, tsrcb);
+mnemonic = "shl2add";
+break;
 case OE_RRR(SHL3ADDX, 0, X0):
 case OE_RRR(SHL3ADDX, 0, X1):
 case OE_RRR(SHL3ADDX, 7, Y0):
 case OE_RRR(SHL3ADDX, 7, Y1):
+tcg_gen_shli_tl(tdest, tsrca, 3);
+tcg_gen_add_tl(tdest, tdest, tsrcb);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "shl3addx";
+break;
 case OE_RRR(SHL3ADD, 0, X0):
 case OE_RRR(SHL3ADD, 0, X1):
 case OE_RRR(SHL3ADD, 1, Y0):
 case OE_RRR(SHL3ADD, 1, Y1):
+tcg_gen_shli_tl(tdest, tsrca, 3);
+tcg_gen_add_tl(tdest, tdest, tsrcb);
+mnemonic = "shl3add";
+break;
 case OE_RRR(SHLX, 0, X0):
 case OE_RRR(SHLX, 0, X1):
 case OE_RRR(SHL, 0, X0):
@@ -471,16 +525,27 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(STNT4, 0, X1):
 case OE_RRR(STNT, 0, X1):
 case OE_RRR(ST, 0, X1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(SUBXSC, 0, X0):
 case OE_RRR(SUBXSC, 0, X1):
+gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_sub_tl);
+mnemonic = "subxsc";
+break;
 case OE_RRR(SUBX, 0, X0):
 case OE_RRR(SUBX, 0, X1):
 case OE_RRR(SUBX, 0, Y0):
 case OE_RRR(SUBX, 0, Y1):
+tcg_gen_sub_tl(tdest, tsrca, tsrcb);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "subx";
+break;
 case OE_RRR(SUB, 0, X0):
 case OE_RRR(SUB, 0, X1):
 case OE_RRR(SUB, 0, Y0):
 case OE_RRR(SUB, 0, Y1):
+tcg_gen_sub_tl(tdest, tsrca, tsrcb);
+mnemonic = "sub";
+break;
 case OE_R

[Qemu-devel] [PATCH v16 16/35] host-utils: Add revbit functions

2015-09-14 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 include/qemu/host-utils.h | 77 +++
 1 file changed, 77 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 7d36ebf..3ef97d5 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -26,6 +26,7 @@
 #define HOST_UTILS_H 1
 
 #include "qemu/compiler.h"   /* QEMU_GNUC_PREREQ */
+#include "qemu/bswap.h"
 #include 
 #include 
 
@@ -391,6 +392,80 @@ static inline int ctpop64(uint64_t val)
 #endif
 }
 
+/**
+ * revbit8 - reverse the bits in an 8-bit value.
+ * @x: The value to modify.
+ */
+static inline uint8_t revbit8(uint8_t x)
+{
+/* Assign the correct nibble position.  */
+x = ((x & 0xf0) >> 4)
+  | ((x & 0x0f) << 4);
+/* Assign the correct bit position.  */
+x = ((x & 0x88) >> 3)
+  | ((x & 0x44) >> 1)
+  | ((x & 0x22) << 1)
+  | ((x & 0x11) << 3);
+return x;
+}
+
+/**
+ * revbit16 - reverse the bits in a 16-bit value.
+ * @x: The value to modify.
+ */
+static inline uint16_t revbit16(uint16_t x)
+{
+/* Assign the correct byte position.  */
+x = bswap16(x);
+/* Assign the correct nibble position.  */
+x = ((x & 0xf0f0) >> 4)
+  | ((x & 0x0f0f) << 4);
+/* Assign the correct bit position.  */
+x = ((x & 0x) >> 3)
+  | ((x & 0x) >> 1)
+  | ((x & 0x) << 1)
+  | ((x & 0x) << 3);
+return x;
+}
+
+/**
+ * revbit32 - reverse the bits in a 32-bit value.
+ * @x: The value to modify.
+ */
+static inline uint32_t revbit32(uint32_t x)
+{
+/* Assign the correct byte position.  */
+x = bswap32(x);
+/* Assign the correct nibble position.  */
+x = ((x & 0xf0f0f0f0u) >> 4)
+  | ((x & 0x0f0f0f0fu) << 4);
+/* Assign the correct bit position.  */
+x = ((x & 0xu) >> 3)
+  | ((x & 0xu) >> 1)
+  | ((x & 0xu) << 1)
+  | ((x & 0xu) << 3);
+return x;
+}
+
+/**
+ * revbit64 - reverse the bits in a 64-bit value.
+ * @x: The value to modify.
+ */
+static inline uint64_t revbit64(uint64_t x)
+{
+/* Assign the correct byte position.  */
+x = bswap64(x);
+/* Assign the correct nibble position.  */
+x = ((x & 0xf0f0f0f0f0f0f0f0ull) >> 4)
+  | ((x & 0x0f0f0f0f0f0f0f0full) << 4);
+/* Assign the correct bit position.  */
+x = ((x & 0xull) >> 3)
+  | ((x & 0xull) >> 1)
+  | ((x & 0xull) << 1)
+  | ((x & 0xull) << 3);
+return x;
+}
+
 /* Host type specific sizes of these routines.  */
 
 #if ULONG_MAX == UINT32_MAX
@@ -399,12 +474,14 @@ static inline int ctpop64(uint64_t val)
 # define clol   clo32
 # define ctol   cto32
 # define ctpopl ctpop32
+# define revbitl revbit32
 #elif ULONG_MAX == UINT64_MAX
 # define clzl   clz64
 # define ctzl   ctz64
 # define clol   clo64
 # define ctol   cto64
 # define ctpopl ctpop64
+# define revbitl revbit64
 #else
 # error Unknown sizeof long
 #endif
-- 
2.4.3




[Qemu-devel] [PATCH v16 26/35] target-tilegx: Handle shift instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 56 +--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 9604320..c18e60c 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -470,6 +470,7 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 TCGv tdest = dest_gr(dc, dest);
 TCGv tsrca = load_gr(dc, srca);
 TCGv tsrcb = load_gr(dc, srcb);
+TCGv t0;
 const char *mnemonic;
 
 switch (opext) {
@@ -662,7 +663,10 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(ROTL, 0, X1):
 case OE_RRR(ROTL, 6, Y0):
 case OE_RRR(ROTL, 6, Y1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+tcg_gen_andi_tl(tdest, tsrcb, 63);
+tcg_gen_rotl_tl(tdest, tsrca, tdest);
+mnemonic = "rotl";
+break;
 case OE_RRR(SHL1ADDX, 0, X0):
 case OE_RRR(SHL1ADDX, 0, X1):
 case OE_RRR(SHL1ADDX, 7, Y0):
@@ -716,21 +720,45 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 break;
 case OE_RRR(SHLX, 0, X0):
 case OE_RRR(SHLX, 0, X1):
+tcg_gen_andi_tl(tdest, tsrcb, 31);
+tcg_gen_shl_tl(tdest, tsrca, tdest);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "shlx";
+break;
 case OE_RRR(SHL, 0, X0):
 case OE_RRR(SHL, 0, X1):
 case OE_RRR(SHL, 6, Y0):
 case OE_RRR(SHL, 6, Y1):
+tcg_gen_andi_tl(tdest, tsrcb, 63);
+tcg_gen_shl_tl(tdest, tsrca, tdest);
+mnemonic = "shl";
+break;
 case OE_RRR(SHRS, 0, X0):
 case OE_RRR(SHRS, 0, X1):
 case OE_RRR(SHRS, 6, Y0):
 case OE_RRR(SHRS, 6, Y1):
+tcg_gen_andi_tl(tdest, tsrcb, 63);
+tcg_gen_sar_tl(tdest, tsrca, tdest);
+mnemonic = "shrs";
+break;
 case OE_RRR(SHRUX, 0, X0):
 case OE_RRR(SHRUX, 0, X1):
+t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, tsrcb, 31);
+tcg_gen_ext32u_tl(tdest, tsrca);
+tcg_gen_shr_tl(tdest, tdest, t0);
+tcg_gen_ext32s_tl(tdest, tdest);
+tcg_temp_free(t0);
+mnemonic = "shrux";
+break;
 case OE_RRR(SHRU, 0, X0):
 case OE_RRR(SHRU, 0, X1):
 case OE_RRR(SHRU, 6, Y0):
 case OE_RRR(SHRU, 6, Y1):
-return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+tcg_gen_andi_tl(tdest, tsrcb, 63);
+tcg_gen_shr_tl(tdest, tsrca, tdest);
+mnemonic = "shru";
+break;
 case OE_RRR(SHUFFLEBYTES, 0, X0):
 gen_helper_shufflebytes(tdest, load_gr(dc, dest), tsrca, tsrca);
 mnemonic = "shufflebytes";
@@ -1064,22 +1092,46 @@ static TileExcp gen_rri_opcode(DisasContext *dc, 
unsigned opext,
 case OE_SH(ROTLI, X1):
 case OE_SH(ROTLI, Y0):
 case OE_SH(ROTLI, Y1):
+tcg_gen_rotli_tl(tdest, tsrca, imm);
+mnemonic = "rotli";
+break;
 case OE_SH(SHLI, X0):
 case OE_SH(SHLI, X1):
 case OE_SH(SHLI, Y0):
 case OE_SH(SHLI, Y1):
+tcg_gen_shli_tl(tdest, tsrca, imm);
+mnemonic = "shli";
+break;
 case OE_SH(SHLXI, X0):
 case OE_SH(SHLXI, X1):
+tcg_gen_shli_tl(tdest, tsrca, imm & 31);
+tcg_gen_ext32s_tl(tdest, tdest);
+mnemonic = "shlxi";
+break;
 case OE_SH(SHRSI, X0):
 case OE_SH(SHRSI, X1):
 case OE_SH(SHRSI, Y0):
 case OE_SH(SHRSI, Y1):
+tcg_gen_sari_tl(tdest, tsrca, imm);
+mnemonic = "shrsi";
+break;
 case OE_SH(SHRUI, X0):
 case OE_SH(SHRUI, X1):
 case OE_SH(SHRUI, Y0):
 case OE_SH(SHRUI, Y1):
+tcg_gen_shri_tl(tdest, tsrca, imm);
+mnemonic = "shrui";
+break;
 case OE_SH(SHRUXI, X0):
 case OE_SH(SHRUXI, X1):
+if ((imm & 31) == 0) {
+tcg_gen_ext32s_tl(tdest, tsrca);
+} else {
+tcg_gen_ext32u_tl(tdest, tsrca);
+tcg_gen_shri_tl(tdest, tdest, imm & 31);
+}
+mnemonic = "shlxi";
+break;
 case OE_SH(V1SHLI, X0):
 case OE_SH(V1SHLI, X1):
 case OE_SH(V1SHRSI, X0):
-- 
2.4.3




[Qemu-devel] [PATCH v16 10/35] target-tilegx: Add several helpers for instructions translation

2015-09-14 Thread Richard Henderson
From: Chen Gang 

The related instructions are exception, cntlz, cnttz, shufflebytes.

Reviewed-by: Peter Maydell 
Signed-off-by: Chen Gang 
Message-Id: 
[rth: Remove incorrect implementation of add_saturate.]
Signed-off-by: Richard Henderson 
---
 target-tilegx/helper.c | 70 ++
 target-tilegx/helper.h |  4 +++
 2 files changed, 74 insertions(+)
 create mode 100644 target-tilegx/helper.c
 create mode 100644 target-tilegx/helper.h

diff --git a/target-tilegx/helper.c b/target-tilegx/helper.c
new file mode 100644
index 000..5b37a8c
--- /dev/null
+++ b/target-tilegx/helper.c
@@ -0,0 +1,70 @@
+/*
+ * QEMU TILE-Gx helpers
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "exec/helper-proto.h"
+
+void helper_exception(CPUTLGState *env, uint32_t excp)
+{
+CPUState *cs = CPU(tilegx_env_get_cpu(env));
+
+cs->exception_index = excp;
+cpu_loop_exit(cs);
+}
+
+uint64_t helper_cntlz(uint64_t arg)
+{
+return clz64(arg);
+}
+
+uint64_t helper_cnttz(uint64_t arg)
+{
+return ctz64(arg);
+}
+
+/*
+ * Functional Description
+ * uint64_t a = rf[SrcA];
+ * uint64_t b = rf[SrcB];
+ * uint64_t d = rf[Dest];
+ * uint64_t output = 0;
+ * unsigned int counter;
+ * for (counter = 0; counter < (WORD_SIZE / BYTE_SIZE); counter++)
+ * {
+ * int sel = getByte (b, counter) & 0xf;
+ * uint8_t byte = (sel < 8) ? getByte (d, sel) : getByte (a, (sel - 
8));
+ * output = setByte (output, counter, byte);
+ * }
+ * rf[Dest] = output;
+ */
+uint64_t helper_shufflebytes(uint64_t dest, uint64_t srca, uint64_t srcb)
+{
+uint64_t vdst = 0;
+int count;
+
+for (count = 0; count < 64; count += 8) {
+uint64_t sel = srcb >> count;
+uint64_t src = (sel & 8) ? srca : dest;
+vdst |= extract64(src, (sel & 7) * 8, 8) << count;
+}
+
+return vdst;
+}
diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h
new file mode 100644
index 000..fd5517e
--- /dev/null
+++ b/target-tilegx/helper.h
@@ -0,0 +1,4 @@
+DEF_HELPER_2(exception, noreturn, env, i32)
+DEF_HELPER_FLAGS_1(cntlz, TCG_CALL_NO_RWG_SE, i64, i64)
+DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64)
+DEF_HELPER_FLAGS_3(shufflebytes, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
-- 
2.4.3




[Qemu-devel] [PATCH v16 14/35] target-tilegx: Handle simple logical operations

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 99 +--
 1 file changed, 96 insertions(+), 3 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 58289b7..68c7db2 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -106,9 +106,64 @@ static void gen_exception(DisasContext *dc, TileExcp num)
 dc->exit_tb = true;
 }
 
+static bool check_gr(DisasContext *dc, uint8_t reg)
+{
+if (likely(reg < TILEGX_R_COUNT)) {
+return true;
+}
+
+switch (reg) {
+case TILEGX_R_SN:
+case TILEGX_R_ZERO:
+break;
+case TILEGX_R_IDN0:
+case TILEGX_R_IDN1:
+gen_exception(dc, TILEGX_EXCP_REG_IDN_ACCESS);
+break;
+case TILEGX_R_UDN0:
+case TILEGX_R_UDN1:
+case TILEGX_R_UDN2:
+case TILEGX_R_UDN3:
+gen_exception(dc, TILEGX_EXCP_REG_UDN_ACCESS);
+break;
+default:
+g_assert_not_reached();
+}
+return false;
+}
+
+static TCGv load_zero(DisasContext *dc)
+{
+if (TCGV_IS_UNUSED_I64(dc->zero)) {
+dc->zero = tcg_const_i64(0);
+}
+return dc->zero;
+}
+
+static TCGv load_gr(DisasContext *dc, unsigned reg)
+{
+if (check_gr(dc, reg)) {
+return cpu_regs[reg];
+}
+return load_zero(dc);
+}
+
+static TCGv dest_gr(DisasContext *dc, unsigned reg)
+{
+int n;
+
+/* Skip the result, mark the exception if necessary, and continue */
+check_gr(dc, reg);
+
+n = dc->num_wb++;
+dc->wb[n].reg = reg;
+return dc->wb[n].val = tcg_temp_new_i64();
+}
+
 static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
   unsigned dest, unsigned srca)
 {
+TCGv tdest, tsrca;
 const char *mnemonic;
 
 /* Eliminate nops before doing anything else.  */
@@ -132,6 +187,9 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 return TILEGX_EXCP_NONE;
 }
 
+tdest = dest_gr(dc, dest);
+tsrca = load_gr(dc, srca);
+
 switch (opext) {
 case OE_RR_X0(CNTLZ):
 case OE_RR_Y0(CNTLZ):
@@ -180,8 +238,12 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RR_Y0(PCNT):
 case OE_RR_X0(REVBITS):
 case OE_RR_Y0(REVBITS):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RR_X0(REVBYTES):
 case OE_RR_Y0(REVBYTES):
+tcg_gen_bswap64_tl(tdest, tsrca);
+mnemonic = "revbytes";
+break;
 case OE_RR_X1(SWINT0):
 case OE_RR_X1(SWINT1):
 case OE_RR_X1(SWINT2):
@@ -207,6 +269,9 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
opext,
 static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
unsigned dest, unsigned srca, unsigned srcb)
 {
+TCGv tdest = dest_gr(dc, dest);
+TCGv tsrca = load_gr(dc, srca);
+TCGv tsrcb = load_gr(dc, srcb);
 const char *mnemonic;
 
 switch (opext) {
@@ -220,10 +285,14 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(ADD, 0, X1):
 case OE_RRR(ADD, 0, Y0):
 case OE_RRR(ADD, 0, Y1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(AND, 0, X0):
 case OE_RRR(AND, 0, X1):
 case OE_RRR(AND, 5, Y0):
 case OE_RRR(AND, 5, Y1):
+tcg_gen_and_tl(tdest, tsrca, tsrcb);
+mnemonic = "and";
+break;
 case OE_RRR(CMOVEQZ, 0, X0):
 case OE_RRR(CMOVEQZ, 4, Y0):
 case OE_RRR(CMOVNEZ, 0, X0):
@@ -334,14 +403,21 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(MZ, 0, X1):
 case OE_RRR(MZ, 4, Y0):
 case OE_RRR(MZ, 4, Y1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(NOR, 0, X0):
 case OE_RRR(NOR, 0, X1):
 case OE_RRR(NOR, 5, Y0):
 case OE_RRR(NOR, 5, Y1):
+tcg_gen_nor_tl(tdest, tsrca, tsrcb);
+mnemonic = "nor";
+break;
 case OE_RRR(OR, 0, X0):
 case OE_RRR(OR, 0, X1):
 case OE_RRR(OR, 5, Y0):
 case OE_RRR(OR, 5, Y1):
+tcg_gen_or_tl(tdest, tsrca, tsrcb);
+mnemonic = "or";
+break;
 case OE_RRR(ROTL, 0, X0):
 case OE_RRR(ROTL, 0, X1):
 case OE_RRR(ROTL, 6, Y0):
@@ -539,10 +615,14 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 case OE_RRR(V4SUBSC, 0, X1):
 case OE_RRR(V4SUB, 0, X0):
 case OE_RRR(V4SUB, 0, X1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_RRR(XOR, 0, X0):
 case OE_RRR(XOR, 0, X1):
 case OE_RRR(XOR, 5, Y0):
 case OE_RRR(XOR, 5, Y1):
+tcg_gen_xor_tl(tdest, tsrca, tsrcb);
+mnemonic = "xor";
+break;
 default:
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 }
@@ -555,6 +635,8 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned 
opext,
 static TileExcp gen_rri_opcode(DisasContext *dc, unsigned opext,
unsigned dest, unsigned srca, int imm)

[Qemu-devel] [PATCH v16 05/35] target-tilegx: Modify opcode_tilegx.h to fit QEMU usage

2015-09-14 Thread Richard Henderson
From: Chen Gang 

Use 'inline' instead of '__inline', and also use 'uint64_t' instead of
"unsigned long long"

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 target-tilegx/opcode_tilegx.h | 220 +-
 1 file changed, 110 insertions(+), 110 deletions(-)

diff --git a/target-tilegx/opcode_tilegx.h b/target-tilegx/opcode_tilegx.h
index d76ff2d..33b71a9 100644
--- a/target-tilegx/opcode_tilegx.h
+++ b/target-tilegx/opcode_tilegx.h
@@ -23,7 +23,7 @@
 
 #ifndef __ASSEMBLER__
 
-typedef unsigned long long tilegx_bundle_bits;
+typedef uint64_t tilegx_bundle_bits;
 
 /* These are the bits that determine if a bundle is in the X encoding. */
 #define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
@@ -66,360 +66,360 @@ typedef tilegx_bundle_bits tile_bundle_bits;
 /* 64-bit pattern for a { bpt ; nop } bundle. */
 #define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
 
-static __inline unsigned int
+static inline unsigned int
 get_BFEnd_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 12)) & 0x3f);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 24)) & 0xf);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_BFStart_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 18)) & 0x3f);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_BrOff_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x003f) |
  (((unsigned int)(n >> 37)) & 0x0001ffc0);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_BrType_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 54)) & 0x1f);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Dest_Imm8_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x003f) |
  (((unsigned int)(n >> 43)) & 0x00c0);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Dest_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 0)) & 0x3f);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Dest_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x3f);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Dest_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 0)) & 0x3f);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Dest_Y1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x3f);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm16_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 12)) & 0x);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm16_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 43)) & 0x);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 20)) & 0xff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 51)) & 0xff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm8_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 12)) & 0xff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm8_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 43)) & 0xff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm8_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 12)) & 0xff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Imm8_Y1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 43)) & 0xff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_JumpOff_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x7ff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 58)) & 0x1);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_MF_Imm14_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 37)) & 0x3fff);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_MT_Imm14_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x003f) |
  (((unsigned int)(n >> 37)) & 0x3fc0);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Mode(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 62)) & 0x3);
 }
 
-static __inline unsigned int
+static inline unsigned int
 get_Opcode_X0(tilegx_bundle_bits 

[Qemu-devel] [PATCH v16 22/35] target-tilegx: Handle conditional branch instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 51 +++
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 81033bb..5d7aefa 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -1089,30 +1089,55 @@ static TileExcp gen_branch_opcode_x1(DisasContext *dc, 
unsigned ext,
 target_ulong tgt = dc->pc + off * TILEGX_BUNDLE_SIZE_IN_BYTES;
 const char *mnemonic;
 
-switch (ext) {
-case BEQZT_BRANCH_OPCODE_X1:
+dc->jmp.dest = tcg_const_tl(tgt);
+dc->jmp.val1 = tcg_temp_new();
+tcg_gen_mov_tl(dc->jmp.val1, load_gr(dc, srca));
+
+/* Note that the "predict taken" opcodes have bit 0 clear.
+   Therefore, fold the two cases together by setting bit 0.  */
+switch (ext | 1) {
 case BEQZ_BRANCH_OPCODE_X1:
-case BNEZT_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_EQ;
+mnemonic = "beqz";
+break;
 case BNEZ_BRANCH_OPCODE_X1:
-case BLBC_BRANCH_OPCODE_X1:
-case BGEZT_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_NE;
+mnemonic = "bnez";
+break;
 case BGEZ_BRANCH_OPCODE_X1:
-case BGTZT_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_GE;
+mnemonic = "bgez";
+break;
 case BGTZ_BRANCH_OPCODE_X1:
-case BLBCT_BRANCH_OPCODE_X1:
-case BLBST_BRANCH_OPCODE_X1:
-case BLBS_BRANCH_OPCODE_X1:
-case BLEZT_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_GT;
+mnemonic = "bgtz";
+break;
 case BLEZ_BRANCH_OPCODE_X1:
-case BLTZT_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_LE;
+mnemonic = "blez";
+break;
 case BLTZ_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_LT;
+mnemonic = "bltz";
+break;
+case BLBC_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_EQ;
+tcg_gen_andi_tl(dc->jmp.val1, dc->jmp.val1, 1);
+mnemonic = "blbc";
+break;
+case BLBS_BRANCH_OPCODE_X1:
+dc->jmp.cond = TCG_COND_NE;
+tcg_gen_andi_tl(dc->jmp.val1, dc->jmp.val1, 1);
+mnemonic = "blbs";
+break;
 default:
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 }
 
 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
-qemu_log("%s %s, " TARGET_FMT_lx " <%s>",
- mnemonic, reg_names[srca], tgt, lookup_symbol(tgt));
+qemu_log("%s%s %s, " TARGET_FMT_lx " <%s>",
+ mnemonic, ext & 1 ? "" : "t",
+ reg_names[srca], tgt, lookup_symbol(tgt));
 }
 return TILEGX_EXCP_NONE;
 }
-- 
2.4.3




[Qemu-devel] [PATCH v16 20/35] target-tilegx: Handle post-increment load and store instructions

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/translate.c | 94 +++
 1 file changed, 86 insertions(+), 8 deletions(-)

diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index d3b4eae..bbea252 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -228,6 +228,20 @@ static TileExcp gen_st_opcode(DisasContext *dc, unsigned 
dest, unsigned srca,
 return TILEGX_EXCP_NONE;
 }
 
+static TileExcp gen_st_add_opcode(DisasContext *dc, unsigned srca, unsigned 
srcb,
+  int imm, TCGMemOp memop, const char *name)
+{
+TCGv tsrca = load_gr(dc, srca);
+TCGv tsrcb = load_gr(dc, srcb);
+
+tcg_gen_qemu_st_tl(tsrcb, tsrca, dc->mmuidx, memop);
+tcg_gen_addi_tl(dest_gr(dc, srca), tsrca, imm);
+
+qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %d", name,
+  reg_names[srca], reg_names[srcb], imm);
+return TILEGX_EXCP_NONE;
+}
+
 static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
   unsigned dest, unsigned srca)
 {
@@ -824,6 +838,7 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned 
opext,
 TCGv tdest = dest_gr(dc, dest);
 TCGv tsrca = load_gr(dc, srca);
 const char *mnemonic;
+TCGMemOp memop;
 
 switch (opext) {
 case OE(ADDI_OPCODE_Y0, 0, Y0):
@@ -854,21 +869,72 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned 
opext,
 case OE_IM(CMPLTSI, X1):
 case OE_IM(CMPLTUI, X0):
 case OE_IM(CMPLTUI, X1):
+return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 case OE_IM(LD1S_ADD, X1):
+memop = MO_SB;
+mnemonic = "ld1s_add";
+goto do_load_add;
 case OE_IM(LD1U_ADD, X1):
+memop = MO_UB;
+mnemonic = "ld1u_add";
+goto do_load_add;
 case OE_IM(LD2S_ADD, X1):
+memop = MO_TESW;
+mnemonic = "ld2s_add";
+goto do_load_add;
 case OE_IM(LD2U_ADD, X1):
+memop = MO_TEUW;
+mnemonic = "ld2u_add";
+goto do_load_add;
 case OE_IM(LD4S_ADD, X1):
+memop = MO_TESL;
+mnemonic = "ld4s_add";
+goto do_load_add;
 case OE_IM(LD4U_ADD, X1):
+memop = MO_TEUL;
+mnemonic = "ld4u_add";
+goto do_load_add;
 case OE_IM(LDNT1S_ADD, X1):
+memop = MO_SB;
+mnemonic = "ldnt1s_add";
+goto do_load_add;
 case OE_IM(LDNT1U_ADD, X1):
+memop = MO_UB;
+mnemonic = "ldnt1u_add";
+goto do_load_add;
 case OE_IM(LDNT2S_ADD, X1):
+memop = MO_TESW;
+mnemonic = "ldnt2s_add";
+goto do_load_add;
 case OE_IM(LDNT2U_ADD, X1):
+memop = MO_TEUW;
+mnemonic = "ldnt2u_add";
+goto do_load_add;
 case OE_IM(LDNT4S_ADD, X1):
+memop = MO_TESL;
+mnemonic = "ldnt4s_add";
+goto do_load_add;
 case OE_IM(LDNT4U_ADD, X1):
+memop = MO_TEUL;
+mnemonic = "ldnt4u_add";
+goto do_load_add;
 case OE_IM(LDNT_ADD, X1):
+memop = MO_TEQ;
+mnemonic = "ldnt_add";
+goto do_load_add;
 case OE_IM(LD_ADD, X1):
+memop = MO_TEQ;
+mnemonic = "ldnt_add";
+do_load_add:
+tcg_gen_qemu_ld_tl(tdest, tsrca, dc->mmuidx, memop);
+tcg_gen_addi_tl(dest_gr(dc, srca), tsrca, imm);
+break;
 case OE_IM(LDNA_ADD, X1):
+tcg_gen_andi_tl(tdest, tsrca, ~7);
+tcg_gen_qemu_ld_tl(tdest, tdest, dc->mmuidx, MO_TEQ);
+tcg_gen_addi_tl(dest_gr(dc, srca), tsrca, imm);
+mnemonic = "ldna_add";
+break;
 case OE_IM(MFSPR, X1):
 case OE_IM(MTSPR, X1):
 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
@@ -877,14 +943,6 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned 
opext,
 tcg_gen_ori_tl(tdest, tsrca, imm);
 mnemonic = "ori";
 break;
-case OE_IM(ST1_ADD, X1):
-case OE_IM(ST2_ADD, X1):
-case OE_IM(ST4_ADD, X1):
-case OE_IM(STNT1_ADD, X1):
-case OE_IM(STNT2_ADD, X1):
-case OE_IM(STNT4_ADD, X1):
-case OE_IM(STNT_ADD, X1):
-case OE_IM(ST_ADD, X1):
 case OE_IM(V1ADDI, X0):
 case OE_IM(V1ADDI, X1):
 case OE_IM(V1CMPEQI, X0):
@@ -1291,6 +1349,26 @@ static TileExcp decode_x1(DisasContext *dc, 
tilegx_bundle_bits bundle)
 
 case IMM8_OPCODE_X1:
 ext = get_Imm8OpcodeExtension_X1(bundle);
+imm = (int8_t)get_Dest_Imm8_X1(bundle);
+srcb = get_SrcB_X1(bundle);
+switch (ext) {
+case ST1_ADD_IMM8_OPCODE_X1:
+return gen_st_add_opcode(dc, srca, srcb, imm, MO_UB, "st1_add");
+case ST2_ADD_IMM8_OPCODE_X1:
+return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEUW, "st2_add");
+case ST4_ADD_IMM8_OPCODE_X1:
+return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEUL, "st4_add");
+case STNT1_ADD_IMM8_OPCODE_X1:
+return gen_st_add_opcode(dc, srca, srcb, imm, MO_UB, "stnt1_ad

[Qemu-devel] [PATCH v16 09/35] target-tilegx: Add cpu basic features for linux-user

2015-09-14 Thread Richard Henderson
From: Chen Gang 

It implements minimized cpu features for linux-user.

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 target-tilegx/cpu.c | 170 ++
 target-tilegx/cpu.h | 175 
 2 files changed, 345 insertions(+)
 create mode 100644 target-tilegx/cpu.c
 create mode 100644 target-tilegx/cpu.h

diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c
new file mode 100644
index 000..87aee24
--- /dev/null
+++ b/target-tilegx/cpu.c
@@ -0,0 +1,170 @@
+/*
+ * QEMU TILE-Gx CPU
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+static void tilegx_cpu_dump_state(CPUState *cs, FILE *f,
+  fprintf_function cpu_fprintf, int flags)
+{
+static const char * const reg_names[TILEGX_R_COUNT] = {
+ "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+ "r8",  "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+"r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+"r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+"r48", "r49", "r50", "r51",  "bp",  "tp",  "sp",  "lr"
+};
+
+TileGXCPU *cpu = TILEGX_CPU(cs);
+CPUTLGState *env = &cpu->env;
+int i;
+
+for (i = 0; i < TILEGX_R_COUNT; i++) {
+cpu_fprintf(f, "%-4s" TARGET_FMT_lx "%s",
+reg_names[i], env->regs[i],
+(i % 4) == 3 ? "\n" : " ");
+}
+cpu_fprintf(f, "PC  " TARGET_FMT_lx " CEX " TARGET_FMT_lx "\n\n",
+env->pc, env->spregs[TILEGX_SPR_CMPEXCH]);
+}
+
+TileGXCPU *cpu_tilegx_init(const char *cpu_model)
+{
+TileGXCPU *cpu;
+
+cpu = TILEGX_CPU(object_new(TYPE_TILEGX_CPU));
+
+object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+
+return cpu;
+}
+
+static void tilegx_cpu_set_pc(CPUState *cs, vaddr value)
+{
+TileGXCPU *cpu = TILEGX_CPU(cs);
+
+cpu->env.pc = value;
+}
+
+static bool tilegx_cpu_has_work(CPUState *cs)
+{
+return true;
+}
+
+static void tilegx_cpu_reset(CPUState *s)
+{
+TileGXCPU *cpu = TILEGX_CPU(s);
+TileGXCPUClass *tcc = TILEGX_CPU_GET_CLASS(cpu);
+CPUTLGState *env = &cpu->env;
+
+tcc->parent_reset(s);
+
+memset(env, 0, sizeof(CPUTLGState));
+tlb_flush(s, 1);
+}
+
+static void tilegx_cpu_realizefn(DeviceState *dev, Error **errp)
+{
+CPUState *cs = CPU(dev);
+TileGXCPUClass *tcc = TILEGX_CPU_GET_CLASS(dev);
+
+cpu_reset(cs);
+qemu_init_vcpu(cs);
+
+tcc->parent_realize(dev, errp);
+}
+
+static void tilegx_cpu_initfn(Object *obj)
+{
+CPUState *cs = CPU(obj);
+TileGXCPU *cpu = TILEGX_CPU(obj);
+CPUTLGState *env = &cpu->env;
+static bool tcg_initialized;
+
+cs->env_ptr = env;
+cpu_exec_init(cs, &error_abort);
+
+if (tcg_enabled() && !tcg_initialized) {
+tcg_initialized = true;
+tilegx_tcg_init();
+}
+}
+
+static void tilegx_cpu_do_interrupt(CPUState *cs)
+{
+cs->exception_index = -1;
+}
+
+static int tilegx_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+   int mmu_idx)
+{
+cpu_dump_state(cs, stderr, fprintf, 0);
+return 1;
+}
+
+static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+tilegx_cpu_do_interrupt(cs);
+return true;
+}
+return false;
+}
+
+static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+CPUClass *cc = CPU_CLASS(oc);
+TileGXCPUClass *tcc = TILEGX_CPU_CLASS(oc);
+
+tcc->parent_realize = dc->realize;
+dc->realize = tilegx_cpu_realizefn;
+
+tcc->parent_reset = cc->reset;
+cc->reset = tilegx_cpu_reset;
+
+cc->has_work = tilegx_cpu_has_work;
+cc->do_interrupt = tilegx_cpu_do_interrupt;
+cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
+cc->dump_state = tilegx_cpu_dump_state;
+cc->set_pc = tilegx_cpu_set_pc;
+cc->handle_mmu_fa

[Qemu-devel] [PATCH v16 01/35] linux-user: tilegx: Add architecture related features

2015-09-14 Thread Richard Henderson
From: Chen Gang 

They are based on Linux kernel tilegx architecture for 64 bit binary,
and also based on tilegx ABI reference document, and also reference from
other targets implementations.

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 linux-user/tilegx/syscall.h|  40 +
 linux-user/tilegx/syscall_nr.h | 324 +
 linux-user/tilegx/target_cpu.h |  35 
 linux-user/tilegx/target_signal.h  |  28 
 linux-user/tilegx/target_structs.h |  46 ++
 linux-user/tilegx/termbits.h   | 274 +++
 6 files changed, 747 insertions(+)
 create mode 100644 linux-user/tilegx/syscall.h
 create mode 100644 linux-user/tilegx/syscall_nr.h
 create mode 100644 linux-user/tilegx/target_cpu.h
 create mode 100644 linux-user/tilegx/target_signal.h
 create mode 100644 linux-user/tilegx/target_structs.h
 create mode 100644 linux-user/tilegx/termbits.h

diff --git a/linux-user/tilegx/syscall.h b/linux-user/tilegx/syscall.h
new file mode 100644
index 000..653ece1
--- /dev/null
+++ b/linux-user/tilegx/syscall.h
@@ -0,0 +1,40 @@
+#ifndef TILEGX_SYSCALLS_H
+#define TILEGX_SYSCALLS_H
+
+#define UNAME_MACHINE "tilegx"
+#define UNAME_MINIMUM_RELEASE "3.19"
+
+#define MMAP_SHIFT TARGET_PAGE_BITS
+
+#define TILEGX_IS_ERRNO(ret) \
+   ((ret) > 0xf000ULL) /* errno is 0 -- 4096 */
+
+typedef uint64_t tilegx_reg_t;
+
+struct target_pt_regs {
+
+union {
+/* Saved main processor registers; 56..63 are special. */
+tilegx_reg_t regs[56];
+struct {
+tilegx_reg_t __regs[53];
+tilegx_reg_t tp;/* aliases regs[TREG_TP] */
+tilegx_reg_t sp;/* aliases regs[TREG_SP] */
+tilegx_reg_t lr;/* aliases regs[TREG_LR] */
+};
+};
+
+/* Saved special registers. */
+tilegx_reg_t pc;/* stored in EX_CONTEXT_K_0 */
+tilegx_reg_t ex1;   /* stored in EX_CONTEXT_K_1 (PL and ICS bit) */
+tilegx_reg_t faultnum;  /* fault number (INT_SWINT_1 for syscall) */
+tilegx_reg_t orig_r0;   /* r0 at syscall entry, else zero */
+tilegx_reg_t flags; /* flags (see below) */
+tilegx_reg_t cmpexch;   /* value of CMPEXCH_VALUE SPR at interrupt */
+tilegx_reg_t pad[2];
+};
+
+#define TARGET_MLOCKALL_MCL_CURRENT 1
+#define TARGET_MLOCKALL_MCL_FUTURE  2
+
+#endif
diff --git a/linux-user/tilegx/syscall_nr.h b/linux-user/tilegx/syscall_nr.h
new file mode 100644
index 000..1dca348
--- /dev/null
+++ b/linux-user/tilegx/syscall_nr.h
@@ -0,0 +1,324 @@
+#ifndef TILEGX_SYSCALL_NR
+#define TILEGX_SYSCALL_NR
+
+/*
+ * Copy from linux kernel asm-generic/unistd.h, which tilegx uses.
+ */
+#define TARGET_NR_io_setup  0
+#define TARGET_NR_io_destroy1
+#define TARGET_NR_io_submit 2
+#define TARGET_NR_io_cancel 3
+#define TARGET_NR_io_getevents  4
+#define TARGET_NR_setxattr  5
+#define TARGET_NR_lsetxattr 6
+#define TARGET_NR_fsetxattr 7
+#define TARGET_NR_getxattr  8
+#define TARGET_NR_lgetxattr 9
+#define TARGET_NR_fgetxattr 10
+#define TARGET_NR_listxattr 11
+#define TARGET_NR_llistxattr12
+#define TARGET_NR_flistxattr13
+#define TARGET_NR_removexattr   14
+#define TARGET_NR_lremovexattr  15
+#define TARGET_NR_fremovexattr  16
+#define TARGET_NR_getcwd17
+#define TARGET_NR_lookup_dcookie18
+#define TARGET_NR_eventfd2  19
+#define TARGET_NR_epoll_create1 20
+#define TARGET_NR_epoll_ctl 21
+#define TARGET_NR_epoll_pwait   22
+#define TARGET_NR_dup   23
+#define TARGET_NR_dup3  24
+#define TARGET_NR_fcntl 25
+#define TARGET_NR_inotify_init1 26
+#define TARGET_NR_inotify_add_watch 27
+#define TARGET_NR_inotify_rm_watch  28
+#define TARGET_NR_ioctl 29
+#define TARGET_NR_ioprio_set30
+#define TARGET_NR_ioprio_get31
+#define TARGET_NR_flock 32
+#define TARGET_NR_mknodat   33
+#define TARGET_NR_mkdirat   34
+#define TARGET_NR_unlinkat  35
+#define TARGET_NR_symlinkat 36
+#define TARGET_NR_linkat37
+#define TARGET_NR_renameat  38
+#define TARGET_NR_umount2   39
+#define TARGET_NR_mount 40
+#define TARGET_NR_pivot_root41
+#define TARGET_NR_nfsservctl

[Qemu-devel] [PATCH v16 12/35] target-tilegx: Generate SEGV properly

2015-09-14 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 linux-user/main.c   | 3 +++
 target-tilegx/cpu.c | 5 -
 target-tilegx/cpu.h | 2 ++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index f3a37a2..57c1942 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3460,6 +3460,9 @@ void cpu_loop(CPUTLGState *env)
 case TILEGX_EXCP_REG_UDN_ACCESS:
 gen_sigill_reg(env);
 break;
+case TILEGX_EXCP_SEGV:
+gen_sigsegv_mapper(env, env->excaddr);
+break;
 default:
 fprintf(stderr, "trapnr is %d[0x%x].\n", trapnr, trapnr);
 g_assert_not_reached();
diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c
index 87aee24..78b73e4 100644
--- a/target-tilegx/cpu.c
+++ b/target-tilegx/cpu.c
@@ -119,7 +119,10 @@ static void tilegx_cpu_do_interrupt(CPUState *cs)
 static int tilegx_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx)
 {
-cpu_dump_state(cs, stderr, fprintf, 0);
+TileGXCPU *cpu = TILEGX_CPU(cs);
+
+cs->exception_index = TILEGX_EXCP_SEGV;
+cpu->env.excaddr = address;
 return 1;
 }
 
diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
index 2c86cd3..3a62d20 100644
--- a/target-tilegx/cpu.h
+++ b/target-tilegx/cpu.h
@@ -60,6 +60,7 @@ enum {
 typedef enum {
 TILEGX_EXCP_NONE = 0,
 TILEGX_EXCP_SYSCALL = 1,
+TILEGX_EXCP_SEGV = 2,
 TILEGX_EXCP_OPCODE_UNKNOWN = 0x101,
 TILEGX_EXCP_OPCODE_UNIMPLEMENTED = 0x102,
 TILEGX_EXCP_OPCODE_CMPEXCH = 0x103,
@@ -87,6 +88,7 @@ typedef struct CPUTLGState {
 
 #if defined(CONFIG_USER_ONLY)
 uint32_t excparam; /* exception parameter */
+uint64_t excaddr;  /* exception address */
 #endif
 
 CPU_COMMON
-- 
2.4.3




[Qemu-devel] [PATCH v16 08/35] target-tilegx: Add special register information from Tilera Corporation

2015-09-14 Thread Richard Henderson
From: Chen Gang 

The related copy is from Linux kernel "arch/tile/include/uapi/arch/
spr_def_64.h".

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 target-tilegx/spr_def_64.h | 216 +
 1 file changed, 216 insertions(+)
 create mode 100644 target-tilegx/spr_def_64.h

diff --git a/target-tilegx/spr_def_64.h b/target-tilegx/spr_def_64.h
new file mode 100644
index 000..67a6c17
--- /dev/null
+++ b/target-tilegx/spr_def_64.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#ifndef __DOXYGEN__
+
+#ifndef __ARCH_SPR_DEF_64_H__
+#define __ARCH_SPR_DEF_64_H__
+
+#define SPR_AUX_PERF_COUNT_0 0x2105
+#define SPR_AUX_PERF_COUNT_1 0x2106
+#define SPR_AUX_PERF_COUNT_CTL 0x2107
+#define SPR_AUX_PERF_COUNT_STS 0x2108
+#define SPR_CMPEXCH_VALUE 0x2780
+#define SPR_CYCLE 0x2781
+#define SPR_DONE 0x2705
+#define SPR_DSTREAM_PF 0x2706
+#define SPR_EVENT_BEGIN 0x2782
+#define SPR_EVENT_END 0x2783
+#define SPR_EX_CONTEXT_0_0 0x2580
+#define SPR_EX_CONTEXT_0_1 0x2581
+#define SPR_EX_CONTEXT_0_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_0_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_0_1__PL_MASK  0x3
+#define SPR_EX_CONTEXT_0_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_0_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_0_1__ICS_MASK  0x4
+#define SPR_EX_CONTEXT_1_0 0x2480
+#define SPR_EX_CONTEXT_1_1 0x2481
+#define SPR_EX_CONTEXT_1_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_1_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_1_1__PL_MASK  0x3
+#define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_1_1__ICS_MASK  0x4
+#define SPR_EX_CONTEXT_2_0 0x2380
+#define SPR_EX_CONTEXT_2_1 0x2381
+#define SPR_EX_CONTEXT_2_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_2_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_2_1__PL_MASK  0x3
+#define SPR_EX_CONTEXT_2_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_2_1__ICS_MASK  0x4
+#define SPR_FAIL 0x2707
+#define SPR_IDN_AVAIL_EN 0x1a05
+#define SPR_IDN_DATA_AVAIL 0x0a80
+#define SPR_IDN_DEADLOCK_TIMEOUT 0x1806
+#define SPR_IDN_DEMUX_COUNT_0 0x0a05
+#define SPR_IDN_DEMUX_COUNT_1 0x0a06
+#define SPR_IDN_DIRECTION_PROTECT 0x1405
+#define SPR_IDN_PENDING 0x0a08
+#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1
+#define SPR_INTCTRL_0_STATUS 0x2505
+#define SPR_INTCTRL_1_STATUS 0x2405
+#define SPR_INTCTRL_2_STATUS 0x2305
+#define SPR_INTERRUPT_CRITICAL_SECTION 0x2708
+#define SPR_INTERRUPT_MASK_0 0x2506
+#define SPR_INTERRUPT_MASK_1 0x2406
+#define SPR_INTERRUPT_MASK_2 0x2306
+#define SPR_INTERRUPT_MASK_RESET_0 0x2507
+#define SPR_INTERRUPT_MASK_RESET_1 0x2407
+#define SPR_INTERRUPT_MASK_RESET_2 0x2307
+#define SPR_INTERRUPT_MASK_SET_0 0x2508
+#define SPR_INTERRUPT_MASK_SET_1 0x2408
+#define SPR_INTERRUPT_MASK_SET_2 0x2308
+#define SPR_INTERRUPT_VECTOR_BASE_0 0x2509
+#define SPR_INTERRUPT_VECTOR_BASE_1 0x2409
+#define SPR_INTERRUPT_VECTOR_BASE_2 0x2309
+#define SPR_INTERRUPT_VECTOR_BASE_3 0x2209
+#define SPR_IPI_EVENT_0 0x1f05
+#define SPR_IPI_EVENT_1 0x1e05
+#define SPR_IPI_EVENT_2 0x1d05
+#define SPR_IPI_EVENT_RESET_0 0x1f06
+#define SPR_IPI_EVENT_RESET_1 0x1e06
+#define SPR_IPI_EVENT_RESET_2 0x1d06
+#define SPR_IPI_EVENT_SET_0 0x1f07
+#define SPR_IPI_EVENT_SET_1 0x1e07
+#define SPR_IPI_EVENT_SET_2 0x1d07
+#define SPR_IPI_MASK_0 0x1f08
+#define SPR_IPI_MASK_1 0x1e08
+#define SPR_IPI_MASK_2 0x1d08
+#define SPR_IPI_MASK_RESET_0 0x1f09
+#define SPR_IPI_MASK_RESET_1 0x1e09
+#define SPR_IPI_MASK_RESET_2 0x1d09
+#define SPR_IPI_MASK_SET_0 0x1f0a
+#define SPR_IPI_MASK_SET_1 0x1e0a
+#define SPR_IPI_MASK_SET_2 0x1d0a
+#define SPR_MPL_AUX_PERF_COUNT_SET_0 0x2100
+#define SPR_MPL_AUX_PERF_COUNT_SET_1 0x2101
+#define SPR_MPL_AUX_PERF_COUNT_SET_2 0x2102
+#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700
+#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701
+#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702
+#define SPR_MPL_IDN_ACCESS_SET_0 0x0a00
+#define SPR_MPL_IDN_ACCESS_SET_1 0x0a01
+#define SPR_MPL_IDN_ACCESS_SET_2 0x0a02
+#define SPR_MPL_IDN_AVAIL_SET_0 0x1a00
+#define SPR_MPL_IDN_AVAIL_SET_1 0x1a01
+#define SPR_MPL_IDN_AVAIL_SET_2 0x1a02
+#define SPR_MPL_IDN_COMPLETE_SET_0 0x0500
+#define SPR_MPL_IDN_COMPLETE_SET_1 0x0501
+#define SPR_MPL_IDN_COMPLETE_SET_2 0x0502
+#define SPR_MPL_IDN_FIREWALL_SET_0 0x1400
+#define SPR_MPL_IDN_FIREWALL_SET_1 0x1401
+#define SPR_MPL_IDN_FIREWALL_SET_2 0x1402
+#define SPR_MPL_IDN_TIMER_SET_0 0x1800
+#define SPR_MPL_IDN_TIMER_

[Qemu-devel] [PATCH v16 06/35] target-tilegx: Modify _SPECIAL_ opcodes

2015-09-14 Thread Richard Henderson
Both ADDX_SPECIAL_0_OPCODE_Y1 and ADD_SPECIAL_0_OPCODE_Y1
do not appear to be "special" in any way, except that they
don't follow the normal naming convention using _RRR_.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/opcode_tilegx.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-tilegx/opcode_tilegx.h b/target-tilegx/opcode_tilegx.h
index 33b71a9..3b8bf4f 100644
--- a/target-tilegx/opcode_tilegx.h
+++ b/target-tilegx/opcode_tilegx.h
@@ -830,11 +830,11 @@ enum
   ADDX_RRR_0_OPCODE_X0 = 2,
   ADDX_RRR_0_OPCODE_X1 = 2,
   ADDX_RRR_0_OPCODE_Y0 = 0,
-  ADDX_SPECIAL_0_OPCODE_Y1 = 0,
+  ADDX_RRR_0_OPCODE_Y1 = 0,
   ADD_RRR_0_OPCODE_X0 = 3,
   ADD_RRR_0_OPCODE_X1 = 3,
   ADD_RRR_0_OPCODE_Y0 = 1,
-  ADD_SPECIAL_0_OPCODE_Y1 = 1,
+  ADD_RRR_0_OPCODE_Y1 = 1,
   ANDI_IMM8_OPCODE_X0 = 3,
   ANDI_IMM8_OPCODE_X1 = 3,
   ANDI_OPCODE_Y0 = 2,
-- 
2.4.3




[Qemu-devel] [PATCH v16 13/35] target-tilegx: Add TILE-Gx building files

2015-09-14 Thread Richard Henderson
From: Chen Gang 

Add related configuration and make files for tilegx.
The target can now build, though not run anything.

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 configure | 2 ++
 default-configs/tilegx-linux-user.mak | 1 +
 target-tilegx/Makefile.objs   | 1 +
 3 files changed, 4 insertions(+)
 create mode 100644 default-configs/tilegx-linux-user.mak
 create mode 100644 target-tilegx/Makefile.objs

diff --git a/configure b/configure
index d7c24cd..2225c39 100755
--- a/configure
+++ b/configure
@@ -5450,6 +5450,8 @@ case "$target_name" in
   s390x)
 gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml s390-vx.xml 
s390-cr.xml"
   ;;
+  tilegx)
+  ;;
   tricore)
   ;;
   unicore32)
diff --git a/default-configs/tilegx-linux-user.mak 
b/default-configs/tilegx-linux-user.mak
new file mode 100644
index 000..3e47493
--- /dev/null
+++ b/default-configs/tilegx-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for tilegx-linux-user
diff --git a/target-tilegx/Makefile.objs b/target-tilegx/Makefile.objs
new file mode 100644
index 000..8b3dc76
--- /dev/null
+++ b/target-tilegx/Makefile.objs
@@ -0,0 +1 @@
+obj-y += cpu.o translate.o helper.o
-- 
2.4.3




[Qemu-devel] [PATCH v16 07/35] target-tilegx: Fix LDNA_ADD_IMM8_OPCODE_X1

2015-09-14 Thread Richard Henderson
An obvious typo in the mnemonic here.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target-tilegx/opcode_tilegx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-tilegx/opcode_tilegx.h b/target-tilegx/opcode_tilegx.h
index 3b8bf4f..989436d 100644
--- a/target-tilegx/opcode_tilegx.h
+++ b/target-tilegx/opcode_tilegx.h
@@ -1015,7 +1015,7 @@ enum
   LD_UNARY_OPCODE_X1 = 29,
   LNK_UNARY_OPCODE_X1 = 30,
   LNK_UNARY_OPCODE_Y1 = 14,
-  LWNA_ADD_IMM8_OPCODE_X1 = 21,
+  LDNA_ADD_IMM8_OPCODE_X1 = 21,
   MFSPR_IMM8_OPCODE_X1 = 22,
   MF_UNARY_OPCODE_X1 = 31,
   MM_BF_OPCODE_X0 = 7,
-- 
2.4.3




[Qemu-devel] [PATCH v16 04/35] target-tilegx: Add opcode basic implementation from Tilera Corporation

2015-09-14 Thread Richard Henderson
From: Chen Gang 

It is copied from Linux kernel "arch/tile/include/uapi/arch/
opcode_tilegx.h".

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 target-tilegx/opcode_tilegx.h | 1406 +
 1 file changed, 1406 insertions(+)
 create mode 100644 target-tilegx/opcode_tilegx.h

diff --git a/target-tilegx/opcode_tilegx.h b/target-tilegx/opcode_tilegx.h
new file mode 100644
index 000..d76ff2d
--- /dev/null
+++ b/target-tilegx/opcode_tilegx.h
@@ -0,0 +1,1406 @@
+/* TILE-Gx opcode information.
+ *
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ *
+ *
+ *
+ *
+ */
+
+#ifndef __ARCH_OPCODE_H__
+#define __ARCH_OPCODE_H__
+
+#ifndef __ASSEMBLER__
+
+typedef unsigned long long tilegx_bundle_bits;
+
+/* These are the bits that determine if a bundle is in the X encoding. */
+#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
+
+enum
+{
+  /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
+  TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
+
+  /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
+  TILEGX_NUM_PIPELINE_ENCODINGS = 5,
+
+  /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
+  TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
+
+  /* Instructions take this many bytes. */
+  TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
+
+  /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
+  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
+
+  /* Bundles should be aligned modulo this number of bytes. */
+  TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
+(1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
+
+  /* Number of registers (some are magic, such as network I/O). */
+  TILEGX_NUM_REGISTERS = 64,
+};
+
+/* Make a few "tile_" variables to simplify common code between
+   architectures.  */
+
+typedef tilegx_bundle_bits tile_bundle_bits;
+#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES
+#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
+#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
+  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
+#define TILE_BPT_BUNDLE TILEGX_BPT_BUNDLE
+
+/* 64-bit pattern for a { bpt ; nop } bundle. */
+#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
+
+static __inline unsigned int
+get_BFEnd_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 24)) & 0xf);
+}
+
+static __inline unsigned int
+get_BFStart_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3f);
+}
+
+static __inline unsigned int
+get_BrOff_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x003f) |
+ (((unsigned int)(n >> 37)) & 0x0001ffc0);
+}
+
+static __inline unsigned int
+get_BrType_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 54)) & 0x1f);
+}
+
+static __inline unsigned int
+get_Dest_Imm8_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x003f) |
+ (((unsigned int)(n >> 43)) & 0x00c0);
+}
+
+static __inline unsigned int
+get_Dest_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Imm16_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x);
+}
+
+static __inline unsigned int
+get_Imm16_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x);
+}
+
+static __inline unsigned int
+get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 20)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 51)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0xff);

[Qemu-devel] [PATCH v16 00/35] TileGX basic instructions

2015-09-14 Thread Richard Henderson
Incorporating review from v15, some of which was in v14 but
I somehow skipped over.

Major changes are:
  * revbit functions for host-utils.h
  * implementation of atomic operations not split across two patches
  * unsigned vector shifts avoid a loop.


r~


Chen Gang (9):
  linux-user: tilegx: Add architecture related features
  linux-user: Support tilegx architecture in linux-user
  linux-user: Conditionalize syscalls which are not defined in tilegx
  target-tilegx: Add opcode basic implementation from Tilera Corporation
  target-tilegx: Modify opcode_tilegx.h to fit QEMU usage
  target-tilegx: Add special register information from Tilera
Corporation
  target-tilegx: Add cpu basic features for linux-user
  target-tilegx: Add several helpers for instructions translation
  target-tilegx: Add TILE-Gx building files

Richard Henderson (26):
  target-tilegx: Modify _SPECIAL_ opcodes
  target-tilegx: Fix LDNA_ADD_IMM8_OPCODE_X1
  target-tilegx: Framework for decoding bundles
  target-tilegx: Generate SEGV properly
  target-tilegx: Handle simple logical operations
  target-tilegx: Handle arithmetic instructions
  host-utils: Add revbit functions
  target-arm: Use new revbit functions
  target-tilegx: Handle most bit manipulation instructions
  target-tilegx: Handle basic load and store instructions
  target-tilegx: Handle post-increment load and store instructions
  target-tilegx: Handle unconditional jump instructions
  target-tilegx: Handle conditional branch instructions
  target-tilegx: Handle comparison instructions
  target-tilegx: Implement system and memory management instructions
  target-tilegx: Handle bitfield instructions
  target-tilegx: Handle shift instructions
  target-tilegx: Handle conditional move instructions
  target-tilegx: Handle scalar multiply instructions
  target-tilegx: Handle mask instructions
  target-tilegx: Handle v1cmpeq, v1cmpne
  target-tilegx: Handle mtspr, mfspr
  target-tilegx: Handle atomic instructions
  target-tilegx: Handle v4int_l/h
  target-tilegx: Handle v1shli, v1shrui
  target-tilegx: Handle v1shl, v1shru, v1shrs

 configure |2 +
 default-configs/tilegx-linux-user.mak |1 +
 include/elf.h |2 +
 include/qemu/host-utils.h |   77 ++
 linux-user/elfload.c  |   23 +
 linux-user/main.c |  238 
 linux-user/syscall.c  |   50 +-
 linux-user/syscall_defs.h |   14 +-
 linux-user/tilegx/syscall.h   |   40 +
 linux-user/tilegx/syscall_nr.h|  324 +
 linux-user/tilegx/target_cpu.h|   35 +
 linux-user/tilegx/target_signal.h |   28 +
 linux-user/tilegx/target_structs.h|   46 +
 linux-user/tilegx/termbits.h  |  274 +
 target-arm/helper-a64.c   |   15 +-
 target-arm/helper.c   |   12 +-
 target-tilegx/Makefile.objs   |1 +
 target-tilegx/cpu.c   |  173 +++
 target-tilegx/cpu.h   |  179 +++
 target-tilegx/helper.c|   80 ++
 target-tilegx/helper.h|   10 +
 target-tilegx/opcode_tilegx.h | 1406 +
 target-tilegx/simd_helper.c   |   55 +
 target-tilegx/spr_def_64.h|  216 
 target-tilegx/translate.c | 2161 +
 25 files changed, 5431 insertions(+), 31 deletions(-)
 create mode 100644 default-configs/tilegx-linux-user.mak
 create mode 100644 linux-user/tilegx/syscall.h
 create mode 100644 linux-user/tilegx/syscall_nr.h
 create mode 100644 linux-user/tilegx/target_cpu.h
 create mode 100644 linux-user/tilegx/target_signal.h
 create mode 100644 linux-user/tilegx/target_structs.h
 create mode 100644 linux-user/tilegx/termbits.h
 create mode 100644 target-tilegx/Makefile.objs
 create mode 100644 target-tilegx/cpu.c
 create mode 100644 target-tilegx/cpu.h
 create mode 100644 target-tilegx/helper.c
 create mode 100644 target-tilegx/helper.h
 create mode 100644 target-tilegx/opcode_tilegx.h
 create mode 100644 target-tilegx/simd_helper.c
 create mode 100644 target-tilegx/spr_def_64.h
 create mode 100644 target-tilegx/translate.c

-- 
2.4.3




[Qemu-devel] [PATCH v16 03/35] linux-user: Conditionalize syscalls which are not defined in tilegx

2015-09-14 Thread Richard Henderson
From: Chen Gang 

Some of architectures (e.g. tilegx), several syscall macros are not
supported, so switch them.

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 50 +-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 973cc2f..d1d3eb2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -213,7 +213,7 @@ static int gettid(void) {
 return -ENOSYS;
 }
 #endif
-#ifdef __NR_getdents
+#if defined(TARGET_NR_getdents) && defined(__NR_getdents)
 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, 
count);
 #endif
 #if !defined(__NR_getdents) || \
@@ -5640,6 +5640,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 ret = get_errno(write(arg1, p, arg3));
 unlock_user(p, arg2, 0);
 break;
+#ifdef TARGET_NR_open
 case TARGET_NR_open:
 if (!(p = lock_user_string(arg1)))
 goto efault;
@@ -5648,6 +5649,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
   arg3));
 unlock_user(p, arg1, 0);
 break;
+#endif
 case TARGET_NR_openat:
 if (!(p = lock_user_string(arg2)))
 goto efault;
@@ -5662,9 +5664,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 case TARGET_NR_brk:
 ret = do_brk(arg1);
 break;
+#ifdef TARGET_NR_fork
 case TARGET_NR_fork:
 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
 break;
+#endif
 #ifdef TARGET_NR_waitpid
 case TARGET_NR_waitpid:
 {
@@ -5699,6 +5703,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 unlock_user(p, arg1, 0);
 break;
 #endif
+#ifdef TARGET_NR_link
 case TARGET_NR_link:
 {
 void * p2;
@@ -5712,6 +5717,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 unlock_user(p, arg1, 0);
 }
 break;
+#endif
 #if defined(TARGET_NR_linkat)
 case TARGET_NR_linkat:
 {
@@ -5729,12 +5735,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 }
 break;
 #endif
+#ifdef TARGET_NR_unlink
 case TARGET_NR_unlink:
 if (!(p = lock_user_string(arg1)))
 goto efault;
 ret = get_errno(unlink(p));
 unlock_user(p, arg1, 0);
 break;
+#endif
 #if defined(TARGET_NR_unlinkat)
 case TARGET_NR_unlinkat:
 if (!(p = lock_user_string(arg2)))
@@ -5851,12 +5859,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 }
 break;
 #endif
+#ifdef TARGET_NR_mknod
 case TARGET_NR_mknod:
 if (!(p = lock_user_string(arg1)))
 goto efault;
 ret = get_errno(mknod(p, arg2, arg3));
 unlock_user(p, arg1, 0);
 break;
+#endif
 #if defined(TARGET_NR_mknodat)
 case TARGET_NR_mknodat:
 if (!(p = lock_user_string(arg2)))
@@ -5865,12 +5875,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 unlock_user(p, arg2, 0);
 break;
 #endif
+#ifdef TARGET_NR_chmod
 case TARGET_NR_chmod:
 if (!(p = lock_user_string(arg1)))
 goto efault;
 ret = get_errno(chmod(p, arg2));
 unlock_user(p, arg1, 0);
 break;
+#endif
 #ifdef TARGET_NR_break
 case TARGET_NR_break:
 goto unimplemented;
@@ -6005,6 +6017,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 }
 break;
 #endif
+#ifdef TARGET_NR_utimes
 case TARGET_NR_utimes:
 {
 struct timeval *tvp, tv[2];
@@ -6023,6 +6036,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 unlock_user(p, arg1, 0);
 }
 break;
+#endif
 #if defined(TARGET_NR_futimesat)
 case TARGET_NR_futimesat:
 {
@@ -6051,12 +6065,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 case TARGET_NR_gtty:
 goto unimplemented;
 #endif
+#ifdef TARGET_NR_access
 case TARGET_NR_access:
 if (!(p = lock_user_string(arg1)))
 goto efault;
 ret = get_errno(access(path(p), arg2));
 unlock_user(p, arg1, 0);
 break;
+#endif
 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
 case TARGET_NR_faccessat:
 if (!(p = lock_user_string(arg2)))
@@ -6081,6 +6097,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 case TARGET_NR_kill:
 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
 break;
+#ifdef TARGET_NR_rename
 case TARGET_NR_rename:
 {
 void *p2;
@@ -6094,6 +6111,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 unlock_user(p, arg1, 0);
 }
 break;
+#endif
 #if defined(TARGET_NR_renameat)
 case TARGET_NR_renameat:
 {
@@ -6109,12 +6127,14 @@ abi_long do_s

[Qemu-devel] [PATCH v16 02/35] linux-user: Support tilegx architecture in linux-user

2015-09-14 Thread Richard Henderson
From: Chen Gang 

Add main working flow feature, system call processing feature, and elf64
tilegx binary loading feature, based on Linux kernel tilegx 64-bit
implementation.

[rth: Moved all of the implementation of atomic instructions to a later patch.]

Signed-off-by: Chen Gang 
Reviewed-by: Peter Maydell 
Message-Id: 
Signed-off-by: Richard Henderson 
---
 include/elf.h |  2 ++
 linux-user/elfload.c  | 23 
 linux-user/main.c | 69 +++
 linux-user/syscall_defs.h | 14 ++
 4 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/include/elf.h b/include/elf.h
index 4afd474..79859f0 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -133,6 +133,8 @@ typedef int64_t  Elf64_Sxword;
 
 #define EM_AARCH64  183
 
+#define EM_TILEGX   191 /* TILE-Gx */
+
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL0
 #define DT_NEEDED  1
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index eca0c7f..39f3282 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1218,6 +1218,29 @@ static inline void init_thread(struct target_pt_regs 
*regs, struct image_info *i
 
 #endif /* TARGET_S390X */
 
+#ifdef TARGET_TILEGX
+
+/* 42 bits real used address, a half for user mode */
+#define ELF_START_MMAP (0x00200ULL)
+
+#define elf_check_arch(x) ((x) == EM_TILEGX)
+
+#define ELF_CLASS   ELFCLASS64
+#define ELF_DATAELFDATA2LSB
+#define ELF_ARCHEM_TILEGX
+
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
+{
+regs->pc = infop->entry;
+regs->sp = infop->start_stack;
+
+}
+
+#define ELF_EXEC_PAGESIZE65536 /* TILE-Gx page size is 64KB */
+
+#endif /* TARGET_TILEGX */
+
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 4ba7228..f3a37a2 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3412,6 +3412,64 @@ void cpu_loop(CPUS390XState *env)
 
 #endif /* TARGET_S390X */
 
+#ifdef TARGET_TILEGX
+
+static void gen_sigsegv_mapper(CPUTLGState *env, target_ulong addr)
+{
+target_siginfo_t info;
+
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+info.si_code = TARGET_SEGV_MAPERR;
+info._sifields._sigfault._addr = addr;
+queue_signal(env, info.si_signo, &info);
+}
+
+static void gen_sigill_reg(CPUTLGState *env)
+{
+target_siginfo_t info;
+
+info.si_signo = TARGET_SIGILL;
+info.si_errno = 0;
+info.si_code = TARGET_ILL_PRVREG;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, &info);
+}
+
+void cpu_loop(CPUTLGState *env)
+{
+CPUState *cs = CPU(tilegx_env_get_cpu(env));
+int trapnr;
+
+while (1) {
+cpu_exec_start(cs);
+trapnr = cpu_tilegx_exec(cs);
+cpu_exec_end(cs);
+switch (trapnr) {
+case TILEGX_EXCP_SYSCALL:
+env->regs[TILEGX_R_RE] = do_syscall(env, env->regs[TILEGX_R_NR],
+env->regs[0], env->regs[1],
+env->regs[2], env->regs[3],
+env->regs[4], env->regs[5],
+env->regs[6], env->regs[7]);
+env->regs[TILEGX_R_ERR] = TILEGX_IS_ERRNO(env->regs[TILEGX_R_RE])
+  ? - 
env->regs[TILEGX_R_RE]
+  : 0;
+break;
+case TILEGX_EXCP_REG_IDN_ACCESS:
+case TILEGX_EXCP_REG_UDN_ACCESS:
+gen_sigill_reg(env);
+break;
+default:
+fprintf(stderr, "trapnr is %d[0x%x].\n", trapnr, trapnr);
+g_assert_not_reached();
+}
+process_pending_signals(env);
+}
+}
+
+#endif
+
 THREAD CPUState *thread_cpu;
 
 void task_settid(TaskState *ts)
@@ -4377,6 +4435,17 @@ int main(int argc, char **argv, char **envp)
 env->psw.mask = regs->psw.mask;
 env->psw.addr = regs->psw.addr;
 }
+#elif defined(TARGET_TILEGX)
+{
+int i;
+for (i = 0; i < TILEGX_R_COUNT; i++) {
+env->regs[i] = regs->regs[i];
+}
+for (i = 0; i < TILEGX_SPR_COUNT; i++) {
+env->spregs[i] = 0;
+}
+env->pc = regs->pc;
+}
 #else
 #error unsupported target CPU
 #endif
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 5256fe5..cdc8db4 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -64,8 +64,9 @@
 #endif
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
-|| defined(TARGET_M68K) || defined(TARGET_CRIS) || 
defined(TARGET_UNICORE32) \
-|| defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+|| defined(TARGET_M68K) || defined(TARGET_CRIS) \
+|| defi

Re: [Qemu-devel] virtio-gpu: cursor update not in sync with resource update

2015-09-14 Thread Dave Airlie
On 15 September 2015 at 07:14, Marc-André Lureau
 wrote:
> Hi
>
> On Mon, Sep 14, 2015 at 11:08 PM, Dave Airlie  wrote:
>> Currently the kernel driver does this:
>>
>> ret = virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 
>> 0,
>>  cpu_to_le32(64),
>>  cpu_to_le32(64),
>>  0, 0, &fence);
>> if (!ret) {
>> reservation_object_add_excl_fence(qobj->tbo.resv,
>>   &fence->f);
>> virtio_gpu_object_wait(qobj, false);
>> }
>>
>> before moving the cursor, shouldn't that suffice?
>>
>> Do we fail the transfer sometimes?
>
>
> That's apparently not in Gerd tree.

Interesting, I'm not sure where this got lost,

I had it in my clone of Gerd's tree from a while back.

Dave.



Re: [Qemu-devel] virtio-gpu: cursor update not in sync with resource update

2015-09-14 Thread Marc-André Lureau
Hi

On Mon, Sep 14, 2015 at 11:08 PM, Dave Airlie  wrote:
> Currently the kernel driver does this:
>
> ret = virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 
> 0,
>  cpu_to_le32(64),
>  cpu_to_le32(64),
>  0, 0, &fence);
> if (!ret) {
> reservation_object_add_excl_fence(qobj->tbo.resv,
>   &fence->f);
> virtio_gpu_object_wait(qobj, false);
> }
>
> before moving the cursor, shouldn't that suffice?
>
> Do we fail the transfer sometimes?


That's apparently not in Gerd tree.

-- 
Marc-André Lureau



Re: [Qemu-devel] [RFT PATCH v1 0/3] net: smc91c111 can_receive fixes

2015-09-14 Thread Richard Purdie
Hi Peter,

On Thu, 2015-09-10 at 21:23 -0700, Peter Crosthwaite wrote:
> This should hopefully fix your bug, while addressing the extra concern
> I raised.
> 
> There was also inconsistent behaviour with corking packets through a
> soft reset which I notice and fixed.
> 
> Please let me know if this works for you.

I've run it through a few builds/tests in place of my own patches and so
far it seems to be working, thanks!

Cheers,

Richard




Re: [Qemu-devel] [edk2] Windows does not support DataTableRegion at all [was: docs: describe QEMU's VMGenID design]

2015-09-14 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Laszlo Ersek had to 
walk into mine at 11:20:28 on Monday 14 September 2015 and say:

> On 09/14/15 18:53, Bill Paul wrote:
> > Of all the gin joints in all the towns in all the world, Laszlo Ersek had
> > to
> > 
> > walk into mine at 03:24:42 on Monday 14 September 2015 and say:
> >> On 09/14/15 10:24, Igor Mammedov wrote:
> >>> On Sun, 13 Sep 2015 15:34:51 +0300
> >>> 
> >>> "Michael S. Tsirkin"  wrote:
>  On Sun, Sep 13, 2015 at 01:56:44PM +0200, Laszlo Ersek wrote:
> > As the subject suggests, I have terrible news.
> > 
> > I'll preserve the full context here, so that it's easy to scroll back
> > to the ASL for reference.
> > 
> > I'm also CC'ing edk2-devel, because a number of BIOS developers
> > should be congregating there.
>  
>  Wow, bravo! It does look like we need to go back to
>  the drawing board.
> > 
> > I read your original post on this with great interest, and I applaud your
> > determination in tracking this down. Nice job.
> 
> Thank you!
> 
> > Sadly, it seems you too have
> > fallen victim to the "If It Works With Windows, It Must Be Ok" syndrome.
> 
> Well, I'd put it like this: we've fallen victim to a publicly
> undocumented feature gap / divergence from the ACPI spec in Windows'
> ACPI.SYS.
> 
> > Now, I realize that as far as this particular situation is concerned,
> > even if Microsoft decided to add support for DataTableRegion() tomorrow,
> > it wouldn't really help because there are too many different versions of
> > Windows in the field and there's no way to retroactively patch them all.
> > (Gee, that sounds familiar...)
> 
> Correct.
> 
> > Nevertheless, am I correct in saying that this is in fact a bug in
> > Microsoft's ACPI implementation (both in their ASL compiler and in the
> > AML parser)?
> 
> Absolutely. You are absolutely right.
> 
> We implemented the VMGENID spec with some undeniable creativity, but it
> broke down because the AML interpreter in Windows does not support an
> ACPI 2.0 feature.
> 
> (That interpreter is supposed to be ACPI 4.0 compliant, minimally; at
> least if we can judge it after the "matching" AML.exe's stated
> compatibility level, which is ACPI 4.0 in the standalone download, and
> 5.0 if you get it as part of the WDK.)
> 
> > Unless
> > DataTableRegion() is specified to be optional in some way (I don't know
> > if it is or not, but I doubt it),
> 
> It's not, to the best of my knowledge.
> 
> > this sounds like an clear cut case of non-
> > compliance with the ACPI spec.
> 
> Yes, it's precisely that.
> 
> > And if that's true, isn't there any way to get
> > Microsoft to fix it?
> 
> I don't know. Is there?

You would think that someone at Intel would know someone at Microsoft that 
could put some wheels in motion. (All this technology and still we have 
trouble communicating. :P )
 
> Microsoft continue to release updates (KB*) for Windows 7, Windows 8,
> Windows 10, and I think rolling a fix out for those would cover our
> needs quite okay.
> 
> But:
> - This would force QEMU/KVM host users to upgrade their Windows guest.
>   Maybe not such a big hurdle, but I reckon Windows sysadmins are
>   really conservative about installing updates. Perhaps we could solve
>   this issue but documentation.

I agree with you that it's a hassle, but so is patching any other Windows bug. 
And while this particular use of DataTableRegion() affects VMs, it has bearing 
on bare metal installations too.
 
> - More importantly, how do I even *report* this bug? How do I convince
>   Microsoft to implement a whole missing feature in their ACPI compiler
>   and interpreter? Can I demonstrate business justification?
>
>   I'm doubtful especially because DataTableRegion's usefulness is quite
>   apparent to the ACPI developer in search for parametrization options.
>   DataTableRegion was published as part of ACPI 2.0, on July 27, 2000
>   (more than fifteen years ago). I simply cannot imagine that in all
>   that time *no* physical platform's firmware developer tried to use
>   DataTableRegion.
> 
>   Therefore I can't help but assume that some big BIOS developer
>   company has already reported this to Microsoft, and the feature
>   request has been rejected. So what chance would I have?

I understand what you're saying. But, there has to be some way to deal with 
these sorts of things. If everyone thinks and acts that way, then that's 
effectively letting Microsoft control the ACPI standard by "embracing and 
extending" it. (Or in this case I guess it's embracing and constricting it.)

I think a major part of the problem is that the only standard with which the 
big BIOS developers feel they must comply is the Windows Logo program. The x86 
market is still dominated by Windows users, and getting that Windows badge 
onto the machines is still top priority. If there was a UEFI Forum Logo 
program to which they had to adhere instead, things might be different. But 

Re: [Qemu-devel] virtio-gpu: cursor update not in sync with resource update

2015-09-14 Thread Dave Airlie
On 15 September 2015 at 01:17, Marc-André Lureau
 wrote:
> Hi
>
> On Mon, Sep 14, 2015 at 4:06 PM, Gerd Hoffmann  wrote:
>> The guest can upload different cursors and then switch between them
>> without re-uploading and therefore without ctrl queue updates.  Thats
>> why they have an id in the first place ...
>
> Ok, but the cursor id is reused most of the time. So there are at
> least two things to fix: use different cursor ids for different cursor
> data (with some cache management probably), fix kernel to only upload
> new resource id and wait for data to be transfered. Is that correct?

Currently the kernel driver does this:

ret = virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 0,
 cpu_to_le32(64),
 cpu_to_le32(64),
 0, 0, &fence);
if (!ret) {
reservation_object_add_excl_fence(qobj->tbo.resv,
  &fence->f);
virtio_gpu_object_wait(qobj, false);
}

before moving the cursor, shouldn't that suffice?

Do we fail the transfer sometimes?

Dave.



Re: [Qemu-devel] [PATCH v2 3/5] acpi: pc: add fw_cfg device node to ssdt

2015-09-14 Thread Gabriel L. Somlo
On Mon, Sep 14, 2015 at 04:34:02PM -0400, Gabriel L. Somlo wrote:
> > > So I'll replace the "if (guest_info->fw_cfg)" check with
> > > "if machine-type >= (pc-q35-2.5 or pc-i440fx-2.5))", in v3,
> > > as soon as the patches for the 2.5 machine type make it into
> > > git master (I remember seeing a reviewed-by fly by for that
> > > earlier today :)
> > 
> > Sounds good, assuming you are going to implement the "machine-type >= 
> > pc-2.5"
> > check with something like: 
> > PC_MACHINE_GET_CLASS(machine)->acpi_no_fw_cfg_node.
> 
> Thanks, that gives me something to grep for ;)
> 
> I was going to mimic how other acpi related decisions are made on pc
> (piix or q35), something like below. Might even be the same thing,
> once I learn about PC_MACHINE_GET_CLASS :)

OK, so not exactly the same thing. What's the trade-off between
adding a boolean field to PCMachineClass vs. PcGuestInfo? Either
would work technically, and PcGuestInfo already has a bunch of
acpi related booleans. But if the new canonical place for this
kind of thing is PCMachineClass rather than PcGuestInfo, it's OK
with me...

Please advise.

Thanks,
--Gabriel



Re: [Qemu-devel] [PATCH v2 3/5] acpi: pc: add fw_cfg device node to ssdt

2015-09-14 Thread Gabriel L. Somlo
On Mon, Sep 14, 2015 at 05:16:44PM -0300, Eduardo Habkost wrote:
> On Mon, Sep 14, 2015 at 02:16:49PM -0400, Gabriel L. Somlo wrote:
> > On Mon, Sep 14, 2015 at 01:09:41PM -0300, Eduardo Habkost wrote:
> > > On Mon, Sep 14, 2015 at 10:57:31AM -0400, Gabriel L. Somlo wrote:
> > > > Add a fw_cfg device node to the ACPI SSDT. While the guest-side
> > > > BIOS can't utilize this information (since it has to access the
> > > > hard-coded fw_cfg device to extract ACPI tables to begin with),
> > > > having fw_cfg listed in ACPI will help the guest kernel keep a
> > > > more accurate inventory of in-use IO port regions.
> > > > 
> > > > Signed-off-by: Gabriel Somlo 
> > > > ---
> > > >  hw/i386/acpi-build.c | 20 
> > > >  1 file changed, 20 insertions(+)
> > > > 
> > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > index 95e0c65..ecdb3a5 100644
> > > > --- a/hw/i386/acpi-build.c
> > > > +++ b/hw/i386/acpi-build.c
> > > > @@ -1071,6 +1071,26 @@ build_ssdt(GArray *table_data, GArray *linker,
> > > >  aml_append(scope, aml_name_decl("_S5", pkg));
> > > >  aml_append(ssdt, scope);
> > > >  
> > > > +if (guest_info->fw_cfg) {
> > > 
> > > I sent a reply to v1 a few minutes before seeing v2. Copying it here for
> > > reference:
> > > 
> > > Is this function ever going to be called without fw_cfg set?
> > > acpi_setup() returns immediately if fw_cfg isn't available.
> > 
> > You're right, build_ssdt() is called from acpi_build(), which is
> > called directly from acpi_setup(), and also indirectly via
> > acpi_build_update() via acpi_add_rom_blob(), but all that eventually
> > ties back to acpi_setup(), *after* it already established that
> > guest_info->fw_cfg is non-NULL.
> > 
> > > Also, this changes guest ABI, so you will need to add some compat flag
> > > to PCMachineClass indicating if the device node should be added.
> > 
> > So I'll replace the "if (guest_info->fw_cfg)" check with
> > "if machine-type >= (pc-q35-2.5 or pc-i440fx-2.5))", in v3,
> > as soon as the patches for the 2.5 machine type make it into
> > git master (I remember seeing a reviewed-by fly by for that
> > earlier today :)
> 
> Sounds good, assuming you are going to implement the "machine-type >= pc-2.5"
> check with something like: PC_MACHINE_GET_CLASS(machine)->acpi_no_fw_cfg_node.

Thanks, that gives me something to grep for ;)

I was going to mimic how other acpi related decisions are made on pc
(piix or q35), something like below. Might even be the same thing,
once I learn about PC_MACHINE_GET_CLASS :)

Thanks,
--Gabriel


diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3f925b2..8219ed9 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -64,6 +64,7 @@ static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 static bool pci_enabled = true;
 static bool has_acpi_build = true;
 static bool rsdp_in_ram = true;
+static bool has_acpi_fw_cfg = true;
 static int legacy_acpi_table_size;
 static bool smbios_defaults = true;
 static bool smbios_legacy_mode;
@@ -168,6 +169,7 @@ static void pc_init1(MachineState *machine,
 guest_info->isapc_ram_fw = !pci_enabled;
 guest_info->has_reserved_memory = has_reserved_memory;
 guest_info->rsdp_in_ram = rsdp_in_ram;
+guest_info->has_acpi_fw_cfg = has_acpi_fw_cfg;
 
 if (smbios_defaults) {
 MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -316,6 +318,7 @@ static void pc_compat_2_2(MachineState *machine)
 {
 pc_compat_2_3(machine);
 rsdp_in_ram = false;
+has_acpi_fw_cfg = false;
 machine->suppress_vmdesc = true;
 }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 11601ab..29daf08 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -52,6 +52,7 @@
 
 static bool has_acpi_build = true;
 static bool rsdp_in_ram = true;
+static bool has_acpi_fw_cfg = true;
 static bool smbios_defaults = true;
 static bool smbios_legacy_mode;
 static bool smbios_uuid_encoded = true;
@@ -154,6 +155,7 @@ static void pc_q35_init(MachineState *machine)
 guest_info->has_acpi_build = has_acpi_build;
 guest_info->has_reserved_memory = has_reserved_memory;
 guest_info->rsdp_in_ram = rsdp_in_ram;
+guest_info->has_acpi_fw_cfg = has_acpi_fw_cfg;
 
 /* Migration was not supported in 2.0 for Q35, so do not bother
  * with this hack (see hw/i386/acpi-build.c).
@@ -299,6 +301,7 @@ static void pc_compat_2_2(MachineState *machine)
 {
 pc_compat_2_3(machine);
 rsdp_in_ram = false;
+has_acpi_fw_cfg = false;
 machine->suppress_vmdesc = true;
 }
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index fadcaa4..4896475 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -103,6 +103,7 @@ struct PcGuestInfo {
 bool has_acpi_build;
 bool has_reserved_memory;
 bool rsdp_in_ram;
+bool has_acpi_fw_cfg;
 };
 
 /* parallel.c */



Re: [Qemu-devel] [PATCH 2/2] linux-user: remove MAX_ARG_PAGES limit

2015-09-14 Thread Peter Maydell
On 14 September 2015 at 20:37, Stefan Bruens
 wrote:
> On Thursday 03 September 2015 18:27:20 Peter Maydell wrote:
>> On 2 September 2015 at 02:38, Stefan Brüns 
> wrote:
>> > Instead of creating a temporary copy for the whole environment and
>> > the arguments, directly copy everything to the target stack.
>> >
>> > For this to work, we have to change the order of stack creation and
>> > copying the arguments.
>> >
>> > Signed-off-by: Stefan Brüns 
>>
>> Reviewed-by: Peter Maydell 
>>
>> Thanks for working through the code review process.
>>
>> thanks
>> -- PMM
>
> Hi Peter,
>
> is there anything that needs to be done before picking up these two patches?

Nope. It's just waiting on Riku to pick them up (I've cc'd him;
it's usually a good idea to cc the relevant submaintainer
listed in the MAINTAINERS file). Riku doesn't generally have
much time to do QEMU related work these days though so there's
sometimes a lag on linux-user patches getting into master.

thanks
-- PMM



  1   2   3   4   >