Re: [Qemu-devel] [PATCH] target-mips: silence NaNs for cvt.s.d and cvt.d.s

2016-01-24 Thread Peter Maydell
On 24 January 2016 at 03:42, Maciej W. Rozycki  wrote:
>
>  FYI, I posted a more general fix to this a while ago, however the review
> regrettably went nowhere.  See the archive of discussion starting at:
> 
> for details, including the justification and further design consideration.

The relevant review is in this bit of the thread
http://lists.nongnu.org/archive/html/qemu-devel/2015-02/msg00897.html
(which you can't trivially get to from the original top level post
since the mailing list archive regrettably splits archives by month
and doesn't track threads between months).

ARM does the same thing that this patch does for MIPS (silence
NaNs in the calling function after the conversion happens), but as
I mention in that email this is broken and really should be dealt
with via target-specific hooks in the conversion routines.

thanks
-- PMM



Re: [Qemu-devel] [PATCH v14 0/8] Block replication for continuous checkpoints

2016-01-24 Thread Wen Congyang

Stefan:ping

Do you have time to review this series patchset?

Thanks
Wen Congyang

At 2016/1/13 17:18, Changlong Xie wrote:

Block replication is a very important feature which is used for
continuous checkpoints(for example: COLO).

You can get the detailed information about block replication from here:
http://wiki.qemu.org/Features/BlockReplication

Usage:
Please refer to docs/block-replication.txt

This patch series is based on the following patch series:
1. http://lists.nongnu.org/archive/html/qemu-devel/2015-12/msg04570.html

You can get the patch here:
https://github.com/Pating/qemu/tree/changlox/block-replication-v14

You can get the patch with framework here:
https://github.com/Pating/qemu/tree/changlox/colo_framework_v13

TODO:
1. Continuous block replication. It will be started after basic functions
are accepted.

Changs Log:
V14:
1. Implement auto complete active commit
2. Implement active commit block job for replication.c
3. Address the comments from Stefan, add replication-specific API and data
structure, also remove old block layer APIs
V13:
1. Rebase to the newest codes
2. Remove redundant marcos and semicolon in replication.c
3. Fix typos in block-replication.txt
V12:
1. Rebase to the newest codes
2. Use backing reference to replcace 'allow-write-backing-file'
V11:
1. Reopen the backing file when starting blcok replication if it is not
opened in R/W mode
2. Unblock BLOCK_OP_TYPE_BACKUP_SOURCE and BLOCK_OP_TYPE_BACKUP_TARGET
when opening backing file
3. Block the top BDS so there is only one block job for the top BDS and
its backing chain.
V10:
1. Use blockdev-remove-medium and blockdev-insert-medium to replace backing
reference.
2. Address the comments from Eric Blake
V9:
1. Update the error messages
2. Rebase to the newest qemu
3. Split child add/delete support. These patches are sent in another patchset.
V8:
1. Address Alberto Garcia's comments
V7:
1. Implement adding/removing quorum child. Remove the option non-connect.
2. Simplify the backing refrence option according to Stefan Hajnoczi's 
suggestion
V6:
1. Rebase to the newest qemu.
V5:
1. Address the comments from Gong Lei
2. Speed the failover up. The secondary vm can take over very quickly even
if there are too many I/O requests.
V4:
1. Introduce a new driver replication to avoid touch nbd and qcow2.
V3:
1: use error_setg() instead of error_set()
2. Add a new block job API
3. Active disk, hidden disk and nbd target uses the same AioContext
4. Add a testcase to test new hbitmap API
V2:
1. Redesign the secondary qemu(use image-fleecing)
2. Use Error objects to return error message
3. Address the comments from Max Reitz and Eric Blake

Wen Congyang (8):
   unblock backup operations in backing file
   Store parent BDS in BdrvChild
   Backup: clear all bitmap when doing block checkpoint
   Allow creating backup jobs when opening BDS
   docs: block replication's description
   auto complete active commit
   Implement new driver for block replication
   support replication driver in blockdev-add

  block.c  |  19 ++
  block/Makefile.objs  |   3 +-
  block/backup.c   |  14 +
  block/mirror.c   |  13 +-
  block/replication-comm.c |  66 +
  block/replication.c  | 590 +++
  blockdev.c   |   2 +-
  blockjob.c   |  11 +
  docs/block-replication.txt   | 229 +++
  include/block/block_int.h|   4 +-
  include/block/blockjob.h |  12 +
  include/block/replication-comm.h |  50 
  qapi/block-core.json |  33 ++-
  qemu-img.c   |   2 +-
  14 files changed, 1038 insertions(+), 10 deletions(-)
  create mode 100644 block/replication-comm.c
  create mode 100644 block/replication.c
  create mode 100644 docs/block-replication.txt
  create mode 100644 include/block/replication-comm.h





Re: [Qemu-devel] [PATCH v11 7/7] arm_mptimer: Convert to use ptimer

2016-01-24 Thread Dmitry Osipenko

Hello Peter,

24.01.2016 08:25, Peter Crosthwaite пишет:

[snip]


+timerblock_run(tb->timer, control, (value != 0) && (control & 1));
  break;
  case 8: /* Control.  */
-old = tb->control;
-tb->control = value;
-if (value & 1) {
-if ((old & 1) && (tb->count != 0)) {
-/* Do nothing if timer is ticking right now.  */
-break;
+if ((value & 1) && (control & 3) != (value & 3)) {
+uint64_t count = (value & 0xff00) ? 1 : 
ptimer_get_count(tb->timer);
+if ((count == 0) && (value & 2)) {
+timerblock_set_count(tb->timer, value, &count);


This looks like a weird corner-case, what does it do exactly? I can't
follow it so it needs a comment :)



It does the following:

mode | prescaler | reload if counter == 0 | tick immediately if counter == 0

oneshot  == 0   0 0
oneshot  != 0   0 1
periodic == 0   1 0
periodic != 0   0 1

If writing control register with prescaler = 0, then for one-shot timer with 
counter == 0 or periodic timer with load = counter == 0 this is NOP. Will add a 
comment.


Thanks for review!

--
Dmitry



Re: [Qemu-devel] [PATCH v11 6/7] hw/ptimer: Legalize running with delta = load = 0 and abort on period = 0

2016-01-24 Thread Dmitry Osipenko

24.01.2016 07:28, Peter Crosthwaite пишет:

[snip]


  /* Set counter frequency in Hz.  */
  void ptimer_set_freq(ptimer_state *s, uint32_t freq)
  {
+g_assert(freq != 0);
  s->delta = ptimer_get_count(s);
  s->period = 10ll / freq;
  s->period_frac = (10ll << 32) / freq;


I noticed that this should be g_assert(freq != 0 && freq <= 10), 
otherwise it possible to make period = 0 for the running timer when setting freq 
> 1GHz, which doesn't make sense because we can't set period < 1ns.


Or maybe we should clamp period = max(1, period), freq = min(10, freq) 
to "allow" higher timer freq's?


What do you think?

--
Dmitry



Re: [Qemu-devel] [vfio-users] [PATCH v2 1/3] input: add qemu_input_qcode_to_linux + qemu_input_linux_to_qcode

2016-01-24 Thread Jonathan Scruggs
Hi Gerd,

A couple of options I have been wondering about.

1)
Is it possible to have an option that would enable running a program on the
host on switching, IE when both CRTL keys are pressed. It would run on the
host regardless if it was on the guest machine when the keys pressed.
An option like 'onswitchexecute=/usr/bin/monitorswitch'

Something like that. I have a small program that switches the monitor input
via I2C direct (if interested: http://pastebin.com/6Hd0pafF). The program
would need to be modified a little bit to not use a variable input. but to
somehow detect what it's currently at and then switch to the opposite --
shouldn't be too hard.

2)
This would be useful for number idea one.
Instead of both CTRL keys, could the hotkey be something like
CTRL+SHIFT+ALT+1 for the host, and then each guest would set an option of 2
through 9. Since this is really only good for dedicated graphics cards, the
most I've heard of is 7 in one machine and that was a crazy build. A normal
person would have two cards, namely MS Windows Gaming Rig and GNU/Linux.
However, some may want three, which is very doable on most systems. So,
CTRL+SHIFT+ALT+2 or +3 to get to the other systems.

It can connect into point one, as the cheap and dirty monitor switcher code
takes an input and my monitor has three inputs, so a person could write
code to switch anything to anything. The option could have a variable
string that when called by your Input patches, would replace the variable
place holder with the machine being called, IE:
'execonswitch=/usr/bin/monitorswitch %COMPNUM'
Or something like that.

Hope you like the ideas.
Jon

On 18 January 2016 at 14:13, Gerd Hoffmann  wrote:

> On Mo, 2016-01-18 at 11:47 +, Jonathan Scruggs wrote:
> > Hi Gerd,
> >
> > Would there be a way to add repeating keys back in that doesn't cause
> > issues? Maybe slow down the repeat cycle? Or is this strictly a issue
> > with how the actual event drivers or the buffers work and would need
> > changing to that on the host side?
>
> I don't know ...
>
> > In my mind it seams fairly straightforward in just forwarding these
> > events to the VM.
>
> I assumed that as well, it was there initially and only removed after it
> turned out to cause problems.
>
> I've added a patch to the git branch bringing it back, but guarded with
> a new config option (repeat={on,off}) and turned off by default.
>
> > Would it be different if the keyboard was using the PS/2 versus the
> > USB interface on the guest? I have a USB controller added for the
> > guest but the keyboard and mouse are on PS/2 interfaces.
>
> Worth testing.  Just add "-device usb-kbd" to the qemu command line and
> see what happens ...
>
> > A second thought. What if you made the keyboard and mouse USB only,
> > then on the guest, make sure the USB controller is using Message
> > Signal-Based interrupts. On Windows, the controller was set to the old
> > style Line-Based. The slow downs could be caused by a lake in speed
> > with he interrupts and USB polling speed.
>
> In case windows is new enough to have xhci support (win8+) you can try
> using a xhci hostadapter, which supports MSI (uhci and ehci don't), then
> hook up the usb keyboard to it.
>
> "-device nec-usb-xhci,id=xhci -device usb-kbd,bus=xhci.0"
>
> cheers,
>   Gerd
>
>


Re: [Qemu-devel] [PATCH 04/13] cuda: port SET_AUTO_RATE command to new framework

2016-01-24 Thread Hervé Poussineau

Le 23/01/2016 21:40, Hervé Poussineau a écrit :

Take requested autopoll rate into account

Signed-off-by: Hervé Poussineau 
---
  hw/misc/macio/cuda.c | 31 +++
  hw/ppc/mac.h |  1 +
  2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 37406fc..9ec642f 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -105,7 +105,6 @@
  #define CUDA_COMBINED_FORMAT_IIC  0x25

  #define CUDA_TIMER_FREQ (470 / 6)
-#define CUDA_ADB_POLL_FREQ 50

  /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
  #define RTC_OFFSET  2082844800
@@ -531,7 +530,7 @@ static void cuda_adb_poll(void *opaque)
  }
  timer_mod(s->adb_poll_timer,
 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-   (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
+   (get_ticks_per_sec() / (1000 / s->auto_rate_ms)));
  }

  /* description of commands */
@@ -559,7 +558,7 @@ static bool cuda_cmd_autopoll(CUDAState *s,
  if (autopoll) {
  timer_mod(s->adb_poll_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-  (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
+  (get_ticks_per_sec() / (1000 / s->auto_rate_ms)));
  } else {
  timer_del(s->adb_poll_timer);
  }
@@ -567,8 +566,32 @@ static bool cuda_cmd_autopoll(CUDAState *s,
  return true;
  }

+static bool cuda_cmd_set_autorate(CUDAState *s,
+  const uint8_t *in_data, int in_len,
+  uint8_t *out_data, int *out_len)
+{
+if (in_len != 1) {
+return false;
+}
+
+/* we don't want a period of 0 ms */
+/* FIXME: check what real hardware does */
+if (in_data[0] == 0) {
+return;


This 'return' should be changed into a 'return false'.


+}
+
+s->auto_rate_ms = in_data[0];
+if (s->autopoll) {
+timer_mod(s->adb_poll_timer,
+  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+  (get_ticks_per_sec() / (1000 / s->auto_rate_ms)));
+}
+return true;
+}
+
  static const CudaCommand handlers[] = {
  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
+{ CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
  };

  static void cuda_receive_packet(CUDAState *s,
@@ -618,7 +641,6 @@ static void cuda_receive_packet(CUDAState *s,
  return;
  case CUDA_FILE_SERVER_FLAG:
  case CUDA_SET_DEVICE_LIST:
-case CUDA_SET_AUTO_RATE:
  case CUDA_SET_POWER_MESSAGES:
  cuda_send_packet_to_host(s, obuf, 3);
  return;
@@ -824,6 +846,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
  s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;

  s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
+s->auto_rate_ms = 20;
  }

  static void cuda_initfn(Object *obj)
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index e375ed2..90fcb69 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -111,6 +111,7 @@ typedef struct CUDAState {
  int data_out_index;

  qemu_irq irq;
+uint8_t auto_rate_ms;
  uint8_t autopoll;
  uint8_t data_in[128];
  uint8_t data_out[16];






Re: [Qemu-devel] [Qemu-ppc] [PATCH 05/13] cuda: port SET_DEVICE_LIST command to new framework

2016-01-24 Thread Programmingkid

On Jan 23, 2016, at 3:41 PM, qemu-ppc-requ...@nongnu.org wrote:

> Message: 6
> Date: Sat, 23 Jan 2016 21:40:02 +0100
> From: Herv? Poussineau 
> To: qemu-devel@nongnu.org
> Cc: Alyssa Milburn , Herv? Poussineau
>   , qemu-...@nongnu.org, David Gibson
>   
> Subject: [Qemu-ppc] [PATCH 05/13] cuda: port SET_DEVICE_LIST command
>   to new  framework
> Message-ID: <1453581610-23179-6-git-send-email-hpous...@reactos.org>
> Content-Type: text/plain; charset=UTF-8
> 
> Take device list mask into account when polling ADB devices.
> 
> Signed-off-by: Herv? Poussineau 
> ---
> hw/input/adb.c | 18 ++
> hw/misc/macio/cuda.c   | 17 +++--
> hw/ppc/mac.h   |  1 +
> include/hw/input/adb.h |  2 +-
> roms/SLOF  |  2 +-
> roms/openbios  |  2 +-
> 6 files changed, 29 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/input/adb.c b/hw/input/adb.c
> index 09eead9..d05fdfd 100644
> --- a/hw/input/adb.c
> +++ b/hw/input/adb.c
> @@ -88,7 +88,7 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const 
> uint8_t *buf, int len)
> }
> 
> /* XXX: move that to cuda ? */
> -int adb_poll(ADBBusState *s, uint8_t *obuf)
> +int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
> {
> ADBDevice *d;
> int olen, i;
> @@ -99,13 +99,15 @@ int adb_poll(ADBBusState *s, uint8_t *obuf)
> if (s->poll_index >= s->nb_devices)
> s->poll_index = 0;
> d = s->devices[s->poll_index];
> -buf[0] = ADB_READREG | (d->devaddr << 4);
> -olen = adb_request(s, obuf + 1, buf, 1);
> -/* if there is data, we poll again the same device */
> -if (olen > 0) {
> -obuf[0] = buf[0];
> -olen++;
> -break;
> +if ((1 << d->devaddr) & poll_mask) {
> +buf[0] = ADB_READREG | (d->devaddr << 4);
> +olen = adb_request(s, obuf + 1, buf, 1);
> +/* if there is data, we poll again the same device */
> +if (olen > 0) {
> +obuf[0] = buf[0];
> +olen++;
> +break;
> +}
> }
> s->poll_index++;
> }
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 9ec642f..9af8e1d 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -522,7 +522,7 @@ static void cuda_adb_poll(void *opaque)
> uint8_t obuf[ADB_MAX_OUT_LEN + 2];
> int olen;
> 
> -olen = adb_poll(&s->adb_bus, obuf + 2);
> +olen = adb_poll(&s->adb_bus, obuf + 2, s->poll_mask);
> if (olen > 0) {
> obuf[0] = ADB_PACKET;
> obuf[1] = 0x40; /* polled data */
> @@ -589,9 +589,22 @@ static bool cuda_cmd_set_autorate(CUDAState *s,
> return true;
> }
> 
> +static bool cuda_cmd_set_device_list(CUDAState *s,
> + const uint8_t *in_data, int in_len,
> + uint8_t *out_data, int *out_len)
> +{
> +if (in_len != 2) {
> +return false;
> +}
> +
> +s->poll_mask = (((uint16_t)in_data[0]) << 8) | in_data[1];
> +return true;
> +}
> +
> static const CudaCommand handlers[] = {
> { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
> { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
> +{ CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list },
> };
> 
> static void cuda_receive_packet(CUDAState *s,
> @@ -640,7 +653,6 @@ static void cuda_receive_packet(CUDAState *s,
> cuda_send_packet_to_host(s, obuf, 7);
> return;
> case CUDA_FILE_SERVER_FLAG:
> -case CUDA_SET_DEVICE_LIST:
> case CUDA_SET_POWER_MESSAGES:
> cuda_send_packet_to_host(s, obuf, 3);
> return;
> @@ -847,6 +859,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
> 
> s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
> s->auto_rate_ms = 20;
> +s->poll_mask = 0x;
> }
> 
> static void cuda_initfn(Object *obj)
> diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
> index 90fcb69..506f7a8 100644
> --- a/hw/ppc/mac.h
> +++ b/hw/ppc/mac.h
> @@ -111,6 +111,7 @@ typedef struct CUDAState {
> int data_out_index;
> 
> qemu_irq irq;
> +uint16_t poll_mask;
> uint8_t auto_rate_ms;
> uint8_t autopoll;
> uint8_t data_in[128];
> diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
> index bdfccd4..db51d03 100644
> --- a/include/hw/input/adb.h
> +++ b/include/hw/input/adb.h
> @@ -79,7 +79,7 @@ struct ADBBusState {
> 
> int adb_request(ADBBusState *s, uint8_t *buf_out,
> const uint8_t *buf, int len);
> -int adb_poll(ADBBusState *s, uint8_t *buf_out);
> +int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
> 
> #define TYPE_ADB_KEYBOARD "adb-keyboard"
> #define TYPE_ADB_MOUSE "adb-mouse"
> diff --git a/roms/SLOF b/roms/SLOF
> index b4c9380..811277a 16
> --- a/roms/SLOF
> +++ b/roms/SLOF
> @@ -1 +1 @@
> -Subproject commit b4c93802a5b2c72f096649c497ec9ff5708e4456
> +Subpro

Re: [Qemu-devel] [PATCH 11/13] cuda: port SET_TIME command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:08PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 24 ++--
>  1 file changed, 18 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 55e9cff..49a79fc 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -673,6 +673,23 @@ static bool cuda_cmd_get_time(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_set_time(CUDAState *s,
> +  const uint8_t *in_data, int in_len,
> +  uint8_t *out_data, int *out_len)
> +{
> +uint32_t ti;
> +
> +if (in_len != 4) {
> +return false;
> +}
> +
> +ti = (((uint32_t)in_data[1]) << 24) + (((uint32_t)in_data[2]) << 16)
> + + (((uint32_t)in_data[3]) << 8) + in_data[4];
> +s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
> +   / get_ticks_per_sec());
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
> @@ -684,6 +701,7 @@ static const CudaCommand handlers[] = {
>  { CUDA_SET_POWER_MESSAGES, "SET_POWER_MESSAGES",
>cuda_cmd_set_power_message },
>  { CUDA_GET_TIME, "GET_TIME", cuda_cmd_get_time },
> +{ CUDA_SET_TIME, "SET_TIME", cuda_cmd_set_time },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -691,7 +709,6 @@ static void cuda_receive_packet(CUDAState *s,
>  {
>  uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] };
>  int i, out_len = 0;
> -uint32_t ti;
>  
>  for (i = 0; i < ARRAY_SIZE(handlers); i++) {
>  const CudaCommand *desc = &handlers[i];
> @@ -718,11 +735,6 @@ static void cuda_receive_packet(CUDAState *s,
>  case CUDA_GET_6805_ADDR:
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;
> -case CUDA_SET_TIME:
> -ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + 
> (((uint32_t)data[3]) << 8) + data[4];
> -s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 
> get_ticks_per_sec());
> -cuda_send_packet_to_host(s, obuf, 3);
> -return;
>  case CUDA_COMBINED_FORMAT_IIC:
>  obuf[0] = ERROR_PACKET;
>  obuf[1] = 0x5;

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 04/13] cuda: port SET_AUTO_RATE command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:01PM +0100, Hervé Poussineau wrote:
> Take requested autopoll rate into account

Commit message needs some work - as far as I can tell this is
not just moving this to the new framework, but implementing it -
previously the command was silently ignored.

> 
> Signed-off-by: Hervé Poussineau 
> ---
>  hw/misc/macio/cuda.c | 31 +++
>  hw/ppc/mac.h |  1 +
>  2 files changed, 28 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 37406fc..9ec642f 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -105,7 +105,6 @@
>  #define CUDA_COMBINED_FORMAT_IIC 0x25
>  
>  #define CUDA_TIMER_FREQ (470 / 6)
> -#define CUDA_ADB_POLL_FREQ 50
>  
>  /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
>  #define RTC_OFFSET  2082844800
> @@ -531,7 +530,7 @@ static void cuda_adb_poll(void *opaque)
>  }
>  timer_mod(s->adb_poll_timer,
> qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> -   (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
> +   (get_ticks_per_sec() / (1000 / s->auto_rate_ms)));

I believe you can reduce the rounding errors by expressing this as:
(s->auto_rate_ms * get_ticks_per_sec()) / 1000


>  }
>  
>  /* description of commands */
> @@ -559,7 +558,7 @@ static bool cuda_cmd_autopoll(CUDAState *s,
>  if (autopoll) {
>  timer_mod(s->adb_poll_timer,
>qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> -  (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
> +  (get_ticks_per_sec() / (1000 / s->auto_rate_ms)));
>  } else {
>  timer_del(s->adb_poll_timer);
>  }
> @@ -567,8 +566,32 @@ static bool cuda_cmd_autopoll(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_set_autorate(CUDAState *s,
> +  const uint8_t *in_data, int in_len,
> +  uint8_t *out_data, int *out_len)
> +{
> +if (in_len != 1) {
> +return false;
> +}
> +
> +/* we don't want a period of 0 ms */
> +/* FIXME: check what real hardware does */
> +if (in_data[0] == 0) {
> +return;
> +}
> +
> +s->auto_rate_ms = in_data[0];
> +if (s->autopoll) {
> +timer_mod(s->adb_poll_timer,
> +  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> +  (get_ticks_per_sec() / (1000 / s->auto_rate_ms)));

IIUC this will make the next even occur in auto_rate_ms milliseconds,
rather than auto_rate_ms from the previous event.  i.e. it discards
any time elapsed on the currently running timer.

That may be the intended behaviour, or at least close enough that it
doesn't matter, but I think it deserves comment.

> +}
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
> +{ CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -618,7 +641,6 @@ static void cuda_receive_packet(CUDAState *s,
>  return;
>  case CUDA_FILE_SERVER_FLAG:
>  case CUDA_SET_DEVICE_LIST:
> -case CUDA_SET_AUTO_RATE:
>  case CUDA_SET_POWER_MESSAGES:
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;
> @@ -824,6 +846,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
>  s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
>  
>  s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
> +s->auto_rate_ms = 20;
>  }
>  
>  static void cuda_initfn(Object *obj)
> diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
> index e375ed2..90fcb69 100644
> --- a/hw/ppc/mac.h
> +++ b/hw/ppc/mac.h
> @@ -111,6 +111,7 @@ typedef struct CUDAState {
>  int data_out_index;
>  
>  qemu_irq irq;
> +uint8_t auto_rate_ms;
>  uint8_t autopoll;
>  uint8_t data_in[128];
>  uint8_t data_out[16];

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 07/13] cuda: port RESET_SYSTEM command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:04PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 17 +
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index df4797f..70a5d0c 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -613,11 +613,24 @@ static bool cuda_cmd_powerdown(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_reset_system(CUDAState *s,
> +  const uint8_t *in_data, int in_len,
> +  uint8_t *out_data, int *out_len)
> +{
> +if (in_len != 0) {
> +return false;
> +}
> +
> +qemu_system_reset_request();
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
>  { CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list },
>  { CUDA_POWERDOWN, "POWERDOWN", cuda_cmd_powerdown },
> +{ CUDA_RESET_SYSTEM, "RESET_SYSTEM", cuda_cmd_reset_system },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -669,10 +682,6 @@ static void cuda_receive_packet(CUDAState *s,
>  case CUDA_SET_POWER_MESSAGES:
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;
> -case CUDA_RESET_SYSTEM:
> -cuda_send_packet_to_host(s, obuf, 3);
> -qemu_system_reset_request();
> -return;
>  case CUDA_COMBINED_FORMAT_IIC:
>  obuf[0] = ERROR_PACKET;
>  obuf[1] = 0x5;

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 03/13] cuda: port AUTOPOLL command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:00PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 40 +---
>  1 file changed, 25 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index f27dd19..37406fc 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -543,14 +543,38 @@ typedef struct CudaCommand {
>  uint8_t *out_args, int *out_len);
>  } CudaCommand;
>  
> +static bool cuda_cmd_autopoll(CUDAState *s,
> +  const uint8_t *in_data, int in_len,
> +  uint8_t *out_data, int *out_len)
> +{
> +int autopoll;
> +
> +if (in_len != 1) {
> +return false;
> +}
> +
> +autopoll = (in_data[0] != 0);
> +if (autopoll != s->autopoll) {
> +s->autopoll = autopoll;
> +if (autopoll) {
> +timer_mod(s->adb_poll_timer,
> +  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> +  (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
> +} else {
> +timer_del(s->adb_poll_timer);
> +}
> +}
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
> +{ CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
>  const uint8_t *data, int len)
>  {
>  uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] };
> -int autopoll;
>  int i, out_len = 0;
>  uint32_t ti;
>  
> @@ -576,20 +600,6 @@ static void cuda_receive_packet(CUDAState *s,
>  }
>  
>  switch(data[0]) {
> -case CUDA_AUTOPOLL:
> -autopoll = (data[1] != 0);
> -if (autopoll != s->autopoll) {
> -s->autopoll = autopoll;
> -if (autopoll) {
> -timer_mod(s->adb_poll_timer,
> -   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> -   (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
> -} else {
> -timer_del(s->adb_poll_timer);
> -}
> -}
> -cuda_send_packet_to_host(s, obuf, 3);
> -return;
>  case CUDA_GET_6805_ADDR:
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 02/13] cuda: reject unknown commands

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:39:59PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 
> ---
>  hw/misc/macio/cuda.c | 25 -
>  1 file changed, 16 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 69f69c2..f27dd19 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -589,15 +589,15 @@ static void cuda_receive_packet(CUDAState *s,
>  }
>  }
>  cuda_send_packet_to_host(s, obuf, 3);
> -break;
> +return;
>  case CUDA_GET_6805_ADDR:
>  cuda_send_packet_to_host(s, obuf, 3);
> -break;
> +return;
>  case CUDA_SET_TIME:
>  ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + 
> (((uint32_t)data[3]) << 8) + data[4];
>  s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 
> get_ticks_per_sec());
>  cuda_send_packet_to_host(s, obuf, 3);
> -break;
> +return;
>  case CUDA_GET_TIME:
>  ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 
> get_ticks_per_sec());
>  obuf[3] = ti >> 24;
> @@ -605,28 +605,28 @@ static void cuda_receive_packet(CUDAState *s,
>  obuf[5] = ti >> 8;
>  obuf[6] = ti;
>  cuda_send_packet_to_host(s, obuf, 7);
> -break;
> +return;
>  case CUDA_FILE_SERVER_FLAG:
>  case CUDA_SET_DEVICE_LIST:
>  case CUDA_SET_AUTO_RATE:
>  case CUDA_SET_POWER_MESSAGES:
>  cuda_send_packet_to_host(s, obuf, 3);
> -break;
> +return;
>  case CUDA_POWERDOWN:
>  cuda_send_packet_to_host(s, obuf, 3);
>  qemu_system_shutdown_request();
> -break;
> +return;
>  case CUDA_RESET_SYSTEM:
>  cuda_send_packet_to_host(s, obuf, 3);
>  qemu_system_reset_request();
> -break;
> +return;
>  case CUDA_COMBINED_FORMAT_IIC:
>  obuf[0] = ERROR_PACKET;
>  obuf[1] = 0x5;
>  obuf[2] = CUDA_PACKET;
>  obuf[3] = data[0];
>  cuda_send_packet_to_host(s, obuf, 4);
> -break;
> +return;
>  case CUDA_GET_SET_IIC:
>  if (len == 4) {
>  cuda_send_packet_to_host(s, obuf, 3);
> @@ -637,10 +637,17 @@ static void cuda_receive_packet(CUDAState *s,
>  obuf[3] = data[0];
>  cuda_send_packet_to_host(s, obuf, 4);
>  }
> -break;
> +return;
>  default:
>  break;
>  }
> +
> +qemu_log_mask(LOG_GUEST_ERROR, "CUDA: unknown command 0x%02x\n", 
> data[0]);

AFAICT qemu_log isn't much used these days, and it's not already used
in this file.  I think you'd be better off with either CUDA_DPRINTF()
or a tracepoint.

> +obuf[0] = ERROR_PACKET;
> +obuf[1] = 0x2; /* unknown command */
> +obuf[2] = CUDA_PACKET;
> +obuf[3] = data[0];
> +cuda_send_packet_to_host(s, obuf, 4);
>  }
>  
>  static void cuda_receive_packet_from_host(CUDAState *s,

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 01/13] cuda: add a framework to handle commands

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:39:58PM +0100, Hervé Poussineau wrote:
> Next commits will port existing CUDA commands to this framework.
> 
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 34 ++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 9db4c64..69f69c2 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -534,13 +534,47 @@ static void cuda_adb_poll(void *opaque)
> (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
>  }
>  
> +/* description of commands */
> +typedef struct CudaCommand {
> +uint8_t command;
> +const char *name;
> +bool (*handler)(CUDAState *s,
> +const uint8_t *in_args, int in_len,
> +uint8_t *out_args, int *out_len);
> +} CudaCommand;
> +
> +static const CudaCommand handlers[] = {
> +};
> +
>  static void cuda_receive_packet(CUDAState *s,
>  const uint8_t *data, int len)
>  {
>  uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] };
>  int autopoll;
> +int i, out_len = 0;
>  uint32_t ti;
>  
> +for (i = 0; i < ARRAY_SIZE(handlers); i++) {
> +const CudaCommand *desc = &handlers[i];
> +if (desc->command == data[0]) {
> +CUDA_DPRINTF("handling command %s\n", desc->name);
> +out_len = 0;
> +if (desc->handler(s, data + 1, len - 1, obuf + 3, &out_len)) {
> +cuda_send_packet_to_host(s, obuf, 3 + out_len);
> +} else {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "CUDA: %s: wrong parameters %d\n",
> +  desc->name, len);
> +obuf[0] = ERROR_PACKET;
> +obuf[1] = 0x5; /* bad parameters */
> +obuf[2] = CUDA_PACKET;
> +obuf[3] = data[0];
> +cuda_send_packet_to_host(s, obuf, 4);
> +}
> +return;
> +}
> +}
> +
>  switch(data[0]) {
>  case CUDA_AUTOPOLL:
>  autopoll = (data[1] != 0);

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 00/13] cuda: misc fixes and cleanups

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:39:57PM +0100, Hervé Poussineau wrote:
> Hi,
> 
> This patchset cleans up a little bit the Apple CUDA emulation:
> - correctly reject unknown commands
> - correctly reject commands with wrong parameters
> - support changing the frequency of auto-polling
> - support changing device list probed in auto-poll
> - add logs when using FILE_SERVER_FLAG/SET_POWER_MESSAGE
> - remove unused commands (GET/SET_6805_ADDR)
> - remove unimplemented GET_SET_IIC/COMBINED_FORMAT_IIC
> 
> GET_SET_IIC/COMBINED_FORMAT_IIC commands should be added again once
> we implement the I2C bus provided by CUDA.
> 
> This also fixes MacBugs hanging at startup in the absence of
> ADB mouse input.
> 
> Hervé

This series looks sound in concept, but there's a couple of things I
need before applying it:
  * On inspection I noticed a handful of small problems, noted in
comments on the individual patches
  * I'm not really set up to test Mac, so if I can get a Tested-by
from someone who can, that would be good (Mark?).

Thanks,
David.

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 05/13] cuda: port SET_DEVICE_LIST command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:02PM +0100, Hervé Poussineau wrote:
> Take device list mask into account when polling ADB devices.

Again, this appears to implement the command, not just move it.


> Signed-off-by: Hervé Poussineau 
> ---
>  hw/input/adb.c | 18 ++
>  hw/misc/macio/cuda.c   | 17 +++--
>  hw/ppc/mac.h   |  1 +
>  include/hw/input/adb.h |  2 +-
>  roms/SLOF  |  2 +-
>  roms/openbios  |  2 +-
>  6 files changed, 29 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/input/adb.c b/hw/input/adb.c
> index 09eead9..d05fdfd 100644
> --- a/hw/input/adb.c
> +++ b/hw/input/adb.c
> @@ -88,7 +88,7 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const 
> uint8_t *buf, int len)
>  }
>  
>  /* XXX: move that to cuda ? */
> -int adb_poll(ADBBusState *s, uint8_t *obuf)
> +int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
>  {
>  ADBDevice *d;
>  int olen, i;
> @@ -99,13 +99,15 @@ int adb_poll(ADBBusState *s, uint8_t *obuf)
>  if (s->poll_index >= s->nb_devices)
>  s->poll_index = 0;
>  d = s->devices[s->poll_index];
> -buf[0] = ADB_READREG | (d->devaddr << 4);
> -olen = adb_request(s, obuf + 1, buf, 1);
> -/* if there is data, we poll again the same device */
> -if (olen > 0) {
> -obuf[0] = buf[0];
> -olen++;
> -break;
> +if ((1 << d->devaddr) & poll_mask) {
> +buf[0] = ADB_READREG | (d->devaddr << 4);
> +olen = adb_request(s, obuf + 1, buf, 1);
> +/* if there is data, we poll again the same device */
> +if (olen > 0) {
> +obuf[0] = buf[0];
> +olen++;
> +break;
> +}
>  }
>  s->poll_index++;
>  }
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 9ec642f..9af8e1d 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -522,7 +522,7 @@ static void cuda_adb_poll(void *opaque)
>  uint8_t obuf[ADB_MAX_OUT_LEN + 2];
>  int olen;
>  
> -olen = adb_poll(&s->adb_bus, obuf + 2);
> +olen = adb_poll(&s->adb_bus, obuf + 2, s->poll_mask);
>  if (olen > 0) {
>  obuf[0] = ADB_PACKET;
>  obuf[1] = 0x40; /* polled data */
> @@ -589,9 +589,22 @@ static bool cuda_cmd_set_autorate(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_set_device_list(CUDAState *s,
> + const uint8_t *in_data, int in_len,
> + uint8_t *out_data, int *out_len)
> +{
> +if (in_len != 2) {
> +return false;
> +}
> +
> +s->poll_mask = (((uint16_t)in_data[0]) << 8) | in_data[1];
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
> +{ CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -640,7 +653,6 @@ static void cuda_receive_packet(CUDAState *s,
>  cuda_send_packet_to_host(s, obuf, 7);
>  return;
>  case CUDA_FILE_SERVER_FLAG:
> -case CUDA_SET_DEVICE_LIST:
>  case CUDA_SET_POWER_MESSAGES:
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;
> @@ -847,6 +859,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
>  
>  s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
>  s->auto_rate_ms = 20;
> +s->poll_mask = 0x;
>  }
>  
>  static void cuda_initfn(Object *obj)
> diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
> index 90fcb69..506f7a8 100644
> --- a/hw/ppc/mac.h
> +++ b/hw/ppc/mac.h
> @@ -111,6 +111,7 @@ typedef struct CUDAState {
>  int data_out_index;
>  
>  qemu_irq irq;
> +uint16_t poll_mask;
>  uint8_t auto_rate_ms;
>  uint8_t autopoll;
>  uint8_t data_in[128];
> diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
> index bdfccd4..db51d03 100644
> --- a/include/hw/input/adb.h
> +++ b/include/hw/input/adb.h
> @@ -79,7 +79,7 @@ struct ADBBusState {
>  
>  int adb_request(ADBBusState *s, uint8_t *buf_out,
>  const uint8_t *buf, int len);
> -int adb_poll(ADBBusState *s, uint8_t *buf_out);
> +int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
>  
>  #define TYPE_ADB_KEYBOARD "adb-keyboard"
>  #define TYPE_ADB_MOUSE "adb-mouse"
> diff --git a/roms/SLOF b/roms/SLOF
> index b4c9380..811277a 16
> --- a/roms/SLOF
> +++ b/roms/SLOF
> @@ -1 +1 @@
> -Subproject commit b4c93802a5b2c72f096649c497ec9ff5708e4456
> +Subproject commit 811277ac91f674a9273e2b529791e9b75350f3e8
> diff --git a/roms/openbios b/roms/openbios
> index 3caee17..18f02b1 16
> --- a/roms/openbios
> +++ b/roms/openbios
> @@ -1 +1 @@
> -Subproject commit 3caee1794ac3f742315823d8447d21f33ce019e9
> +Subproject commit 18f02b14de795c1aab4f

Re: [Qemu-devel] [PATCH 09/13] cuda: port SET_POWER_MESSAGES command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:06PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 

Revieed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 19 ---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 294e8fb..64a3e79 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -639,6 +639,20 @@ static bool cuda_cmd_set_file_server_flag(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_set_power_message(CUDAState *s,
> +   const uint8_t *in_data, int in_len,
> +   uint8_t *out_data, int *out_len)
> +{
> +if (in_len != 1) {
> +return false;
> +}
> +
> +qemu_log_mask(LOG_UNIMP,
> +  "CUDA: unimplemented command SET_POWER_MESSAGE %d\n",
> +  in_data[0]);
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
> @@ -647,6 +661,8 @@ static const CudaCommand handlers[] = {
>  { CUDA_RESET_SYSTEM, "RESET_SYSTEM", cuda_cmd_reset_system },
>  { CUDA_FILE_SERVER_FLAG, "FILE_SERVER_FLAG",
>cuda_cmd_set_file_server_flag },
> +{ CUDA_SET_POWER_MESSAGES, "SET_POWER_MESSAGES",
> +  cuda_cmd_set_power_message },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -694,9 +710,6 @@ static void cuda_receive_packet(CUDAState *s,
>  obuf[6] = ti;
>  cuda_send_packet_to_host(s, obuf, 7);
>  return;
> -case CUDA_SET_POWER_MESSAGES:
> -cuda_send_packet_to_host(s, obuf, 3);
> -return;
>  case CUDA_COMBINED_FORMAT_IIC:
>  obuf[0] = ERROR_PACKET;
>  obuf[1] = 0x5;

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] cuda.c: return error for unknown commands

2016-01-24 Thread David Gibson
On Fri, Jan 22, 2016 at 11:07:24PM +, Alyssa Milburn wrote:
> This avoids MacsBug hanging at startup in the absence of ADB mouse
> input, by replying with an error (which is also what MOL does) when
> it sends an unknown command (0x1c).
> 
> Signed-off-by: Alyssa Milburn 

I've applied this to ppc-for-2.6 for now, since it looks like it
addresses a real problem, and I can't see that it could break things
any worse than they are broken already.

I think Hervé's patches need a few tweaks, but I do hope to apply them
on top in the not too distant future.

> ---
>  hw/misc/macio/cuda.c | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 9db4c64..7e57de5 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -605,6 +605,11 @@ static void cuda_receive_packet(CUDAState *s,
>  }
>  break;
>  default:
> +obuf[0] = ERROR_PACKET;
> +obuf[1] = 0x2;
> +obuf[2] = CUDA_PACKET;
> +obuf[3] = data[0];
> +cuda_send_packet_to_host(s, obuf, 4);
>  break;
>  }
>  }

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 10/13] cuda: port GET_TIME command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:07PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 29 +
>  1 file changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 64a3e79..55e9cff 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -653,6 +653,26 @@ static bool cuda_cmd_set_power_message(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_get_time(CUDAState *s,
> +  const uint8_t *in_data, int in_len,
> +  uint8_t *out_data, int *out_len)
> +{
> +uint32_t ti;
> +
> +if (in_len != 0) {
> +return false;
> +}
> +
> +ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
> +   / get_ticks_per_sec());
> +out_data[0] = ti >> 24;
> +out_data[1] = ti >> 16;
> +out_data[2] = ti >> 8;
> +out_data[3] = ti;
> +*out_len = 4;
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
> @@ -663,6 +683,7 @@ static const CudaCommand handlers[] = {
>cuda_cmd_set_file_server_flag },
>  { CUDA_SET_POWER_MESSAGES, "SET_POWER_MESSAGES",
>cuda_cmd_set_power_message },
> +{ CUDA_GET_TIME, "GET_TIME", cuda_cmd_get_time },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -702,14 +723,6 @@ static void cuda_receive_packet(CUDAState *s,
>  s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 
> get_ticks_per_sec());
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;
> -case CUDA_GET_TIME:
> -ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 
> get_ticks_per_sec());
> -obuf[3] = ti >> 24;
> -obuf[4] = ti >> 16;
> -obuf[5] = ti >> 8;
> -obuf[6] = ti;
> -cuda_send_packet_to_host(s, obuf, 7);
> -return;
>  case CUDA_COMBINED_FORMAT_IIC:
>  obuf[0] = ERROR_PACKET;
>  obuf[1] = 0x5;

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 06/13] cuda: port POWERDOWN command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:03PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 17 +
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 9af8e1d..df4797f 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -601,10 +601,23 @@ static bool cuda_cmd_set_device_list(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_powerdown(CUDAState *s,
> +   const uint8_t *in_data, int in_len,
> +   uint8_t *out_data, int *out_len)
> +{
> +if (in_len != 0) {
> +return false;
> +}
> +
> +qemu_system_shutdown_request();
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
>  { CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list },
> +{ CUDA_POWERDOWN, "POWERDOWN", cuda_cmd_powerdown },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -656,10 +669,6 @@ static void cuda_receive_packet(CUDAState *s,
>  case CUDA_SET_POWER_MESSAGES:
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;
> -case CUDA_POWERDOWN:
> -cuda_send_packet_to_host(s, obuf, 3);
> -qemu_system_shutdown_request();
> -return;
>  case CUDA_RESET_SYSTEM:
>  cuda_send_packet_to_host(s, obuf, 3);
>  qemu_system_reset_request();

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 08/13] cuda: port FILE_SERVER_FLAG command to new framework

2016-01-24 Thread David Gibson
On Sat, Jan 23, 2016 at 09:40:05PM +0100, Hervé Poussineau wrote:
> This command tells if computer should automatically wake-up after a power 
> loss.
> 
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

> ---
>  hw/misc/macio/cuda.c | 17 -
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 70a5d0c..294e8fb 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -625,12 +625,28 @@ static bool cuda_cmd_reset_system(CUDAState *s,
>  return true;
>  }
>  
> +static bool cuda_cmd_set_file_server_flag(CUDAState *s,
> +  const uint8_t *in_data, int in_len,
> +  uint8_t *out_data, int *out_len)
> +{
> +if (in_len != 1) {
> +return false;
> +}
> +
> +qemu_log_mask(LOG_UNIMP,
> +  "CUDA: unimplemented command FILE_SERVER_FLAG %d\n",
> +  in_data[0]);
> +return true;
> +}
> +
>  static const CudaCommand handlers[] = {
>  { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
>  { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
>  { CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list },
>  { CUDA_POWERDOWN, "POWERDOWN", cuda_cmd_powerdown },
>  { CUDA_RESET_SYSTEM, "RESET_SYSTEM", cuda_cmd_reset_system },
> +{ CUDA_FILE_SERVER_FLAG, "FILE_SERVER_FLAG",
> +  cuda_cmd_set_file_server_flag },
>  };
>  
>  static void cuda_receive_packet(CUDAState *s,
> @@ -678,7 +694,6 @@ static void cuda_receive_packet(CUDAState *s,
>  obuf[6] = ti;
>  cuda_send_packet_to_host(s, obuf, 7);
>  return;
> -case CUDA_FILE_SERVER_FLAG:
>  case CUDA_SET_POWER_MESSAGES:
>  cuda_send_packet_to_host(s, obuf, 3);
>  return;

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] hw/pci-host/uninorth.c: Add support for Apple's PCI bridge register 0x48

2016-01-24 Thread David Gibson
On Fri, Jan 22, 2016 at 07:13:28PM +, Mark Cave-Ayland wrote:
> On 22/01/16 18:26, Programmingkid wrote:
> 
> > On Jan 22, 2016, at 11:46 AM, Mark Cave-Ayland wrote:
> > 
> >> On 22/01/16 16:09, Programmingkid wrote:
> >>
> >>> Apple has custom PCI bridge registers that are not a part of any known 
> >>> standard. This patch implements register 0x48. With this patch the 
> >>> AppleMacRiscPCI kernel extension no longer prints these error messages 
> >>> for the mac99 target:
> >>> AppleMacRiscPCI: bad range 2(8000:0100)
> >>> AppleMacRiscPCI: bad range 2(8100:1000)
> >>> AppleMacRiscPCI: bad range 2(8108:0008)
> >>>
> >>> Signed-off-by: John Arbuckle 
> >>>
> >>> ---
> >>> hw/pci-host/uninorth.c |4 
> >>> 1 files changed, 4 insertions(+), 0 deletions(-)
> >>>
> >>> diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
> >>> index 215b64f..6541b10 100644
> >>> --- a/hw/pci-host/uninorth.c
> >>> +++ b/hw/pci-host/uninorth.c
> >>> @@ -330,6 +330,10 @@ static void unin_agp_pci_host_realize(PCIDevice *d, 
> >>> Error **errp)
> >>> d->config[0x0C] = 0x08; // cache_line_size
> >>> d->config[0x0D] = 0x10; // latency_timer
> >>> //d->config[0x34] = 0x80; // capabilities_pointer
> >>> +d->config[0x48] = 0x0;
> >>> +d->config[0x49] = 0x0;
> >>> +d->config[0x4a] = 0x0;
> >>> +d->config[0x4b] = 0x1;
> >>> }
> >>>
> >>> static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp)
> >>
> >> Tested-by: Mark Cave-Ayland 
> >>
> >> As this config space register is seemingly an Apple custom option (or at
> >> least I can't find a mention of it in the PCI-PCI bridge spec) I think
> >> this should have a comment explaining exactly what it does, and should
> >> reference both AppleMacRiscPCI.cpp filename and the enum for the
> >> register value (0x48 == kMacRISCPCIAddressSelect).
> > 
> > Is this what you want:
> > 
> > Apple has custom PCI bridge registers that are not a part of any known 
> > standard. This patch implements register 0x48. With this patch the 
> > AppleMacRiscPCI kernel extension no longer prints these error messages for 
> > the mac99 target:
> > AppleMacRiscPCI: bad range 2(8000:0100)
> > AppleMacRiscPCI: bad range 2(8100:1000)
> > AppleMacRiscPCI: bad range 2(8108:0008)
> > 
> > In Apple's AppleMacRiscPCI.h source code, the register is defined as 
> > kMacRISCPCIAddressSelect. It is accessed in the AppleMacRiscPCI.cpp file. 
> > What this register is used for is determining the address a pci bridge 
> > range that is kept track of by the operating system. 
> > 
> >> I'd also like to see a note explaining that this sets up the register to
> >> match the PCI memory region base/size currently used in QEMU/OpenBIOS
> >> too in order to provide a hint that if one changes, so must the other.
> > 
> > Note: OpenBIOS in the arch/ppc/qemu/init.c file has a structure with an 
> > index of [ARCH_MAC99]. It keeps track of the PCI MMIO range for the mac99 
> > target. If a change happens to either this file or the AppleMacRiscPCI 
> > kernel extension, the other would have to be changed as well.
> 
> It's mostly down to Alex/David (so please wait for some initial
> feedback) but I'd prefer to see something along these lines:
> 
> 
> Subject: uninorth.c: add support for UniNorth kMacRISCPCIAddressSelect
> (0x48) register
> 
> Darwin/OS X use the undocumented kMacRISCPCIAddressSelect (0x48) to
> configure PCI memory space size for mac99 machines. Without this
> register, warnings similar to below are emitted to the console during boot:
> 
> AppleMacRiscPCI: bad range 2(8000:0100)
> AppleMacRiscPCI: bad range 2(8100:1000)
> AppleMacRiscPCI: bad range 2(8108:0008)
> 
> Based upon the algorithm in Darwin's AppleMacRiscPCI.cpp driver, set the
> kMacRISCPCIAddressSelect register so that Darwin considers the PCI
> memory space to be at 0x8000 (size 0x1000) which matches that
> currently used by QEMU and OpenBIOS.

That's much better - without the context mentioning Darwin / OS X, the
filename isn't much use.

> Similarly I think a 2-line comment should be added in the actual code
> itself e.g.
> 
> /* Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI memory
> space with base 0x8000, size 0x1000 for Apple's AppleMacRiscPCI
> driver */

I've applied the patch to ppc-for-2.6, but I've revised the commit
message and comment as suggested by Mark.

John, in future do remember that the people reviewing patches probably
won't be working in the same sub-area as you: the commit message needs
to provide enough context for them to understand why the patch is
desirable.


> >> BTW is the register required for any of the other uni-north realize
> >> functions? Alex?
> > 
> > 
> > My guess is no. Only the AppleMacRiscPCI kernel extension needs to know 
> > those details.
> 
> I was thinking more about AGP and non-AGP uninorth bridges, but there is
> definitely some overlap as you can see that

Re: [Qemu-devel] [PATCH v2] .travis.yml: migrate to container builds

2016-01-24 Thread David Gibson
On Thu, Jan 21, 2016 at 10:28:05PM +, Alex Bennée wrote:
> This moves the Travis tests from the legacy VM infrastructure (which
> only seems to run 5-6 jobs at once) to the new container based approach.
> 
> The principle difference is there is no sudo in the containers so all
> packages are installed using the apt add-on. This means one of the build
> combinations can be dropped as it was only for checking the build with
> additional packages.
> 
> Signed-off-by: Alex Bennée 

Tested-by: David Gibson 
Reviewed-by: David Gibson 

-- 
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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v13 00/10] Block replication for continuous checkpoints

2016-01-24 Thread Wen Congyang
On 01/22/2016 11:14 PM, Dr. David Alan Gilbert wrote:
> Hi,
>   I can trigger a segfault if I wire in the block replication together with
> a quorum instance; it only triggers with both of them present but,
> it looks like the problem is a disagreement about the number of quorum
> members;  I'm triggering this on the 'colo-v2.4-periodic-mode' branch
> that is posted in the colo-framework set that I think includes this set
> (from https://github.com/coloft/qemu.git).
> 
> To trigger:
> ./git/colo/jan-16/try/x86_64-softmmu/qemu-system-x86_64 -nographic -S
> 
> (qemu) drive_add 0 
> if=none,id=colo-disk0,file.filename=/home/localvms/bugzilla.raw,driver=raw,node-name=node0
> (qemu) drive_add 1 
> if=none,id=active-disk0,throttling.bps-total=7000,driver=replication,mode=secondary,file.driver=qcow2,file.file.filename=/run/colo-active-disk.qcow2,file.backing.driver=qcow2,file.backing.file.filename=/run/colo-hidden-disk.qcow2,file.backing.backing=colo-disk0
> (qemu) drive_add 2 
> if=none,id=top-quorum,driver=quorum,read-pattern=fifo,vote-threshold=1,children.0=active-disk0
> (qemu) device_add virtio-blk-pci,drive=top-quorum,addr=9
> 
> *** Error in `/root/colo/jan-2016/./try/x86_64-softmmu/qemu-system-x86_64': 
> free(): invalid pointer: 0x55a8fdf0 ***
> === Backtrace: =
> /lib64/libc.so.6(+0x7cfe1)[0x7110ffe1]
> /lib64/libglib-2.0.so.0(g_free+0xf)[0x71ecc36f]
> /root/colo/jan-2016/./try/x86_64-softmmu/qemu-system-x86_64
> Program received signal SIGABRT, Aborted.
> 0x710c85f7 in raise () from /lib64/libc.so.6
> (gdb) where
> #0  0x710c85f7 in raise () from /lib64/libc.so.6
> #1  0x710c9ce8 in abort () from /lib64/libc.so.6
> #2  0x71108317 in __libc_message () from /lib64/libc.so.6
> #3  0x7110ffe1 in _int_free () from /lib64/libc.so.6
> #4  0x71ecc36f in g_free () from /lib64/libglib-2.0.so.0
> #5  0x559dfdd7 in qemu_iovec_destroy (qiov=0x57815410) at 
> /root/colo/jan-2016/qemu/util/iov.c:378
> #6  0x55989cce in quorum_aio_finalize (acb=0x57815350) at 
> /root/colo/jan-2016/qemu/block/quorum.c:171
> 171   qemu_iovec_destroy(&acb->qcrs[i].qiov);
> (gdb) list
> 166   
> 167   if (acb->is_read) {
> 168   /* on the quorum case acb->child_iter == s->num_children - 1 */
> 169   for (i = 0; i <= acb->child_iter; i++) {
> 170   qemu_vfree(acb->qcrs[i].buf);
> 171   qemu_iovec_destroy(&acb->qcrs[i].qiov);
> 172   }
> 173   }
> 174   
> 175   g_free(acb->qcrs);
> (gdb) p acb->child_iter
> $1 = 1
> (gdb) p i
> $3 = 1

Thanks for your test. Can you give me the following information:
1. acb->ret's value
2. s->num_children

I think it is quorum's bug, and acb->ret is < 0.

Thanks
Wen Congyang

> 
> #7  0x5598afca in quorum_aio_cb (opaque=, ret=-5)
> at /root/colo/jan-2016/qemu/block/quorum.c:302
> #8  0x559990ee in bdrv_co_complete (acb=0x57815410) at 
> /root/colo/jan-2016/qemu/block/io.c:2122
> .
> 
> So I guess acb->child_iter is wrong, since we only have one child on that 
> quorum?
> and we're trying to do a destroy on the second child.
> 
> Dave
> --
> Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
> 
> 
> .
> 






Re: [Qemu-devel] [PATCH v9 2/3] quorum: implement bdrv_add_child() and bdrv_del_child()

2016-01-24 Thread Wen Congyang
On 01/23/2016 04:02 AM, Dr. David Alan Gilbert wrote:
> * Alberto Garcia (be...@igalia.com) wrote:
>> On Thu 21 Jan 2016 05:58:42 PM CET, Eric Blake  wrote:
>> In general, what do you do to make sure that the data in a new Quorum
>> child is consistent with that of the rest of the array?
>
> Quorum can have more than one child when it starts. But we don't do
> the similar check. So I don't think we should do such check here.

 Yes, but when you start a VM you can verify in advance that all
 members of the Quorum have the same data. If you do that on a running
 VM how can you know if the new disk is consistent with the others?
>>>
>>> User error if it is not.  Just the same as it is user error if you
>>> request a shallow drive-mirror but the destination is not the same
>>> contents as the backing file.  I don't think qemu has to protect us
>>> from user error in this case.
>>
>> But the backing file is read-only so the user can guarantee that the
>> destination has the same data before the shallow mirror. How do you do
>> that in this case?
> 
> I think in the colo case they're relying on doing a block migrate
> to synchronise the remote disk prior to switching into colo mode.

Yes, we can do a block migration to sync the disk. After the migration finished,
we stop block migration before starting colo.

Thanks
Wen Congyang

> 
> Dave
> 
>> Berto
> --
> Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
> 
> 
> .
> 






[Qemu-devel] [PULL 04/28] macio: add dma_active to VMStateDescription

2016-01-24 Thread David Gibson
From: Mark Cave-Ayland 

Make sure that we include the value of dma_active in the migration stream.

Signed-off-by: Mark Cave-Ayland 
Acked-by: John Snow 
Signed-off-by: David Gibson 
---
 hw/ide/macio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 110af46..a39bdc0 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -516,11 +516,12 @@ static const MemoryRegionOps pmac_ide_ops = {
 
 static const VMStateDescription vmstate_pmac = {
 .name = "ide",
-.version_id = 3,
+.version_id = 4,
 .minimum_version_id = 0,
 .fields = (VMStateField[]) {
 VMSTATE_IDE_BUS(bus, MACIOIDEState),
 VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState),
+VMSTATE_BOOL(dma_active, MACIOIDEState),
 VMSTATE_END_OF_LIST()
 }
 };
-- 
2.5.0




[Qemu-devel] [PULL 02/28] target-ppc: use cpu_write_xer() helper in cpu_post_load

2016-01-24 Thread David Gibson
From: Mark Cave-Ayland 

Otherwise some internal xer variables fail to get set post-migration.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Alexey Kardashevskiy 
Signed-off-by: David Gibson 
---
 target-ppc/machine.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index f4ac761..b61c060 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -168,7 +168,7 @@ static int cpu_post_load(void *opaque, int version_id)
 env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
 env->lr = env->spr[SPR_LR];
 env->ctr = env->spr[SPR_CTR];
-env->xer = env->spr[SPR_XER];
+cpu_write_xer(env, env->spr[SPR_XER]);
 #if defined(TARGET_PPC64)
 env->cfar = env->spr[SPR_CFAR];
 #endif
-- 
2.5.0




[Qemu-devel] [PULL 13/28] pseries: Clean up error handling in spapr_validate_node_memory()

2016-01-24 Thread David Gibson
Use error_setg() and return an error, rather than using an explicit exit().

Also improve messages, and be more explicit about which constraint failed.

Signed-off-by: David Gibson 
Reviewed-by: Bharata B Rao 
Reviewed-by: Thomas Huth 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr.c | 37 ++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 447fa5d..5793205 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1698,27 +1698,34 @@ static void 
spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr)
  * to SPAPR_MEMORY_BLOCK_SIZE(256MB), then refuse to start the guest
  * since we can't support such unaligned sizes with DRCONF_MEMORY.
  */
-static void spapr_validate_node_memory(MachineState *machine)
+static void spapr_validate_node_memory(MachineState *machine, Error **errp)
 {
 int i;
 
-if (machine->maxram_size % SPAPR_MEMORY_BLOCK_SIZE ||
-machine->ram_size % SPAPR_MEMORY_BLOCK_SIZE) {
-error_report("Can't support memory configuration where RAM size "
- "0x" RAM_ADDR_FMT " or maxmem size "
- "0x" RAM_ADDR_FMT " isn't aligned to %llu MB",
- machine->ram_size, machine->maxram_size,
- SPAPR_MEMORY_BLOCK_SIZE/M_BYTE);
-exit(EXIT_FAILURE);
+if (machine->ram_size % SPAPR_MEMORY_BLOCK_SIZE) {
+error_setg(errp, "Memory size 0x" RAM_ADDR_FMT
+   " is not aligned to %llu MiB",
+   machine->ram_size,
+   SPAPR_MEMORY_BLOCK_SIZE / M_BYTE);
+return;
+}
+
+if (machine->maxram_size % SPAPR_MEMORY_BLOCK_SIZE) {
+error_setg(errp, "Maximum memory size 0x" RAM_ADDR_FMT
+   " is not aligned to %llu MiB",
+   machine->ram_size,
+   SPAPR_MEMORY_BLOCK_SIZE / M_BYTE);
+return;
 }
 
 for (i = 0; i < nb_numa_nodes; i++) {
 if (numa_info[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) {
-error_report("Can't support memory configuration where memory size"
- " %" PRIx64 " of node %d isn't aligned to %llu MB",
- numa_info[i].node_mem, i,
- SPAPR_MEMORY_BLOCK_SIZE/M_BYTE);
-exit(EXIT_FAILURE);
+error_setg(errp,
+   "Node %d memory size 0x" RAM_ADDR_FMT
+   " is not aligned to %llu MiB",
+   i, numa_info[i].node_mem,
+   SPAPR_MEMORY_BLOCK_SIZE / M_BYTE);
+return;
 }
 }
 }
@@ -1808,7 +1815,7 @@ static void ppc_spapr_init(MachineState *machine)
   XICS_IRQS);
 
 if (smc->dr_lmb_enabled) {
-spapr_validate_node_memory(machine);
+spapr_validate_node_memory(machine, &error_fatal);
 }
 
 /* init CPUs */
-- 
2.5.0




[Qemu-devel] [PULL 05/28] mac_dbdma: add DBDMA controller state to VMStateDescription

2016-01-24 Thread David Gibson
From: Mark Cave-Ayland 

Make sure that we include the DBDMA controller state in the migration
stream.

Signed-off-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/misc/macio/mac_dbdma.c | 40 
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
index 5ee8f02..161f49e 100644
--- a/hw/misc/macio/mac_dbdma.c
+++ b/hw/misc/macio/mac_dbdma.c
@@ -712,20 +712,52 @@ static const MemoryRegionOps dbdma_ops = {
 },
 };
 
-static const VMStateDescription vmstate_dbdma_channel = {
-.name = "dbdma_channel",
+static const VMStateDescription vmstate_dbdma_io = {
+.name = "dbdma_io",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(addr, struct DBDMA_io),
+VMSTATE_INT32(len, struct DBDMA_io),
+VMSTATE_INT32(is_last, struct DBDMA_io),
+VMSTATE_INT32(is_dma_out, struct DBDMA_io),
+VMSTATE_BOOL(processing, struct DBDMA_io),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const VMStateDescription vmstate_dbdma_cmd = {
+.name = "dbdma_cmd",
 .version_id = 0,
 .minimum_version_id = 0,
 .fields = (VMStateField[]) {
+VMSTATE_UINT16(req_count, dbdma_cmd),
+VMSTATE_UINT16(command, dbdma_cmd),
+VMSTATE_UINT32(phy_addr, dbdma_cmd),
+VMSTATE_UINT32(cmd_dep, dbdma_cmd),
+VMSTATE_UINT16(res_count, dbdma_cmd),
+VMSTATE_UINT16(xfer_status, dbdma_cmd),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const VMStateDescription vmstate_dbdma_channel = {
+.name = "dbdma_channel",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
 VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS),
+VMSTATE_STRUCT(io, struct DBDMA_channel, 0, vmstate_dbdma_io, 
DBDMA_io),
+VMSTATE_STRUCT(current, struct DBDMA_channel, 0, vmstate_dbdma_cmd,
+   dbdma_cmd),
 VMSTATE_END_OF_LIST()
 }
 };
 
 static const VMStateDescription vmstate_dbdma = {
 .name = "dbdma",
-.version_id = 2,
-.minimum_version_id = 2,
+.version_id = 3,
+.minimum_version_id = 3,
 .fields = (VMStateField[]) {
 VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1,
  vmstate_dbdma_channel, DBDMA_channel),
-- 
2.5.0




[Qemu-devel] [PULL 09/28] spapr: Remove abuse of rtas_ld() in h_client_architecture_support

2016-01-24 Thread David Gibson
h_client_architecture_support() uses rtas_ld() for general purpose memory
access, despite the fact that it's not an RTAS routine at all and rtas_ld
makes things more awkward.

Clean this up by replacing rtas_ld() calls with appropriate ldXX_phys()
calls.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_hcall.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index cebceea..9dbdba9 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -861,7 +861,8 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu_,
   target_ulong opcode,
   target_ulong *args)
 {
-target_ulong list = args[0], ov_table;
+target_ulong list = ppc64_phys_to_real(args[0]);
+target_ulong ov_table, ov5;
 PowerPCCPUClass *pcc_ = POWERPC_CPU_GET_CLASS(cpu_);
 CPUState *cs;
 bool cpu_match = false, cpu_update = true, memory_update = false;
@@ -875,9 +876,9 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu_,
 for (counter = 0; counter < 512; ++counter) {
 uint32_t pvr, pvr_mask;
 
-pvr_mask = rtas_ld(list, 0);
+pvr_mask = ldl_be_phys(&address_space_memory, list);
 list += 4;
-pvr = rtas_ld(list, 0);
+pvr = ldl_be_phys(&address_space_memory, list);
 list += 4;
 
 trace_spapr_cas_pvr_try(pvr);
@@ -948,14 +949,13 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu_,
 /* For the future use: here @ov_table points to the first option vector */
 ov_table = list;
 
-list = cas_get_option_vector(5, ov_table);
-if (!list) {
+ov5 = cas_get_option_vector(5, ov_table);
+if (!ov5) {
 return H_SUCCESS;
 }
 
 /* @list now points to OV 5 */
-list += 2;
-ov5_byte2 = rtas_ld(list, 0) >> 24;
+ov5_byte2 = ldub_phys(&address_space_memory, ov5 + 2);
 if (ov5_byte2 & OV5_DRCONF_MEMORY) {
 memory_update = true;
 }
-- 
2.5.0




[Qemu-devel] [PULL 00/28] ppc-for-2.6 queue 20160125

2016-01-24 Thread David Gibson
The following changes since commit 047e363b05679724d6b784c6ec6310697fe48ba0:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-softfloat-20160122' 
into staging (2016-01-22 15:19:21 +)

are available in the git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-2.6-20160125

for you to fetch changes up to ce3b7990c1ddf70b29f00eb878bb693471f9bc36:

  uninorth.c: add support for UniNorth kMacRISCPCIAddressSelect (0x48) register 
(2016-01-25 10:35:50 +1100)


ppc patch queue for 2016-01-25

Currently accumulated patches for target-ppc, pseries machine type and
related devices.
* Cleanup of error handling code in spapr
* A number of fixes for Macintosh devices for the benefit of MacOS 9 and X
* Remove some abuses of the RTAS memory access functions in spapr
* Fixes for the gdbstub (and monitor debug) for VMX and VSX extensions.
* Fix pseries machine hotplug memory under TCG


Alyssa Milburn (1):
  cuda.c: return error for unknown commands

Anton Blanchard (1):
  target-ppc: gdbstub: Add VSX support

Benjamin Herrenschmidt (1):
  target-ppc: Use sensible POWER8/POWER8E versions

Bharata B Rao (1):
  spapr: Don't create ibm,dynamic-reconfiguration-memory w/o DR LMBs

David Gibson (12):
  spapr: Small fixes to rtas_ibm_get_system_parameter, remove rtas_st_buffer
  spapr: Remove rtas_st_buffer_direct()
  spapr: Remove abuse of rtas_ld() in h_client_architecture_support
  ppc: Clean up error handling in ppc_set_compat()
  pseries: Clean up error handling of spapr_cpu_init()
  pseries: Clean up error handling in spapr_validate_node_memory()
  pseries: Clean up error handling in spapr_vga_init()
  pseries: Clean up error handling in spapr_rtas_register()
  pseries: Clean up error handling in xics_system_init()
  pseries: Clean up error reporting in ppc_spapr_init()
  pseries: Clean up error reporting in htab migration functions
  pseries: Allow TCG h_enter to work with hotplugged memory

Greg Kurz (6):
  target-ppc: kvm: fix floating point registers sync on little-endian hosts
  target-ppc: rename and export maybe_bswap_register()
  target-ppc: gdbstub: fix float registers for little-endian guests
  target-ppc: gdbstub: introduce avr_need_swap()
  target-ppc: gdbstub: fix altivec registers for little-endian guests
  target-ppc: gdbstub: fix spe registers for little-endian guests

Mark Cave-Ayland (5):
  target-ppc: use cpu_write_xer() helper in cpu_post_load
  macio: use the existing IDEDMA aiocb to hold the active DMA aiocb
  macio: add dma_active to VMStateDescription
  mac_dbdma: add DBDMA controller state to VMStateDescription
  cuda: add missing fields to VMStateDescription

Programmingkid (1):
  uninorth.c: add support for UniNorth kMacRISCPCIAddressSelect (0x48) 
register

 configure   |   6 +-
 gdb-xml/power-vsx.xml   |  44 +++
 hw/ide/macio.c  |  23 +-
 hw/ide/macio.c.orig | 634 
 hw/misc/macio/cuda.c|  12 +-
 hw/misc/macio/mac_dbdma.c   |  40 ++-
 hw/pci-host/uninorth.c  |   9 +
 hw/ppc/mac.h|   1 -
 hw/ppc/spapr.c  | 112 
 hw/ppc/spapr_hcall.c|  43 ++-
 hw/ppc/spapr_rtas.c |  50 ++--
 include/hw/ppc/spapr.h  |  36 +--
 target-ppc/cpu-models.c |  12 +-
 target-ppc/cpu-models.h |   4 +-
 target-ppc/cpu.h|   3 +-
 target-ppc/gdbstub.c|  10 +-
 target-ppc/kvm.c|  12 +
 target-ppc/machine.c|   2 +-
 target-ppc/translate_init.c |  97 +--
 19 files changed, 988 insertions(+), 162 deletions(-)
 create mode 100644 gdb-xml/power-vsx.xml
 create mode 100644 hw/ide/macio.c.orig



[Qemu-devel] [PULL 01/28] target-ppc: Use sensible POWER8/POWER8E versions

2016-01-24 Thread David Gibson
From: Benjamin Herrenschmidt 

We never released anything older than POWER8 DD2.0 and POWER8E DD2.1,
so let's use these versions, without that some firmware or Linux code
might fail to use some HW features that were non functional in earlier
internal only spins of the chip.

Signed-off-by: Benjamin Herrenschmidt 
Signed-off-by: David Gibson 
---
 target-ppc/cpu-models.c | 12 ++--
 target-ppc/cpu-models.h |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index 4d5ab4b..349783e 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1138,10 +1138,10 @@
 "POWER7 v2.3")
 POWERPC_DEF("POWER7+_v2.1",  CPU_POWERPC_POWER7P_v21,POWER7,
 "POWER7+ v2.1")
-POWERPC_DEF("POWER8E_v1.0",  CPU_POWERPC_POWER8E_v10,POWER8,
-"POWER8E v1.0")
-POWERPC_DEF("POWER8_v1.0",   CPU_POWERPC_POWER8_v10, POWER8,
-"POWER8 v1.0")
+POWERPC_DEF("POWER8E_v2.1",  CPU_POWERPC_POWER8E_v21,POWER8,
+"POWER8E v2.1")
+POWERPC_DEF("POWER8_v2.0",   CPU_POWERPC_POWER8_v20, POWER8,
+"POWER8 v2.0")
 POWERPC_DEF("970_v2.2",  CPU_POWERPC_970_v22,970,
 "PowerPC 970 v2.2")
 POWERPC_DEF("970fx_v1.0",CPU_POWERPC_970FX_v10,  970,
@@ -1389,8 +1389,8 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
 { "POWER5gs", "POWER5+_v2.1" },
 { "POWER7", "POWER7_v2.3" },
 { "POWER7+", "POWER7+_v2.1" },
-{ "POWER8E", "POWER8E_v1.0" },
-{ "POWER8", "POWER8_v1.0" },
+{ "POWER8E", "POWER8E_v2.1" },
+{ "POWER8", "POWER8_v2.0" },
 { "970", "970_v2.2" },
 { "970fx", "970fx_v3.1" },
 { "970mp", "970mp_v1.1" },
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 9d80e72..2992427 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -557,9 +557,9 @@ enum {
 CPU_POWERPC_POWER7P_BASE   = 0x004A,
 CPU_POWERPC_POWER7P_v21= 0x004A0201,
 CPU_POWERPC_POWER8E_BASE   = 0x004B,
-CPU_POWERPC_POWER8E_v10= 0x004B0100,
+CPU_POWERPC_POWER8E_v21= 0x004B0201,
 CPU_POWERPC_POWER8_BASE= 0x004D,
-CPU_POWERPC_POWER8_v10 = 0x004D0100,
+CPU_POWERPC_POWER8_v20 = 0x004D0200,
 CPU_POWERPC_970_v22= 0x00390202,
 CPU_POWERPC_970FX_v10  = 0x00391100,
 CPU_POWERPC_970FX_v20  = 0x003C0200,
-- 
2.5.0




[Qemu-devel] [PULL 10/28] spapr: Don't create ibm, dynamic-reconfiguration-memory w/o DR LMBs

2016-01-24 Thread David Gibson
From: Bharata B Rao 

If guest doesn't have any dynamically reconfigurable (DR) logical memory
blocks (LMB), then we shouldn't create ibm,dynamic-reconfiguration-memory
device tree node.

Signed-off-by: Bharata B Rao 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 50e5a26..86e5023 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -763,6 +763,13 @@ static int spapr_populate_drconf_memory(sPAPRMachineState 
*spapr, void *fdt)
 int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1;
 
 /*
+ * Don't create the node if there are no DR LMBs.
+ */
+if (!nr_lmbs) {
+return 0;
+}
+
+/*
  * Allocate enough buffer size to fit in ibm,dynamic-memory
  * or ibm,associativity-lookup-arrays
  */
@@ -868,7 +875,7 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
 _FDT((spapr_fixup_cpu_dt(fdt, spapr)));
 }
 
-/* Generate memory nodes or ibm,dynamic-reconfiguration-memory node */
+/* Generate ibm,dynamic-reconfiguration-memory node if required */
 if (memory_update && smc->dr_lmb_enabled) {
 _FDT((spapr_populate_drconf_memory(spapr, fdt)));
 }
-- 
2.5.0




[Qemu-devel] [PULL 15/28] pseries: Clean up error handling in spapr_rtas_register()

2016-01-24 Thread David Gibson
The errors detected in this function necessarily indicate bugs in the rest
of the qemu code, rather than an external or configuration problem.

So, a simple assert() is more appropriate than any more complex error
reporting.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr_rtas.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index eac1556..130c917 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -664,17 +664,11 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 
 void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
 {
-if (!((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX))) {
-fprintf(stderr, "RTAS invalid token 0x%x\n", token);
-exit(1);
-}
+assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
 
 token -= RTAS_TOKEN_BASE;
-if (rtas_table[token].name) {
-fprintf(stderr, "RTAS call \"%s\" is registered already as 0x%x\n",
-rtas_table[token].name, token);
-exit(1);
-}
+
+assert(!rtas_table[token].name);
 
 rtas_table[token].name = name;
 rtas_table[token].fn = fn;
-- 
2.5.0




[Qemu-devel] [PULL 12/28] pseries: Clean up error handling of spapr_cpu_init()

2016-01-24 Thread David Gibson
Currently spapr_cpu_init() is hardcoded to handle any errors as fatal.
That works for now, since it's only called from initial setup where an
error here means we really can't proceed.

However, we'll want to handle this more flexibly for cpu hotplug in future
so generalize this using the error reporting infrastructure.  While we're
at it make a small cleanup in a related part of ppc_spapr_init() to use
error_report() instead of an old-style explicit fprintf().

Signed-off-by: David Gibson 
Reviewed-by: Bharata B Rao 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 672815f..447fa5d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1624,7 +1624,8 @@ static void spapr_boot_set(void *opaque, const char 
*boot_device,
 machine->boot_order = g_strdup(boot_device);
 }
 
-static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu)
+static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
+   Error **errp)
 {
 CPUPPCState *env = &cpu->env;
 
@@ -1642,7 +1643,13 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, 
PowerPCCPU *cpu)
 }
 
 if (cpu->max_compat) {
-ppc_set_compat(cpu, cpu->max_compat, &error_fatal);
+Error *local_err = NULL;
+
+ppc_set_compat(cpu, cpu->max_compat, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
 }
 
 xics_cpu_setup(spapr->icp, cpu);
@@ -1811,10 +1818,10 @@ static void ppc_spapr_init(MachineState *machine)
 for (i = 0; i < smp_cpus; i++) {
 cpu = cpu_ppc_init(machine->cpu_model);
 if (cpu == NULL) {
-fprintf(stderr, "Unable to find PowerPC CPU definition\n");
+error_report("Unable to find PowerPC CPU definition");
 exit(1);
 }
-spapr_cpu_init(spapr, cpu);
+spapr_cpu_init(spapr, cpu, &error_fatal);
 }
 
 if (kvm_enabled()) {
-- 
2.5.0




[Qemu-devel] [PULL 11/28] ppc: Clean up error handling in ppc_set_compat()

2016-01-24 Thread David Gibson
Current ppc_set_compat() returns -1 for errors, and also (unconditionally)
reports an error message.  The caller in h_client_architecture_support()
may then report it again using an outdated fprintf().

Clean this up by using the modern error reporting mechanisms.  Also add
strerror(errno) to the error message.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr.c  |  4 +---
 hw/ppc/spapr_hcall.c| 10 +-
 target-ppc/cpu.h|  2 +-
 target-ppc/translate_init.c | 13 +++--
 4 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 86e5023..672815f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1642,9 +1642,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, 
PowerPCCPU *cpu)
 }
 
 if (cpu->max_compat) {
-if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
-exit(1);
-}
+ppc_set_compat(cpu, cpu->max_compat, &error_fatal);
 }
 
 xics_cpu_setup(spapr->icp, cpu);
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 9dbdba9..e9c057d 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -837,7 +837,7 @@ static target_ulong cas_get_option_vector(int vector, 
target_ulong table)
 typedef struct {
 PowerPCCPU *cpu;
 uint32_t cpu_version;
-int ret;
+Error *err;
 } SetCompatState;
 
 static void do_set_compat(void *arg)
@@ -845,7 +845,7 @@ static void do_set_compat(void *arg)
 SetCompatState *s = arg;
 
 cpu_synchronize_state(CPU(s->cpu));
-s->ret = ppc_set_compat(s->cpu, s->cpu_version);
+ppc_set_compat(s->cpu, s->cpu_version, &s->err);
 }
 
 #define get_compat_level(cpuver) ( \
@@ -930,13 +930,13 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu_,
 SetCompatState s = {
 .cpu = POWERPC_CPU(cs),
 .cpu_version = cpu_version,
-.ret = 0
+.err = NULL,
 };
 
 run_on_cpu(cs, do_set_compat, &s);
 
-if (s.ret < 0) {
-fprintf(stderr, "Unable to set compatibility mode\n");
+if (s.err) {
+error_report_err(s.err);
 return H_HARDWARE;
 }
 }
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 9706000..b3b89e6 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1210,7 +1210,7 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);
 
 void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 int ppc_get_compat_smt_threads(PowerPCCPU *cpu);
-int ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version);
+void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp);
 
 /* Time-base and decrementer management */
 #ifndef NO_CPU_IO_DEFS
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 4ab2d92..678957a 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9186,7 +9186,7 @@ int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
 return ret;
 }
 
-int ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version)
+void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp)
 {
 int ret = 0;
 CPUPPCState *env = &cpu->env;
@@ -9208,12 +9208,13 @@ int ppc_set_compat(PowerPCCPU *cpu, uint32_t 
cpu_version)
 break;
 }
 
-if (kvm_enabled() && kvmppc_set_compat(cpu, cpu->cpu_version) < 0) {
-error_report("Unable to set compatibility mode in KVM");
-ret = -1;
+if (kvm_enabled()) {
+ret = kvmppc_set_compat(cpu, cpu->cpu_version);
+if (ret < 0) {
+error_setg_errno(errp, -ret,
+ "Unable to set CPU compatibility mode in KVM");
+}
 }
-
-return ret;
 }
 
 static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
-- 
2.5.0




[Qemu-devel] [PULL 07/28] spapr: Small fixes to rtas_ibm_get_system_parameter, remove rtas_st_buffer

2016-01-24 Thread David Gibson
rtas_st_buffer() appears in spapr.h as though it were a widely used helper,
but in fact it is only used for saving data in a format used by
rtas_ibm_get_system_parameter().  This changes it to a local helper more
specifically for that function.

While we're there fix a couple of small defects in
rtas_ibm_get_system_parameter:
  - For the string value SPLPAR_CHARACTERISTICS, it wasn't including the
terminating \0 in the length which it should according to LoPAPR
7.3.16.1
  - It now checks that the supplied buffer has at least enough space for
the length of the returned data, and returns an error if it does not.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_rtas.c| 21 +
 include/hw/ppc/spapr.h | 28 +---
 2 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 34b12a3..8b702b5 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -228,6 +228,19 @@ static void rtas_stop_self(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 env->msr = 0;
 }
 
+static inline int sysparm_st(target_ulong addr, target_ulong len,
+ const void *val, uint16_t vallen)
+{
+hwaddr phys = ppc64_phys_to_real(addr);
+
+if (len < 2) {
+return RTAS_OUT_SYSPARM_PARAM_ERROR;
+}
+stw_be_phys(&address_space_memory, phys, vallen);
+cpu_physical_memory_write(phys + 2, val, MIN(len - 2, vallen));
+return RTAS_OUT_SUCCESS;
+}
+
 static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
   sPAPRMachineState *spapr,
   uint32_t token, uint32_t nargs,
@@ -237,7 +250,7 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
 target_ulong parameter = rtas_ld(args, 0);
 target_ulong buffer = rtas_ld(args, 1);
 target_ulong length = rtas_ld(args, 2);
-target_ulong ret = RTAS_OUT_SUCCESS;
+target_ulong ret;
 
 switch (parameter) {
 case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS: {
@@ -249,18 +262,18 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
   current_machine->ram_size / M_BYTE,
   smp_cpus,
   max_cpus);
-rtas_st_buffer(buffer, length, (uint8_t *)param_val, 
strlen(param_val));
+ret = sysparm_st(buffer, length, param_val, strlen(param_val) + 1);
 g_free(param_val);
 break;
 }
 case RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE: {
 uint8_t param_val = DIAGNOSTICS_RUN_MODE_DISABLED;
 
-rtas_st_buffer(buffer, length, ¶m_val, sizeof(param_val));
+ret = sysparm_st(buffer, length, ¶m_val, sizeof(param_val));
 break;
 }
 case RTAS_SYSPARM_UUID:
-rtas_st_buffer(buffer, length, qemu_uuid, (qemu_uuid_set ? 16 : 0));
+ret = sysparm_st(buffer, length, qemu_uuid, (qemu_uuid_set ? 16 : 0));
 break;
 default:
 ret = RTAS_OUT_NOT_SUPPORTED;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 53af76a..1e10fc9 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -408,14 +408,15 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
 #define RTAS_SLOT_PERM_ERR_LOG   2
 
 /* RTAS return codes */
-#define RTAS_OUT_SUCCESS0
-#define RTAS_OUT_NO_ERRORS_FOUND1
-#define RTAS_OUT_HW_ERROR   -1
-#define RTAS_OUT_BUSY   -2
-#define RTAS_OUT_PARAM_ERROR-3
-#define RTAS_OUT_NOT_SUPPORTED  -3
-#define RTAS_OUT_NO_SUCH_INDICATOR  -3
-#define RTAS_OUT_NOT_AUTHORIZED -9002
+#define RTAS_OUT_SUCCESS0
+#define RTAS_OUT_NO_ERRORS_FOUND1
+#define RTAS_OUT_HW_ERROR   -1
+#define RTAS_OUT_BUSY   -2
+#define RTAS_OUT_PARAM_ERROR-3
+#define RTAS_OUT_NOT_SUPPORTED  -3
+#define RTAS_OUT_NO_SUCH_INDICATOR  -3
+#define RTAS_OUT_NOT_AUTHORIZED -9002
+#define RTAS_OUT_SYSPARM_PARAM_ERROR-
 
 /* RTAS tokens */
 #define RTAS_TOKEN_BASE  0x2000
@@ -513,17 +514,6 @@ static inline void rtas_st_buffer_direct(target_ulong phys,
   MIN(buffer_len, phys_len));
 }
 
-static inline void rtas_st_buffer(target_ulong phys, target_ulong phys_len,
-  uint8_t *buffer, uint16_t buffer_len)
-{
-if (phys_len < 2) {
-return;
-}
-stw_be_phys(&address_space_memory,
-ppc64_phys_to_real(phys), buffer_len);
-rtas_st_buffer_direct(phys + 2, phys_len - 2, buffer, buffer_len);
-}
-
 typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
   uint32_t token,
   uint32_t nargs, target_ulong args,
-- 
2.5.0




[Qemu-devel] [PULL 20/28] target-ppc: rename and export maybe_bswap_register()

2016-01-24 Thread David Gibson
From: Greg Kurz 

This helper will be used to support FP, Altivec and VSX registers when
the guest is little-endian.

Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 target-ppc/cpu.h |  1 +
 target-ppc/gdbstub.c | 10 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index b3b89e6..2bc96b4 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2355,4 +2355,5 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu);
  */
 PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id);
 
+void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len);
 #endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c
index 14675f4..b20bb0c 100644
--- a/target-ppc/gdbstub.c
+++ b/target-ppc/gdbstub.c
@@ -88,7 +88,7 @@ static int ppc_gdb_register_len(int n)
the proper ordering for the binary, and cannot be changed.
For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
the current mode of the chip to see if we're running in little-endian.  */
-static void maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
+void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
 {
 #ifndef CONFIG_USER_ONLY
 if (!msr_le) {
@@ -158,7 +158,7 @@ int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 break;
 }
 }
-maybe_bswap_register(env, mem_buf, r);
+ppc_maybe_bswap_register(env, mem_buf, r);
 return r;
 }
 
@@ -214,7 +214,7 @@ int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t 
*mem_buf, int n)
 break;
 }
 }
-maybe_bswap_register(env, mem_buf, r);
+ppc_maybe_bswap_register(env, mem_buf, r);
 return r;
 }
 
@@ -227,7 +227,7 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 if (!r) {
 return r;
 }
-maybe_bswap_register(env, mem_buf, r);
+ppc_maybe_bswap_register(env, mem_buf, r);
 if (n < 32) {
 /* gprs */
 env->gpr[n] = ldtul_p(mem_buf);
@@ -277,7 +277,7 @@ int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t 
*mem_buf, int n)
 if (!r) {
 return r;
 }
-maybe_bswap_register(env, mem_buf, r);
+ppc_maybe_bswap_register(env, mem_buf, r);
 if (n < 32) {
 /* gprs */
 env->gpr[n] = ldq_p(mem_buf);
-- 
2.5.0




[Qemu-devel] [PULL 14/28] pseries: Clean up error handling in spapr_vga_init()

2016-01-24 Thread David Gibson
Use error_setg() to return an error rather than an explicit exit().
Previously it was an exit(0) instead of a non-zero exit code, which was
simply a bug.  Also improve the error message.

While we're at it change the type of spapr_vga_init() to bool since that's
how we're using it anyway.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 5793205..c04666d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1245,7 +1245,7 @@ static void spapr_rtc_create(sPAPRMachineState *spapr)
 }
 
 /* Returns whether we want to use VGA or not */
-static int spapr_vga_init(PCIBus *pci_bus)
+static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
 {
 switch (vga_interface_type) {
 case VGA_NONE:
@@ -1256,9 +1256,9 @@ static int spapr_vga_init(PCIBus *pci_bus)
 case VGA_VIRTIO:
 return pci_vga_init(pci_bus) != NULL;
 default:
-fprintf(stderr, "This vga model is not supported,"
-"currently it only supports -vga std\n");
-exit(0);
+error_setg(errp,
+   "Unsupported VGA mode, only -vga std or -vga virtio is 
supported");
+return false;
 }
 }
 
@@ -1933,7 +1933,7 @@ static void ppc_spapr_init(MachineState *machine)
 }
 
 /* Graphics */
-if (spapr_vga_init(phb->bus)) {
+if (spapr_vga_init(phb->bus, &error_fatal)) {
 spapr->has_graphics = true;
 machine->usb |= defaults_enabled() && !machine->usb_disabled;
 }
-- 
2.5.0




[Qemu-devel] [PULL 21/28] target-ppc: gdbstub: fix float registers for little-endian guests

2016-01-24 Thread David Gibson
From: Greg Kurz 

Let's reuse the ppc_maybe_bswap_register() helper, like we already do
with the general registers.

Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 target-ppc/translate_init.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 678957a..aabf754 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8755,10 +8755,12 @@ static int gdb_get_float_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 {
 if (n < 32) {
 stfq_p(mem_buf, env->fpr[n]);
+ppc_maybe_bswap_register(env, mem_buf, 8);
 return 8;
 }
 if (n == 32) {
 stl_p(mem_buf, env->fpscr);
+ppc_maybe_bswap_register(env, mem_buf, 4);
 return 4;
 }
 return 0;
@@ -8767,10 +8769,12 @@ static int gdb_get_float_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 {
 if (n < 32) {
+ppc_maybe_bswap_register(env, mem_buf, 8);
 env->fpr[n] = ldfq_p(mem_buf);
 return 8;
 }
 if (n == 32) {
+ppc_maybe_bswap_register(env, mem_buf, 4);
 helper_store_fpscr(env, ldl_p(mem_buf), 0x);
 return 4;
 }
-- 
2.5.0




[Qemu-devel] [PULL 18/28] pseries: Clean up error reporting in htab migration functions

2016-01-24 Thread David Gibson
The functions for migrating the hash page table on pseries machine type
(htab_save_setup() and htab_load()) can report some errors with an
explicit fprintf() before returning an appropriate error code.  Change some
of these to use error_report() instead. htab_save_setup() is omitted for
now to avoid conflicts with some other in-progress work.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4d88a29..5df9274 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1533,7 +1533,7 @@ static int htab_load(QEMUFile *f, void *opaque, int 
version_id)
 int fd = -1;
 
 if (version_id < 1 || version_id > 1) {
-fprintf(stderr, "htab_load() bad version\n");
+error_report("htab_load() bad version");
 return -EINVAL;
 }
 
@@ -1554,8 +1554,8 @@ static int htab_load(QEMUFile *f, void *opaque, int 
version_id)
 
 fd = kvmppc_get_htab_fd(true);
 if (fd < 0) {
-fprintf(stderr, "Unable to open fd to restore KVM hash table: 
%s\n",
-strerror(errno));
+error_report("Unable to open fd to restore KVM hash table: %s",
+ strerror(errno));
 }
 }
 
@@ -1575,9 +1575,9 @@ static int htab_load(QEMUFile *f, void *opaque, int 
version_id)
 if ((index + n_valid + n_invalid) >
 (HTAB_SIZE(spapr) / HASH_PTE_SIZE_64)) {
 /* Bad index in stream */
-fprintf(stderr, "htab_load() bad index %d (%hd+%hd entries) "
-"in htab stream (htab_shift=%d)\n", index, n_valid, 
n_invalid,
-spapr->htab_shift);
+error_report(
+"htab_load() bad index %d (%hd+%hd entries) in htab stream 
(htab_shift=%d)",
+index, n_valid, n_invalid, spapr->htab_shift);
 return -EINVAL;
 }
 
-- 
2.5.0




[Qemu-devel] [PULL 06/28] cuda: add missing fields to VMStateDescription

2016-01-24 Thread David Gibson
From: Mark Cave-Ayland 

Include some fields missed from the previous VMState conversion to the
migration stream, as well as the new SR_INT delay timer.

Signed-off-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 9db4c64..3556852 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -704,15 +704,17 @@ static const VMStateDescription vmstate_cuda_timer = {
 
 static const VMStateDescription vmstate_cuda = {
 .name = "cuda",
-.version_id = 2,
-.minimum_version_id = 2,
+.version_id = 3,
+.minimum_version_id = 3,
 .fields = (VMStateField[]) {
 VMSTATE_UINT8(a, CUDAState),
 VMSTATE_UINT8(b, CUDAState),
+VMSTATE_UINT8(last_b, CUDAState),
 VMSTATE_UINT8(dira, CUDAState),
 VMSTATE_UINT8(dirb, CUDAState),
 VMSTATE_UINT8(sr, CUDAState),
 VMSTATE_UINT8(acr, CUDAState),
+VMSTATE_UINT8(last_acr, CUDAState),
 VMSTATE_UINT8(pcr, CUDAState),
 VMSTATE_UINT8(ifr, CUDAState),
 VMSTATE_UINT8(ier, CUDAState),
@@ -727,6 +729,7 @@ static const VMStateDescription vmstate_cuda = {
 VMSTATE_STRUCT_ARRAY(timers, CUDAState, 2, 1,
  vmstate_cuda_timer, CUDATimer),
 VMSTATE_TIMER_PTR(adb_poll_timer, CUDAState),
+VMSTATE_TIMER_PTR(sr_delay_timer, CUDAState),
 VMSTATE_END_OF_LIST()
 }
 };
-- 
2.5.0




[Qemu-devel] [PULL 17/28] pseries: Clean up error reporting in ppc_spapr_init()

2016-01-24 Thread David Gibson
This function includes a number of explicit fprintf()s for errors.
Change these to use error_report() instead.

Also replace the single exit(EXIT_FAILURE) with an explicit exit(1), since
the latter is the more usual idiom in qemu by a large margin.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b93dc10..4d88a29 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1788,8 +1788,8 @@ static void ppc_spapr_init(MachineState *machine)
 }
 
 if (spapr->rma_size > node0_size) {
-fprintf(stderr, "Error: Numa node 0 has to span the RMA 
(%#08"HWADDR_PRIx")\n",
-spapr->rma_size);
+error_report("Numa node 0 has to span the RMA (%#08"HWADDR_PRIx")",
+ spapr->rma_size);
 exit(1);
 }
 
@@ -1855,10 +1855,10 @@ static void ppc_spapr_init(MachineState *machine)
 ram_addr_t hotplug_mem_size = machine->maxram_size - machine->ram_size;
 
 if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
-error_report("Specified number of memory slots %" PRIu64
- " exceeds max supported %d",
+error_report("Specified number of memory slots %"
+ PRIu64" exceeds max supported %d",
  machine->ram_slots, SPAPR_MAX_RAM_SLOTS);
-exit(EXIT_FAILURE);
+exit(1);
 }
 
 spapr->hotplug_memory.base = ROUND_UP(machine->ram_size,
@@ -1954,8 +1954,9 @@ static void ppc_spapr_init(MachineState *machine)
 }
 
 if (spapr->rma_size < (MIN_RMA_SLOF << 20)) {
-fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
-"%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF);
+error_report(
+"pSeries SLOF firmware requires >= %ldM guest RMA (Real Mode Area 
memory)",
+MIN_RMA_SLOF);
 exit(1);
 }
 
@@ -1971,8 +1972,8 @@ static void ppc_spapr_init(MachineState *machine)
 kernel_le = kernel_size > 0;
 }
 if (kernel_size < 0) {
-fprintf(stderr, "qemu: error loading %s: %s\n",
-kernel_filename, load_elf_strerror(kernel_size));
+error_report("error loading %s: %s",
+ kernel_filename, load_elf_strerror(kernel_size));
 exit(1);
 }
 
@@ -1985,8 +1986,8 @@ static void ppc_spapr_init(MachineState *machine)
 initrd_size = load_image_targphys(initrd_filename, initrd_base,
   load_limit - initrd_base);
 if (initrd_size < 0) {
-fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
-initrd_filename);
+error_report("could not load initial ram disk '%s'",
+ initrd_filename);
 exit(1);
 }
 } else {
-- 
2.5.0




[Qemu-devel] [PULL 26/28] pseries: Allow TCG h_enter to work with hotplugged memory

2016-01-24 Thread David Gibson
The implementation of the H_ENTER hypercall for PAPR guests needs to
enforce correct access attributes on the inserted HPTE.  This means
determining if the HPTE's real address is a regular RAM address (which
requires attributes for coherent access) or an IO address (which requires
attributes for cache-inhibited access).

At the moment this check is implemented with (raddr < machine->ram_size),
but that only handles addresses in the base RAM area, not any hotplugged
RAM.

This patch corrects the problem with a new helper.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_hcall.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index e9c057d..c4ae255 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -84,10 +84,25 @@ static inline bool valid_pte_index(CPUPPCState *env, 
target_ulong pte_index)
 return true;
 }
 
+static bool is_ram_address(sPAPRMachineState *spapr, hwaddr addr)
+{
+MachineState *machine = MACHINE(spapr);
+MemoryHotplugState *hpms = &spapr->hotplug_memory;
+
+if (addr < machine->ram_size) {
+return true;
+}
+if ((addr >= hpms->base)
+&& ((addr - hpms->base) < memory_region_size(&hpms->mr))) {
+return true;
+}
+
+return false;
+}
+
 static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 target_ulong opcode, target_ulong *args)
 {
-MachineState *machine = MACHINE(spapr);
 CPUPPCState *env = &cpu->env;
 target_ulong flags = args[0];
 target_ulong pte_index = args[1];
@@ -119,7 +134,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 
 raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1);
 
-if (raddr < machine->ram_size) {
+if (is_ram_address(spapr, raddr)) {
 /* Regular RAM - should have WIMG=0010 */
 if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {
 return H_PARAMETER;
-- 
2.5.0




[Qemu-devel] [PULL 27/28] cuda.c: return error for unknown commands

2016-01-24 Thread David Gibson
From: Alyssa Milburn 

This avoids MacsBug hanging at startup in the absence of ADB mouse
input, by replying with an error (which is also what MOL does) when
it sends an unknown command (0x1c).

Signed-off-by: Alyssa Milburn 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 3556852..5e4d5d5 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -605,6 +605,11 @@ static void cuda_receive_packet(CUDAState *s,
 }
 break;
 default:
+obuf[0] = ERROR_PACKET;
+obuf[1] = 0x2;
+obuf[2] = CUDA_PACKET;
+obuf[3] = data[0];
+cuda_send_packet_to_host(s, obuf, 4);
 break;
 }
 }
-- 
2.5.0




[Qemu-devel] [PULL 08/28] spapr: Remove rtas_st_buffer_direct()

2016-01-24 Thread David Gibson
rtas_st_buffer_direct() is a not particularly useful wrapper around
cpu_physical_memory_write().  All the callers are in
rtas_ibm_configure_connector, where it's better handled by local helper.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_rtas.c| 17 ++---
 include/hw/ppc/spapr.h |  8 
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 8b702b5..eac1556 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -505,6 +505,13 @@ out:
 #define CC_VAL_DATA_OFFSET ((CC_IDX_PROP_DATA_OFFSET + 1) * 4)
 #define CC_WA_LEN 4096
 
+static void configure_connector_st(target_ulong addr, target_ulong offset,
+   const void *buf, size_t len)
+{
+cpu_physical_memory_write(ppc64_phys_to_real(addr + offset),
+  buf, MIN(len, CC_WA_LEN - offset));
+}
+
 static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
  sPAPRMachineState *spapr,
  uint32_t token, uint32_t nargs,
@@ -570,8 +577,7 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
 /* provide the name of the next OF node */
 wa_offset = CC_VAL_DATA_OFFSET;
 rtas_st(wa_addr, CC_IDX_NODE_NAME_OFFSET, wa_offset);
-rtas_st_buffer_direct(wa_addr + wa_offset, CC_WA_LEN - wa_offset,
-  (uint8_t *)name, strlen(name) + 1);
+configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
 resp = SPAPR_DR_CC_RESPONSE_NEXT_CHILD;
 break;
 case FDT_END_NODE:
@@ -596,8 +602,7 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
 /* provide the name of the next OF property */
 wa_offset = CC_VAL_DATA_OFFSET;
 rtas_st(wa_addr, CC_IDX_PROP_NAME_OFFSET, wa_offset);
-rtas_st_buffer_direct(wa_addr + wa_offset, CC_WA_LEN - wa_offset,
-  (uint8_t *)name, strlen(name) + 1);
+configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
 
 /* provide the length and value of the OF property. data gets
  * placed immediately after NULL terminator of the OF property's
@@ -606,9 +611,7 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
 wa_offset += strlen(name) + 1,
 rtas_st(wa_addr, CC_IDX_PROP_LEN, prop_len);
 rtas_st(wa_addr, CC_IDX_PROP_DATA_OFFSET, wa_offset);
-rtas_st_buffer_direct(wa_addr + wa_offset, CC_WA_LEN - wa_offset,
-  (uint8_t *)((struct fdt_property 
*)prop)->data,
-  prop_len);
+configure_connector_st(wa_addr, wa_offset, prop->data, prop_len);
 resp = SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY;
 break;
 case FDT_END:
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 1e10fc9..1f9e722 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -506,14 +506,6 @@ static inline void rtas_st(target_ulong phys, int n, 
uint32_t val)
 stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n), val);
 }
 
-static inline void rtas_st_buffer_direct(target_ulong phys,
- target_ulong phys_len,
- uint8_t *buffer, uint16_t buffer_len)
-{
-cpu_physical_memory_write(ppc64_phys_to_real(phys), buffer,
-  MIN(buffer_len, phys_len));
-}
-
 typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
   uint32_t token,
   uint32_t nargs, target_ulong args,
-- 
2.5.0




[Qemu-devel] [PULL 03/28] macio: use the existing IDEDMA aiocb to hold the active DMA aiocb

2016-01-24 Thread David Gibson
From: Mark Cave-Ayland 

Currently the aiocb is held within MACIOIDEState, however the IDE core code
assumes that the current actvie DMA aiocb is held in aiocb in a few places,
e.g. ide_bus_reset() and ide_reset().

Switch over to using IDEDMA aiocb to store the aiocb for the current active
DMA request so that bus resets and restarts are handled correctly. As a
consequence we can now use ide_set_inactive() rather than handling its
functionality ourselves.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: John Snow 
Signed-off-by: David Gibson 
---
 hw/ide/macio.c  |  20 +-
 hw/ide/macio.c.orig | 634 
 hw/ppc/mac.h|   1 -
 3 files changed, 646 insertions(+), 9 deletions(-)
 create mode 100644 hw/ide/macio.c.orig

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index d4031b6..110af46 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -119,8 +119,8 @@ static void pmac_dma_read(BlockBackend *blk,
 MACIO_DPRINTF("--- Block read transfer - sector_num: %" PRIx64 "  "
   "nsector: %x\n", (offset >> 9), (bytes >> 9));
 
-m->aiocb = blk_aio_readv(blk, (offset >> 9), &io->iov, (bytes >> 9),
- cb, io);
+s->bus->dma->aiocb = blk_aio_readv(blk, (offset >> 9), &io->iov,
+ (bytes >> 9), cb, io);
 }
 
 static void pmac_dma_write(BlockBackend *blk,
@@ -204,8 +204,8 @@ static void pmac_dma_write(BlockBackend *blk,
 MACIO_DPRINTF("--- Block write transfer - sector_num: %" PRIx64 "  "
   "nsector: %x\n", (offset >> 9), (bytes >> 9));
 
-m->aiocb = blk_aio_writev(blk, (offset >> 9), &io->iov, (bytes >> 9),
-  cb, io);
+s->bus->dma->aiocb = blk_aio_writev(blk, (offset >> 9), &io->iov,
+ (bytes >> 9), cb, io);
 }
 
 static void pmac_dma_trim(BlockBackend *blk,
@@ -231,8 +231,8 @@ static void pmac_dma_trim(BlockBackend *blk,
 s->io_buffer_index += io->len;
 io->len = 0;
 
-m->aiocb = ide_issue_trim(blk, (offset >> 9), &io->iov, (bytes >> 9),
-  cb, io);
+s->bus->dma->aiocb = ide_issue_trim(blk, (offset >> 9), &io->iov,
+ (bytes >> 9), cb, io);
 }
 
 static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
@@ -291,6 +291,8 @@ done:
 } else {
 block_acct_done(blk_get_stats(s->blk), &s->acct);
 }
+
+ide_set_inactive(s, false);
 io->dma_end(opaque);
 }
 
@@ -305,7 +307,6 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
 
 if (ret < 0) {
 MACIO_DPRINTF("DMA error: %d\n", ret);
-m->aiocb = NULL;
 ide_dma_error(s);
 goto done;
 }
@@ -356,6 +357,8 @@ done:
 block_acct_done(blk_get_stats(s->blk), &s->acct);
 }
 }
+
+ide_set_inactive(s, false);
 io->dma_end(opaque);
 }
 
@@ -393,8 +396,9 @@ static void pmac_ide_transfer(DBDMA_io *io)
 static void pmac_ide_flush(DBDMA_io *io)
 {
 MACIOIDEState *m = io->opaque;
+IDEState *s = idebus_active_if(&m->bus);
 
-if (m->aiocb) {
+if (s->bus->dma->aiocb) {
 blk_drain_all();
 }
 }
diff --git a/hw/ide/macio.c.orig b/hw/ide/macio.c.orig
new file mode 100644
index 000..d4031b6
--- /dev/null
+++ b/hw/ide/macio.c.orig
@@ -0,0 +1,634 @@
+/*
+ * QEMU IDE Emulation: MacIO support.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "hw/hw.h"
+#include "hw/ppc/mac.h"
+#include "hw/ppc/mac_dbdma.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/dma.h"
+
+#include 
+
+/* debug MACIO */
+// #define DEBUG_MACIO
+
+#ifdef DEBUG_MACIO
+static const int debug_macio = 1;
+#else
+static const int debug_macio = 0;
+#endif
+
+#define MACIO_DPRINTF(fmt, ...) do { \
+if (debug_macio) { \
+printf(fmt , ## __VA_ARGS__); \
+} \
+} while (

[Qemu-devel] [PULL 16/28] pseries: Clean up error handling in xics_system_init()

2016-01-24 Thread David Gibson
Use the error handling infrastructure to pass an error out from
try_create_xics() instead of assuming &error_abort - the caller is in a
better position to decide on error handling policy.

Also change the error handling from an &error_abort to &error_fatal, since
this occurs during the initial machine construction and could be triggered
by bad configuration rather than a program error.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Markus Armbruster 
---
 hw/ppc/spapr.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c04666d..b93dc10 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -111,7 +111,7 @@ static XICSState *try_create_xics(const char *type, int 
nr_servers,
 }
 
 static XICSState *xics_system_init(MachineState *machine,
-   int nr_servers, int nr_irqs)
+   int nr_servers, int nr_irqs, Error **errp)
 {
 XICSState *icp = NULL;
 
@@ -130,7 +130,7 @@ static XICSState *xics_system_init(MachineState *machine,
 }
 
 if (!icp) {
-icp = try_create_xics(TYPE_XICS, nr_servers, nr_irqs, &error_abort);
+icp = try_create_xics(TYPE_XICS, nr_servers, nr_irqs, errp);
 }
 
 return icp;
@@ -1812,7 +1812,7 @@ static void ppc_spapr_init(MachineState *machine)
 spapr->icp = xics_system_init(machine,
   DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
smp_threads),
-  XICS_IRQS);
+  XICS_IRQS, &error_fatal);
 
 if (smc->dr_lmb_enabled) {
 spapr_validate_node_memory(machine, &error_fatal);
-- 
2.5.0




[Qemu-devel] [PULL 22/28] target-ppc: gdbstub: introduce avr_need_swap()

2016-01-24 Thread David Gibson
From: Greg Kurz 

This helper will be used to support Altivec registers in little-endian guests.
This patch does not change functionnality.

Note: I had to put the helper some lines away from the gdb_*_avr_reg()
routines to get a more readable patch.

Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 target-ppc/translate_init.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index aabf754..54720ca 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8751,6 +8751,15 @@ static void dump_ppc_insns (CPUPPCState *env)
 }
 #endif
 
+static bool avr_need_swap(CPUPPCState *env)
+{
+#ifdef HOST_WORDS_BIGENDIAN
+return false;
+#else
+return true;
+#endif
+}
+
 static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 {
 if (n < 32) {
@@ -8784,13 +8793,13 @@ static int gdb_set_float_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 {
 if (n < 32) {
-#ifdef HOST_WORDS_BIGENDIAN
-stq_p(mem_buf, env->avr[n].u64[0]);
-stq_p(mem_buf+8, env->avr[n].u64[1]);
-#else
-stq_p(mem_buf, env->avr[n].u64[1]);
-stq_p(mem_buf+8, env->avr[n].u64[0]);
-#endif
+if (!avr_need_swap(env)) {
+stq_p(mem_buf, env->avr[n].u64[0]);
+stq_p(mem_buf+8, env->avr[n].u64[1]);
+} else {
+stq_p(mem_buf, env->avr[n].u64[1]);
+stq_p(mem_buf+8, env->avr[n].u64[0]);
+}
 return 16;
 }
 if (n == 32) {
@@ -8807,13 +8816,13 @@ static int gdb_get_avr_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 {
 if (n < 32) {
-#ifdef HOST_WORDS_BIGENDIAN
-env->avr[n].u64[0] = ldq_p(mem_buf);
-env->avr[n].u64[1] = ldq_p(mem_buf+8);
-#else
-env->avr[n].u64[1] = ldq_p(mem_buf);
-env->avr[n].u64[0] = ldq_p(mem_buf+8);
-#endif
+if (!avr_need_swap(env)) {
+env->avr[n].u64[0] = ldq_p(mem_buf);
+env->avr[n].u64[1] = ldq_p(mem_buf+8);
+} else {
+env->avr[n].u64[1] = ldq_p(mem_buf);
+env->avr[n].u64[0] = ldq_p(mem_buf+8);
+}
 return 16;
 }
 if (n == 32) {
-- 
2.5.0




[Qemu-devel] [PULL 28/28] uninorth.c: add support for UniNorth kMacRISCPCIAddressSelect (0x48) register

2016-01-24 Thread David Gibson
From: Programmingkid 

Darwin/OS X use the undocumented kMacRISCPCIAddressSelect (0x48) to
configure PCI memory space size for mac99 machines. Without this
register, warnings similar to below are emitted to the console during boot:

AppleMacRiscPCI: bad range 2(8000:0100)
AppleMacRiscPCI: bad range 2(8100:1000)
AppleMacRiscPCI: bad range 2(8108:0008)

Based upon the algorithm in Darwin's AppleMacRiscPCI.cpp driver, set the
kMacRISCPCIAddressSelect register so that Darwin considers the PCI
memory space to be at 0x8000 (size 0x1000) which matches that
currently used by QEMU and OpenBIOS.

Signed-off-by: John Arbuckle 
Tested-by: Mark Cave-Ayland 
[commit message and comment revised as suggested by Mark Cave-Ayland]
Signed-off-by: David Gibson 
---
 hw/pci-host/uninorth.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index 215b64f..d4aff84 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -330,6 +330,15 @@ static void unin_agp_pci_host_realize(PCIDevice *d, Error 
**errp)
 d->config[0x0C] = 0x08; // cache_line_size
 d->config[0x0D] = 0x10; // latency_timer
 //d->config[0x34] = 0x80; // capabilities_pointer
+/*
+ * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI
+ * memory space with base 0x8000, size 0x1000 for Apple's
+ * AppleMacRiscPCI driver
+ */
+d->config[0x48] = 0x0;
+d->config[0x49] = 0x0;
+d->config[0x4a] = 0x0;
+d->config[0x4b] = 0x1;
 }
 
 static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp)
-- 
2.5.0




[Qemu-devel] [PULL 19/28] target-ppc: kvm: fix floating point registers sync on little-endian hosts

2016-01-24 Thread David Gibson
From: Greg Kurz 

On VSX capable CPUs, the 32 FP registers are mapped to the high-bits
of the 32 first VSX registers. So if you have:

VSR31 = (uint128) 0x0102030405060708090a0b0c0d0e0f00

then

FPR31 = (uint64) 0x0102030405060708

The kernel stores the VSX registers in the fp_state struct following the
host endian element ordering.

On big-endian:

fp_state.fpr[31][0] = 0x0102030405060708
fp_state.fpr[31][1] = 0x090a0b0c0d0e0f00

On little-endian:

fp_state.fpr[31][0] = 0x090a0b0c0d0e0f00
fp_state.fpr[31][1] = 0x0102030405060708

The KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctls preserve this ordering, but
QEMU considers it as big-endian and always copies element [0] to the
fpr[] array and element [1] to the vsr[] array. This does not work with
little-endian hosts, and you will get:

(qemu) p $f31
0x90a0b0c0d0e0f00

instead of:

(qemu) p $f31
0x102030405060708

This patch fixes the element ordering for little-endian hosts.

Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 target-ppc/kvm.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 9940a90..4524999 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -650,8 +650,13 @@ static int kvm_put_fp(CPUState *cs)
 for (i = 0; i < 32; i++) {
 uint64_t vsr[2];
 
+#ifdef HOST_WORDS_BIGENDIAN
 vsr[0] = float64_val(env->fpr[i]);
 vsr[1] = env->vsr[i];
+#else
+vsr[0] = env->vsr[i];
+vsr[1] = float64_val(env->fpr[i]);
+#endif
 reg.addr = (uintptr_t) &vsr;
 reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
 
@@ -721,10 +726,17 @@ static int kvm_get_fp(CPUState *cs)
 vsx ? "VSR" : "FPR", i, strerror(errno));
 return ret;
 } else {
+#ifdef HOST_WORDS_BIGENDIAN
 env->fpr[i] = vsr[0];
 if (vsx) {
 env->vsr[i] = vsr[1];
 }
+#else
+env->fpr[i] = vsr[1];
+if (vsx) {
+env->vsr[i] = vsr[0];
+}
+#endif
 }
 }
 }
-- 
2.5.0




[Qemu-devel] [PULL 23/28] target-ppc: gdbstub: fix altivec registers for little-endian guests

2016-01-24 Thread David Gibson
From: Greg Kurz 

Altivec registers are 128-bit wide. They are stored in memory as two
64-bit values that must be byteswapped when the guest is little-endian.
Let's reuse the ppc_maybe_bswap_register() helper for this.

We also need to fix the ordering of the 64-bit elements according to
the target endianness, for both system and user mode.

Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 target-ppc/translate_init.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 54720ca..4c29912 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8754,9 +8754,9 @@ static void dump_ppc_insns (CPUPPCState *env)
 static bool avr_need_swap(CPUPPCState *env)
 {
 #ifdef HOST_WORDS_BIGENDIAN
-return false;
+return msr_le;
 #else
-return true;
+return !msr_le;
 #endif
 }
 
@@ -8800,14 +8800,18 @@ static int gdb_get_avr_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 stq_p(mem_buf, env->avr[n].u64[1]);
 stq_p(mem_buf+8, env->avr[n].u64[0]);
 }
+ppc_maybe_bswap_register(env, mem_buf, 8);
+ppc_maybe_bswap_register(env, mem_buf + 8, 8);
 return 16;
 }
 if (n == 32) {
 stl_p(mem_buf, env->vscr);
+ppc_maybe_bswap_register(env, mem_buf, 4);
 return 4;
 }
 if (n == 33) {
 stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]);
+ppc_maybe_bswap_register(env, mem_buf, 4);
 return 4;
 }
 return 0;
@@ -8816,6 +8820,8 @@ static int gdb_get_avr_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 {
 if (n < 32) {
+ppc_maybe_bswap_register(env, mem_buf, 8);
+ppc_maybe_bswap_register(env, mem_buf + 8, 8);
 if (!avr_need_swap(env)) {
 env->avr[n].u64[0] = ldq_p(mem_buf);
 env->avr[n].u64[1] = ldq_p(mem_buf+8);
@@ -8826,10 +8832,12 @@ static int gdb_set_avr_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 return 16;
 }
 if (n == 32) {
+ppc_maybe_bswap_register(env, mem_buf, 4);
 env->vscr = ldl_p(mem_buf);
 return 4;
 }
 if (n == 33) {
+ppc_maybe_bswap_register(env, mem_buf, 4);
 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
 return 4;
 }
-- 
2.5.0




Re: [Qemu-devel] [PATCH v13 00/10] Block replication for continuous checkpoints

2016-01-24 Thread Wen Congyang
On 01/22/2016 11:14 PM, Dr. David Alan Gilbert wrote:
> Hi,
>   I can trigger a segfault if I wire in the block replication together with
> a quorum instance; it only triggers with both of them present but,
> it looks like the problem is a disagreement about the number of quorum
> members;  I'm triggering this on the 'colo-v2.4-periodic-mode' branch
> that is posted in the colo-framework set that I think includes this set
> (from https://github.com/coloft/qemu.git).
> 
> To trigger:
> ./git/colo/jan-16/try/x86_64-softmmu/qemu-system-x86_64 -nographic -S
> 
> (qemu) drive_add 0 
> if=none,id=colo-disk0,file.filename=/home/localvms/bugzilla.raw,driver=raw,node-name=node0
> (qemu) drive_add 1 
> if=none,id=active-disk0,throttling.bps-total=7000,driver=replication,mode=secondary,file.driver=qcow2,file.file.filename=/run/colo-active-disk.qcow2,file.backing.driver=qcow2,file.backing.file.filename=/run/colo-hidden-disk.qcow2,file.backing.backing=colo-disk0
> (qemu) drive_add 2 
> if=none,id=top-quorum,driver=quorum,read-pattern=fifo,vote-threshold=1,children.0=active-disk0
> (qemu) device_add virtio-blk-pci,drive=top-quorum,addr=9
> 
> *** Error in `/root/colo/jan-2016/./try/x86_64-softmmu/qemu-system-x86_64': 
> free(): invalid pointer: 0x55a8fdf0 ***
> === Backtrace: =
> /lib64/libc.so.6(+0x7cfe1)[0x7110ffe1]
> /lib64/libglib-2.0.so.0(g_free+0xf)[0x71ecc36f]
> /root/colo/jan-2016/./try/x86_64-softmmu/qemu-system-x86_64
> Program received signal SIGABRT, Aborted.
> 0x710c85f7 in raise () from /lib64/libc.so.6
> (gdb) where
> #0  0x710c85f7 in raise () from /lib64/libc.so.6
> #1  0x710c9ce8 in abort () from /lib64/libc.so.6
> #2  0x71108317 in __libc_message () from /lib64/libc.so.6
> #3  0x7110ffe1 in _int_free () from /lib64/libc.so.6
> #4  0x71ecc36f in g_free () from /lib64/libglib-2.0.so.0
> #5  0x559dfdd7 in qemu_iovec_destroy (qiov=0x57815410) at 
> /root/colo/jan-2016/qemu/util/iov.c:378
> #6  0x55989cce in quorum_aio_finalize (acb=0x57815350) at 
> /root/colo/jan-2016/qemu/block/quorum.c:171
> 171   qemu_iovec_destroy(&acb->qcrs[i].qiov);
> (gdb) list
> 166   
> 167   if (acb->is_read) {
> 168   /* on the quorum case acb->child_iter == s->num_children - 1 */
> 169   for (i = 0; i <= acb->child_iter; i++) {
> 170   qemu_vfree(acb->qcrs[i].buf);
> 171   qemu_iovec_destroy(&acb->qcrs[i].qiov);
> 172   }
> 173   }
> 174   
> 175   g_free(acb->qcrs);
> (gdb) p acb->child_iter
> $1 = 1
> (gdb) p i
> $3 = 1
> 
> #7  0x5598afca in quorum_aio_cb (opaque=, ret=-5)
> at /root/colo/jan-2016/qemu/block/quorum.c:302
> #8  0x559990ee in bdrv_co_complete (acb=0x57815410) at 
> /root/colo/jan-2016/qemu/block/io.c:2122
> .
> 
> So I guess acb->child_iter is wrong, since we only have one child on that 
> quorum?
> and we're trying to do a destroy on the second child.

Can you try the following patch:
>From 3f2c5ec288cd9a36afb392b4bba24029f3e9345a Mon Sep 17 00:00:00 2001
From: Wen Congyang 
Date: Mon, 25 Jan 2016 09:18:09 +0800
Subject: [PATCH] quorum: fix segfault when read fails in fifo mode

Signed-off-by: Wen Congyang 
---
 block/quorum.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/quorum.c b/block/quorum.c
index a5ae4b8..0965277 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -295,6 +295,9 @@ static void quorum_aio_cb(void *opaque, int ret)
 quorum_copy_qiov(acb->qiov, &acb->qcrs[acb->child_iter].qiov);
 }
 acb->vote_ret = ret;
+if (ret < 0) {
+acb->child_iter--;
+}
 quorum_aio_finalize(acb);
 return;
 }
-- 
2.5.0



> 
> Dave
> --
> Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
> 
> 
> .
> 






[Qemu-devel] [PULL 24/28] target-ppc: gdbstub: fix spe registers for little-endian guests

2016-01-24 Thread David Gibson
From: Greg Kurz 

Let's reuse the ppc_maybe_bswap_register() helper, like we already do
with the general registers.

Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 target-ppc/translate_init.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 4c29912..6625bb5 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8849,6 +8849,7 @@ static int gdb_get_spe_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 if (n < 32) {
 #if defined(TARGET_PPC64)
 stl_p(mem_buf, env->gpr[n] >> 32);
+ppc_maybe_bswap_register(env, mem_buf, 4);
 #else
 stl_p(mem_buf, env->gprh[n]);
 #endif
@@ -8856,10 +8857,12 @@ static int gdb_get_spe_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 }
 if (n == 32) {
 stq_p(mem_buf, env->spe_acc);
+ppc_maybe_bswap_register(env, mem_buf, 8);
 return 8;
 }
 if (n == 33) {
 stl_p(mem_buf, env->spe_fscr);
+ppc_maybe_bswap_register(env, mem_buf, 4);
 return 4;
 }
 return 0;
@@ -8870,7 +8873,11 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 if (n < 32) {
 #if defined(TARGET_PPC64)
 target_ulong lo = (uint32_t)env->gpr[n];
-target_ulong hi = (target_ulong)ldl_p(mem_buf) << 32;
+target_ulong hi;
+
+ppc_maybe_bswap_register(env, mem_buf, 4);
+
+hi = (target_ulong)ldl_p(mem_buf) << 32;
 env->gpr[n] = lo | hi;
 #else
 env->gprh[n] = ldl_p(mem_buf);
@@ -8878,10 +8885,12 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 return 4;
 }
 if (n == 32) {
+ppc_maybe_bswap_register(env, mem_buf, 8);
 env->spe_acc = ldq_p(mem_buf);
 return 8;
 }
 if (n == 33) {
+ppc_maybe_bswap_register(env, mem_buf, 4);
 env->spe_fscr = ldl_p(mem_buf);
 return 4;
 }
-- 
2.5.0




[Qemu-devel] [PULL 25/28] target-ppc: gdbstub: Add VSX support

2016-01-24 Thread David Gibson
From: Anton Blanchard 

Add the XML and functions to get and set VSX registers.

Signed-off-by: Anton Blanchard 
(fixed little-endian guests)
Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 configure   |  6 +++---
 gdb-xml/power-vsx.xml   | 44 
 target-ppc/translate_init.c | 24 
 3 files changed, 71 insertions(+), 3 deletions(-)
 create mode 100644 gdb-xml/power-vsx.xml

diff --git a/configure b/configure
index 44ac9ab..d96d646 100755
--- a/configure
+++ b/configure
@@ -5632,20 +5632,20 @@ case "$target_name" in
   ppc64)
 TARGET_BASE_ARCH=ppc
 TARGET_ABI_DIR=ppc
-gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml"
+gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml power-vsx.xml"
   ;;
   ppc64le)
 TARGET_ARCH=ppc64
 TARGET_BASE_ARCH=ppc
 TARGET_ABI_DIR=ppc
-gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml"
+gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml power-vsx.xml"
   ;;
   ppc64abi32)
 TARGET_ARCH=ppc64
 TARGET_BASE_ARCH=ppc
 TARGET_ABI_DIR=ppc
 echo "TARGET_ABI32=y" >> $config_target_mak
-gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml"
+gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml power-vsx.xml"
   ;;
   sh4|sh4eb)
 TARGET_ARCH=sh4
diff --git a/gdb-xml/power-vsx.xml b/gdb-xml/power-vsx.xml
new file mode 100644
index 000..fd290e9
--- /dev/null
+++ b/gdb-xml/power-vsx.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6625bb5..f6babd2 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8897,6 +8897,26 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t 
*mem_buf, int n)
 return 0;
 }
 
+static int gdb_get_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+if (n < 32) {
+stq_p(mem_buf, env->vsr[n]);
+ppc_maybe_bswap_register(env, mem_buf, 8);
+return 8;
+}
+return 0;
+}
+
+static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+if (n < 32) {
+ppc_maybe_bswap_register(env, mem_buf, 8);
+env->vsr[n] = ldq_p(mem_buf);
+return 8;
+}
+return 0;
+}
+
 static int ppc_fixup_cpu(PowerPCCPU *cpu)
 {
 CPUPPCState *env = &cpu->env;
@@ -9002,6 +9022,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error 
**errp)
 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
  34, "power-spe.xml", 0);
 }
+if (pcc->insns_flags2 & PPC2_VSX) {
+gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
+ 32, "power-vsx.xml", 0);
+}
 
 qemu_init_vcpu(cs);
 
-- 
2.5.0




Re: [Qemu-devel] COLO: how to flip a secondary to a primary?

2016-01-24 Thread Wen Congyang
On 01/23/2016 03:35 AM, Dr. David Alan Gilbert wrote:
> Hi,
>   I've been looking at what's needed to add a new secondary after
> a primary failed; from the block side it doesn't look as hard
> as I'd expected, perhaps you can tell me if I'm missing something!
> 
> The normal primary setup is:
> 
>quorum
>   Real disk
>   nbd client

quorum
   real disk
   replication
  nbd client

> 
> The normal secondary setup is:
>replication
>   active-disk
>   hidden-disk
>   Real-disk

IIRC, we can do it like this:
quorum
   replication
  active-disk
  hidden-disk
  real-disk

> 
> With a couple of minor code hacks; I changed the secondary to be:
> 
>quorum
>   replication
> active-disk
> hidden-disk
> Real-disk
>   dummy-disk

after failover,
quorum
   replicaion(old, mode is secondary)
 active-disk
 hidden-disk*
 real-disk*
   replication(new, mode is primary)
 nbd-client

In the newest version, we active commit active-disk to real-disk.
So it will be:
quorum
   replicaion(old, mode is secondary)
 active-disk(it is real disk now)
   replication(new, mode is primary)
 nbd-client

> 
> and then after the primary fails, I start a new secondary
> on another host and then on the old secondary do:
> 
>   nbd_server_stop
>   stop
>   x_block_change top-quorum -d children.0 # deletes use of real disk, 
> leaves dummy
>   drive_del active-disk0
>   x_block_change top-quorum -a node-real-disk
>   x_block_change top-quorum -d children.1 # Seems to have deleted the 
> dummy?!, the disk is now child 0
>   drive_add buddy 
> driver=replication,mode=primary,file.driver=nbd,file.host=ibpair,file.port=8889,file.export=colo-disk0,node-name=nbd-client,if=none,cache=none
>   x_block_change top-quorum -a nbd-client
>   c
>   migrate_set_capability x-colo on
>   migrate -d -b tcp:ibpair:
> 
> and I think that means what was the secondary, has the same disk
> structure as a normal primary.
> That's not quite happy yet, and I've not figured out why - but the
> order/structure of the block devices looks right?
> 
> Notes:
>a) The dummy serves two purposes, 1) it works around the segfault
>   I reported in the other mail, 2) when I delete the real disk in the
>   first x_block_change it means the quorum still has 1 disk so doesn't
>   get upset.

I don't understand the purpose 2.

>b) I had to remove the restriction in quorum_start_replication
>   on which mode it would run in. 

IIRC, this check will be removed.

>c) I'm not really sure everything knows it's in secondary mode yet, and
>   I'm not convinced whether the replication is doing the right thing.
>d) The migrate -d -b   eventually fails on the destination, not worked out 
> why
>   yet.

Can you give me the error message?

>e) Adding/deleting children on quorum is hard having to use the 
> children.0/1
>   notation when you've added children using node names - it's worrying
>   which number is which; is there a way to give them a name?

No. I think we can improve 'info block' output.

>f) I've not thought about the colo-proxy that much yet - I guess that
>   existing connections need to keep their sequence number offset but
>   new connections made by what is now the primary dont need to do anything
>   special.

Hailiang or Zhijian can answer this question.

Thanks
Wen Congyang

> 
> Dave
> --
> Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
> 
> 
> .
> 






Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-24 Thread Hailiang Zhang

On 2016/1/22 18:38, Daniel P. Berrange wrote:

On Fri, Jan 22, 2016 at 06:35:48PM +0800, Hailiang Zhang wrote:

On 2016/1/22 18:07, Daniel P. Berrange wrote:

On Fri, Jan 22, 2016 at 04:36:44PM +0800, zhanghailiang wrote:

This series is a prerequisite for COLO, here we add each netdev
a default buffer filter, it is disabled by default, and has
no side effect for delivering packets in net layer.


Why can't whatever is launching QEMU just setup filters explicitly
if they want to use COLO ? I'm not seeing an obvious compelling
reason to add this by default and then add extra code to deal
with special casing its behaviour.



The main reason is, we hope to support hot add network during VM's COLO
lifetime in the future. (I'm not quite sure if this usage case is really exist,
but we don't want the VM in COLO state has too many limitations.)

Maybe add an option that users can control if they want to use COLO or not is 
more
acceptable ? With this option, we can decide whether to add the default filter 
or not.
Or, we could dynamically add filter while users ask to go into COLO state for 
VM.
(We have discussed this before in community, and Jason suggested me to add 
default
filter for each netdev to support hot-add network during COLO state).

What's your suggestion ?


Why can't the app hot-adding the network interface also configure a
filter at that time if they're using COLO ?



Yes, they can certainly do that, but they will need to do more works:
1) netdev_add/device_add add NIC 2) identify if VM is in COLO state
3) if step 2) is YES, object-add filter for the new NIC.

Is this acceptable ?


Regards,
Daniel







Re: [Qemu-devel] COLO: how to flip a secondary to a primary?

2016-01-24 Thread Li Zhijian



On 01/25/2016 09:32 AM, Wen Congyang wrote:

>f) I've not thought about the colo-proxy that much yet - I guess that
>   existing connections need to keep their sequence number offset but


Strictly speaking, after failover, we only need to keep servicing for the tcp 
connections which are
established after the last checkpoint but not all existing connections. Because 
after a checkpoint
(primary and secondary node works well), primary vm and secondary vm is same, 
that means the existing
tcp connection has the same sequence。


>   new connections made by what is now the primary dont need to do anything
>   special.

Yes, you are right.



Hailiang or Zhijian can answer this question.



Thanks
Li Zhijian





Re: [Qemu-devel] [PATCH v7 15/15] iotests: Add "qemu-img map" test for VMDK extents

2016-01-24 Thread Fam Zheng
On Sat, 01/23 00:51, Max Reitz wrote:
> On 22.01.2016 04:06, Fam Zheng wrote:
> > Reviewed-by: Eric Blake 
> > Reviewed-by: Stefan Hajnoczi 
> > Signed-off-by: Fam Zheng 
> > ---
> >  tests/qemu-iotests/059 | 10 ++
> >  tests/qemu-iotests/059.out | 38 ++
> >  2 files changed, 48 insertions(+)
> > 
> > diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
> > index 0ded0c3..261d8b0 100755
> > --- a/tests/qemu-iotests/059
> > +++ b/tests/qemu-iotests/059
> > @@ -133,6 +133,16 @@ $QEMU_IO -c "write -P 0xa 900G 512" "$TEST_IMG" | 
> > _filter_qemu_io
> >  $QEMU_IO -c "read -v 900G 1024" "$TEST_IMG" | _filter_qemu_io
> >  
> >  echo
> > +echo "=== Testing qemu-img map on extents ==="
> > +for fmt in twoGbMaxExtentSparse twoGbMaxExtentFlat; do
> > +IMGOPTS="subformat=$fmt" _make_test_img 31G
> > +$QEMU_IO -c "write 65024 1k" "$TEST_IMG" | _filter_qemu_io
> > +$QEMU_IO -c "write 2147483136 1k" "$TEST_IMG" | _filter_qemu_io
> > +$QEMU_IO -c "write 5G 1k" "$TEST_IMG" | _filter_qemu_io
> > +$QEMU_IMG map "$TEST_IMG" | _filter_testdir
> > +done
> > +
> > +echo
> >  echo "=== Testing afl image with a very large capacity ==="
> >  _use_sample_img afl9.vmdk.bz2
> >  _img_info
> > diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
> > index 9d506cb..9f5e5cc 100644
> > --- a/tests/qemu-iotests/059.out
> > +++ b/tests/qemu-iotests/059.out
> > @@ -2335,6 +2335,44 @@ e103f0:  00 00 00 00 00 00 00 00 00 00 00 00 00 
> > 00 00 00  
> >  read 1024/1024 bytes at offset 966367641600
> >  1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> >  
> > +=== Testing qemu-img map on extents ===
> > +Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=33285996544 
> > subformat=twoGbMaxExtentSparse
> > +wrote 1024/1024 bytes at offset 65024
> > +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > +wrote 1024/1024 bytes at offset 2147483136
> > +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > +wrote 1024/1024 bytes at offset 5368709120
> > +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > +Offset  Length  Mapped to   File
> > +0   0x2 0x5 
> > TEST_DIR/iotest-version3-s001.vmdk
> > +0x7fff  0x1 0x7 
> > TEST_DIR/iotest-version3-s001.vmdk
> > +0x8000  0x1 0x5 
> > TEST_DIR/iotest-version3-s002.vmdk
> > +0x14000 0x1 0x5 
> > TEST_DIR/iotest-version3-s003.vmdk
> > +Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=33285996544 
> > subformat=twoGbMaxExtentFlat
> > +wrote 1024/1024 bytes at offset 65024
> > +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > +wrote 1024/1024 bytes at offset 2147483136
> > +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > +wrote 1024/1024 bytes at offset 5368709120
> > +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > +Offset  Length  Mapped to   File
> > +0   0x8000  0   
> > TEST_DIR/iotest-version3-f001.vmdk
> > +0x8000  0x8000  0   
> > TEST_DIR/iotest-version3-f002.vmdk
> > +0x1 0x8000  0   
> > TEST_DIR/iotest-version3-f003.vmdk
> > +0x18000 0x8000  0   
> > TEST_DIR/iotest-version3-f004.vmdk
> > +0x2 0x8000  0   
> > TEST_DIR/iotest-version3-f005.vmdk
> > +0x28000 0x8000  0   
> > TEST_DIR/iotest-version3-f006.vmdk
> > +0x3 0x8000  0   
> > TEST_DIR/iotest-version3-f007.vmdk
> > +0x38000 0x8000  0   
> > TEST_DIR/iotest-version3-f008.vmdk
> > +0x4 0x8000  0   
> > TEST_DIR/iotest-version3-f009.vmdk
> > +0x48000 0x8000  0   
> > TEST_DIR/iotest-version3-f010.vmdk
> > +0x5 0x8000  0   
> > TEST_DIR/iotest-version3-f011.vmdk
> > +0x58000 0x8000  0   
> > TEST_DIR/iotest-version3-f012.vmdk
> > +0x6 0x8000  0   
> > TEST_DIR/iotest-version3-f013.vmdk
> > +0x68000 0x8000  0   
> > TEST_DIR/iotest-version3-f014.vmdk
> > +0x7 0x8000  0   
> > TEST_DIR/iotest-version3-f015.vmdk
> > +0x78000 0x4000  0   
> > TEST_DIR/iotest-version3-f016.vmdk
> > +
> 
> I'm afraid I'm getting a different output here:
> 
> 0xf000  0x2000  0xf000  ...-f001.vmdk
> 0x7000  0x1000  0x7000  ...-f001.vmdk
> 0x8000  0x1000  0   ...-f002.vmdk
> 0x14000 0x1000  0x4000  ...-f003.vmdk

Will take a look.

> 
> (and also, I'm getting an error "qemu-img: Could not open
> '/tmp/test/t.vmdk': VMDK version 3 must be rea

[Qemu-devel] [PATCH] vmdk: Fix converting to streamOptimized

2016-01-24 Thread Fam Zheng
Commit d62d9dc4b8 lifted streamOptimized images's version to 3, but we
now refuse to open version 3 images read-write.  We need to make
streamOptimized an exception to allow converting to it. This fixes the
accidentally broken iotests case 059 for the same reason.

Signed-off-by: Fam Zheng 
---
 block/vmdk.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 698679d..4a5850b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -571,6 +571,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
 VmdkExtent *extent;
 BDRVVmdkState *s = bs->opaque;
 int64_t l1_backup_offset = 0;
+bool compressed;
 
 ret = bdrv_pread(file->bs, sizeof(magic), &header, sizeof(header));
 if (ret < 0) {
@@ -645,6 +646,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
 header = footer.header;
 }
 
+compressed =
+le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
 if (le32_to_cpu(header.version) > 3) {
 char buf[64];
 snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
@@ -652,7 +655,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
 error_setg(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bdrv_get_device_or_node_name(bs), "vmdk", buf);
 return -ENOTSUP;
-} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
+} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) &&
+   !compressed) {
 /* VMware KB 2064959 explains that version 3 added support for
  * persistent changed block tracking (CBT), and backup software can
  * read it as version=1 if it doesn't care about the changed area
-- 
2.4.3




[Qemu-devel] [PATCH v8 00/15] qemu-img map: Allow driver to return file of the allocated block

2016-01-24 Thread Fam Zheng
v8: Fix patch 15. [Max]
Add Max's rev-by in patch 1.

v7: Rebase, update patch 1 for two new bdrv_get_block_status_above() callers in
qemu-img.c. [Max]
Add Max's rev-by in patch 12.

Original cover letter
-

I stumbled upon this when looking at external bitmap formats.

Current "qemu-img map" command only displays filename if the data is allocated
in bs (bs->file) itself, or in the backing chain. Otherwise, it displays an
unfriendly error message:

$ qemu-img create -f vmdk -o subformat=monolithicFlat /tmp/test.vmdk 1G

$ qemu-img map /tmp/test.vmdk
Offset  Length  Mapped to   File
qemu-img: File contains external, encrypted or compressed clusters.

This can be improved. This series extends the .bdrv_co_get_block_status
callback, to let block driver return the BDS of file; then updates all driver
to implement it; and lastly, it changes qemu-img to use this information in
"map" command:


$ qemu-img map /tmp/test.vmdk
Offset  Length  Mapped to   File
0   0x4000  0   /tmp/test-flat.vmdk

$ qemu-img map --output json /tmp/test.vmdk
[{"length": 1073741824, "start": 0, "zero": false, "offset": 0, "depth": 0,
  "file": "/tmp/test-flat.vmdk", "data": true}
]


Fam Zheng (15):
  block: Add "file" output parameter to block status query functions
  qcow: Assign bs->file->bs to file in qcow_co_get_block_status
  qcow2: Assign bs->file->bs to file in qcow2_co_get_block_status
  raw: Assign bs to file in raw_co_get_block_status
  iscsi: Assign bs to file in iscsi_co_get_block_status
  parallels: Assign bs->file->bs to file in
parallels_co_get_block_status
  qed: Assign bs->file->bs to file in bdrv_qed_co_get_block_status
  sheepdog: Assign bs to file in sd_co_get_block_status
  vdi: Assign bs->file->bs to file in vdi_co_get_block_status
  vpc: Assign bs->file->bs to file in vpc_co_get_block_status
  vmdk: Return extent's file in bdrv_get_block_status
  block: Use returned *file in bdrv_co_get_block_status
  qemu-img: In "map", use the returned "file" from bdrv_get_block_status
  qemu-img: Make MapEntry a QAPI struct
  iotests: Add "qemu-img map" test for VMDK extents

 block/io.c | 42 +++
 block/iscsi.c  |  9 +++--
 block/mirror.c |  3 +-
 block/parallels.c  |  3 +-
 block/qcow.c   |  3 +-
 block/qcow2.c  |  3 +-
 block/qed.c|  6 +++-
 block/raw-posix.c  |  4 ++-
 block/raw_bsd.c|  4 ++-
 block/sheepdog.c   |  5 ++-
 block/vdi.c|  3 +-
 block/vmdk.c   | 12 ---
 block/vpc.c|  4 ++-
 block/vvfat.c  |  2 +-
 include/block/block.h  | 11 +++---
 include/block/block_int.h  |  3 +-
 qapi/block-core.json   | 27 +++
 qemu-img.c | 84 --
 tests/qemu-iotests/059 | 10 ++
 tests/qemu-iotests/059.out | 26 ++
 20 files changed, 194 insertions(+), 70 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v8 03/15] qcow2: Assign bs->file->bs to file in qcow2_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/qcow2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/qcow2.c b/block/qcow2.c
index d4ea6b4..8babecd 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1349,6 +1349,7 @@ static int64_t coroutine_fn 
qcow2_co_get_block_status(BlockDriverState *bs,
 !s->cipher) {
 index_in_cluster = sector_num & (s->cluster_sectors - 1);
 cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
+*file = bs->file->bs;
 status |= BDRV_BLOCK_OFFSET_VALID | cluster_offset;
 }
 if (ret == QCOW2_CLUSTER_ZERO) {
-- 
2.4.3




[Qemu-devel] [PATCH v8 02/15] qcow: Assign bs->file->bs to file in qcow_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/qcow.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/qcow.c b/block/qcow.c
index 4202797..251910c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -510,6 +510,7 @@ static int64_t coroutine_fn 
qcow_co_get_block_status(BlockDriverState *bs,
 return BDRV_BLOCK_DATA;
 }
 cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
+*file = bs->file->bs;
 return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | cluster_offset;
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v8 10/15] vpc: Assign bs->file->bs to file in vpc_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/vpc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block/vpc.c b/block/vpc.c
index a070307..f504536 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -589,6 +589,7 @@ static int64_t coroutine_fn 
vpc_co_get_block_status(BlockDriverState *bs,
 
 if (be32_to_cpu(footer->type) == VHD_FIXED) {
 *pnum = nb_sectors;
+*file = bs->file->bs;
 return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
(sector_num << BDRV_SECTOR_BITS);
 }
@@ -610,6 +611,7 @@ static int64_t coroutine_fn 
vpc_co_get_block_status(BlockDriverState *bs,
 /* *pnum can't be greater than one block for allocated
  * sectors since there is always a bitmap in between. */
 if (allocated) {
+*file = bs->file->bs;
 return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
 }
 if (nb_sectors == 0) {
-- 
2.4.3




[Qemu-devel] [PATCH v8 06/15] parallels: Assign bs->file->bs to file in parallels_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/parallels.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/parallels.c b/block/parallels.c
index e2de308..645521d 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -274,6 +274,7 @@ static int64_t coroutine_fn 
parallels_co_get_block_status(BlockDriverState *bs,
 return 0;
 }
 
+*file = bs->file->bs;
 return (offset << BDRV_SECTOR_BITS) |
 BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
 }
-- 
2.4.3




[Qemu-devel] [PATCH v8 01/15] block: Add "file" output parameter to block status query functions

2016-01-24 Thread Fam Zheng
The added parameter can be used to return the BDS pointer which the
valid offset is referring to. Its value should be ignored unless
BDRV_BLOCK_OFFSET_VALID in ret is set.

Until block drivers fill in the right value, let's clear it explicitly
right before calling .bdrv_get_block_status.

The "bs->file" condition in bdrv_co_get_block_status is kept now to keep iotest
case 102 passing, and will be fixed once all drivers return the right file
pointer.

Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 block/io.c| 38 ++
 block/iscsi.c |  6 --
 block/mirror.c|  3 ++-
 block/parallels.c |  2 +-
 block/qcow.c  |  2 +-
 block/qcow2.c |  2 +-
 block/qed.c   |  3 ++-
 block/raw-posix.c |  3 ++-
 block/raw_bsd.c   |  3 ++-
 block/sheepdog.c  |  2 +-
 block/vdi.c   |  2 +-
 block/vmdk.c  |  2 +-
 block/vpc.c   |  2 +-
 block/vvfat.c |  2 +-
 include/block/block.h | 11 +++
 include/block/block_int.h |  3 ++-
 qemu-img.c| 13 +
 17 files changed, 64 insertions(+), 35 deletions(-)

diff --git a/block/io.c b/block/io.c
index 5bb353a..0836991 100644
--- a/block/io.c
+++ b/block/io.c
@@ -664,6 +664,7 @@ int bdrv_write_zeroes(BlockDriverState *bs, int64_t 
sector_num,
 int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags)
 {
 int64_t target_sectors, ret, nb_sectors, sector_num = 0;
+BlockDriverState *file;
 int n;
 
 target_sectors = bdrv_nb_sectors(bs);
@@ -676,7 +677,7 @@ int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags 
flags)
 if (nb_sectors <= 0) {
 return 0;
 }
-ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n);
+ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n, &file);
 if (ret < 0) {
 error_report("error getting block status at sector %" PRId64 ": 
%s",
  sector_num, strerror(-ret));
@@ -1466,6 +1467,7 @@ int bdrv_flush_all(void)
 typedef struct BdrvCoGetBlockStatusData {
 BlockDriverState *bs;
 BlockDriverState *base;
+BlockDriverState **file;
 int64_t sector_num;
 int nb_sectors;
 int *pnum;
@@ -1490,7 +1492,8 @@ typedef struct BdrvCoGetBlockStatusData {
  */
 static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
  int64_t sector_num,
- int nb_sectors, int *pnum)
+ int nb_sectors, int *pnum,
+ BlockDriverState **file)
 {
 int64_t total_sectors;
 int64_t n;
@@ -1520,16 +1523,19 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 return ret;
 }
 
-ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum);
+*file = NULL;
+ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,
+file);
 if (ret < 0) {
 *pnum = 0;
+*file = NULL;
 return ret;
 }
 
 if (ret & BDRV_BLOCK_RAW) {
 assert(ret & BDRV_BLOCK_OFFSET_VALID);
 return bdrv_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS,
- *pnum, pnum);
+ *pnum, pnum, file);
 }
 
 if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
@@ -1549,10 +1555,11 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 if (bs->file &&
 (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
 (ret & BDRV_BLOCK_OFFSET_VALID)) {
+BlockDriverState *file2;
 int file_pnum;
 
 ret2 = bdrv_co_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS,
-*pnum, &file_pnum);
+*pnum, &file_pnum, &file2);
 if (ret2 >= 0) {
 /* Ignore errors.  This is just providing extra information, it
  * is useful but not necessary.
@@ -1577,14 +1584,15 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status_above(BlockDriverState *bs,
 BlockDriverState *base,
 int64_t sector_num,
 int nb_sectors,
-int *pnum)
+int *pnum,
+BlockDriverState **file)
 {
 BlockDriverState *p;
 int64_t ret = 0;
 
 assert(bs != base);
 for (p = bs; p != base; p = backing_bs(p)) {
-ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum);
+ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum, file);
 if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) {
 break;
 }
@@ -1603,7 +1611,8 @@ static void coroutine_fn 
bdrv_get_block_status_above_co_entry(void *opaque)
   

[Qemu-devel] [PATCH v8 12/15] block: Use returned *file in bdrv_co_get_block_status

2016-01-24 Thread Fam Zheng
Now that all drivers return the right "file" pointer, we can use it.

Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 block/io.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/io.c b/block/io.c
index 0836991..d704d32 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1552,13 +1552,13 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 }
 }
 
-if (bs->file &&
+if (*file && *file != bs &&
 (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
 (ret & BDRV_BLOCK_OFFSET_VALID)) {
 BlockDriverState *file2;
 int file_pnum;
 
-ret2 = bdrv_co_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS,
+ret2 = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
 *pnum, &file_pnum, &file2);
 if (ret2 >= 0) {
 /* Ignore errors.  This is just providing extra information, it
-- 
2.4.3




[Qemu-devel] [PATCH v8 14/15] qemu-img: Make MapEntry a QAPI struct

2016-01-24 Thread Fam Zheng
The "flags" bit mask is expanded to two booleans, "data" and "zero";
"bs" is replaced with "filename" string.

Refactor the merge conditions in img_map() into entry_mergeable().

Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 qapi/block-core.json | 27 
 qemu-img.c   | 71 +++-
 2 files changed, 69 insertions(+), 29 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0a915ed..30c2e5f 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -186,6 +186,33 @@
'*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }
 
 ##
+# @MapEntry:
+#
+# Mapping information from a virtual block range to a host file range
+#
+# @start: the start byte of the mapped virtual range
+#
+# @length: the number of bytes of the mapped virtual range
+#
+# @data: whether the mapped range has data
+#
+# @zero: whether the virtual blocks are zeroed
+#
+# @depth: the depth of the mapping
+#
+# @offset: #optional the offset in file that the virtual sectors are mapped to
+#
+# @filename: #optional filename that is referred to by @offset
+#
+# Since: 2.6
+#
+##
+{ 'struct': 'MapEntry',
+  'data': {'start': 'int', 'length': 'int', 'data': 'bool',
+   'zero': 'bool', 'depth': 'int', '*offset': 'int',
+   '*filename': 'str' } }
+
+##
 # @BlockdevCacheInfo
 #
 # Cache mode information for a block device
diff --git a/qemu-img.c b/qemu-img.c
index c8bc63f..f121980 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2147,47 +2147,37 @@ static int img_info(int argc, char **argv)
 return 0;
 }
 
-
-typedef struct MapEntry {
-int flags;
-int depth;
-int64_t start;
-int64_t length;
-int64_t offset;
-BlockDriverState *bs;
-} MapEntry;
-
 static void dump_map_entry(OutputFormat output_format, MapEntry *e,
MapEntry *next)
 {
 switch (output_format) {
 case OFORMAT_HUMAN:
-if ((e->flags & BDRV_BLOCK_DATA) &&
-!(e->flags & BDRV_BLOCK_OFFSET_VALID)) {
+if (e->data && !e->has_offset) {
 error_report("File contains external, encrypted or compressed 
clusters.");
 exit(1);
 }
-if ((e->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) == BDRV_BLOCK_DATA) 
{
+if (e->data && !e->zero) {
 printf("%#-16"PRIx64"%#-16"PRIx64"%#-16"PRIx64"%s\n",
-   e->start, e->length, e->offset, e->bs->filename);
+   e->start, e->length,
+   e->has_offset ? e->offset : 0,
+   e->has_filename ? e->filename : "");
 }
 /* This format ignores the distinction between 0, ZERO and ZERO|DATA.
  * Modify the flags here to allow more coalescing.
  */
-if (next &&
-(next->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) != 
BDRV_BLOCK_DATA) {
-next->flags &= ~BDRV_BLOCK_DATA;
-next->flags |= BDRV_BLOCK_ZERO;
+if (next && (!next->data || next->zero)) {
+next->data = false;
+next->zero = true;
 }
 break;
 case OFORMAT_JSON:
-printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64", \"depth\": 
%d,"
-   " \"zero\": %s, \"data\": %s",
+printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64","
+   " \"depth\": %"PRId64", \"zero\": %s, \"data\": %s",
(e->start == 0 ? "[" : ",\n"),
e->start, e->length, e->depth,
-   (e->flags & BDRV_BLOCK_ZERO) ? "true" : "false",
-   (e->flags & BDRV_BLOCK_DATA) ? "true" : "false");
-if (e->flags & BDRV_BLOCK_OFFSET_VALID) {
+   e->zero ? "true" : "false",
+   e->data ? "true" : "false");
+if (e->has_offset) {
 printf(", \"offset\": %"PRId64"", e->offset);
 }
 putchar('}');
@@ -2233,13 +2223,39 @@ static int get_block_status(BlockDriverState *bs, 
int64_t sector_num,
 
 e->start = sector_num * BDRV_SECTOR_SIZE;
 e->length = nb_sectors * BDRV_SECTOR_SIZE;
-e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;
+e->data = !!(ret & BDRV_BLOCK_DATA);
+e->zero = !!(ret & BDRV_BLOCK_ZERO);
 e->offset = ret & BDRV_BLOCK_OFFSET_MASK;
+e->has_offset = !!(ret & BDRV_BLOCK_OFFSET_VALID);
 e->depth = depth;
-e->bs = file;
+if (file && e->has_offset) {
+e->has_filename = true;
+e->filename = file->filename;
+}
 return 0;
 }
 
+static inline bool entry_mergeable(const MapEntry *curr, const MapEntry *next)
+{
+if (curr->length == 0) {
+return false;
+}
+if (curr->zero != next->zero ||
+curr->data != next->data ||
+curr->depth != next->depth ||
+curr->has_filename != next->has_filename ||
+curr->has_offset != next->has_offset) {
+return false;
+}
+if (curr->has_filename && strcmp(curr->filename, next->filenam

[Qemu-devel] [PATCH v8 08/15] sheepdog: Assign bs to file in sd_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/sheepdog.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 2ea05a6..a0098c1 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2739,6 +2739,9 @@ sd_co_get_block_status(BlockDriverState *bs, int64_t 
sector_num, int nb_sectors,
 if (*pnum > nb_sectors) {
 *pnum = nb_sectors;
 }
+if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {
+*file = bs;
+}
 return ret;
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v8 04/15] raw: Assign bs to file in raw_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/raw-posix.c | 1 +
 block/raw_bsd.c   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 3ef9b25..8866121 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1861,6 +1861,7 @@ static int64_t coroutine_fn 
raw_co_get_block_status(BlockDriverState *bs,
 *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
 ret = BDRV_BLOCK_ZERO;
 }
+*file = bs;
 return ret | BDRV_BLOCK_OFFSET_VALID | start;
 }
 
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 9a8933b..fd355d5 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -119,6 +119,7 @@ static int64_t coroutine_fn 
raw_co_get_block_status(BlockDriverState *bs,
 BlockDriverState **file)
 {
 *pnum = nb_sectors;
+*file = bs;
 return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
(sector_num << BDRV_SECTOR_BITS);
 }
-- 
2.4.3




[Qemu-devel] [PATCH v8 11/15] vmdk: Return extent's file in bdrv_get_block_status

2016-01-24 Thread Fam Zheng
Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 block/vmdk.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index e1d3e27..f8f7fcf 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1274,6 +1274,7 @@ static int64_t coroutine_fn 
vmdk_co_get_block_status(BlockDriverState *bs,
  0, 0);
 qemu_co_mutex_unlock(&s->lock);
 
+index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
 switch (ret) {
 case VMDK_ERROR:
 ret = -EIO;
@@ -1286,14 +1287,15 @@ static int64_t coroutine_fn 
vmdk_co_get_block_status(BlockDriverState *bs,
 break;
 case VMDK_OK:
 ret = BDRV_BLOCK_DATA;
-if (extent->file == bs->file && !extent->compressed) {
-ret |= BDRV_BLOCK_OFFSET_VALID | offset;
+if (!extent->compressed) {
+ret |= BDRV_BLOCK_OFFSET_VALID;
+ret |= (offset + (index_in_cluster << BDRV_SECTOR_BITS))
+& BDRV_BLOCK_OFFSET_MASK;
 }
-
+*file = extent->file->bs;
 break;
 }
 
-index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
 n = extent->cluster_sectors - index_in_cluster;
 if (n > nb_sectors) {
 n = nb_sectors;
-- 
2.4.3




[Qemu-devel] [PATCH v8 15/15] iotests: Add "qemu-img map" test for VMDK extents

2016-01-24 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/059 | 10 ++
 tests/qemu-iotests/059.out | 26 ++
 2 files changed, 36 insertions(+)

diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 0ded0c3..0332bbb 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -133,6 +133,16 @@ $QEMU_IO -c "write -P 0xa 900G 512" "$TEST_IMG" | 
_filter_qemu_io
 $QEMU_IO -c "read -v 900G 1024" "$TEST_IMG" | _filter_qemu_io
 
 echo
+echo "=== Testing qemu-img map on extents ==="
+for fmt in monolithicSparse twoGbMaxExtentSparse; do
+IMGOPTS="subformat=$fmt" _make_test_img 31G
+$QEMU_IO -c "write 65024 1k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write 2147483136 1k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write 5G 1k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG map "$TEST_IMG" | _filter_testdir
+done
+
+echo
 echo "=== Testing afl image with a very large capacity ==="
 _use_sample_img afl9.vmdk.bz2
 _img_info
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 9d506cb..5e041d7 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -2050,6 +2050,7 @@ wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 512/512 bytes at offset 10240
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-img: Could not open 
'/home/fam/build/last/tests/qemu-iotests/scratch/t.vmdk': VMDK version 3 must 
be read only
 
 === Testing monolithicFlat with internally generated JSON file name ===
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
subformat=monolithicFlat
@@ -2335,6 +2336,31 @@ e103f0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00  
 read 1024/1024 bytes at offset 966367641600
 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
+=== Testing qemu-img map on extents ===
+Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=33285996544 
subformat=monolithicSparse
+wrote 1024/1024 bytes at offset 65024
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 2147483136
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 5368709120
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Offset  Length  Mapped to   File
+0   0x2 0x3fTEST_DIR/iotest-version3.vmdk
+0x7fff  0x2 0x41TEST_DIR/iotest-version3.vmdk
+0x14000 0x1 0x43TEST_DIR/iotest-version3.vmdk
+Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=33285996544 
subformat=twoGbMaxExtentSparse
+wrote 1024/1024 bytes at offset 65024
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 2147483136
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 5368709120
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Offset  Length  Mapped to   File
+0   0x2 0x5 
TEST_DIR/iotest-version3-s001.vmdk
+0x7fff  0x1 0x7 
TEST_DIR/iotest-version3-s001.vmdk
+0x8000  0x1 0x5 
TEST_DIR/iotest-version3-s002.vmdk
+0x14000 0x1 0x5 
TEST_DIR/iotest-version3-s003.vmdk
+
 === Testing afl image with a very large capacity ===
 qemu-img: Can't get size of device 'image': File too large
 *** done
-- 
2.4.3




[Qemu-devel] [PATCH v8 05/15] iscsi: Assign bs to file in iscsi_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/iscsi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/iscsi.c b/block/iscsi.c
index e182557..9fe76f4 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -625,6 +625,9 @@ out:
 if (iTask.task != NULL) {
 scsi_free_scsi_task(iTask.task);
 }
+if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {
+*file = bs;
+}
 return ret;
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v8 07/15] qed: Assign bs->file->bs to file in bdrv_qed_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/qed.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/qed.c b/block/qed.c
index 8f6f841..404be1e 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -693,6 +693,7 @@ typedef struct {
 uint64_t pos;
 int64_t status;
 int *pnum;
+BlockDriverState **file;
 } QEDIsAllocatedCB;
 
 static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t 
len)
@@ -704,6 +705,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, 
uint64_t offset, size_t l
 case QED_CLUSTER_FOUND:
 offset |= qed_offset_into_cluster(s, cb->pos);
 cb->status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
+*cb->file = cb->bs->file->bs;
 break;
 case QED_CLUSTER_ZERO:
 cb->status = BDRV_BLOCK_ZERO;
@@ -735,6 +737,7 @@ static int64_t coroutine_fn 
bdrv_qed_co_get_block_status(BlockDriverState *bs,
 .pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE,
 .status = BDRV_BLOCK_OFFSET_MASK,
 .pnum = pnum,
+.file = file,
 };
 QEDRequest request = { .l2_table = NULL };
 
-- 
2.4.3




[Qemu-devel] [PATCH v8 09/15] vdi: Assign bs->file->bs to file in vdi_co_get_block_status

2016-01-24 Thread Fam Zheng
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 block/vdi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/vdi.c b/block/vdi.c
index 294c438..b403243 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -551,6 +551,7 @@ static int64_t coroutine_fn 
vdi_co_get_block_status(BlockDriverState *bs,
 offset = s->header.offset_data +
   (uint64_t)bmap_entry * s->block_size +
   sector_in_block * SECTOR_SIZE;
+*file = bs->file->bs;
 return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v8 13/15] qemu-img: In "map", use the returned "file" from bdrv_get_block_status

2016-01-24 Thread Fam Zheng
Now all drivers should return a correct "file", we can make use of it,
even with the recursion into backing chain above.

Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Fam Zheng 
---
 qemu-img.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-img.c b/qemu-img.c
index e653b2f..c8bc63f 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2236,7 +2236,7 @@ static int get_block_status(BlockDriverState *bs, int64_t 
sector_num,
 e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;
 e->offset = ret & BDRV_BLOCK_OFFSET_MASK;
 e->depth = depth;
-e->bs = bs;
+e->bs = file;
 return 0;
 }
 
-- 
2.4.3




Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-24 Thread Jason Wang


On 01/22/2016 06:07 PM, Daniel P. Berrange wrote:
> On Fri, Jan 22, 2016 at 04:36:44PM +0800, zhanghailiang wrote:
>> This series is a prerequisite for COLO, here we add each netdev
>> a default buffer filter, it is disabled by default, and has
>> no side effect for delivering packets in net layer.
> Why can't whatever is launching QEMU just setup filters explicitly
> if they want to use COLO ? I'm not seeing an obvious compelling
> reason to add this by default and then add extra code to deal
> with special casing its behaviour.

Two things here I think. The first is the management role for COLO,
maybe it's time to discuss it now. And if management can do this, it's
ok for not implementing default filter now. Second is the default filter
itself, I still think it's not bad to have it for the future, and with
the ability to specify, change or disable the default filter. This could
simplify management and testing.

Back to this series, it mixes several things (bugs fixings, new 'status'
filed, default filter implementation, and a special handling for
filter-buffer). Better split them.

Thanks
>
>> Besides, patch 1 fixes the ouput information of 'info network' command
>> for filter.
>>
>> zhanghailiang (7):
>>   net/filter: Fix the output information for command 'info network'
>>   net/filter: Add a 'status' property for filter object
>>   net/filter: Skip the disabled filter when delivering packets
>>   net/filter: Introduce a helper to add a filter to the netdev
>>   filter-buffer: Accept zero interval
>>   net/filter: Add a default filter to each netdev
>>   net/filter: prevent the default filter to be deleted
>>
>>  include/net/filter.h |  25 +++-
>>  net/dump.c   |   2 -
>>  net/filter-buffer.c  |  10 
>>  net/filter.c | 163 
>> +--
>>  net/net.c|  27 -
>>  5 files changed, 194 insertions(+), 33 deletions(-)
> Regards,
> Daniel




Re: [Qemu-devel] [PATCH] net: walk through filters reversely if traffic is outgress

2016-01-24 Thread Jason Wang


On 01/22/2016 04:11 PM, Li Zhijian wrote:
> Previously, if the netdev has more than one filters, the ingress
> or outgress traffic pass the filter in the same order. this patch
> is to make the outgress pass the filter in a reverse order

Need a description why we need this.

>
> Signed-off-by: Wen Congyang 
> Signed-off-by: Li Zhijian 
> ---
>  include/net/net.h |  4 +++-
>  net/filter.c  | 21 +++--
>  net/net.c | 23 ++-
>  3 files changed, 40 insertions(+), 8 deletions(-)
>
> diff --git a/include/net/net.h b/include/net/net.h
> index 7af3e15..1d807cc 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -79,6 +79,8 @@ typedef struct NetClientInfo {
>  SetVnetBE *set_vnet_be;
>  } NetClientInfo;
>  
> +QTAILQ_HEAD(NetFilterHead, NetFilterState);
> +
>  struct NetClientState {
>  NetClientInfo *info;
>  int link_down;
> @@ -92,7 +94,7 @@ struct NetClientState {
>  NetClientDestructor *destructor;
>  unsigned int queue_index;
>  unsigned rxfilter_notify_enabled:1;
> -QTAILQ_HEAD(, NetFilterState) filters;
> +struct NetFilterHead filters;
>  };
>  
>  typedef struct NICState {
> diff --git a/net/filter.c b/net/filter.c
> index 5d90f83..17a8398 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -34,6 +34,22 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf,
>  return 0;
>  }
>  
> +static NetFilterState *netfilter_next(NetFilterState *nf,
> +  NetFilterDirection dir)
> +{
> +NetFilterState *next;
> +
> +if (dir == NET_FILTER_DIRECTION_TX) {
> +/* forward walk through filters */
> +next = QTAILQ_NEXT(nf, next);
> +} else {
> +/* reverse order */
> +next = QTAILQ_PREV(nf, NetFilterHead, next);
> +}
> +
> +return next;
> +}
> +
>  ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
>  unsigned flags,
>  const struct iovec *iov,
> @@ -43,7 +59,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
>  int ret = 0;
>  int direction;
>  NetFilterState *nf = opaque;
> -NetFilterState *next = QTAILQ_NEXT(nf, next);
> +NetFilterState *next = NULL;
>  
>  if (!sender || !sender->peer) {
>  /* no receiver, or sender been deleted, no need to pass it further */
> @@ -61,6 +77,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
>  direction = nf->direction;
>  }
>  
> +next = netfilter_next(nf, direction);
>  while (next) {
>  /*
>   * if qemu_netfilter_pass_to_next been called, means that
> @@ -73,7 +90,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
>  if (ret) {
>  return ret;
>  }
> -next = QTAILQ_NEXT(next, next);
> +next = netfilter_next(next, direction);
>  }
>  
>  /*
> diff --git a/net/net.c b/net/net.c
> index 87dd356..05ec996 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -580,11 +580,24 @@ static ssize_t filter_receive_iov(NetClientState *nc,
>  ssize_t ret = 0;
>  NetFilterState *nf = NULL;
>  
> -QTAILQ_FOREACH(nf, &nc->filters, next) {
> -ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
> - iovcnt, sent_cb);
> -if (ret) {
> -return ret;
> +assert(direction == NET_FILTER_DIRECTION_TX ||
> +   direction == NET_FILTER_DIRECTION_RX);
> +

Don't get why we need this assert.

Other looks good.

> +if (direction == NET_FILTER_DIRECTION_TX) {
> +QTAILQ_FOREACH(nf, &nc->filters, next) {
> +ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
> + iovcnt, sent_cb);
> +if (ret) {
> +return ret;
> +}
> +}
> +} else {
> +QTAILQ_FOREACH_REVERSE(nf, &nc->filters, NetFilterHead, next) {
> +ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
> + iovcnt, sent_cb);
> +if (ret) {
> +return ret;
> +}
>  }
>  }
>  




Re: [Qemu-devel] [PATCH RFC 1/7] net/filter: Fix the output information for command 'info network'

2016-01-24 Thread Jason Wang


On 01/22/2016 04:36 PM, zhanghailiang wrote:
> The properties of netfilter object could be changed by 'qom-set'
> command, but the output of 'info network' command is not updated,
> because it got the old information through nf->info_str, it will
> not be updated while we change the value of netfilter's property.
>
> Here we split a the helper function that could colletct the output
> information for filter, and also remove the useless member
> 'info_str' from struct NetFilterState.
>
> Signed-off-by: zhanghailiang 
> ---

Looks like a bug fix. Please send as a independent formal patch and
better cc Markus and Eric for better reviewing.

Thanks

>  include/net/filter.h |  3 ++-
>  net/filter.c | 47 ++-
>  net/net.c|  5 -
>  3 files changed, 32 insertions(+), 23 deletions(-)
>
> diff --git a/include/net/filter.h b/include/net/filter.h
> index 2deda36..8a20138 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -55,7 +55,6 @@ struct NetFilterState {
>  char *netdev_id;
>  NetClientState *netdev;
>  NetFilterDirection direction;
> -char info_str[256];
>  QTAILQ_ENTRY(NetFilterState) next;
>  };
>  
> @@ -74,4 +73,6 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
>  int iovcnt,
>  void *opaque);
>  
> +void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
> +
>  #endif /* QEMU_NET_FILTER_H */
> diff --git a/net/filter.c b/net/filter.c
> index 5d90f83..40254bd 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -128,6 +128,31 @@ static void netfilter_init(Object *obj)
>   NULL);
>  }
>  
> +void netfilter_print_info(NetFilterState *nf, char *output_str, int size)
> +{
> +char *str, *info;
> +ObjectProperty *prop;
> +ObjectPropertyIterator iter;
> +StringOutputVisitor *ov;
> +
> +/* generate info str */
> +object_property_iter_init(&iter, OBJECT(nf));
> +while ((prop = object_property_iter_next(&iter))) {
> +if (!strcmp(prop->name, "type")) {
> +continue;
> +}
> +ov = string_output_visitor_new(false);
> +object_property_get(OBJECT(nf), string_output_get_visitor(ov),
> +prop->name, NULL);
> +str = string_output_get_string(ov);
> +string_output_visitor_cleanup(ov);
> +info = g_strdup_printf(",%s=%s", prop->name, str);
> +g_strlcat(output_str, info, size);
> +g_free(str);
> +g_free(info);
> +}
> +}
> +
>  static void netfilter_complete(UserCreatable *uc, Error **errp)
>  {
>  NetFilterState *nf = NETFILTER(uc);
> @@ -135,10 +160,7 @@ static void netfilter_complete(UserCreatable *uc, Error 
> **errp)
>  NetFilterClass *nfc = NETFILTER_GET_CLASS(uc);
>  int queues;
>  Error *local_err = NULL;
> -char *str, *info;
> -ObjectProperty *prop;
> -ObjectPropertyIterator iter;
> -StringOutputVisitor *ov;
> +
>  
>  if (!nf->netdev_id) {
>  error_setg(errp, "Parameter 'netdev' is required");
> @@ -172,23 +194,6 @@ static void netfilter_complete(UserCreatable *uc, Error 
> **errp)
>  }
>  }
>  QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next);
> -
> -/* generate info str */
> -object_property_iter_init(&iter, OBJECT(nf));
> -while ((prop = object_property_iter_next(&iter))) {
> -if (!strcmp(prop->name, "type")) {
> -continue;
> -}
> -ov = string_output_visitor_new(false);
> -object_property_get(OBJECT(nf), string_output_get_visitor(ov),
> -prop->name, errp);
> -str = string_output_get_string(ov);
> -string_output_visitor_cleanup(ov);
> -info = g_strdup_printf(",%s=%s", prop->name, str);
> -g_strlcat(nf->info_str, info, sizeof(nf->info_str));
> -g_free(str);
> -g_free(info);
> -}
>  }
>  
>  static void netfilter_finalize(Object *obj)
> diff --git a/net/net.c b/net/net.c
> index 87dd356..87de7c0 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1198,9 +1198,12 @@ void print_net_client(Monitor *mon, NetClientState *nc)
>  }
>  QTAILQ_FOREACH(nf, &nc->filters, next) {
>  char *path = object_get_canonical_path_component(OBJECT(nf));
> +char info[256] = { 0 };
> +
> +netfilter_print_info(nf, info, sizeof(info));
>  monitor_printf(mon, "  - %s: type=%s%s\n", path,
> object_get_typename(OBJECT(nf)),
> -   nf->info_str);
> +   info);
>  g_free(path);
>  }
>  }




Re: [Qemu-devel] [PATCH RFC 3/7] net/filter: Skip the disabled filter when delivering packets

2016-01-24 Thread Jason Wang


On 01/22/2016 05:32 PM, Wen Congyang wrote:
> On 01/22/2016 04:36 PM, zhanghailiang wrote:
>> If the filter is disabled, don't go through it.
>>
>> Signed-off-by: zhanghailiang 
>> ---
>>  include/net/filter.h | 5 +
>>  net/net.c| 4 
>>  2 files changed, 9 insertions(+)
>>
>> diff --git a/include/net/filter.h b/include/net/filter.h
>> index 9ed5ec6..d797ee4 100644
>> --- a/include/net/filter.h
>> +++ b/include/net/filter.h
>> @@ -74,6 +74,11 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState 
>> *sender,
>>  int iovcnt,
>>  void *opaque);
>>  
>> +static inline bool qemu_need_skip_netfilter(NetFilterState *nf)
>> +{
>> +return nf->enabled ? false : true;
>> +}
>> +
>>  void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
>>  
>>  #endif /* QEMU_NET_FILTER_H */
>> diff --git a/net/net.c b/net/net.c
>> index 87de7c0..ec43105 100644
>> --- a/net/net.c
>> +++ b/net/net.c
>> @@ -581,6 +581,10 @@ static ssize_t filter_receive_iov(NetClientState *nc,
>>  NetFilterState *nf = NULL;
>>  
>>  QTAILQ_FOREACH(nf, &nc->filters, next) {
>> +/* Don't go through filter if it is off */
>> +if (qemu_need_skip_netfilter(nf)) {
>> +continue;
>> +}
>>  ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
>>   iovcnt, sent_cb);
>>  if (ret) {
>>
> qemu_netfilter_pass_to_next() shoule also be updated.

Then let's better move it to qemu_netfiler_receive().

>
> Thanks
> Wen Congyang
>
>
>
>




Re: [Qemu-devel] [PATCH RFC 2/7] net/filter: Add a 'status' property for filter object

2016-01-24 Thread Jason Wang


On 01/22/2016 04:36 PM, zhanghailiang wrote:
> With this property, users can control if this filter is 'enable'
> or 'disable'. The default behavior for filter is enabled.
>
> Signed-off-by: zhanghailiang 

Let's squash patch 3 into this for a complete implementation of 'status'.

> ---
>  include/net/filter.h |  1 +
>  net/filter.c | 36 
>  2 files changed, 37 insertions(+)
>
> diff --git a/include/net/filter.h b/include/net/filter.h
> index 8a20138..9ed5ec6 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -55,6 +55,7 @@ struct NetFilterState {
>  char *netdev_id;
>  NetClientState *netdev;
>  NetFilterDirection direction;
> +bool enabled;
>  QTAILQ_ENTRY(NetFilterState) next;
>  };
>  
> diff --git a/net/filter.c b/net/filter.c
> index 40254bd..f4933cc 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -117,8 +117,41 @@ static void netfilter_set_direction(Object *obj, int 
> direction, Error **errp)
>  nf->direction = direction;
>  }
>  
> +static char *netfilter_get_status(Object *obj, Error **errp)
> +{
> +NetFilterState *nf = NETFILTER(obj);
> +
> +if (nf->enabled) {
> +return g_strdup("enable");
> +} else {
> +return g_strdup("disable");
> +}
> +}
> +
> +static void netfilter_set_status(Object *obj, const char *str, Error **errp)
> +{
> +NetFilterState *nf = NETFILTER(obj);
> +
> +if (!strcmp(str, "enable")) {
> +nf->enabled = true;
> +} else if (!strcmp(str, "disable")) {
> +nf->enabled = false;
> +} else {
> +error_setg(errp, "Invalid value for netfilter status, "
> + "should be 'enable' or 'disable'");
> +}
> +}
> +
>  static void netfilter_init(Object *obj)
>  {
> +NetFilterState *nf = NETFILTER(obj);
> +
> +/*
> +* If not configured with 'status' property, the default status
> +* for netfilter will be enabled.
> +*/
> +nf->enabled = true;
> +
>  object_property_add_str(obj, "netdev",
>  netfilter_get_netdev_id, netfilter_set_netdev_id,
>  NULL);
> @@ -126,6 +159,9 @@ static void netfilter_init(Object *obj)
>   NetFilterDirection_lookup,
>   netfilter_get_direction, 
> netfilter_set_direction,
>   NULL);
> +object_property_add_str(obj, "status",
> +netfilter_get_status, netfilter_set_status,
> +NULL);
>  }
>  
>  void netfilter_print_info(NetFilterState *nf, char *output_str, int size)




[Qemu-devel] [PATCH 03/10] target-ppc: Rework ppc_store_slb

2016-01-24 Thread David Gibson
ppc_store_slb updates the SLB for PPC cpus with 64-bit hash MMUs.
Currently it takes two parameters, which contain values encoded as the
register arguments to the slbmte instruction, one register contains the
ESID portion of the SLBE and also the slot number, the other contains the
VSID portion of the SLBE.

We're shortly going to want to do some SLB updates from other code where
it is more convenient to supply the slot number and ESID separately, so
rework this function and its callers to work this way.

As a bonus, this slightly simplifies the emulation of segment registers for
when running a 32-bit OS on a 64-bit CPU.

Signed-off-by: David Gibson 
---
 target-ppc/kvm.c|  2 +-
 target-ppc/mmu-hash64.c | 24 +---
 target-ppc/mmu-hash64.h |  3 ++-
 target-ppc/mmu_helper.c | 14 +-
 4 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 98d7ba6..18c7ba2 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1205,7 +1205,7 @@ int kvm_arch_get_registers(CPUState *cs)
  * Only restore valid entries
  */
 if (rb & SLB_ESID_V) {
-ppc_store_slb(cpu, rb, rs);
+ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfff, rs);
 }
 }
 #endif
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 03e25fd..5a6d33b 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -135,28 +135,30 @@ void helper_slbie(CPUPPCState *env, target_ulong addr)
 }
 }
 
-int ppc_store_slb(PowerPCCPU *cpu, target_ulong rb, target_ulong rs)
+int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
+  target_ulong esid, target_ulong vsid)
 {
 CPUPPCState *env = &cpu->env;
-int slot = rb & 0xfff;
 ppc_slb_t *slb = &env->slb[slot];
 
-if (rb & (0x1000 - env->slb_nr)) {
-return -1; /* Reserved bits set or slot too high */
+if (slot >= env->slb_nr) {
+return -1; /* Bad slot number */
+}
+if (esid & ~(SLB_ESID_ESID | SLB_ESID_V)) {
+return -1; /* Reserved bits set */
 }
-if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
+if (vsid & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
 return -1; /* Bad segment size */
 }
-if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
+if ((vsid & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
 return -1; /* 1T segment on MMU that doesn't support it */
 }
 
-/* Mask out the slot number as we store the entry */
-slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
-slb->vsid = rs;
+slb->esid = esid;
+slb->vsid = vsid;
 
 LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
-" %016" PRIx64 "\n", __func__, slot, rb, rs,
+" %016" PRIx64 "\n", __func__, slot, esid, vsid,
 slb->esid, slb->vsid);
 
 return 0;
@@ -196,7 +198,7 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, 
target_ulong rs)
 {
 PowerPCCPU *cpu = ppc_env_get_cpu(env);
 
-if (ppc_store_slb(cpu, rb, rs) < 0) {
+if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfff, rs) < 0) {
 helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_INVAL);
 }
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index 6e3de7e..24fd2c4 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -6,7 +6,8 @@
 #ifdef TARGET_PPC64
 void ppc_hash64_check_page_sizes(PowerPCCPU *cpu, Error **errp);
 void dump_slb(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU *cpu);
-int ppc_store_slb(PowerPCCPU *cpu, target_ulong rb, target_ulong rs);
+int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
+  target_ulong esid, target_ulong vsid);
 hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
 int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw,
 int mmu_idx);
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 0ab73bc..c040b17 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -2088,21 +2088,17 @@ void helper_store_sr(CPUPPCState *env, target_ulong 
srnum, target_ulong value)
 (int)srnum, value, env->sr[srnum]);
 #if defined(TARGET_PPC64)
 if (env->mmu_model & POWERPC_MMU_64) {
-uint64_t rb = 0, rs = 0;
+uint64_t esid, vsid;
 
 /* ESID = srnum */
-rb |= ((uint32_t)srnum & 0xf) << 28;
-/* Set the valid bit */
-rb |= SLB_ESID_V;
-/* Index = ESID */
-rb |= (uint32_t)srnum;
+esid = ((uint64_t)(srnum & 0xf) << 28) | SLB_ESID_V;
 
 /* VSID = VSID */
-rs |= (value & 0xfff) << 12;
+vsid = (value & 0xfff) << 12;
 /* flags = flags */
-rs |= ((value >> 27) & 0xf) << 8;
+vsid |= ((value >> 27) & 0xf) << 8;
 
-ppc_store_slb(cpu, rb, rs);
+ppc_stor

[Qemu-devel] [PATCH 01/10] target-ppc: Remove unused kvmppc_read_segment_page_sizes() stub

2016-01-24 Thread David Gibson
This stub function is in the !KVM ifdef in target-ppc/kvm_ppc.h.  However
no such function exists on the KVM side, or is ever used.

I think this originally referenced a function which read host page size
information from /proc, for we we now use the KVM GET_SMMU_INFO extension
instead.

In any case, it has no function now, so remove it.

Signed-off-by: David Gibson 
---
 target-ppc/kvm_ppc.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 5e1333d..62406ce 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -98,11 +98,6 @@ static inline int kvmppc_get_hypercall(CPUPPCState *env, 
uint8_t *buf, int buf_l
 return -1;
 }
 
-static inline int kvmppc_read_segment_page_sizes(uint32_t *prop, int maxcells)
-{
-return -1;
-}
-
 static inline int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level)
 {
 return -1;
-- 
2.5.0




[Qemu-devel] [PATCH 04/10] target-ppc: Rework SLB page size lookup

2016-01-24 Thread David Gibson
Currently, the ppc_hash64_page_shift() function looks up a page size based
on information in an SLB entry.  It open codes the bit translation for
existing CPUs, however different CPU models can have different SLB
encodings.  We already store those in the 'sps' table in CPUPPCState, but
we don't currently enforce that that actually matches the logic in
ppc_hash64_page_shift.

This patch reworks lookup of page size from SLB in several ways:
  * ppc_store_slb() will now fail (triggering an illegal instruction
exception) if given a bad SLB page size encoding
  * On success ppc_store_slb() stores a pointer to the relevant entry in
the page size table in the SLB entry.  This is looked up directly from
the published table of page size encodings, so can't get out ot sync.
  * ppc_hash64_htab_lookup() and others now use this precached page size
information rather than decoding the SLB values
  * Adjust ppc_hash64_pte_raddr() to take a page shift directly
instead of an SLB entry.  We'll be wanting the flexibility shortly.
  * Adjust ppc_hash64_pte_raddr() to take a page shift directly
instead of an SLB entry.  Both callers now have easy access to this,
and we'll need the flexibility shortly.

Signed-off-by: David Gibson 
---
 target-ppc/cpu.h|  1 +
 target-ppc/machine.c| 20 ++
 target-ppc/mmu-hash64.c | 71 ++---
 3 files changed, 59 insertions(+), 33 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 2bc96b4..0820390 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -419,6 +419,7 @@ typedef struct ppc_slb_t ppc_slb_t;
 struct ppc_slb_t {
 uint64_t esid;
 uint64_t vsid;
+const struct ppc_one_seg_page_size *sps;
 };
 
 #define MAX_SLB_ENTRIES 64
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index b61c060..ca62d3e 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -2,6 +2,7 @@
 #include "hw/boards.h"
 #include "sysemu/kvm.h"
 #include "helper_regs.h"
+#include "mmu-hash64.h"
 
 static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
 {
@@ -352,11 +353,30 @@ static bool slb_needed(void *opaque)
 return (cpu->env.mmu_model & POWERPC_MMU_64);
 }
 
+static int slb_post_load(void *opaque, int version_id)
+{
+PowerPCCPU *cpu = opaque;
+CPUPPCState *env = &cpu->env;
+int i;
+
+/* We've pulled in the raw esid and vsid values from the migration
+ * stream, but we need to recompute the page size pointers */
+for (i = 0; i < env->slb_nr; i++) {
+if (ppc_store_slb(cpu, i, env->slb[i].esid, env->slb[i].vsid) < 0) {
+/* Migration source had bad values in its SLB */
+return -1;
+}
+}
+
+return 0;
+}
+
 static const VMStateDescription vmstate_slb = {
 .name = "cpu/slb",
 .version_id = 1,
 .minimum_version_id = 1,
 .needed = slb_needed,
+.post_load = slb_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_INT32_EQUAL(env.slb_nr, PowerPCCPU),
 VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, MAX_SLB_ENTRIES),
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 5a6d33b..28ad361 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -19,6 +19,7 @@
  */
 #include "cpu.h"
 #include "exec/helper-proto.h"
+#include "qemu/error-report.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
 #include "mmu-hash64.h"
@@ -140,6 +141,8 @@ int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
 {
 CPUPPCState *env = &cpu->env;
 ppc_slb_t *slb = &env->slb[slot];
+const struct ppc_one_seg_page_size *sps = NULL;
+int i;
 
 if (slot >= env->slb_nr) {
 return -1; /* Bad slot number */
@@ -154,8 +157,29 @@ int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
 return -1; /* 1T segment on MMU that doesn't support it */
 }
 
+for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
+const struct ppc_one_seg_page_size *sps1 = &env->sps.sps[i];
+
+if (!sps1->page_shift) {
+break;
+}
+
+if ((vsid & SLB_VSID_LLP_MASK) == sps1->slb_enc) {
+sps = sps1;
+break;
+}
+}
+
+if (!sps) {
+error_report("Bad page size encoding in SLB store: slot "TARGET_FMT_lu
+ " esid 0x"TARGET_FMT_lx" vsid 0x"TARGET_FMT_lx,
+ slot, esid, vsid);
+return -1;
+}
+
 slb->esid = esid;
 slb->vsid = vsid;
+slb->sps = sps;
 
 LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
 " %016" PRIx64 "\n", __func__, slot, esid, vsid,
@@ -394,24 +418,6 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, 
hwaddr hash,
 return -1;
 }
 
-static uint64_t ppc_hash64_page_shift(ppc_slb_t *slb)
-{
-uint64_t epnshift;
-
-/* Page size according to the SLB, which we use to generate the
- * EPN for hash table lookup..  When we implement more recent MMU
- * extensions this 

[Qemu-devel] [PATCH 09/10] target-ppc: Helper to determine page size information from hpte alone

2016-01-24 Thread David Gibson
h_enter() in the spapr code needs to know the page size of the HPTE it's
about to insert.  Unlike other paths that do this, it doesn't have access
to the SLB, so at the moment it determines this with some open-coded
tests which assume POWER7 or POWER8 page size encodings.

To make this more flexible add ppc_hash64_hpte_page_shift_noslb() to
determine both the "base" page size per segment, and the individual
effective page size from an HPTE alone.

This means that the spapr code should now be able to handle any page size
listed in the env->sps table.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_hcall.c| 25 ++---
 target-ppc/mmu-hash64.c | 35 +++
 target-ppc/mmu-hash64.h |  3 +++
 3 files changed, 44 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index dedc7e0..a535c73 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -72,31 +72,18 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 target_ulong pte_index = args[1];
 target_ulong pteh = args[2];
 target_ulong ptel = args[3];
-target_ulong page_shift = 12;
+unsigned apshift, spshift;
 target_ulong raddr;
 target_ulong index;
 uint64_t token;
 
-/* only handle 4k and 16M pages for now */
-if (pteh & HPTE64_V_LARGE) {
-#if 0 /* We don't support 64k pages yet */
-if ((ptel & 0xf000) == 0x1000) {
-/* 64k page */
-} else
-#endif
-if ((ptel & 0xff000) == 0) {
-/* 16M page */
-page_shift = 24;
-/* lowest AVA bit must be 0 for 16M pages */
-if (pteh & 0x80) {
-return H_PARAMETER;
-}
-} else {
-return H_PARAMETER;
-}
+apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel, &spshift);
+if (!apshift) {
+/* Bad page size encoding */
+return H_PARAMETER;
 }
 
-raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1);
+raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);
 
 if (is_ram_address(spapr, raddr)) {
 /* Regular RAM - should have WIMG=0010 */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 2be04e9..db57a63 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -512,6 +512,41 @@ static unsigned hpte_page_shift(const struct 
ppc_one_seg_page_size *sps,
 return 0; /* Bad page size encoding */
 }
 
+unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
+  uint64_t pte0, uint64_t pte1,
+  unsigned *seg_page_shift)
+{
+CPUPPCState *env = &cpu->env;
+int i;
+
+if (!(pte0 & HPTE64_V_LARGE)) {
+*seg_page_shift = 12;
+return 12;
+}
+
+/*
+ * The encodings in env->sps need to be carefully chosen so that
+ * this gives an unambiguous result.
+ */
+for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
+const struct ppc_one_seg_page_size *sps = &env->sps.sps[i];
+unsigned shift;
+
+if (!sps->page_shift) {
+break;
+}
+
+shift = hpte_page_shift(sps, pte0, pte1);
+if (shift) {
+*seg_page_shift = sps->page_shift;
+return shift;
+}
+}
+
+*seg_page_shift = 0;
+return 0;
+}
+
 static hwaddr ppc_hash64_pte_raddr(unsigned page_shift, ppc_hash_pte64_t pte,
target_ulong eaddr)
 {
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index 293a951..34cf975 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -16,6 +16,9 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu, target_ulong 
index,
 void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
target_ulong pte_index,
target_ulong pte0, target_ulong pte1);
+unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
+  uint64_t pte0, uint64_t pte1,
+  unsigned *seg_page_shift);
 #endif
 
 /*
-- 
2.5.0




[Qemu-devel] [PATCH 05/10] target-ppc: Use actual page size encodings from HPTE

2016-01-24 Thread David Gibson
At present the 64-bit hash MMU code uses information from the SLB to
determine the page size of a translation.  We do need that information to
correctly look up the hash table.  However the MMU also allows a
possibly larger page size to be encoded into the HPTE itself, which is used
to populate the TLB.  At present qemu doesn't check that, and so doesn't
support the MPSS "Multiple Page Size per Segment" feature.

This makes a start on allowing this, by adding an hpte_page_shift()
function which looks up the page size of an HPTE.  We use this to validate
page sizes encodings on faults, and populate the qemu TLB with larger
page sizes when appropriate.

Signed-off-by: David Gibson 
---
 target-ppc/mmu-hash64.c | 74 ++---
 1 file changed, 70 insertions(+), 4 deletions(-)

diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 28ad361..bcad826 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -21,6 +21,7 @@
 #include "exec/helper-proto.h"
 #include "qemu/error-report.h"
 #include "sysemu/kvm.h"
+#include "qemu/error-report.h"
 #include "kvm_ppc.h"
 #include "mmu-hash64.h"
 
@@ -474,6 +475,43 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
 return pte_offset;
 }
 
+static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
+uint64_t pte0, uint64_t pte1)
+{
+int i;
+
+if (!(pte0 & HPTE64_V_LARGE)) {
+if (sps->page_shift != 12) {
+/* 4kiB page in a non 4kiB segment */
+return 0;
+}
+/* Normal 4kiB page */
+return 12;
+}
+
+for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
+const struct ppc_one_page_size *ps = &sps->enc[i];
+uint64_t mask;
+
+if (!ps->page_shift) {
+break;
+}
+
+if (ps->page_shift == 12) {
+/* L bit is set so this can't be a 4kiB page */
+continue;
+}
+
+mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
+
+if ((pte1 & mask) == ps->pte_enc) {
+return ps->page_shift;
+}
+}
+
+return 0; /* Bad page size encoding */
+}
+
 static hwaddr ppc_hash64_pte_raddr(unsigned page_shift, ppc_hash_pte64_t pte,
target_ulong eaddr)
 {
@@ -489,6 +527,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, 
target_ulong eaddr,
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = &cpu->env;
 ppc_slb_t *slb;
+unsigned apshift;
 hwaddr pte_offset;
 ppc_hash_pte64_t pte;
 int pp_prot, amr_prot, prot;
@@ -552,6 +591,28 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, 
target_ulong eaddr,
 qemu_log_mask(CPU_LOG_MMU,
 "found PTE at offset %08" HWADDR_PRIx "\n", pte_offset);
 
+/* Validate page size encoding */
+apshift = hpte_page_shift(slb->sps, pte.pte0, pte.pte1);
+if (!apshift) {
+error_report("Bad page size encoding in HPTE 0x%"PRIx64" - 0x%"PRIx64
+ " @ 0x%"HWADDR_PRIx, pte.pte0, pte.pte1, pte_offset);
+/* Treat it like a hash miss for the guest */
+if (rwx == 2) {
+cs->exception_index = POWERPC_EXCP_ISI;
+env->error_code = 0x4000;
+} else {
+cs->exception_index = POWERPC_EXCP_DSI;
+env->error_code = 0;
+env->spr[SPR_DAR] = eaddr;
+if (rwx == 1) {
+env->spr[SPR_DSISR] = 0x4200;
+} else {
+env->spr[SPR_DSISR] = 0x4000;
+}
+}
+return 1;
+}
+
 /* 5. Check access permissions */
 
 pp_prot = ppc_hash64_pte_prot(cpu, slb, pte);
@@ -604,10 +665,10 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, 
target_ulong eaddr,
 
 /* 7. Determine the real address from the PTE */
 
-raddr = ppc_hash64_pte_raddr(slb->sps->page_shift, pte, eaddr);
+raddr = ppc_hash64_pte_raddr(apshift, pte, eaddr);
 
 tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
- prot, mmu_idx, TARGET_PAGE_SIZE);
+ prot, mmu_idx, 1ULL << apshift);
 
 return 0;
 }
@@ -618,6 +679,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, 
target_ulong addr)
 ppc_slb_t *slb;
 hwaddr pte_offset;
 ppc_hash_pte64_t pte;
+unsigned apshift;
 
 if (msr_dr == 0) {
 /* In real mode the top 4 effective address bits are ignored */
@@ -634,8 +696,12 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, 
target_ulong addr)
 return -1;
 }
 
-return ppc_hash64_pte_raddr(slb->sps->page_shift, pte, addr)
-& TARGET_PAGE_MASK;
+apshift = hpte_page_shift(slb->sps, pte.pte0, pte.pte1);
+if (!apshift) {
+return -1;
+}
+
+return ppc_hash64_pte_raddr(apshift, pte, addr) & TARGET_PAGE_MASK;
 }
 
 void ppc_hash64_store_hpte(PowerPCCPU *cpu,
-- 
2.5.0




[Qemu-devel] [PATCH 06/10] target-ppc: Remove unused mmu models from ppc_tlb_invalidate_one

2016-01-24 Thread David Gibson
ppc_tlb_invalidate_one() has a big switch handling many different MMU
types.  However, most of those branches can never be reached:

It is called from 3 places: from remove_hpte() and h_protect() in
spapr_hcall.c (which always has a 64-bit hash MMU type), and from
helper_tlbie() in mmu_helper.c.

Calls to helper_tlbie() are generated from gen_tlbiel, gen_tlbiel and
gen_tlbiva.  The first two are only used with the PPC_MEM_TLBIE flag,
set only with 32-bit or 64-bit hash MMU models, and gen_tlbiva() is
used only on 440 and 460 models with the BookE mmu model.

These means the exhaustive list of MMU types which may call
ppc_tlb_invalidate_one() is: POWERPC_MMU_SOFT_6xx, POWERPC_MMU_601,
POWERPC_MMU_32B, POWERPC_MMU_SOFT_74xx, POWERPC_MMU_64B, POWERPC_MMU_2_03,
POWERPC_MMU_2_06, POWERPC_MMU_2_07 and POWERPC_MMU_BOOKE.

Clean up by removing logic for all other MMU types from
ppc_tlb_invalidate_one().

Signed-off-by: David Gibson 
---
 target-ppc/mmu_helper.c | 20 ++--
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index c040b17..82ebe5d 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1971,25 +1971,10 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, 
target_ulong addr)
 ppc6xx_tlb_invalidate_virt(env, addr, 1);
 }
 break;
-case POWERPC_MMU_SOFT_4xx:
-case POWERPC_MMU_SOFT_4xx_Z:
-ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
-break;
-case POWERPC_MMU_REAL:
-cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n");
-break;
-case POWERPC_MMU_MPC8xx:
-/* XXX: TODO */
-cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n");
-break;
 case POWERPC_MMU_BOOKE:
 /* XXX: TODO */
 cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n");
 break;
-case POWERPC_MMU_BOOKE206:
-/* XXX: TODO */
-cpu_abort(CPU(cpu), "BookE 2.06 MMU model is not implemented\n");
-break;
 case POWERPC_MMU_32B:
 case POWERPC_MMU_601:
 /* tlbie invalidate TLBs for all segments */
@@ -2031,9 +2016,8 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, 
target_ulong addr)
 break;
 #endif /* defined(TARGET_PPC64) */
 default:
-/* XXX: TODO */
-cpu_abort(CPU(cpu), "Unknown MMU model\n");
-break;
+/* Should never reach here with other MMU models */
+assert(0);
 }
 #else
 ppc_tlb_invalidate_all(env);
-- 
2.5.0




[Qemu-devel] [PATCH 02/10] target-ppc: Convert mmu-hash{32, 64}.[ch] from CPUPPCState to PowerPCCPU

2016-01-24 Thread David Gibson
Like a lot of places these files include a mixture of functions taking
both the older CPUPPCState *env and newer PowerPCCPU *cpu.  Move a step
closer to cleaning this up by standardizing on PowerPCCPU, except for the
helper_* functions which are called with the CPUPPCState * from tcg.

Callers and some related functions are updated as well, the boundaries of
what's changed here are a bit arbitrary.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_hcall.c| 31 ++-
 target-ppc/kvm.c|  2 +-
 target-ppc/mmu-hash32.c | 68 +++--
 target-ppc/mmu-hash32.h | 30 ++-
 target-ppc/mmu-hash64.c | 80 +
 target-ppc/mmu-hash64.h | 21 ++---
 target-ppc/mmu_helper.c | 13 
 7 files changed, 136 insertions(+), 109 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index c4ae255..4707196 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -160,7 +160,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 pte_index &= ~7ULL;
 token = ppc_hash64_start_access(cpu, pte_index);
 for (; index < 8; index++) {
-if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 
0) {
+if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) {
 break;
 }
 }
@@ -170,14 +170,14 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 }
 } else {
 token = ppc_hash64_start_access(cpu, pte_index);
-if (ppc_hash64_load_hpte0(env, token, 0) & HPTE64_V_VALID) {
+if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) {
 ppc_hash64_stop_access(token);
 return H_PTEG_FULL;
 }
 ppc_hash64_stop_access(token);
 }
 
-ppc_hash64_store_hpte(env, pte_index + index,
+ppc_hash64_store_hpte(cpu, pte_index + index,
   pteh | HPTE64_V_HPTE_DIRTY, ptel);
 
 args[0] = pte_index + index;
@@ -191,11 +191,12 @@ typedef enum {
 REMOVE_HW = 3,
 } RemoveResult;
 
-static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
+static RemoveResult remove_hpte(PowerPCCPU *cpu, target_ulong ptex,
 target_ulong avpn,
 target_ulong flags,
 target_ulong *vp, target_ulong *rp)
 {
+CPUPPCState *env = &cpu->env;
 uint64_t token;
 target_ulong v, r, rb;
 
@@ -203,9 +204,9 @@ static RemoveResult remove_hpte(CPUPPCState *env, 
target_ulong ptex,
 return REMOVE_PARM;
 }
 
-token = ppc_hash64_start_access(ppc_env_get_cpu(env), ptex);
-v = ppc_hash64_load_hpte0(env, token, 0);
-r = ppc_hash64_load_hpte1(env, token, 0);
+token = ppc_hash64_start_access(cpu, ptex);
+v = ppc_hash64_load_hpte0(cpu, token, 0);
+r = ppc_hash64_load_hpte1(cpu, token, 0);
 ppc_hash64_stop_access(token);
 
 if ((v & HPTE64_V_VALID) == 0 ||
@@ -215,7 +216,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, 
target_ulong ptex,
 }
 *vp = v;
 *rp = r;
-ppc_hash64_store_hpte(env, ptex, HPTE64_V_HPTE_DIRTY, 0);
+ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY, 0);
 rb = compute_tlbie_rb(v, r, ptex);
 ppc_tlb_invalidate_one(env, rb);
 return REMOVE_SUCCESS;
@@ -224,13 +225,12 @@ static RemoveResult remove_hpte(CPUPPCState *env, 
target_ulong ptex,
 static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
  target_ulong opcode, target_ulong *args)
 {
-CPUPPCState *env = &cpu->env;
 target_ulong flags = args[0];
 target_ulong pte_index = args[1];
 target_ulong avpn = args[2];
 RemoveResult ret;
 
-ret = remove_hpte(env, pte_index, avpn, flags,
+ret = remove_hpte(cpu, pte_index, avpn, flags,
   &args[0], &args[1]);
 
 switch (ret) {
@@ -271,7 +271,6 @@ static target_ulong h_remove(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
   target_ulong opcode, target_ulong *args)
 {
-CPUPPCState *env = &cpu->env;
 int i;
 
 for (i = 0; i < H_BULK_REMOVE_MAX_BATCH; i++) {
@@ -293,7 +292,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 return H_PARAMETER;
 }
 
-ret = remove_hpte(env, *tsh & H_BULK_REMOVE_PTEX, tsl,
+ret = remove_hpte(cpu, *tsh & H_BULK_REMOVE_PTEX, tsl,
   (*tsh & H_BULK_REMOVE_FLAGS) >> 26,
   &v, &r);
 
@@ -330,8 +329,8 @@ static target_ulong h_protect(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 }
 
 token = ppc_hash64_start_access(cpu, pte_index);
-v = ppc_hash64_load_hpte0(env, token, 0);
-r = ppc_hash64_load_hpte1(env, token, 0);
+v = ppc_has

[Qemu-devel] [PATCH 08/10] target-ppc: Add new TLB invalidate by HPTE call for hash64 MMUs

2016-01-24 Thread David Gibson
When HPTEs are removed or modified by hypercalls on spapr, we need to
invalidate the relevant pages in the qemu TLB.

Currently we do that by doing some complicated calculations to work out the
right encoding for the tlbie instruction, then passing that to
ppc_tlb_invalidate_one()... which totally ignores the argument and flushes
the whole tlb.

Avoid that by adding a new flush-by-hpte helper in mmu-hash64.c.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_hcall.c| 46 --
 target-ppc/mmu-hash64.c | 12 
 target-ppc/mmu-hash64.h |  3 +++
 3 files changed, 19 insertions(+), 42 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 4707196..dedc7e0 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -37,42 +37,6 @@ static void set_spr(CPUState *cs, int spr, target_ulong 
value,
 run_on_cpu(cs, do_spr_sync, &s);
 }
 
-static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
- target_ulong pte_index)
-{
-target_ulong rb, va_low;
-
-rb = (v & ~0x7fULL) << 16; /* AVA field */
-va_low = pte_index >> 3;
-if (v & HPTE64_V_SECONDARY) {
-va_low = ~va_low;
-}
-/* xor vsid from AVA */
-if (!(v & HPTE64_V_1TB_SEG)) {
-va_low ^= v >> 12;
-} else {
-va_low ^= v >> 24;
-}
-va_low &= 0x7ff;
-if (v & HPTE64_V_LARGE) {
-rb |= 1; /* L field */
-#if 0 /* Disable that P7 specific bit for now */
-if (r & 0xff000) {
-/* non-16MB large page, must be 64k */
-/* (masks depend on page size) */
-rb |= 0x1000;/* page encoding in LP field */
-rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */
-rb |= (va_low & 0xfe);   /* AVAL field */
-}
-#endif
-} else {
-/* 4kB page */
-rb |= (va_low & 0x7ff) << 12;   /* remaining 11b of AVA */
-}
-rb |= (v >> 54) & 0x300;/* B field */
-return rb;
-}
-
 static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index)
 {
 /*
@@ -198,7 +162,7 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, 
target_ulong ptex,
 {
 CPUPPCState *env = &cpu->env;
 uint64_t token;
-target_ulong v, r, rb;
+target_ulong v, r;
 
 if (!valid_pte_index(env, ptex)) {
 return REMOVE_PARM;
@@ -217,8 +181,7 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, 
target_ulong ptex,
 *vp = v;
 *rp = r;
 ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY, 0);
-rb = compute_tlbie_rb(v, r, ptex);
-ppc_tlb_invalidate_one(env, rb);
+ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
 return REMOVE_SUCCESS;
 }
 
@@ -322,7 +285,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 target_ulong pte_index = args[1];
 target_ulong avpn = args[2];
 uint64_t token;
-target_ulong v, r, rb;
+target_ulong v, r;
 
 if (!valid_pte_index(env, pte_index)) {
 return H_PARAMETER;
@@ -343,10 +306,9 @@ static target_ulong h_protect(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 r |= (flags << 55) & HPTE64_R_PP0;
 r |= (flags << 48) & HPTE64_R_KEY_HI;
 r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
-rb = compute_tlbie_rb(v, r, pte_index);
 ppc_hash64_store_hpte(cpu, pte_index,
   (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0);
-ppc_tlb_invalidate_one(env, rb);
+ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
 /* Don't need a memory barrier, due to qemu's global lock */
 ppc_hash64_store_hpte(cpu, pte_index, v | HPTE64_V_HPTE_DIRTY, r);
 return H_SUCCESS;
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index bcad826..2be04e9 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -725,3 +725,15 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu,
  env->htab_base + pte_index + HASH_PTE_SIZE_64 / 2, pte1);
 }
 }
+
+void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
+   target_ulong pte_index,
+   target_ulong pte0, target_ulong pte1)
+{
+/*
+ * XXX: given the fact that there are too many segments to
+ * invalidate, and we still don't have a tlb_flush_mask(env, n,
+ * mask) in QEMU, we just invalidate all TLBs
+ */
+tlb_flush(CPU(cpu), 1);
+}
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index 24fd2c4..293a951 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -13,6 +13,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong 
address, int rw,
 int mmu_idx);
 void ppc_hash64_store_hpte(PowerPCCPU *cpu, target_ulong index,
target_ulong pte0, target_ulong pte1);
+void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
+   target_ulong pte_in

[Qemu-devel] [PATCH 07/10] target-ppc: Split 44x tlbiva from ppc_tlb_invalidate_one()

2016-01-24 Thread David Gibson
Currently both the tlbiva instruction (used on 44x chips) and the tlbie
instruction (used on hash MMU chips) are both handled via
ppc_tlb_invalidate_one().  This is silly, because they're invoked from
different places, and do different things.

Clean this up by separating out the tlbiva instruction into its own
handling.  In fact the implementation is only a stub anyway.

Signed-off-by: David Gibson 
---
 target-ppc/helper.h |  1 +
 target-ppc/mmu_helper.c | 14 ++
 target-ppc/translate.c  |  2 +-
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 869be15..e5a8f7b 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -544,6 +544,7 @@ DEF_HELPER_2(74xx_tlbd, void, env, tl)
 DEF_HELPER_2(74xx_tlbi, void, env, tl)
 DEF_HELPER_FLAGS_1(tlbia, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(tlbie, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl)
 #if defined(TARGET_PPC64)
 DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl)
 DEF_HELPER_2(load_slb_esid, tl, env, tl)
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 82ebe5d..e9e0edb 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1971,10 +1971,6 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, 
target_ulong addr)
 ppc6xx_tlb_invalidate_virt(env, addr, 1);
 }
 break;
-case POWERPC_MMU_BOOKE:
-/* XXX: TODO */
-cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n");
-break;
 case POWERPC_MMU_32B:
 case POWERPC_MMU_601:
 /* tlbie invalidate TLBs for all segments */
@@ -2116,6 +2112,16 @@ void helper_tlbie(CPUPPCState *env, target_ulong addr)
 ppc_tlb_invalidate_one(env, addr);
 }
 
+void helper_tlbiva(CPUPPCState *env, target_ulong addr)
+{
+PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
+/* tlbiva instruciton only exists on BookE */
+assert(env->mmu_model == POWERPC_MMU_BOOKE);
+/* XXX: TODO */
+cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n");
+}
+
 /* Software driven TLBs management */
 /* PowerPC 602/603 software TLB load instructions helpers */
 static void do_6xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4be7eaa..a05a169 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -5904,7 +5904,7 @@ static void gen_tlbiva(DisasContext *ctx)
 }
 t0 = tcg_temp_new();
 gen_addr_reg_index(ctx, t0);
-gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
+gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
 tcg_temp_free(t0);
 #endif
 }
-- 
2.5.0




[Qemu-devel] [PATCH 10/10] target-ppc: Allow more page sizes for POWER7 & POWER8 in TCG

2016-01-24 Thread David Gibson
Now that the TCG and spapr code has been extended to allow (semi-)
arbitrary page encodings in the CPU's 'sps' table, we can add the many
page sizes supported by real POWER7 and POWER8 hardware that we previously
didn't support in TCG.

Signed-off-by: David Gibson 
---
 target-ppc/mmu-hash64.h |  2 ++
 target-ppc/translate_init.c | 32 
 2 files changed, 34 insertions(+)

diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index 34cf975..ab0f86b 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -48,6 +48,8 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
 #define SLB_VSID_LLP_MASK   (SLB_VSID_L | SLB_VSID_LP)
 #define SLB_VSID_4K 0xULL
 #define SLB_VSID_64K0x0110ULL
+#define SLB_VSID_16M0x0100ULL
+#define SLB_VSID_16G0x0120ULL
 
 /*
  * Hash page table definitions
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f6babd2..32b3679 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8104,6 +8104,36 @@ static Property powerpc_servercpu_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+#ifdef CONFIG_SOFTMMU
+static const struct ppc_segment_page_sizes POWER7_POWER8_sps = {
+.sps = {
+{
+.page_shift = 12, /* 4K */
+.slb_enc = 0,
+.enc = { { .page_shift = 12, .pte_enc = 0 },
+ { .page_shift = 16, .pte_enc = 0x7 },
+ { .page_shift = 24, .pte_enc = 0x38 }, },
+},
+{
+.page_shift = 16, /* 64K */
+.slb_enc = SLB_VSID_64K,
+.enc = { { .page_shift = 16, .pte_enc = 0x1 },
+ { .page_shift = 24, .pte_enc = 0x8 }, },
+},
+{
+.page_shift = 24, /* 16M */
+.slb_enc = SLB_VSID_16M,
+.enc = { { .page_shift = 24, .pte_enc = 0 }, },
+},
+{
+.page_shift = 34, /* 16G */
+.slb_enc = SLB_VSID_16G,
+.enc = { { .page_shift = 34, .pte_enc = 0x3 }, },
+},
+}
+};
+#endif /* CONFIG_SOFTMMU */
+
 static void init_proc_POWER7 (CPUPPCState *env)
 {
 init_proc_book3s_64(env, BOOK3S_CPU_POWER7);
@@ -8167,6 +8197,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
 pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+pcc->sps = &POWER7_POWER8_sps;
 #endif
 pcc->excp_model = POWERPC_EXCP_POWER7;
 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
@@ -8247,6 +8278,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 pcc->mmu_model = POWERPC_MMU_2_07;
 #if defined(CONFIG_SOFTMMU)
 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+pcc->sps = &POWER7_POWER8_sps;
 #endif
 pcc->excp_model = POWERPC_EXCP_POWER7;
 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
-- 
2.5.0




Re: [Qemu-devel] [PATCH RFC 6/7] net/filter: Add a default filter to each netdev

2016-01-24 Thread Jason Wang


On 01/22/2016 04:36 PM, zhanghailiang wrote:
> We add each netdev a default buffer filter, which the name is
> 'nop', and the default buffer filter is disabled, so it has
> no side effect for packets delivering in qemu net layer.
>
> The default buffer filter can be used by COLO or Micro-checkpoint,
> The reason we add the default filter is we hope to support
> hot add network during COLO state in future.
>
> Signed-off-by: zhanghailiang 
> ---
>  include/net/filter.h | 11 +++
>  net/dump.c   |  2 --
>  net/filter.c | 15 ++-
>  net/net.c| 18 ++
>  4 files changed, 43 insertions(+), 3 deletions(-)
>
> diff --git a/include/net/filter.h b/include/net/filter.h
> index c7bd8f9..2043609 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -22,6 +22,16 @@
>  #define NETFILTER_CLASS(klass) \
>  OBJECT_CLASS_CHECK(NetFilterClass, (klass), TYPE_NETFILTER)
>  
> +#define DEFAULT_FILTER_NAME "nop"

Maybe DEFAULT_FILTER_TYPE?

> +
> +#define TYPE_FILTER_BUFFER "filter-buffer"
> +#define TYPE_FILTER_DUMP "filter-dump"
> +
> +#define NETFILTER_ID_BUFFER 1
> +#define NETFILTER_ID_DUMP 2
> +
> +extern const char *const netfilter_type_lookup[];
> +
>  typedef void (FilterSetup) (NetFilterState *nf, Error **errp);
>  typedef void (FilterCleanup) (NetFilterState *nf);
>  /*
> @@ -55,6 +65,7 @@ struct NetFilterState {
>  char *netdev_id;
>  NetClientState *netdev;
>  NetFilterDirection direction;
> +bool is_default;
>  bool enabled;
>  QTAILQ_ENTRY(NetFilterState) next;
>  };
> diff --git a/net/dump.c b/net/dump.c
> index 88d9582..82727a6 100644
> --- a/net/dump.c
> +++ b/net/dump.c
> @@ -229,8 +229,6 @@ int net_init_dump(const NetClientOptions *opts, const 
> char *name,
>  
>  /* Dumping via filter */
>  
> -#define TYPE_FILTER_DUMP "filter-dump"
> -
>  #define FILTER_DUMP(obj) \
>  OBJECT_CHECK(NetFilterDumpState, (obj), TYPE_FILTER_DUMP)
>  
> diff --git a/net/filter.c b/net/filter.c
> index 4d96301..a126a3b 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -21,6 +21,11 @@
>  #include "qapi/qmp-input-visitor.h"
>  #include "monitor/monitor.h"
>  
> +const char *const netfilter_type_lookup[] = {
> +[NETFILTER_ID_BUFFER] = TYPE_FILTER_BUFFER,
> +[NETFILTER_ID_DUMP] = TYPE_FILTER_DUMP,
> +};
> +
>  ssize_t qemu_netfilter_receive(NetFilterState *nf,
> NetFilterDirection direction,
> NetClientState *sender,
> @@ -200,7 +205,7 @@ static void netfilter_complete(UserCreatable *uc, Error 
> **errp)
>  NetFilterClass *nfc = NETFILTER_GET_CLASS(uc);
>  int queues;
>  Error *local_err = NULL;
> -
> +char *path = object_get_canonical_path_component(OBJECT(nf));
>  
>  if (!nf->netdev_id) {
>  error_setg(errp, "Parameter 'netdev' is required");
> @@ -225,6 +230,14 @@ static void netfilter_complete(UserCreatable *uc, Error 
> **errp)
>  }
>  
>  nf->netdev = ncs[0];
> +nf->is_default = !strcmp(path, DEFAULT_FILTER_NAME);
> +/*
> +* For the default buffer filter, it will be disabled by default,
> +* So it will not buffer any packets.
> +*/
> +if (nf->is_default) {
> +nf->enabled = false;
> +}

This seems not very elegant. Besides DEFAULT_FILTER_NAME(TYPE), we may
also want a DEFAULT_FILTER_PROPERTIES? Then you can store the "status"
into properties.

>  
>  if (nfc->setup) {
>  nfc->setup(nf, &local_err);
> diff --git a/net/net.c b/net/net.c
> index ec43105..9630234 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -76,6 +76,12 @@ const char *host_net_devices[] = {
>  
>  int default_net = 1;
>  
> +/*
> + * FIXME: Export this with an option for users to control
> + * this with comand line ?

This could be done in the future.

> + */
> +int default_netfilter = NETFILTER_ID_BUFFER;

Why not just use a string here?

> +
>  /***/
>  /* network device redirectors */
>  
> @@ -1032,6 +1038,18 @@ static int net_client_init1(const void *object, int 
> is_netdev, Error **errp)
>  }
>  return -1;
>  }
> +
> +if (is_netdev) {
> +const Netdev *netdev = object;
> +/*
> +* Here we add each netdev a default filter whose name is 'nop',
> +* it will disabled by default, Users can enable it when necessary.
> +*/

If we support default properties, the above comment could be removed.

> +netdev_add_filter(netdev->id,
> +  netfilter_type_lookup[default_netfilter],
> +  DEFAULT_FILTER_NAME,

I believe some logic to generate id automatically is needed here.

> +  errp);
> +}
>  return 0;
>  }
>  




[Qemu-devel] [PATCH 00/10] Clean up page size handling for ppc 64-bit hash MMUs with TCG

2016-01-24 Thread David Gibson
Encoding of page sizes on 64-bit hash MMUs for Power is rather arcane,
involving control bits in both the SLB and HPTE.  At present we
support a few of the options, but far fewer than real hardware.

We're able to get away with that in practice, because guests use a
device tree property to determine which page sizes are available and
we are setting that to match.  However, the fact that the actual code
doesn't necessarily what we put into the table of available page sizes
is another ugliness.

This series makes a number of cleanups to the page size handling.  The
upshot is that afterwards the softmmu code operates off the same page
size encoding table that is advertised to the guests, ensuring that
they will be in sync.

Finally, we extend the table of allowed sizes for POWER7 and POWER8 to
include the options allowed in hardware (including MPSS).  We can fix
other hash MMU based CPUs in future if anyone cares enough.

Please review, and I'll fold into ppc-for-2.6 for my next pull.

Changes since RFC:
  * Moved lookup of SLB encodings table from SLB lookup time to SLB
store time

David Gibson (10):
  target-ppc: Remove unused kvmppc_read_segment_page_sizes() stub
  target-ppc: Convert mmu-hash{32,64}.[ch] from CPUPPCState to
PowerPCCPU
  target-ppc: Rework ppc_store_slb
  target-ppc: Rework SLB page size lookup
  target-ppc: Use actual page size encodings from HPTE
  target-ppc: Remove unused mmu models from ppc_tlb_invalidate_one
  target-ppc: Split 44x tlbiva from ppc_tlb_invalidate_one()
  target-ppc: Add new TLB invalidate by HPTE call for hash64 MMUs
  target-ppc: Helper to determine page size information from hpte alone
  target-ppc: Allow more page sizes for POWER7 & POWER8 in TCG

 hw/ppc/spapr_hcall.c| 102 
 target-ppc/cpu.h|   1 +
 target-ppc/helper.h |   1 +
 target-ppc/kvm.c|   2 +-
 target-ppc/kvm_ppc.h|   5 -
 target-ppc/machine.c|  20 
 target-ppc/mmu-hash32.c |  68 ++-
 target-ppc/mmu-hash32.h |  30 ++---
 target-ppc/mmu-hash64.c | 286 
 target-ppc/mmu-hash64.h |  30 +++--
 target-ppc/mmu_helper.c |  59 -
 target-ppc/translate.c  |   2 +-
 target-ppc/translate_init.c |  32 +
 13 files changed, 389 insertions(+), 249 deletions(-)

-- 
2.5.0




Re: [Qemu-devel] [PATCH RFC 5/7] filter-buffer: Accept zero interval

2016-01-24 Thread Jason Wang


On 01/22/2016 04:36 PM, zhanghailiang wrote:
> We may want to accept zero interval when VM FT solutions like MC
> or COLO use this filter to release packets on demand.
>
> Signed-off-by: zhanghailiang 
> Reviewed-by: Yang Hongyang 
> ---
>  net/filter-buffer.c | 10 --
>  1 file changed, 10 deletions(-)

Looks a independent patch of this rfc series.

>
> diff --git a/net/filter-buffer.c b/net/filter-buffer.c
> index 57be149..12e0c87 100644
> --- a/net/filter-buffer.c
> +++ b/net/filter-buffer.c
> @@ -103,16 +103,6 @@ static void filter_buffer_setup(NetFilterState *nf, 
> Error **errp)
>  {
>  FilterBufferState *s = FILTER_BUFFER(nf);
>  
> -/*
> - * We may want to accept zero interval when VM FT solutions like MC
> - * or COLO use this filter to release packets on demand.
> - */
> -if (!s->interval) {
> -error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "interval",
> -   "a non-zero interval");
> -return;
> -}
> -
>  s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
>  if (s->interval) {
>  timer_init_us(&s->release_timer, QEMU_CLOCK_VIRTUAL,




Re: [Qemu-devel] [PATCH RFC 4/7] net/filter: Introduce a helper to add a filter to the netdev

2016-01-24 Thread Jason Wang


On 01/22/2016 04:36 PM, zhanghailiang wrote:
> Signed-off-by: zhanghailiang 

Commit log please.

> ---
>  include/net/filter.h |  5 +
>  net/filter.c | 63 
> 
>  2 files changed, 68 insertions(+)
>
> diff --git a/include/net/filter.h b/include/net/filter.h
> index d797ee4..c7bd8f9 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -81,4 +81,9 @@ static inline bool qemu_need_skip_netfilter(NetFilterState 
> *nf)
>  
>  void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
>  
> +void netdev_add_filter(const char *netdev_id,
> +   const char *filter_type,
> +   const char *id,
> +   Error **errp);
> +
>  #endif /* QEMU_NET_FILTER_H */
> diff --git a/net/filter.c b/net/filter.c
> index f4933cc..4d96301 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -16,6 +16,10 @@
>  #include "qom/object_interfaces.h"
>  #include "qemu/iov.h"
>  #include "qapi/string-output-visitor.h"
> +#include "qapi/qmp/qdict.h"
> +#include "qapi/qmp-output-visitor.h"
> +#include "qapi/qmp-input-visitor.h"
> +#include "monitor/monitor.h"
>  
>  ssize_t qemu_netfilter_receive(NetFilterState *nf,
> NetFilterDirection direction,
> @@ -232,6 +236,65 @@ static void netfilter_complete(UserCreatable *uc, Error 
> **errp)
>  QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next);
>  }
>  
> +/*
> +* This will be used by COLO or MC FT, for which they will need
> +* to buffer the packets of VM's net devices, Here we add a default
> +* buffer filter for each netdev. The name of default buffer filter is
> +* 'nop'
> +*/
> +void netdev_add_filter(const char *netdev_id,
> +   const char *filter_type,
> +   const char *id,
> +   Error **errp)
> +{
> +QmpOutputVisitor *qov;
> +QmpInputVisitor *qiv;
> +Visitor *ov, *iv;
> +QObject *obj = NULL;
> +QDict *qdict;
> +void *dummy = NULL;
> +NetClientState *nc = qemu_find_netdev(netdev_id);
> +Error *err = NULL;
> +
> +/* FIXME: Not support multiple queues */
> +if (!nc || nc->queue_index > 1) {
> +return;
> +}
> +/* Not support vhost-net */
> +if (get_vhost_net(nc)) {
> +return;
> +}
> +
> +qov = qmp_output_visitor_new();
> +ov = qmp_output_get_visitor(qov);
> +visit_start_struct(ov,  &dummy, NULL, NULL, 0, &err);
> +if (err) {
> +goto out;
> +}
> +visit_type_str(ov, &nc->name, "netdev", &err);
> +if (err) {
> +goto out;
> +}
> +visit_end_struct(ov, &err);
> +if (err) {
> +goto out;
> +}
> +obj = qmp_output_get_qobject(qov);
> +g_assert(obj != NULL);
> +qdict = qobject_to_qdict(obj);
> +qmp_output_visitor_cleanup(qov);
> +
> +qiv = qmp_input_visitor_new(obj);
> +iv = qmp_input_get_visitor(qiv);
> +object_add(filter_type, id, qdict, iv, &err);
> +qmp_input_visitor_cleanup(qiv);
> +qobject_decref(obj);
> +out:
> +if (err) {
> +error_propagate(errp, err);
> +}
> +}
> +
>  static void netfilter_finalize(Object *obj)
>  {
>  NetFilterState *nf = NETFILTER(obj);




Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-24 Thread Hailiang Zhang

On 2016/1/25 9:59, Hailiang Zhang wrote:

On 2016/1/22 18:38, Daniel P. Berrange wrote:

On Fri, Jan 22, 2016 at 06:35:48PM +0800, Hailiang Zhang wrote:

On 2016/1/22 18:07, Daniel P. Berrange wrote:

On Fri, Jan 22, 2016 at 04:36:44PM +0800, zhanghailiang wrote:

This series is a prerequisite for COLO, here we add each netdev
a default buffer filter, it is disabled by default, and has
no side effect for delivering packets in net layer.


Why can't whatever is launching QEMU just setup filters explicitly
if they want to use COLO ? I'm not seeing an obvious compelling
reason to add this by default and then add extra code to deal
with special casing its behaviour.



The main reason is, we hope to support hot add network during VM's COLO
lifetime in the future. (I'm not quite sure if this usage case is really exist,
but we don't want the VM in COLO state has too many limitations.)

Maybe add an option that users can control if they want to use COLO or not is 
more
acceptable ? With this option, we can decide whether to add the default filter 
or not.
Or, we could dynamically add filter while users ask to go into COLO state for 
VM.
(We have discussed this before in community, and Jason suggested me to add 
default
filter for each netdev to support hot-add network during COLO state).

What's your suggestion ?


Why can't the app hot-adding the network interface also configure a
filter at that time if they're using COLO ?



Yes, they can certainly do that, but they will need to do more works:
1) netdev_add/device_add add NIC 2) identify if VM is in COLO state
3) if step 2) is YES, object-add filter for the new NIC.



Er, i have forgotten something, we have to do some other
works for COLO if we didn't append each netdev a default netfilter.
While do failover work, we should consider to remove the extra filters
or keep them if the users decide if they continue another COLO lifetime
for VM.

Thanks,
Hailiang


Is this acceptable ?




Regards,
Daniel









Re: [Qemu-devel] [PATCH RFC 7/7] net/filter: prevent the default filter to be deleted

2016-01-24 Thread Jason Wang


On 01/22/2016 04:36 PM, zhanghailiang wrote:
> Signed-off-by: zhanghailiang 
> ---
>  net/filter.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/net/filter.c b/net/filter.c
> index a126a3b..4aafff0 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -323,11 +323,19 @@ static void netfilter_finalize(Object *obj)
>  g_free(nf->netdev_id);
>  }
>  
> +static bool netfilter_can_be_deleted(UserCreatable *uc, Error **errp)
> +{
> +NetFilterState *nf = NETFILTER(uc);
> +/* Forbid the default filter to be deleted */
> +return !nf->is_default;
> +}
> +
>  static void netfilter_class_init(ObjectClass *oc, void *data)
>  {
>  UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
>  
>  ucc->complete = netfilter_complete;
> +ucc->can_be_deleted = netfilter_can_be_deleted;
>  }
>  
>  static const TypeInfo netfilter_info = {

This looks unnecessary. As I replied in previous mails, there's no need
to differ default netfilter from others. For COLO specifically, I know
it's a kind of mis-configuration you want to avoid, but that's not the
business of qemu. (Even if this is accepted, user could still mis
configure the netfitler that can break COLO).




[Qemu-devel] Migrating decrementer (was: Re: [PATCH 4/4] target-ppc: ensure we include the decrementer value during migration)

2016-01-24 Thread Mark Cave-Ayland
On 18/01/16 04:51, David Gibson wrote:

> On Fri, Jan 15, 2016 at 05:46:10PM +, Mark Cave-Ayland wrote:
>> On 12/01/16 02:44, David Gibson wrote:
>>
> In other words, isn't this just skipping the decrementer interrupts at
> the qemu level rather than the guest level?
>
> It seems that instead we should be reconstructing the decrementer on
> the destination based on an offset from the timebase.

 Well I haven't really looked at how time warping works during in
 migration for QEMU, however this seems to be the method used by
 hw/ppc/ppc.c's timebase_post_load() function but my understanding is
 that this isn't currently available for the g3beige/mac99 machines?
>>>
>>> Ah.. yes, it looks like the timebase migration stuff is only hooked in
>>> on the pseries machine type.  As far as I can tell it should be
>>> trivial to add it to other machines though - it doesn't appear to rely
>>> on anything outside the common ppc timebase stuff.
>>>
 Should the patch in fact do this but also add decrementer support? And
 if it did, would this have a negative effect on pseries?
>>>
>>> Yes, I think that's the right approach.  Note that rather than
>>> duplicating the logic to adjust the decrementer over migration, it
>>> should be possible to encode the decrementer as a diff from the
>>> timebase across the migration.
>>>
>>> In fact.. I'm not sure it ever makes sense to store the decrementer
>>> value as a direct value, since it's constantly changing - probably
>>> makes more sense to derive it from the timebase whenever it is needed.
>>>
>>> As far as I know that should be fine for pseries.  I think the current
>>> behaviour is probably technically wrong for pseries as well, but the
>>> timing code of our Linux guests is robust enough to handle a small
>>> displacement to the time of the next decrementer interrupt.
>>
>> I've had a bit of an experiment trying to implement something suitable,
>> but I'm not 100% certain I've got this right.
>>
>> >From the code my understanding is that the timebase is effectively
>> free-running and so if a migration takes 5s then you use tb_offset to
>> calculate the difference between the timebase before migration, and
>> subsequently apply the offset for all future reads of the timebase for
>> the lifetime of the CPU (i.e. the migrated guest is effectively living
>> at a point in the past where the timebase is consistent).
> 
> Um.. no.  At least in the usual configuration, the timebase represents
> real, wall-clock time, so we expect it to jump forward across the
> migration downtime.  This is important because the guest will use the
> timebase to calculate real time differences.
> 
> However, the absolute value of the timebase may be different on the
> *host* between source and destination for migration.  So what we need
> to do is before migration we work out the delta between host and guest
> notions of wall clock time (as defined by the guest timebase), and
> transfer that in the migration stream.
> 
> On the destination we initialize the guest timebase so that the guest
> maintains the same realtime offset from the host.  This means that as
> long as source and destination system time is synchronized, guest
> real-time tracking will continue correctly across the migration.
> 
> We do also make sure that the guest timebase never goes backwards, but
> that would only happen if the source and destination host times were
> badly out of sync.

I had a poke at trying to include the timebase state in the Mac machines
but found that enabling this caused migration to freeze, even on top of
my existing (known working) patchset.

Looking closer at the code, I don't think it can work on an x86 TCG host
in its current form since the host/guest clocks are used interchangeably
in places, e.g. in timebase_pre_save() we have this:

uint64_t ticks = cpu_get_host_ticks();
...
tb->guest_timebase = ticks + first_ppc_cpu->env.tb_env->tb_offset;

So this implies that guest_timebase is set in higher resolution host
ticks. But then in timebase_post_load() we have this:

migration_duration_tb = muldiv64(migration_duration_ns, freq,
NANOSECONDS_PER_SECOND);

which calculates the migration time in timebase ticks but then:

guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb);
tb_off_adj = guest_tb - cpu_get_host_ticks();

which mixes tb_remote->guest_timebase in host ticks with
migration_duration_tb in timebase ticks.

I think that tb_off_adj should be in host ticks so should
migration_duration_tb be dropped and guest_tb be calculated from
migration_duration_ns instead? At least given the current mixing of host
ticks and timebase ticks, I think this can only work correctly on PPC
where the two are the same.

One other thing I noticed is that this code "broke" my normal testing
pattern when I tend to launch qemu-system-ppc with -loadvm foo -S with
the machine stopped. In this case the migration duration calculation is
performed at the m

Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-24 Thread Hailiang Zhang

On 2016/1/25 11:32, Jason Wang wrote:



On 01/22/2016 06:07 PM, Daniel P. Berrange wrote:

On Fri, Jan 22, 2016 at 04:36:44PM +0800, zhanghailiang wrote:

This series is a prerequisite for COLO, here we add each netdev
a default buffer filter, it is disabled by default, and has
no side effect for delivering packets in net layer.

Why can't whatever is launching QEMU just setup filters explicitly
if they want to use COLO ? I'm not seeing an obvious compelling
reason to add this by default and then add extra code to deal
with special casing its behaviour.


Two things here I think. The first is the management role for COLO,
maybe it's time to discuss it now. And if management can do this, it's


Yes, better to confirm it as early as possible, the later COLO based on
proxy also have such problem.


ok for not implementing default filter now. Second is the default filter
itself, I still think it's not bad to have it for the future, and with
the ability to specify, change or disable the default filter. This could
simplify management and testing.

Back to this series, it mixes several things (bugs fixings, new 'status'
filed, default filter implementation, and a special handling for
filter-buffer). Better split them.



OK, i will do that, thanks.


Thanks



Besides, patch 1 fixes the ouput information of 'info network' command
for filter.

zhanghailiang (7):
   net/filter: Fix the output information for command 'info network'
   net/filter: Add a 'status' property for filter object
   net/filter: Skip the disabled filter when delivering packets
   net/filter: Introduce a helper to add a filter to the netdev
   filter-buffer: Accept zero interval
   net/filter: Add a default filter to each netdev
   net/filter: prevent the default filter to be deleted

  include/net/filter.h |  25 +++-
  net/dump.c   |   2 -
  net/filter-buffer.c  |  10 
  net/filter.c | 163 +--
  net/net.c|  27 -
  5 files changed, 194 insertions(+), 33 deletions(-)

Regards,
Daniel



.







Re: [Qemu-devel] [PATCH RFC 1/7] net/filter: Fix the output information for command 'info network'

2016-01-24 Thread Hailiang Zhang

On 2016/1/25 13:01, Jason Wang wrote:



On 01/22/2016 04:36 PM, zhanghailiang wrote:

The properties of netfilter object could be changed by 'qom-set'
command, but the output of 'info network' command is not updated,
because it got the old information through nf->info_str, it will
not be updated while we change the value of netfilter's property.

Here we split a the helper function that could colletct the output
information for filter, and also remove the useless member
'info_str' from struct NetFilterState.

Signed-off-by: zhanghailiang 
---


Looks like a bug fix. Please send as a independent formal patch and
better cc Markus and Eric for better reviewing.



OK, by the way, i didn't see there was a corresponding qmp command
for 'info network', is the hmp_info_network just an experimental command ?


Thanks


  include/net/filter.h |  3 ++-
  net/filter.c | 47 ++-
  net/net.c|  5 -
  3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/include/net/filter.h b/include/net/filter.h
index 2deda36..8a20138 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -55,7 +55,6 @@ struct NetFilterState {
  char *netdev_id;
  NetClientState *netdev;
  NetFilterDirection direction;
-char info_str[256];
  QTAILQ_ENTRY(NetFilterState) next;
  };

@@ -74,4 +73,6 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
  int iovcnt,
  void *opaque);

+void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
+
  #endif /* QEMU_NET_FILTER_H */
diff --git a/net/filter.c b/net/filter.c
index 5d90f83..40254bd 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -128,6 +128,31 @@ static void netfilter_init(Object *obj)
   NULL);
  }

+void netfilter_print_info(NetFilterState *nf, char *output_str, int size)
+{
+char *str, *info;
+ObjectProperty *prop;
+ObjectPropertyIterator iter;
+StringOutputVisitor *ov;
+
+/* generate info str */
+object_property_iter_init(&iter, OBJECT(nf));
+while ((prop = object_property_iter_next(&iter))) {
+if (!strcmp(prop->name, "type")) {
+continue;
+}
+ov = string_output_visitor_new(false);
+object_property_get(OBJECT(nf), string_output_get_visitor(ov),
+prop->name, NULL);
+str = string_output_get_string(ov);
+string_output_visitor_cleanup(ov);
+info = g_strdup_printf(",%s=%s", prop->name, str);
+g_strlcat(output_str, info, size);
+g_free(str);
+g_free(info);
+}
+}
+
  static void netfilter_complete(UserCreatable *uc, Error **errp)
  {
  NetFilterState *nf = NETFILTER(uc);
@@ -135,10 +160,7 @@ static void netfilter_complete(UserCreatable *uc, Error 
**errp)
  NetFilterClass *nfc = NETFILTER_GET_CLASS(uc);
  int queues;
  Error *local_err = NULL;
-char *str, *info;
-ObjectProperty *prop;
-ObjectPropertyIterator iter;
-StringOutputVisitor *ov;
+

  if (!nf->netdev_id) {
  error_setg(errp, "Parameter 'netdev' is required");
@@ -172,23 +194,6 @@ static void netfilter_complete(UserCreatable *uc, Error 
**errp)
  }
  }
  QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next);
-
-/* generate info str */
-object_property_iter_init(&iter, OBJECT(nf));
-while ((prop = object_property_iter_next(&iter))) {
-if (!strcmp(prop->name, "type")) {
-continue;
-}
-ov = string_output_visitor_new(false);
-object_property_get(OBJECT(nf), string_output_get_visitor(ov),
-prop->name, errp);
-str = string_output_get_string(ov);
-string_output_visitor_cleanup(ov);
-info = g_strdup_printf(",%s=%s", prop->name, str);
-g_strlcat(nf->info_str, info, sizeof(nf->info_str));
-g_free(str);
-g_free(info);
-}
  }

  static void netfilter_finalize(Object *obj)
diff --git a/net/net.c b/net/net.c
index 87dd356..87de7c0 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1198,9 +1198,12 @@ void print_net_client(Monitor *mon, NetClientState *nc)
  }
  QTAILQ_FOREACH(nf, &nc->filters, next) {
  char *path = object_get_canonical_path_component(OBJECT(nf));
+char info[256] = { 0 };
+
+netfilter_print_info(nf, info, sizeof(info));
  monitor_printf(mon, "  - %s: type=%s%s\n", path,
 object_get_typename(OBJECT(nf)),
-   nf->info_str);
+   info);
  g_free(path);
  }
  }



.







Re: [Qemu-devel] [PATCH RFC 3/7] net/filter: Skip the disabled filter when delivering packets

2016-01-24 Thread Hailiang Zhang

On 2016/1/25 13:04, Jason Wang wrote:



On 01/22/2016 05:32 PM, Wen Congyang wrote:

On 01/22/2016 04:36 PM, zhanghailiang wrote:

If the filter is disabled, don't go through it.

Signed-off-by: zhanghailiang 
---
  include/net/filter.h | 5 +
  net/net.c| 4 
  2 files changed, 9 insertions(+)

diff --git a/include/net/filter.h b/include/net/filter.h
index 9ed5ec6..d797ee4 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -74,6 +74,11 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
  int iovcnt,
  void *opaque);

+static inline bool qemu_need_skip_netfilter(NetFilterState *nf)
+{
+return nf->enabled ? false : true;
+}
+
  void netfilter_print_info(NetFilterState *nf, char *output_str, int size);

  #endif /* QEMU_NET_FILTER_H */
diff --git a/net/net.c b/net/net.c
index 87de7c0..ec43105 100644
--- a/net/net.c
+++ b/net/net.c
@@ -581,6 +581,10 @@ static ssize_t filter_receive_iov(NetClientState *nc,
  NetFilterState *nf = NULL;

  QTAILQ_FOREACH(nf, &nc->filters, next) {
+/* Don't go through filter if it is off */
+if (qemu_need_skip_netfilter(nf)) {
+continue;
+}
  ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
   iovcnt, sent_cb);
  if (ret) {


qemu_netfilter_pass_to_next() shoule also be updated.


Then let's better move it to qemu_netfiler_receive().



Good idea, i will fix it, thanks.



Thanks
Wen Congyang







.







  1   2   >