Re: [Qemu-devel] [PATCH COLO-Frame v9 04/32] migration: Add state records for migration incoming

2015-10-10 Thread zhanghailiang

On 2015/10/10 0:18, Dr. David Alan Gilbert wrote:

* zhanghailiang (zhang.zhanghaili...@huawei.com) wrote:

For migration destination, we also need to know its state,
we will use it in COLO.

Here we add a new member 'state' for MigrationIncomingState,
and also use migrate_set_state() to modify its value.
We fix the first parameter of migrate_set_state(), and make it
public.

Signed-off-by: zhanghailiang 


Reviewed-by: Dr. David Alan Gilbert 

You should split this patch out and submit it by itself; it can go in
without waiting for any other COLO bits.



Ok, will do that.
Besides,  there is still an independent patch in this series.
"[PATCH COLO-Frame v9 07/32] migration: Rename the'file' member of 
MigrationState and
MigrationIncomingState", i know you have done the same thing in your postcopy 
series.
(I noticed that you didn't change the 'file' member in MigartionState ...)
Could you send that modification as an independent series ? So that i can drop 
that patch in
next version.
BTW, is there any plan to merge your postcopy series ?

Thanks,
zhanghailiang


Dave


---
  include/migration/migration.h |  3 +++
  migration/migration.c | 38 +++---
  2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index 05de3a1..a62068f 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -50,6 +50,7 @@ typedef QLIST_HEAD(, LoadStateEntry) LoadStateEntry_Head;
  struct MigrationIncomingState {
  QEMUFile *file;

+int state;
  /* See savevm.c */
  LoadStateEntry_Head loadvm_handlers;
  };
@@ -82,6 +83,8 @@ struct MigrationState
  int64_t dirty_sync_count;
  };

+void migrate_set_state(int *state, int old_state, int new_state);
+
  void process_incoming_migration(QEMUFile *f);

  void qemu_start_incoming_migration(const char *uri, Error **errp);
diff --git a/migration/migration.c b/migration/migration.c
index 593cac0..98133f1 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -89,6 +89,7 @@ MigrationIncomingState 
*migration_incoming_state_new(QEMUFile* f)
  {
  mis_current = g_malloc0(sizeof(MigrationIncomingState));
  mis_current->file = f;
+mis_current->state = MIGRATION_STATUS_NONE;
  QLIST_INIT(&mis_current->loadvm_handlers);

  return mis_current;
@@ -270,11 +271,13 @@ void qemu_start_incoming_migration(const char *uri, Error 
**errp)
  static void process_incoming_migration_co(void *opaque)
  {
  QEMUFile *f = opaque;
+MigrationIncomingState *mis;
  Error *local_err = NULL;
  int ret;

-migration_incoming_state_new(f);
-migrate_generate_event(MIGRATION_STATUS_ACTIVE);
+mis = migration_incoming_state_new(f);
+migrate_set_state(&mis->state, MIGRATION_STATUS_NONE,
+  MIGRATION_STATUS_ACTIVE);
  ret = qemu_loadvm_state(f);

  qemu_fclose(f);
@@ -282,12 +285,14 @@ static void process_incoming_migration_co(void *opaque)
  migration_incoming_state_destroy();

  if (ret < 0) {
-migrate_generate_event(MIGRATION_STATUS_FAILED);
+migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
+  MIGRATION_STATUS_FAILED);
  error_report("load of migration failed: %s", strerror(-ret));
  migrate_decompress_threads_join();
  exit(EXIT_FAILURE);
  }
-migrate_generate_event(MIGRATION_STATUS_COMPLETED);
+migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
+  MIGRATION_STATUS_COMPLETED);
  qemu_announce_self();

  /* Make sure all file formats flush their mutable metadata */
@@ -543,9 +548,9 @@ void qmp_migrate_set_parameters(bool has_compress_level,

  /* shared migration helpers */

-static void migrate_set_state(MigrationState *s, int old_state, int new_state)
+void migrate_set_state(int *state, int old_state, int new_state)
  {
-if (atomic_cmpxchg(&s->state, old_state, new_state) == old_state) {
+if (atomic_cmpxchg(state, old_state, new_state) == old_state) {
  trace_migrate_set_state(new_state);
  migrate_generate_event(new_state);
  }
@@ -574,7 +579,7 @@ static void migrate_fd_cleanup(void *opaque)
  if (s->state != MIGRATION_STATUS_COMPLETED) {
  qemu_savevm_state_cancel();
  if (s->state == MIGRATION_STATUS_CANCELLING) {
-migrate_set_state(s, MIGRATION_STATUS_CANCELLING,
+migrate_set_state(&s->state, MIGRATION_STATUS_CANCELLING,
MIGRATION_STATUS_CANCELLED);
  }
  }
@@ -586,7 +591,8 @@ void migrate_fd_error(MigrationState *s)
  {
  trace_migrate_fd_error();
  assert(s->file == NULL);
-migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_FAILED);
+migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
+  MIGRATION_STATUS_FAILED);
  notifier_list_notify(&migration_state_notifiers, s);
  }

@@ -602,7 +608,

Re: [Qemu-devel] [PATCH v4 2/3] pci: Update pci_regs header

2015-10-10 Thread Knut Omang
On Wed, 2015-10-07 at 16:32 +0300, Marcel Apfelbaum wrote:
> On 09/12/2015 03:36 PM, Knut Omang wrote:
> > Merge in new definitions from kernel v4.2
> > Adds definition necessary to support emulated SR/IOV.
> 
> In the meantime Paolo updated this header to 4.3-RC1, is this patch
> still needed?
> 
> Thanks,
> Marcel

Quite right - it is gone after rebase.

Thanks,
Knut

> > 
> > Signed-off-by: Knut Omang 
> > ---
> >   include/standard-headers/linux/pci_regs.h | 142
> > +-
> >   1 file changed, 118 insertions(+), 24 deletions(-)
> > 
> > diff --git a/include/standard-headers/linux/pci_regs.h
> > b/include/standard-headers/linux/pci_regs.h
> > index 57e8c80..3d56c1e 100644
> > --- a/include/standard-headers/linux/pci_regs.h
> > +++ b/include/standard-headers/linux/pci_regs.h
> > @@ -304,13 +304,14 @@
> >   #define PCI_MSI_PENDING_6420  /* Pending bits
> > register for 32-bit devices */
> > 
> >   /* MSI-X registers */
> > -#define PCI_MSIX_FLAGS 2
> > -#define  PCI_MSIX_FLAGS_QSIZE  0x7FF
> > -#define  PCI_MSIX_FLAGS_ENABLE (1 << 15)
> > -#define  PCI_MSIX_FLAGS_MASKALL(1 << 14)
> > -#define PCI_MSIX_TABLE 4
> > -#define PCI_MSIX_PBA   8
> > +#define PCI_MSIX_FLAGS 2   /* Message Control
> > */
> > +#define  PCI_MSIX_FLAGS_QSIZE  0x7FF   /* Table size */
> > +#define  PCI_MSIX_FLAGS_ENABLE (1 << 15) /* MSI-X enable */
> > +#define  PCI_MSIX_FLAGS_MASKALL(1 << 14) /* Mask all
> > vectors for this function */
> > +#define PCI_MSIX_TABLE 4   /* Table offset */
> > +#define PCI_MSIX_PBA   8   /* Pending Bit Array
> > offset */
> >   #define  PCI_MSIX_FLAGS_BIRMASK   (7 << 0)
> > +#define PCI_CAP_MSIX_SIZEOF12  /* size of MSIX
> > capability structure */
> > 
> >   /* MSI-X entry's format */
> >   #define PCI_MSIX_ENTRY_SIZE   16
> > @@ -517,31 +518,63 @@
> >   #define  PCI_EXP_OBFF_MSG 0x4 /* New message signaling
> > */
> >   #define  PCI_EXP_OBFF_WAKE0x8 /* Re-use WAKE# for
> > OBFF */
> >   #define PCI_EXP_DEVCTL2   40  /* Device
> > Control 2 */
> > -#define  PCI_EXP_DEVCTL2_ARI   0x20/* Alternative
> > Routing-ID */
> > -#define  PCI_EXP_IDO_REQ_EN0x100   /* ID-based
> > ordering request enable */
> > -#define  PCI_EXP_IDO_CMP_EN0x200   /* ID-based
> > ordering completion enable */
> > -#define  PCI_EXP_LTR_EN0x400   /* Latency
> > tolerance reporting */
> > -#define  PCI_EXP_OBFF_MSGA_EN  0x2000  /* OBFF enable
> > with Message type A */
> > -#define  PCI_EXP_OBFF_MSGB_EN  0x4000  /* OBFF enable
> > with Message type B */
> > -#define  PCI_EXP_OBFF_WAKE_EN  0x6000  /* OBFF using
> > WAKE# signaling */
> > +#define  PCI_EXP_DEVCTL2_COMP_TIMEOUT  0x000f  /*
> > Completion Timeout Value */
> > +#define  PCI_EXP_DEVCTL2_ARI   0x0020  /*
> > Alternative Routing-ID */
> > +#define  PCI_EXP_DEVCTL2_IDO_REQ_EN0x0100  /* Allow
> > IDO for requests */
> > +#define  PCI_EXP_DEVCTL2_IDO_CMP_EN0x0200  /* Allow
> > IDO for completions */
> > +#define  PCI_EXP_DEVCTL2_LTR_EN0x0400  /*
> > Enable LTR mechanism */
> > +#define  PCI_EXP_DEVCTL2_OBFF_MSGA_EN  0x2000  /*
> > Enable OBFF Message type A */
> > +#define  PCI_EXP_DEVCTL2_OBFF_MSGB_EN  0x4000  /*
> > Enable OBFF Message type B */
> > +#define  PCI_EXP_DEVCTL2_OBFF_WAKE_EN  0x6000  /* OBFF
> > using WAKE# signaling */
> > +#define PCI_EXP_DEVSTA242  /* Device Status
> > 2 */
> > +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44  /* v2
> > endpoints end here */
> > +#define PCI_EXP_LNKCAP244  /* Link
> > Capabilities 2 */
> > +#define  PCI_EXP_LNKCAP2_SLS_2_5GB 0x0002 /* Supported
> > Speed 2.5GT/s */
> > +#define  PCI_EXP_LNKCAP2_SLS_5_0GB 0x0004 /* Supported
> > Speed 5.0GT/s */
> > +#define  PCI_EXP_LNKCAP2_SLS_8_0GB 0x0008 /* Supported
> > Speed 8.0GT/s */
> > +#define  PCI_EXP_LNKCAP2_CROSSLINK 0x0100 /* Crosslink
> > supported */
> >   #define PCI_EXP_LNKCTL2   48  /* Link Control
> > 2 */
> > -#define PCI_EXP_SLTCTL256  /* Slot Control 2
> > */
> > +#define PCI_EXP_LNKSTA250  /* Link Status 2
> > */
> > +#define PCI_EXP_SLTCAP252  /* Slot
> > Capabilities 2 */
> > +#define PCI_EXP_SLTCTL256  /* Slot Control 2 */
> > +#define PCI_EXP_SLTSTA258  /* Slot Status 2
> > */
> > 
> >   /* Extended Capabilities (PCI-X 2.0 and Express) */
> >   #define PCI_EXT_CAP_ID(header)(header &
> > 0x)
> >   #define PCI_EXT_CAP_VER(header)   ((header >> 16) &
> > 0xf)
> >   #define PCI_EXT_CAP_NEXT(header)  ((header >> 20) & 0xffc)
> > 
> > -#define PCI_EXT_CAP_ID_ERR 1
> > -#define PCI_EXT_CAP_ID_VC  2
> > -#define PCI_EXT_CAP_ID_DSN 3
> > -#define PCI_EXT_CAP_ID_PWR 4
> > -#define PCI_EXT_CAP_ID_VNDR11
> > -#defi

[Qemu-devel] Quick question on NVME on qemu

2015-10-10 Thread sahlot arvind
Hello,

Does qemu emulate a proper NVMe controller?  Can someone please tell me how
can I use it to emulate a proper NVMe controller? Is there some way to
enable logging PCI accesses to NVMe controller so that I can see what
accesses my driver or OS is doing?

Thanks in advance!
Sahlot


[Qemu-devel] [Bug 1357226] Re: qemu: uncaught target signal 11 (Segmentation fault) - core dumped

2015-10-10 Thread Brett Weir
I'm running into this same problem, and it's making automation of
Raspberry Pi builds of my application difficult.

I'm running in a chroot environment:
3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 armv7l 
GNU/Linux

Package: qemu
Version: 1.1.2+dfsg-6a+deb7u11

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

Title:
  qemu: uncaught target signal 11 (Segmentation fault) - core dumped

Status in QEMU:
  New

Bug description:
  steps to reproduce:
  pbuilder-dist utopic armhf create
  pbuilder-dist utopic armhf login
  apt-get install imagemagick
  convert foo.xpm foo.png
  qemu: uncaught target signal 11 (Segmentation fault) - core dumped
  Segmentation fault

  (doesn't matter if images are actually there or not)

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



[Qemu-devel] [Bug 1504513] Re: Socket leak on each call to qemu_socket()

2015-10-10 Thread Mark Pizzolato
I'm not sure that my original report was distributed to the folks who
need to see this.  My primary email address has a DKIM policy (DMARC)
which says that all messages from my address are signed.  I received
various DMARC reports which said that the bug report sent as "From:
m...@mydomain.com" were rejected.  The bug report messages were reasonably
sent with an SMTP envelope from of qemu-devel-
bounces+liq3ea=163@nongnu.org and a "Sender: qemu-devel-
bounces+liq3ea=163@nongnu.org".  Hmm... Maybe 163.com is rewriting
message headers.  In any case, the message would have passed the DMARC
check if my email address was in a "Reply-To: m...@mydomain.com" header
(there was no Reply-To: header), and the "From:" header was a
@nongnu.org address.

I have changed my account to use my users.sourceforge.com forwarding
address and I'm now generating this comment so that hopefully, the whole
message will be widely distributed with a from address which doesn't
have the same DMARC policy.

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

Title:
  Socket leak on each call to qemu_socket()

Status in QEMU:
  New

Bug description:
  On any host platform where SOCK_CLOEXEC is defined (Linux at least), a
  socket is leaked on each call to qemu_socket() AND the socket returned
  hasn't been created with the desired SOCK_CLOEXEC attribute.  The
  qemu_socket routine is:

  Line 272 of util/osdep.c:
  /*
   * Opens a socket with FD_CLOEXEC set
   */
  int qemu_socket(int domain, int type, int protocol)
  {
  int ret;

  #ifdef SOCK_CLOEXEC
  ret = socket(domain, type | SOCK_CLOEXEC, protocol);
  if (ret != -1 || errno != EINVAL) {
  return ret;
  }
  #endif
  ret = socket(domain, type, protocol);
  if (ret >= 0) {
  qemu_set_cloexec(ret);
  }

  return ret;
  }

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



[Qemu-devel] [PATCH v6 1/1] block/gluster: add support for multiple gluster backup volfile servers

2015-10-10 Thread Prasanna Kumar Kalever
This patch adds a way to specify multiple volfile servers to the gluster
block backend of QEMU with tcp|rdma transport types and their port numbers.

Problem:

Currenly VM Image on gluster volume is specified like this:

file=gluster[+tcp]://host[:port]/testvol/a.img

Assuming we have three hosts in trustred pool with replica 3 volume
in action and unfortunately host (mentioned in the command above) went down
for some reason, since the volume is replica 3 we now have other 2 hosts
active from which we can boot the VM.

But currently there is no mechanism to pass the other 2 gluster host
addresses to qemu.

Solution:

New way of specifying VM Image on gluster volume with volfile servers:
(We still support old syntax to maintain backward compatibility)

Basic command line syntax looks like:

Pattern I:
 -drive driver=gluster,
volume=testvol,path=/path/a.raw,
servers.0.host=1.2.3.4,
   [servers.0.port=24007,]
   [servers.0.transport=tcp,]
servers.1.host=5.6.7.8,
   [servers.1.port=24008,]
   [servers.1.transport=rdma,] ...

Pattern II:
 'json:{"driver":"qcow2","file":{"driver":"gluster",
   "volume":"testvol","path":"/path/a.qcow2",
   "servers":[{tuple0},{tuple1}, ...{tupleN}]}}'

   driver  => 'gluster' (protocol name)
   volume  => name of gluster volume where our VM image resides
   path=> absolute path of image in gluster volume

  {tuple}  => {"host":"1.2.3.4"[,"port":"24007","transport":"tcp"]}

   host=> host address (hostname/ipv4/ipv6 addresses)
   port=> port number on which glusterd is listening. (default 24007)
   tranport=> transport type used to connect to gluster management daemon,
   it can be tcp|rdma (default 'tcp')

Examples:
1.
 -drive driver=qcow2,file.driver=gluster,
file.volume=testvol,file.path=/path/a.qcow2,
file.servers.0.host=1.2.3.4,
file.servers.0.port=24007,
file.servers.0.transport=tcp,
file.servers.1.host=5.6.7.8,
file.servers.1.port=24008,
file.servers.1.transport=rdma
2.
 'json:{"driver":"qcow2","file":{"driver":"gluster","volume":"testvol",
 "path":"/path/a.qcow2","servers":
 [{"host":"1.2.3.4","port":"24007","transport":"tcp"},
  {"host":"4.5.6.7","port":"24008","transport":"rdma"}] } }'

This patch gives a mechanism to provide all the server addresses, which are in
replica set, so in case host1 is down VM can still boot from any of the
active hosts.

This is equivalent to the backup-volfile-servers option supported by
mount.glusterfs (FUSE way of mounting gluster volume)

This patch depends on a recent fix in libgfapi raised as part of this work:
http://review.gluster.org/#/c/12114/

Credits: Sincere thanks to Kevin Wolf  and
"Deepak C Shetty"  for inputs and all their support

Signed-off-by: Prasanna Kumar Kalever 
---
v1:
multiple host addresses but common port number and transport type
pattern: URI syntax with query (?) delimitor
syntax:
file=gluster[+transport-type]://host1:24007/testvol/a.img\
 ?servers=host2&servers=host3

v2:
multiple host addresses each have their own port number, but all use
 common transport type
pattern: URI syntax  with query (?) delimiter
syntax:
file=gluster[+transport-type]://[host[:port]]/testvol/a.img\
 [?servers=host1[:port]\
  &servers=host2[:port]]

v3:
multiple host addresses each have their own port number and transport type
pattern: changed to json
syntax:
'json:{"driver":"qcow2","file":{"driver":"gluster","volume":"testvol",
   "path":"/path/a.qcow2","servers":
 [{"host":"1.2.3.4","port":"24007","transport":"tcp"},
  {"host":"4.5.6.7","port":"24008","transport":"rdma"}] } }'

v4, v5:
address comments from "Eric Blake" 
renamed:
'backup-volfile-servers' ->  'volfile-servers'

v6:
address comments from Peter Krempa 
renamed:
 'volname'->  'volume'
 'image-path' ->  'path'
 'server' ->  'host'
 'volfile-servers' ->  'servers'
---
 block/gluster.c  | 563 +--
 qapi/block-core.json |  60 +-
 2 files changed, 514 insertions(+), 109 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 1eb3a8c..c9061af 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -11,6 +11,17 @@
 #include "block/block_int.h"
 #include "qemu/uri.h"
 
+#define GLUSTER_OPT_FILENAME   "filename"
+#define GLUSTER_OPT_VOLUME "volume"
+#define GLUSTER_OPT_PATH   "path"
+#define GLUSTER_OPT_HOST   "host"
+#define GLUSTER_OPT_PORT   "port"
+#define GLUSTER_OPT_TRANSPORT  "transport"
+#define GLUSTER_OPT_SERVER_PATTERN "servers."
+
+#define GLUSTER_DEFAULT_PORT   24007
+#define GLUSTER_DEFAULT_TRANSPORT  "tcp"
+
 typedef struct GlusterAIOCB {
 int64_t size;
 int ret;
@@ -24,22 +35,108 @@ typedef struct BDRVGlusterState {
 struct glfs_fd *fd;
 } BDRV

Re: [Qemu-devel] [PATCH] armv7-m: exit on external reset request

2015-10-10 Thread Michael Davidsaver


On 10/09/2015 02:51 PM, Michael Davidsaver wrote:
> On 10/09/2015 02:18 PM, Peter Crosthwaite wrote:
>> On Fri, Oct 9, 2015 at 10:25 AM, Michael Davidsaver
>>  wrote:
>>>
>>>
>>> On 10/09/2015 12:59 PM, Peter Maydell wrote:
 On 8 October 2015 at 16:40, Michael Davidsaver  
 wrote:
> ...
>  case 0xd0c: /* Application Interrupt/Reset Control.  */
>  if ((value >> 16) == 0x05fa) {
> +if (value & 4) {
> +qemu_system_reset_request();
> +}
>>> ...

 Strictly speaking what this bit does is assert a signal out of
 the CPU to some external power management or similar device
 in the SoC, which then is responsible for doing the reset.
 So just calling qemu_system_reset_request() here is a bit of
 a shortcut. But maybe it's a pragmatic shortcut?
>>>
>>> I'm not sure what you mean by shortcut?  Most targets have some way to 
>>> trigger qemu to exit.  I actually compiled a list recently (see below).  I 
>>> couldn't find one for the lm3s6965evb machine, thus this patch.
>>>
>>
> ...
>> I think it would be better for SoC (or board) level to
>> install the GPIO handler to do the reset. As far as target-arm is
>> concerned this is then just a GPIO.
> 
> I don't think I'm well versed enough in qemu lingo to parse this sentence :)
> Are you concerned about adding this function to AIRCR (which would effect 
> every armv7-m board),
> or about directly calling qemu_system_reset_request() in armv7m_nvic.c?

I think I've answered my own question.  You mean to replace the call to 
qemu_system_reset_request() with something like qemu_irq_pulse()?

I think I see how to do this.  The simplest (adding another named GPIO to the 
NVIC devices) is complicated by the fact that the armv7m_init() doesn't return 
the nvic object, but rather an array of qemu_irq.  Is it reasonable to change 
armv7m_init() to return DeviceState*?



Re: [Qemu-devel] [PATCH] target-tilegx: Let prefetch nop instructions return before allocating dest temporary register

2015-10-10 Thread Chen Gang
Hello all:

It looks I have to spend quite a few free time resources on tilegx gcc
testsuite issues, next (may 2-3 months at least, I guess).

So for tilegx qemu, I guess, I need to start to implement the floating
point, at present. I shall try to finish within this month (although it
seems not quite easy to me).

By the way, excuse me, my English is not quite well, so:

 - I have to try to 'speak' as clearly as I can, so sometimes what I
   said may be not quite polite, please understand.

 - If any members find any issues/bugs which may be related with me,
   please say directly and clearly (or sometimes, I maybe misunderstand,
   then waste our time resources).


Thanks.

On 10/10/15 06:50, Chen Gang wrote:
> 
> On 10/10/15 06:10, Richard Henderson wrote:
>> On 10/09/2015 09:48 AM, Chen Gang wrote:
>>> On 10/7/15 18:17, Chen Gang wrote:
 On 10/7/15 17:19, Richard Henderson wrote:
> On 10/04/2015 10:15 PM, Chen Gang wrote:
>>>  From 40ec3f1c75b4c97e3e0495c9e465be898f48a652 Mon Sep 17 00:00:00 2001
>> From: Chen Gang
>> Date: Sun, 4 Oct 2015 17:34:17 +0800
>> Subject: [PATCH] target-tilegx: Let prefetch nop instructions return 
>> before allocating dest temporary register
>>
>> Or it will cause issue by the dest temporary registers.
>>
>> Signed-off-by: Chen Gang
>> ---
>> target-tilegx/translate.c | 85 
>> +--
>> 1 file changed, 46 insertions(+), 39 deletions(-)
>
> Isn't my patch 14/14 from the last patch set sufficient?
>
>>>
>>> At present, all patches (include 14/14) are integrated into master tree,
>>> so I guess, we have to integrate this patch into master tree next, it
>>> fix the dest temporary registers' issue.
>>
>> What issue?  The prefetch instructions "load" to the zero register,
>> which is never written back to the register file.
>>
> 
> OK, really. But for me, the code is very easy to lead other members to
> make mistakes.
> 
> Thanks.
> 

-- 
Chen Gang (陈刚)

Open, share, and attitude like air, water, and life which God blessed



[Qemu-devel] [PATCH v2] armv7-m: exit on external reset request

2015-10-10 Thread Michael Davidsaver
Implement the SYSRESETREQ bit of the AIRCR register
for armv7-m (ie. cortex-m3) to trigger a GPIO out.

Change armv7m_init to return the DeviceState* for the NVIC.
This allows access to all GPIO blocks, not just the IRQ inputs.
Move qdev_get_gpio_in() calls out of armv7m_init() into
board code for stellaris and stm32f205 boards.

Add GPIO in for the stellaris board which calls
qemu_system_reset_request() on reset request.
---
 hw/arm/armv7m.c|  9 ++---
 hw/arm/stellaris.c | 36 +---
 hw/arm/stm32f205_soc.c | 13 ++---
 hw/intc/armv7m_nvic.c  |  7 ++-
 include/hw/arm/arm.h   |  2 +-
 5 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index eb214db..a80d2ad 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -166,17 +166,15 @@ static void armv7m_reset(void *opaque)
mem_size is in bytes.
Returns the NVIC array.  */
 
-qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
+DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int 
num_irq,
   const char *kernel_filename, const char *cpu_model)
 {
 ARMCPU *cpu;
 CPUARMState *env;
 DeviceState *nvic;
-qemu_irq *pic = g_new(qemu_irq, num_irq);
 int image_size;
 uint64_t entry;
 uint64_t lowaddr;
-int i;
 int big_endian;
 MemoryRegion *hack = g_new(MemoryRegion, 1);
 
@@ -198,9 +196,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int 
mem_size, int num_irq,
 qdev_init_nofail(nvic);
 sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
-for (i = 0; i < num_irq; i++) {
-pic[i] = qdev_get_gpio_in(nvic, i);
-}
 
 #ifdef TARGET_WORDS_BIGENDIAN
 big_endian = 1;
@@ -234,7 +229,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int 
mem_size, int num_irq,
 memory_region_add_subregion(system_memory, 0xf000, hack);
 
 qemu_register_reset(armv7m_reset, cpu);
-return pic;
+return nvic;
 }
 
 static Property bitband_properties[] = {
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 3d6486f..e3b19f3 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -16,6 +16,7 @@
 #include "net/net.h"
 #include "hw/boards.h"
 #include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
 
 #define GPIO_A 0
 #define GPIO_B 1
@@ -1176,6 +1177,13 @@ static int stellaris_adc_init(SysBusDevice *sbd)
 return 0;
 }
 
+static
+void do_sys_reset(void *opaque, int n, int level)
+{
+if(level)
+qemu_system_reset_request();
+}
+
 /* Board init.  */
 static stellaris_board_info stellaris_boards[] = {
   { "LM3S811EVB",
@@ -1210,8 +1218,7 @@ static void stellaris_init(const char *kernel_filename, 
const char *cpu_model,
 0x40024000, 0x40025000, 0x40026000};
 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
 
-qemu_irq *pic;
-DeviceState *gpio_dev[7];
+DeviceState *gpio_dev[7], *nvic;
 qemu_irq gpio_in[7][8];
 qemu_irq gpio_out[7][8];
 qemu_irq adc;
@@ -1241,12 +1248,19 @@ static void stellaris_init(const char *kernel_filename, 
const char *cpu_model,
 vmstate_register_ram_global(sram);
 memory_region_add_subregion(system_memory, 0x2000, sram);
 
-pic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
+nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
   kernel_filename, cpu_model);
 
+qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
+qemu_allocate_irq(&do_sys_reset, NULL, 0));
+
 if (board->dc1 & (1 << 16)) {
 dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
-pic[14], pic[15], pic[16], pic[17], NULL);
+qdev_get_gpio_in(nvic, 14),
+qdev_get_gpio_in(nvic, 15),
+qdev_get_gpio_in(nvic, 16),
+qdev_get_gpio_in(nvic, 17),
+NULL);
 adc = qdev_get_gpio_in(dev, 0);
 } else {
 adc = NULL;
@@ -1255,19 +1269,19 @@ static void stellaris_init(const char *kernel_filename, 
const char *cpu_model,
 if (board->dc2 & (0x1 << i)) {
 dev = sysbus_create_simple(TYPE_STELLARIS_GPTM,
0x4003 + i * 0x1000,
-   pic[timer_irq[i]]);
+   qdev_get_gpio_in(nvic, timer_irq[i]));
 /* TODO: This is incorrect, but we get away with it because
the ADC output is only ever pulsed.  */
 qdev_connect_gpio_out(dev, 0, adc);
 }
 }
 
-stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
+stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28), board, 
nd_table[0].macaddr.a);
 
 for (

[Qemu-devel] [PATCH v3 02/32] acpi: add aml_sizeof

2015-10-10 Thread Xiao Guangrong
Implement SizeOf term which is used by NVDIMM _DSM method in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 8 
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index cbd53f4..a72214d 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1143,6 +1143,14 @@ Aml *aml_derefof(Aml *arg)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSizeOf */
+Aml *aml_sizeof(Aml *arg)
+{
+Aml *var = aml_opcode(0x87 /* SizeOfOp */);
+aml_append(var, arg);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 5a03d33..7296efb 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -275,6 +275,7 @@ Aml *aml_varpackage(uint32_t num_elements);
 Aml *aml_touuid(const char *uuid);
 Aml *aml_unicode(const char *str);
 Aml *aml_derefof(Aml *arg);
+Aml *aml_sizeof(Aml *arg);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 01/32] acpi: add aml_derefof

2015-10-10 Thread Xiao Guangrong
Implement DeRefOf term which is used by NVDIMM _DSM method in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 8 
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 0d4b324..cbd53f4 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1135,6 +1135,14 @@ Aml *aml_unicode(const char *str)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
+Aml *aml_derefof(Aml *arg)
+{
+Aml *var = aml_opcode(0x83 /* DerefOfOp */);
+aml_append(var, arg);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 1b632dc..5a03d33 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -274,6 +274,7 @@ Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const 
char *name);
 Aml *aml_varpackage(uint32_t num_elements);
 Aml *aml_touuid(const char *uuid);
 Aml *aml_unicode(const char *str);
+Aml *aml_derefof(Aml *arg);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 03/32] acpi: add aml_create_field

2015-10-10 Thread Xiao Guangrong
Implement CreateField term which is used by NVDIMM _DSM method in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 13 +
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 14 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index a72214d..9fe5e7b 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1151,6 +1151,19 @@ Aml *aml_sizeof(Aml *arg)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
+Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, const char *name)
+{
+Aml *var = aml_alloc();
+build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+build_append_byte(var->buf, 0x13); /* CreateFieldOp */
+aml_append(var, srcbuf);
+aml_append(var, index);
+aml_append(var, len);
+build_append_namestring(var->buf, "%s", name);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 7296efb..7e1c43b 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -276,6 +276,7 @@ Aml *aml_touuid(const char *uuid);
 Aml *aml_unicode(const char *str);
 Aml *aml_derefof(Aml *arg);
 Aml *aml_sizeof(Aml *arg);
+Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, const char *name);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 08/32] exec: allow memory to be allocated from any kind of path

2015-10-10 Thread Xiao Guangrong
Currently file_ram_alloc() is designed for hugetlbfs, however, the memory
of nvdimm can come from either raw pmem device eg, /dev/pmem, or the file
locates at DAX enabled filesystem

So this patch let it work on any kind of path

Signed-off-by: Xiao Guangrong 
---
 exec.c | 55 ++-
 1 file changed, 14 insertions(+), 41 deletions(-)

diff --git a/exec.c b/exec.c
index 7d90a52..70cb0ef 100644
--- a/exec.c
+++ b/exec.c
@@ -1154,32 +1154,6 @@ void qemu_mutex_unlock_ramlist(void)
 }
 
 #ifdef __linux__
-
-#include 
-
-#define HUGETLBFS_MAGIC   0x958458f6
-
-static long gethugepagesize(const char *path, Error **errp)
-{
-struct statfs fs;
-int ret;
-
-do {
-ret = statfs(path, &fs);
-} while (ret != 0 && errno == EINTR);
-
-if (ret != 0) {
-error_setg_errno(errp, errno, "failed to get page size of file %s",
- path);
-return 0;
-}
-
-if (fs.f_type != HUGETLBFS_MAGIC)
-fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
-
-return fs.f_bsize;
-}
-
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 const char *path,
@@ -1191,22 +1165,21 @@ static void *file_ram_alloc(RAMBlock *block,
 void *ptr;
 void *area = NULL;
 int fd;
-uint64_t hpagesize;
+uint64_t pagesize;
 uint64_t total;
-Error *local_err = NULL;
 size_t offset;
 
-hpagesize = gethugepagesize(path, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
+pagesize = qemu_file_get_page_size(path);
+if (!pagesize) {
+error_setg(errp, "can't get page size for %s", path);
 goto error;
 }
-block->mr->align = hpagesize;
+block->mr->align = pagesize;
 
-if (memory < hpagesize) {
+if (memory < pagesize) {
 error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
-   "or larger than huge page size 0x%" PRIx64,
-   memory, hpagesize);
+   "or larger than page size 0x%" PRIx64,
+   memory, pagesize);
 goto error;
 }
 
@@ -1230,15 +1203,15 @@ static void *file_ram_alloc(RAMBlock *block,
 fd = mkstemp(filename);
 if (fd < 0) {
 error_setg_errno(errp, errno,
- "unable to create backing store for hugepages");
+ "unable to create backing store for path %s", path);
 g_free(filename);
 goto error;
 }
 unlink(filename);
 g_free(filename);
 
-memory = ROUND_UP(memory, hpagesize);
-total = memory + hpagesize;
+memory = ROUND_UP(memory, pagesize);
+total = memory + pagesize;
 
 /*
  * ftruncate is not supported by hugetlbfs in older
@@ -1254,12 +1227,12 @@ static void *file_ram_alloc(RAMBlock *block,
 -1, 0);
 if (ptr == MAP_FAILED) {
 error_setg_errno(errp, errno,
- "unable to allocate memory range for hugepages");
+ "unable to allocate memory range for path %s", path);
 close(fd);
 goto error;
 }
 
-offset = QEMU_ALIGN_UP((uintptr_t)ptr, hpagesize) - (uintptr_t)ptr;
+offset = QEMU_ALIGN_UP((uintptr_t)ptr, pagesize) - (uintptr_t)ptr;
 
 area = mmap(ptr + offset, memory, PROT_READ | PROT_WRITE,
 (block->flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE) |
@@ -1267,7 +1240,7 @@ static void *file_ram_alloc(RAMBlock *block,
 fd, 0);
 if (area == MAP_FAILED) {
 error_setg_errno(errp, errno,
- "unable to map backing store for hugepages");
+ "unable to map backing store for path %s", path);
 munmap(ptr, total);
 close(fd);
 goto error;
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 00/32] implement vNVDIMM

2015-10-10 Thread Xiao Guangrong
Changelog in v3:
There is huge change in this version, thank Igor, Stefan, Paolo, Eduardo,
Michael for their valuable comments, the patchset finally gets better shape.
- changes from Igor's comments:
  1) abstract dimm device type from pc-dimm and create nvdimm device based on
 dimm, then it uses memory backend device as nvdimm's memory and NUMA has
 easily been implemented.
  2) let file-backend device support any kind of filesystem not only for
 hugetlbfs and let it work on file not only for directory which is
 achieved by extending 'mem-path' - if it's a directory then it works as
 current behavior, otherwise if it's file then directly allocates memory
 from it.
  3) we figure out a unused memory hole below 4G that is 0xFF0 ~ 
 0xFFF0, this range is large enough for NVDIMM ACPI as build 64-bit
 ACPI SSDT/DSDT table will break windows XP.
 BTW, only make SSDT.rev = 2 can not work since the width is only depended
 on DSDT.rev based on 19.6.28 DefinitionBlock (Declare Definition Block)
 in ACPI spec:
| Note: For compatibility with ACPI versions before ACPI 2.0, the bit 
| width of Integer objects is dependent on the ComplianceRevision of the DSDT.
| If the ComplianceRevision is less than 2, all integers are restricted to 32 
| bits. Otherwise, full 64-bit integers are used. The version of the DSDT sets 
| the global integer width for all integers, including integers in SSDTs.
  4) use the lowest ACPI spec version to document AML terms.
  5) use "nvdimm" as nvdimm device name instead of "pc-nvdimm"

- changes from Stefan's comments:
  1) do not do endian adjustment in-place since _DSM memory is visible to guest
  2) use target platform's target page size instead of fixed PAGE_SIZE
 definition
  3) lots of code style improvement and typo fixes.
  4) live migration fix
- changes from Paolo's comments:
  1) improve the name of memory region
  
- other changes:
  1) return exact buffer size for _DSM method instead of the page size.
  2) introduce mutex in NVDIMM ACPI as the _DSM memory is shared by all nvdimm
 devices.
  3) NUMA support
  4) implement _FIT method
  5) rename "configdata" to "reserve-label-data"
  6) simplify _DSM arg3 determination
  7) main changelog update to let it reflect v3.

Changlog in v2:
- Use litten endian for DSM method, thanks for Stefan's suggestion

- introduce a new parameter, @configdata, if it's false, Qemu will
  build a static and readonly namespace in memory and use it serveing
  for DSM GET_CONFIG_SIZE/GET_CONFIG_DATA requests. In this case, no
  reserved region is needed at the end of the @file, it is good for
  the user who want to pass whole nvdimm device and make its data
  completely be visible to guest

- divide the source code into separated files and add maintain info

BTW, PCOMMIT virtualization on KVM side is work in progress, hopefully will
be posted on next week

== Background ==
NVDIMM (A Non-Volatile Dual In-line Memory Module) is going to be supported
on Intel's platform. They are discovered via ACPI and configured by _DSM
method of NVDIMM device in ACPI. There has some supporting documents which
can be found at:
ACPI 6: http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf
NVDIMM Namespace: http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf
DSM Interface Example: http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
Driver Writer's Guide: http://pmem.io/documents/NVDIMM_Driver_Writers_Guide.pdf

Currently, the NVDIMM driver has been merged into upstream Linux Kernel and
this patchset tries to enable it in virtualization field

== Design ==
NVDIMM supports two mode accesses, one is PMEM which maps NVDIMM into CPU's
address space then CPU can directly access it as normal memory, another is
BLK which is used as block device to reduce the occupying of CPU address
space

BLK mode accesses NVDIMM via Command Register window and Data Register window.
BLK virtualization has high workload since each sector access will cause at
least two VM-EXIT. So we currently only imperilment vPMEM in this patchset

--- vPMEM design ---
We introduce a new device named "nvdimm", it uses memory backend device as
NVDIMM memory. The file in file-backend device can be a regular file and block 
device. We can use any file when we do test or emulation, however,
in the real word, the files passed to guest are:
- the regular file in the filesystem with DAX enabled created on NVDIMM device
  on host
- the raw PMEM device on host, e,g /dev/pmem0
Memory access on the address created by mmap on these kinds of files can
directly reach NVDIMM device on host.

--- vConfigure data area design ---
Each NVDIMM device has a configure data area which is used to store label
namespace data. In order to emulating this area, we divide the file into two
parts:
- first parts is (0, size - 128K], which is used as PMEM
- 128K at the end of the file, which is used as Label Data Area
So that the label namespace data can be p

[Qemu-devel] [PATCH v3 17/32] dimm: abstract dimm device from pc-dimm

2015-10-10 Thread Xiao Guangrong
A base device, dimm, is abstracted from pc-dimm, so that we can
build nvdimm device based on dimm in the later patch

Signed-off-by: Xiao Guangrong 
---
 default-configs/i386-softmmu.mak   |  1 +
 default-configs/x86_64-softmmu.mak |  1 +
 hw/mem/Makefile.objs   |  3 ++-
 hw/mem/dimm.c  | 11 ++---
 hw/mem/pc-dimm.c   | 46 ++
 include/hw/mem/dimm.h  |  4 ++--
 include/hw/mem/pc-dimm.h   |  7 ++
 7 files changed, 61 insertions(+), 12 deletions(-)
 create mode 100644 hw/mem/pc-dimm.c
 create mode 100644 include/hw/mem/pc-dimm.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 43c96d1..3ece8bb 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -18,6 +18,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_X86_ICH=y
+CONFIG_DIMM=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index dfb8095..92ea7c1 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -18,6 +18,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_X86_ICH=y
+CONFIG_DIMM=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index 7563ef5..cebb4b1 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1 +1,2 @@
-common-obj-$(CONFIG_MEM_HOTPLUG) += dimm.o
+common-obj-$(CONFIG_DIMM) += dimm.o
+common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index e007271..2e35764 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -1,5 +1,5 @@
 /*
- * Dimm device for Memory Hotplug
+ * Dimm device abstraction
  *
  * Copyright ProfitBricks GmbH 2012
  * Copyright (C) 2014 Red Hat Inc
@@ -425,21 +425,13 @@ static void dimm_realize(DeviceState *dev, Error **errp)
 }
 }
 
-static MemoryRegion *dimm_get_memory_region(DIMMDevice *dimm)
-{
-return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
-}
-
 static void dimm_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
-DIMMDeviceClass *ddc = DIMM_CLASS(oc);
 
 dc->realize = dimm_realize;
 dc->props = dimm_properties;
 dc->desc = "DIMM memory module";
-
-ddc->get_memory_region = dimm_get_memory_region;
 }
 
 static TypeInfo dimm_info = {
@@ -449,6 +441,7 @@ static TypeInfo dimm_info = {
 .instance_init = dimm_init,
 .class_init= dimm_class_init,
 .class_size= sizeof(DIMMDeviceClass),
+.abstract  = true,
 };
 
 static void dimm_register_types(void)
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
new file mode 100644
index 000..38323e9
--- /dev/null
+++ b/hw/mem/pc-dimm.c
@@ -0,0 +1,46 @@
+/*
+ * Dimm device for Memory Hotplug
+ *
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "hw/mem/pc-dimm.h"
+
+static MemoryRegion *pc_dimm_get_memory_region(DIMMDevice *dimm)
+{
+return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
+}
+
+static void pc_dimm_class_init(ObjectClass *oc, void *data)
+{
+DIMMDeviceClass *ddc = DIMM_CLASS(oc);
+
+ddc->get_memory_region = pc_dimm_get_memory_region;
+}
+
+static TypeInfo pc_dimm_info = {
+.name  = TYPE_PC_DIMM,
+.parent= TYPE_DIMM,
+.class_init= pc_dimm_class_init,
+};
+
+static void pc_dimm_register_types(void)
+{
+type_register_static(&pc_dimm_info);
+}
+
+type_init(pc_dimm_register_types)
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 5ddbf08..84a62ed 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -1,5 +1,5 @@
 /*
- * PC DIMM device
+ * Dimm device abstraction
  *
  * Copyright ProfitBricks GmbH 2012
  * Copyright (C) 2013-2014 Red Hat Inc
@@ -20,7 +20,7 @@
 #include "sysemu/hostmem.h"
 #include "hw/qdev.h"
 
-#define TYPE_DIMM "pc-dimm"
+#define TYPE_DIMM "dimm"
 #define DIMM(obj) \
 OBJECT_CHECK(DIMMDevice, (obj), TYPE_DIMM)
 #define DIMM_CLASS(oc) \
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
new file mode 100644
index 000..50818c2
--- /dev/null
+++ b/include/hw/mem/pc-dimm

[Qemu-devel] [PATCH v3 07/32] util: introduce qemu_file_get_page_size()

2015-10-10 Thread Xiao Guangrong
There are three places use the some logic to get the page size on
the file path or file fd

This patch introduces qemu_file_get_page_size() to unify the code

Signed-off-by: Xiao Guangrong 
---
 include/qemu/osdep.h |  1 +
 target-ppc/kvm.c | 21 +++--
 util/oslib-posix.c   | 16 
 util/oslib-win32.c   |  5 +
 4 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ef21efb..9c8c0c4 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -286,4 +286,5 @@ void os_mem_prealloc(int fd, char *area, size_t sz);
 
 int qemu_read_password(char *buf, int buf_size);
 
+size_t qemu_file_get_page_size(const char *mem_path);
 #endif
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index f8ea783..ed3424e 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -306,28 +306,13 @@ static void kvm_get_smmu_info(PowerPCCPU *cpu, struct 
kvm_ppc_smmu_info *info)
 
 static long gethugepagesize(const char *mem_path)
 {
-struct statfs fs;
-int ret;
-
-do {
-ret = statfs(mem_path, &fs);
-} while (ret != 0 && errno == EINTR);
+long size = qemu_file_get_page_size(mem_path);
 
-if (ret != 0) {
-fprintf(stderr, "Couldn't statfs() memory path: %s\n",
-strerror(errno));
+if (!size) {
 exit(1);
 }
 
-#define HUGETLBFS_MAGIC   0x958458f6
-
-if (fs.f_type != HUGETLBFS_MAGIC) {
-/* Explicit mempath, but it's ordinary pages */
-return getpagesize();
-}
-
-/* It's hugepage, return the huge page size */
-return fs.f_bsize;
+return size;
 }
 
 static int find_max_supported_pagesize(Object *obj, void *opaque)
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index a0fcdc2..6b5c612 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -380,6 +380,22 @@ static size_t fd_getpagesize(int fd)
 return getpagesize();
 }
 
+size_t qemu_file_get_page_size(const char *path)
+{
+size_t size = 0;
+int fd = qemu_open(path, O_RDONLY);
+
+if (fd < 0) {
+fprintf(stderr, "Could not open %s.\n", path);
+goto exit;
+}
+
+size = fd_getpagesize(fd);
+qemu_close(fd);
+exit:
+return size;
+}
+
 void os_mem_prealloc(int fd, char *area, size_t memory)
 {
 int ret;
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 08f5a9c..1ff1fae 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -462,6 +462,11 @@ size_t getpagesize(void)
 return system_info.dwPageSize;
 }
 
+size_t qemu_file_get_page_size(const char *path)
+{
+return getpagesize();
+}
+
 void os_mem_prealloc(int fd, char *area, size_t memory)
 {
 int i;
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 04/32] acpi: add aml_mutex, aml_acquire, aml_release

2015-10-10 Thread Xiao Guangrong
Implement Mutex, Acquire and Release terms which are used by NVDIMM _DSM method
in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 32 
 include/hw/acpi/aml-build.h |  3 +++
 2 files changed, 35 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 9fe5e7b..ab52692 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1164,6 +1164,38 @@ Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, 
const char *name)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMutex */
+Aml *aml_mutex(const char *name, uint8_t flags)
+{
+Aml *var = aml_alloc();
+build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+build_append_byte(var->buf, 0x01); /* MutexOp */
+build_append_namestring(var->buf, "%s", name);
+build_append_byte(var->buf, flags);
+return var;
+}
+
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAcquire */
+Aml *aml_acquire(Aml *mutex, uint16_t timeout)
+{
+Aml *var = aml_alloc();
+build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+build_append_byte(var->buf, 0x23); /* AcquireOp */
+aml_append(var, mutex);
+build_append_int_noprefix(var->buf, timeout, sizeof(timeout));
+return var;
+}
+
+/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefRelease */
+Aml *aml_release(Aml *mutex)
+{
+Aml *var = aml_alloc();
+build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+build_append_byte(var->buf, 0x27); /* ReleaseOp */
+aml_append(var, mutex);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 7e1c43b..d494c0c 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -277,6 +277,9 @@ Aml *aml_unicode(const char *str);
 Aml *aml_derefof(Aml *arg);
 Aml *aml_sizeof(Aml *arg);
 Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, const char *name);
+Aml *aml_mutex(const char *name, uint8_t flags);
+Aml *aml_acquire(Aml *mutex, uint16_t timeout);
+Aml *aml_release(Aml *mutex);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 06/32] acpi: add aml_object_type

2015-10-10 Thread Xiao Guangrong
Implement ObjectType which is used by NVDIMM _DSM method in
later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 8 
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index d3b071f..c5639b5 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1210,6 +1210,14 @@ Aml *aml_concatenate(Aml *source1, Aml *source2, Aml 
*target)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
+Aml *aml_object_type(Aml *object)
+{
+Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
+aml_append(var, object);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index d4b6d10..77ff965 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -281,6 +281,7 @@ Aml *aml_mutex(const char *name, uint8_t flags);
 Aml *aml_acquire(Aml *mutex, uint16_t timeout);
 Aml *aml_release(Aml *mutex);
 Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target);
+Aml *aml_object_type(Aml *object);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 05/32] acpi: add aml_concatenate

2015-10-10 Thread Xiao Guangrong
Implement Concatenate term which is used by NVDIMM _DSM method
in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 14 ++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index ab52692..d3b071f 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1196,6 +1196,20 @@ Aml *aml_release(Aml *mutex)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
+Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
+{
+Aml *var = aml_opcode(0x73 /* ConcatOp */);
+aml_append(var, source1);
+aml_append(var, source2);
+
+if (target) {
+aml_append(var, target);
+}
+
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index d494c0c..d4b6d10 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -280,6 +280,7 @@ Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, 
const char *name);
 Aml *aml_mutex(const char *name, uint8_t flags);
 Aml *aml_acquire(Aml *mutex, uint16_t timeout);
 Aml *aml_release(Aml *mutex);
+Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 09/32] exec: allow file_ram_alloc to work on file

2015-10-10 Thread Xiao Guangrong
Currently, file_ram_alloc() only works on directory - it creates a file
under @path and do mmap on it

This patch tries to allow it to work on file directly, if @path is a
directory it works as before, otherwise it treats @path as the target
file then directly allocate memory from it

Signed-off-by: Xiao Guangrong 
---
 exec.c | 82 ++
 1 file changed, 52 insertions(+), 30 deletions(-)

diff --git a/exec.c b/exec.c
index 70cb0ef..c8c7e12 100644
--- a/exec.c
+++ b/exec.c
@@ -1154,14 +1154,60 @@ void qemu_mutex_unlock_ramlist(void)
 }
 
 #ifdef __linux__
+static bool path_is_dir(const char *path)
+{
+struct stat fs;
+
+return stat(path, &fs) == 0 && S_ISDIR(fs.st_mode);
+}
+
+static int open_file_path(RAMBlock *block, const char *path, size_t size)
+{
+char *filename;
+char *sanitized_name;
+char *c;
+int fd;
+
+if (!path_is_dir(path)) {
+int flags = (block->flags & RAM_SHARED) ? O_RDWR : O_RDONLY;
+
+flags |= O_EXCL;
+return open(path, flags);
+}
+
+/* Make name safe to use with mkstemp by replacing '/' with '_'. */
+sanitized_name = g_strdup(memory_region_name(block->mr));
+for (c = sanitized_name; *c != '\0'; c++) {
+if (*c == '/') {
+*c = '_';
+}
+}
+filename = g_strdup_printf("%s/qemu_back_mem.%s.XX", path,
+   sanitized_name);
+g_free(sanitized_name);
+fd = mkstemp(filename);
+if (fd >= 0) {
+unlink(filename);
+/*
+ * ftruncate is not supported by hugetlbfs in older
+ * hosts, so don't bother bailing out on errors.
+ * If anything goes wrong with it under other filesystems,
+ * mmap will fail.
+ */
+if (ftruncate(fd, size)) {
+perror("ftruncate");
+}
+}
+g_free(filename);
+
+return fd;
+}
+
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 const char *path,
 Error **errp)
 {
-char *filename;
-char *sanitized_name;
-char *c;
 void *ptr;
 void *area = NULL;
 int fd;
@@ -1189,39 +1235,15 @@ static void *file_ram_alloc(RAMBlock *block,
 goto error;
 }
 
-/* Make name safe to use with mkstemp by replacing '/' with '_'. */
-sanitized_name = g_strdup(memory_region_name(block->mr));
-for (c = sanitized_name; *c != '\0'; c++) {
-if (*c == '/')
-*c = '_';
-}
-
-filename = g_strdup_printf("%s/qemu_back_mem.%s.XX", path,
-   sanitized_name);
-g_free(sanitized_name);
+memory = ROUND_UP(memory, pagesize);
+total = memory + pagesize;
 
-fd = mkstemp(filename);
+fd = open_file_path(block, path, memory);
 if (fd < 0) {
 error_setg_errno(errp, errno,
  "unable to create backing store for path %s", path);
-g_free(filename);
 goto error;
 }
-unlink(filename);
-g_free(filename);
-
-memory = ROUND_UP(memory, pagesize);
-total = memory + pagesize;
-
-/*
- * ftruncate is not supported by hugetlbfs in older
- * hosts, so don't bother bailing out on errors.
- * If anything goes wrong with it under other filesystems,
- * mmap will fail.
- */
-if (ftruncate(fd, memory)) {
-perror("ftruncate");
-}
 
 ptr = mmap(0, total, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
 -1, 0);
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 21/32] nvdimm: implement NVDIMM device abstract

2015-10-10 Thread Xiao Guangrong
Introduce "nvdimm" device which is based on dimm device type

128K memory region which is the minimum namespace label size
required by NVDIMM Namespace Spec locates at the end of
backend memory device is reserved for label data

We can use "-m 1G,maxmem=100G,slots=10 -object memory-backend-file,
id=mem1,size=1G,mem-path=/dev/pmem0 -device nvdimm,memdev=mem1" to
create NVDIMM device for guest

Signed-off-by: Xiao Guangrong 
---
 default-configs/i386-softmmu.mak   |  1 +
 default-configs/x86_64-softmmu.mak |  1 +
 hw/acpi/memory_hotplug.c   |  6 +++
 hw/mem/Makefile.objs   |  1 +
 hw/mem/nvdimm/internal.h   | 17 
 hw/mem/nvdimm/nvdimm.c | 85 ++
 include/hw/mem/nvdimm.h| 33 +++
 7 files changed, 144 insertions(+)
 create mode 100644 hw/mem/nvdimm/internal.h
 create mode 100644 hw/mem/nvdimm/nvdimm.c
 create mode 100644 include/hw/mem/nvdimm.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 3ece8bb..a1b24e5 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -47,6 +47,7 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_NVDIMM = y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index 92ea7c1..e3f5a0b 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -47,6 +47,7 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_NVDIMM = y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index e232641..92cd973 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -1,6 +1,7 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/pc-hotplug.h"
 #include "hw/mem/dimm.h"
+#include "hw/mem/nvdimm.h"
 #include "hw/boards.h"
 #include "hw/qdev-core.h"
 #include "trace.h"
@@ -231,6 +232,11 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, 
MemHotplugState *mem_st,
 {
 MemStatus *mdev;
 
+/* Currently, NVDIMM hotplug has not been supported yet. */
+if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
+return;
+}
+
 mdev = acpi_memory_slot_status(mem_st, dev, errp);
 if (!mdev) {
 return;
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index cebb4b1..e0ff328 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1,2 +1,3 @@
 common-obj-$(CONFIG_DIMM) += dimm.o
 common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
+common-obj-$(CONFIG_NVDIMM) += nvdimm/nvdimm.o
diff --git a/hw/mem/nvdimm/internal.h b/hw/mem/nvdimm/internal.h
new file mode 100644
index 000..c4ba750
--- /dev/null
+++ b/hw/mem/nvdimm/internal.h
@@ -0,0 +1,17 @@
+/*
+ * Non-Volatile Dual In-line Memory Module Virtualization Implementation
+ *
+ * Copyright(C) 2015 Intel Corporation.
+ *
+ * Author:
+ *  Xiao Guangrong 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef NVDIMM_INTERNAL_H
+#define NVDIMM_INTERNAL_H
+
+#define MIN_NAMESPACE_LABEL_SIZE(128UL << 10)
+#endif
diff --git a/hw/mem/nvdimm/nvdimm.c b/hw/mem/nvdimm/nvdimm.c
new file mode 100644
index 000..0850e82
--- /dev/null
+++ b/hw/mem/nvdimm/nvdimm.c
@@ -0,0 +1,85 @@
+/*
+ * Non-Volatile Dual In-line Memory Module Virtualization Implementation
+ *
+ * Copyright(C) 2015 Intel Corporation.
+ *
+ * Author:
+ *  Xiao Guangrong 
+ *
+ * Currently, it only supports PMEM Virtualization.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qapi/visitor.h"
+#include "hw/mem/nvdimm.h"
+#include "internal.h"
+
+static MemoryRegion *nvdimm_get_memory_region(DIMMDevice *dimm)
+{
+NVDIMMDevice *nvdimm = NVDIMM(dimm);
+
+return memory_region_size(&nvdimm->nvdimm_mr) ? &nvdimm->nvdimm_mr : NULL;
+}
+
+static void nvdimm_realize(DIMMDevice *dimm, Error **errp)
+{
+MemoryRegion *mr;
+NVDIMMDevice *nvdimm = NVDIMM(dimm);
+uint64_t size;
+
+nvdimm->label_size = MIN_NAMESPACE_LABEL_SIZE;
+
+mr = host_memory_backend_get_memory(dimm->hostmem, errp);
+size = memory_region_size(mr);
+
+if (size <= nvdimm->label_size) {
+char *path 

[Qemu-devel] [PATCH v3 12/32] pc-dimm: remove DEFAULT_PC_DIMMSIZE

2015-10-10 Thread Xiao Guangrong
It's not used any more

Signed-off-by: Xiao Guangrong 
---
 include/hw/mem/pc-dimm.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index c1ee7b0..15590f1 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -20,8 +20,6 @@
 #include "sysemu/hostmem.h"
 #include "hw/qdev.h"
 
-#define DEFAULT_PC_DIMMSIZE (1024*1024*1024)
-
 #define TYPE_PC_DIMM "pc-dimm"
 #define PC_DIMM(obj) \
 OBJECT_CHECK(PCDIMMDevice, (obj), TYPE_PC_DIMM)
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 10/32] hostmem-file: clean up memory allocation

2015-10-10 Thread Xiao Guangrong
- hostmem-file.c is compiled only if CONFIG_LINUX is enabled so that is
  unnecessary to do the same check in the source file

- the interface, HostMemoryBackendClass->alloc(), is not called many
  times, do not need to check if the memory-region is initialized

Signed-off-by: Xiao Guangrong 
---
 backends/hostmem-file.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index e9b6d21..9097a57 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -46,17 +46,12 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 error_setg(errp, "mem-path property not set");
 return;
 }
-#ifndef CONFIG_LINUX
-error_setg(errp, "-mem-path not supported on this host");
-#else
-if (!memory_region_size(&backend->mr)) {
-backend->force_prealloc = mem_prealloc;
-memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
+
+backend->force_prealloc = mem_prealloc;
+memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
  object_get_canonical_path(OBJECT(backend)),
  backend->size, fb->share,
  fb->mem_path, errp);
-}
-#endif
 }
 
 static void
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 11/32] hostmem-file: use whole file size if possible

2015-10-10 Thread Xiao Guangrong
Use the whole file size if @size is not specified which is useful
if we want to directly pass a file to guest

Signed-off-by: Xiao Guangrong 
---
 backends/hostmem-file.c | 47 +++
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 9097a57..adf2835 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -9,6 +9,9 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
+#include 
+#include 
+
 #include "qemu-common.h"
 #include "sysemu/hostmem.h"
 #include "sysemu/sysemu.h"
@@ -33,20 +36,56 @@ struct HostMemoryBackendFile {
 char *mem_path;
 };
 
+static uint64_t get_file_size(const char *file)
+{
+struct stat stat_buf;
+uint64_t size = 0;
+int fd;
+
+fd = open(file, O_RDONLY);
+if (fd < 0) {
+return 0;
+}
+
+if (stat(file, &stat_buf) < 0) {
+goto exit;
+}
+
+if ((S_ISBLK(stat_buf.st_mode)) && !ioctl(fd, BLKGETSIZE64, &size)) {
+goto exit;
+}
+
+size = lseek(fd, 0, SEEK_END);
+if (size == -1) {
+size = 0;
+}
+exit:
+close(fd);
+return size;
+}
+
 static void
 file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 {
 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
 
-if (!backend->size) {
-error_setg(errp, "can't create backend with size 0");
-return;
-}
 if (!fb->mem_path) {
 error_setg(errp, "mem-path property not set");
 return;
 }
 
+if (!backend->size) {
+/*
+ * use the whole file size if @size is not specified.
+ */
+backend->size = get_file_size(fb->mem_path);
+}
+
+if (!backend->size) {
+error_setg(errp, "can't create backend with size 0");
+return;
+}
+
 backend->force_prealloc = mem_prealloc;
 memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
  object_get_canonical_path(OBJECT(backend)),
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 22/32] nvdimm: init the address region used by NVDIMM ACPI

2015-10-10 Thread Xiao Guangrong
We reserve the memory region 0xFF0 ~ 0xFFF0 for NVDIMM ACPI
which is used as:
- the first page is mapped as MMIO, ACPI write data to this page to
  transfer the control to QEMU

- the second page is RAM-based which used to save the input info of
  _DSM method and QEMU reuse it store output info

- the left is mapped as RAM, it's the buffer returned by _FIT method,
  this is needed by NVDIMM hotplug

Signed-off-by: Xiao Guangrong 
---
 hw/i386/pc.c|   3 ++
 hw/mem/Makefile.objs|   2 +-
 hw/mem/nvdimm/acpi.c| 120 
 include/hw/i386/pc.h|   2 +
 include/hw/mem/nvdimm.h |  19 
 5 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 hw/mem/nvdimm/acpi.c

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6694b18..8fea4c3 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1360,6 +1360,9 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
 exit(EXIT_FAILURE);
 }
 
+nvdimm_init_memory_state(&pcms->nvdimm_memory, system_memory, machine,
+ TARGET_PAGE_SIZE);
+
 pcms->hotplug_memory.base =
 ROUND_UP(0x1ULL + pcms->above_4g_mem_size, 1ULL << 30);
 
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index e0ff328..7310bac 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1,3 +1,3 @@
 common-obj-$(CONFIG_DIMM) += dimm.o
 common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
-common-obj-$(CONFIG_NVDIMM) += nvdimm/nvdimm.o
+common-obj-$(CONFIG_NVDIMM) += nvdimm/nvdimm.o nvdimm/acpi.o
diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
new file mode 100644
index 000..b640874
--- /dev/null
+++ b/hw/mem/nvdimm/acpi.c
@@ -0,0 +1,120 @@
+/*
+ * NVDIMM ACPI Implementation
+ *
+ * Copyright(C) 2015 Intel Corporation.
+ *
+ * Author:
+ *  Xiao Guangrong 
+ *
+ * NFIT is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT)
+ * and the DSM specfication can be found at:
+ *   http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
+ *
+ * Currently, it only supports PMEM Virtualization.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qemu-common.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/mem/nvdimm.h"
+#include "internal.h"
+
+/* System Physical Address Range Structure */
+struct nfit_spa {
+uint16_t type;
+uint16_t length;
+uint16_t spa_index;
+uint16_t flags;
+uint32_t reserved;
+uint32_t proximity_domain;
+uint8_t type_guid[16];
+uint64_t spa_base;
+uint64_t spa_length;
+uint64_t mem_attr;
+} QEMU_PACKED;
+typedef struct nfit_spa nfit_spa;
+
+/* Memory Device to System Physical Address Range Mapping Structure */
+struct nfit_memdev {
+uint16_t type;
+uint16_t length;
+uint32_t nfit_handle;
+uint16_t phys_id;
+uint16_t region_id;
+uint16_t spa_index;
+uint16_t dcr_index;
+uint64_t region_len;
+uint64_t region_offset;
+uint64_t region_dpa;
+uint16_t interleave_index;
+uint16_t interleave_ways;
+uint16_t flags;
+uint16_t reserved;
+} QEMU_PACKED;
+typedef struct nfit_memdev nfit_memdev;
+
+/* NVDIMM Control Region Structure */
+struct nfit_dcr {
+uint16_t type;
+uint16_t length;
+uint16_t dcr_index;
+uint16_t vendor_id;
+uint16_t device_id;
+uint16_t revision_id;
+uint16_t sub_vendor_id;
+uint16_t sub_device_id;
+uint16_t sub_revision_id;
+uint8_t reserved[6];
+uint32_t serial_number;
+uint16_t fic;
+uint16_t num_bcw;
+uint64_t bcw_size;
+uint64_t cmd_offset;
+uint64_t cmd_size;
+uint64_t status_offset;
+uint64_t status_size;
+uint16_t flags;
+uint8_t reserved2[6];
+} QEMU_PACKED;
+typedef struct nfit_dcr nfit_dcr;
+
+static uint64_t nvdimm_device_structure_size(uint64_t slots)
+{
+/* each nvdimm has three structures. */
+return slots * (sizeof(nfit_spa) + sizeof(nfit_memdev) + sizeof(nfit_dcr));
+}
+
+static uint64_t nvdimm_acpi_memory_size(uint64_t slots, uint64_t page_size)
+{
+uint64_t size = nvdimm_device_structure_size(slots);
+
+/* two pages for nvdimm _DSM method. */
+return size + page_size * 2;
+}
+
+void nvdimm_init_memory_state(NVDIMMState *state, MemoryRegion*system_memory,
+  MachineState *machine , uint64_

[Qemu-devel] [PATCH v3 13/32] pc-dimm: make pc_existing_dimms_capacity static and rename it

2015-10-10 Thread Xiao Guangrong
pc_existing_dimms_capacity() can be static since it is not used out of
pc-dimm.c and drop the pc_ prefix to prepare the work which abstracts
dimm device type from pc-dimm

Signed-off-by: Xiao Guangrong 
---
 hw/mem/pc-dimm.c | 73 
 include/hw/mem/pc-dimm.h |  1 -
 2 files changed, 36 insertions(+), 38 deletions(-)

diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 506fe0d..a581622 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -31,6 +31,38 @@ typedef struct pc_dimms_capacity {
  Error**errp;
 } pc_dimms_capacity;
 
+static int existing_dimms_capacity_internal(Object *obj, void *opaque)
+{
+pc_dimms_capacity *cap = opaque;
+uint64_t *size = &cap->size;
+
+if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
+DeviceState *dev = DEVICE(obj);
+
+if (dev->realized) {
+(*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
+cap->errp);
+}
+
+if (cap->errp && *cap->errp) {
+return 1;
+}
+}
+object_child_foreach(obj, existing_dimms_capacity_internal, opaque);
+return 0;
+}
+
+static uint64_t existing_dimms_capacity(Error **errp)
+{
+pc_dimms_capacity cap;
+
+cap.size = 0;
+cap.errp = errp;
+
+existing_dimms_capacity_internal(qdev_get_machine(), &cap);
+return cap.size;
+}
+
 void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
  MemoryRegion *mr, uint64_t align, bool gap,
  Error **errp)
@@ -39,7 +71,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState 
*hpms,
 MachineState *machine = MACHINE(qdev_get_machine());
 PCDIMMDevice *dimm = PC_DIMM(dev);
 Error *local_err = NULL;
-uint64_t existing_dimms_capacity = 0;
+uint64_t dimms_capacity = 0;
 uint64_t addr;
 
 addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, 
&local_err);
@@ -55,17 +87,16 @@ void pc_dimm_memory_plug(DeviceState *dev, 
MemoryHotplugState *hpms,
 goto out;
 }
 
-existing_dimms_capacity = pc_existing_dimms_capacity(&local_err);
+dimms_capacity = existing_dimms_capacity(&local_err);
 if (local_err) {
 goto out;
 }
 
-if (existing_dimms_capacity + memory_region_size(mr) >
+if (dimms_capacity + memory_region_size(mr) >
 machine->maxram_size - machine->ram_size) {
 error_setg(&local_err, "not enough space, currently 0x%" PRIx64
" in use of total hot pluggable 0x" RAM_ADDR_FMT,
-   existing_dimms_capacity,
-   machine->maxram_size - machine->ram_size);
+   dimms_capacity, machine->maxram_size - machine->ram_size);
 goto out;
 }
 
@@ -114,38 +145,6 @@ void pc_dimm_memory_unplug(DeviceState *dev, 
MemoryHotplugState *hpms,
 vmstate_unregister_ram(mr, dev);
 }
 
-static int pc_existing_dimms_capacity_internal(Object *obj, void *opaque)
-{
-pc_dimms_capacity *cap = opaque;
-uint64_t *size = &cap->size;
-
-if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
-DeviceState *dev = DEVICE(obj);
-
-if (dev->realized) {
-(*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
-cap->errp);
-}
-
-if (cap->errp && *cap->errp) {
-return 1;
-}
-}
-object_child_foreach(obj, pc_existing_dimms_capacity_internal, opaque);
-return 0;
-}
-
-uint64_t pc_existing_dimms_capacity(Error **errp)
-{
-pc_dimms_capacity cap;
-
-cap.size = 0;
-cap.errp = errp;
-
-pc_existing_dimms_capacity_internal(qdev_get_machine(), &cap);
-return cap.size;
-}
-
 int qmp_pc_dimm_device_list(Object *obj, void *opaque)
 {
 MemoryDeviceInfoList ***prev = opaque;
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index 15590f1..c1e5774 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -87,7 +87,6 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
 int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
 
 int qmp_pc_dimm_device_list(Object *obj, void *opaque);
-uint64_t pc_existing_dimms_capacity(Error **errp);
 void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
  MemoryRegion *mr, uint64_t align, bool gap,
  Error **errp);
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 27/32] nvdimm: support DSM_CMD_IMPLEMENTED function

2015-10-10 Thread Xiao Guangrong
__DSM is defined in ACPI 6.0: 9.14.1 _DSM (Device Specific Method)

Function 0 is a query function. We do not support any function on root
device and only 3 functions are support for NVDIMM device,
DSM_CMD_NAMESPACE_LABEL_SIZE, DSM_CMD_GET_NAMESPACE_LABEL_DATA and
DSM_CMD_SET_NAMESPACE_LABEL_DATA, that means we currently only allow to access
device's Label Namespace

Signed-off-by: Xiao Guangrong 
---
 hw/mem/nvdimm/acpi.c | 178 ++-
 1 file changed, 177 insertions(+), 1 deletion(-)

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index 3b9399c..cb6a428 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -39,6 +39,22 @@ static void nfit_spa_uuid_pm(uuid_le *uuid)
 memcpy(uuid, &uuid_pm, sizeof(uuid_pm));
 }
 
+static bool dsm_is_root_uuid(uint8_t *uuid)
+{
+uuid_le uuid_root = UUID_LE(0x2f10e7a4, 0x9e91, 0x11e4, 0x89,
+0xd3, 0x12, 0x3b, 0x93, 0xf7, 0x5c, 0xba);
+
+return !memcmp(uuid, &uuid_root, sizeof(uuid_root));
+}
+
+static bool dsm_is_dimm_uuid(uint8_t *uuid)
+{
+uuid_le uuid_dimm = UUID_LE(0x4309ac30, 0x0d11, 0x11e4, 0x91,
+0x91, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66);
+
+return !memcmp(uuid, &uuid_dimm, sizeof(uuid_dimm));
+}
+
 enum {
 NFIT_STRUCTURE_SPA = 0,
 NFIT_STRUCTURE_MEMDEV = 1,
@@ -195,6 +211,22 @@ static uint32_t nvdimm_slot_to_dcr_index(int slot)
 return nvdimm_slot_to_spa_index(slot) + 1;
 }
 
+static NVDIMMDevice
+*get_nvdimm_device_by_handle(GSList *list, uint32_t handle)
+{
+for (; list; list = list->next) {
+NVDIMMDevice *nvdimm = list->data;
+int slot = object_property_get_int(OBJECT(nvdimm), DIMM_SLOT_PROP,
+   NULL);
+
+if (nvdimm_slot_to_handle(slot) == handle) {
+return nvdimm;
+}
+}
+
+return NULL;
+}
+
 static int build_structure_spa(void *buf, NVDIMMDevice *nvdimm)
 {
 nfit_spa *nfit_spa;
@@ -310,6 +342,43 @@ static void build_nfit(void *fit, GSList *device_list, 
GArray *table_offsets,
 
 #define NOTIFY_VALUE  0x99
 
+enum {
+DSM_CMD_IMPLEMENTED = 0,
+
+/* root device commands */
+DSM_CMD_ARS_CAP = 1,
+DSM_CMD_ARS_START = 2,
+DSM_CMD_ARS_QUERY = 3,
+
+/* per-nvdimm device commands */
+DSM_CMD_SMART = 1,
+DSM_CMD_SMART_THRESHOLD = 2,
+DSM_CMD_BLOCK_NVDIMM_FLAGS = 3,
+DSM_CMD_NAMESPACE_LABEL_SIZE = 4,
+DSM_CMD_GET_NAMESPACE_LABEL_DATA = 5,
+DSM_CMD_SET_NAMESPACE_LABEL_DATA = 6,
+DSM_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
+DSM_CMD_GET_VENDOR_EFFECT_LOG = 8,
+DSM_CMD_VENDOR_SPECIFIC = 9,
+};
+
+enum {
+DSM_STATUS_SUCCESS = 0,
+DSM_STATUS_NOT_SUPPORTED = 1,
+DSM_STATUS_NON_EXISTING_MEM_DEV = 2,
+DSM_STATUS_INVALID_PARAS = 3,
+DSM_STATUS_VENDOR_SPECIFIC_ERROR = 4,
+};
+
+#define DSM_REVISION(1)
+
+/* do not support any command except NFIT_CMD_IMPLEMENTED on root. */
+#define ROOT_SUPPORT_CMD(1 << DSM_CMD_IMPLEMENTED)
+#define DIMM_SUPPORT_CMD((1 << DSM_CMD_IMPLEMENTED)   \
+   | (1 << DSM_CMD_NAMESPACE_LABEL_SIZE)  \
+   | (1 << DSM_CMD_GET_NAMESPACE_LABEL_DATA)  \
+   | (1 << DSM_CMD_SET_NAMESPACE_LABEL_DATA))
+
 struct dsm_in {
 uint32_t handle;
 uint8_t arg0[16];
@@ -320,10 +389,19 @@ struct dsm_in {
 } QEMU_PACKED;
 typedef struct dsm_in dsm_in;
 
+struct cmd_out_implemented {
+uint64_t cmd_list;
+};
+typedef struct cmd_out_implemented cmd_out_implemented;
+
 struct dsm_out {
 /* the size of buffer filled by QEMU. */
 uint16_t len;
-uint8_t data[0];
+union {
+uint8_t data[0];
+uint32_t status;
+cmd_out_implemented cmd_implemented;
+};
 } QEMU_PACKED;
 typedef struct dsm_out dsm_out;
 
@@ -334,12 +412,110 @@ static uint64_t dsm_read(void *opaque, hwaddr addr,
 return 0;
 }
 
+static void dsm_write_root(uint32_t function, dsm_in *in, dsm_out *out)
+{
+if (function == DSM_CMD_IMPLEMENTED) {
+out->len = sizeof(out->cmd_implemented);
+out->cmd_implemented.cmd_list = cpu_to_le64(ROOT_SUPPORT_CMD);
+return;
+}
+
+out->len = sizeof(out->status);
+out->status = cpu_to_le32(DSM_STATUS_NOT_SUPPORTED);
+nvdebug("Return status %#x.\n", out->status);
+}
+
+static void dsm_write_nvdimm(uint32_t handle, uint32_t function, dsm_in *in,
+ dsm_out *out)
+{
+GSList *list = nvdimm_get_built_list();
+NVDIMMDevice *nvdimm = get_nvdimm_device_by_handle(list, handle);
+uint32_t status = DSM_STATUS_NON_EXISTING_MEM_DEV;
+uint64_t cmd_list;
+
+if (!nvdimm) {
+out->len = sizeof(out->status);
+goto set_status_free;
+}
+
+switch (function) {
+case DSM_CMD_IMPLEMENTED:
+cmd_list = DIMM_SUPPORT_CMD;
+out->len = sizeof(out->cmd_implemented);
+out->cmd_implemented.cmd_list = 

[Qemu-devel] [PATCH v3 18/32] dimm: get mapped memory region from DIMMDeviceClass->get_memory_region

2015-10-10 Thread Xiao Guangrong
Curretly, the memory region of backed memory is directly mapped to
guest's address space, however, it is not true for nvdimm device

This patch let dimm device realize this fact and use
DIMMDeviceClass->get_memory_region method to get the mapped memory
region

Signed-off-by: Xiao Guangrong 
---
 hw/mem/dimm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 2e35764..b307511 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -373,8 +373,9 @@ static void dimm_get_size(Object *obj, Visitor *v, void 
*opaque,
 int64_t value;
 MemoryRegion *mr;
 DIMMDevice *dimm = DIMM(obj);
+DIMMDeviceClass *ddc = DIMM_GET_CLASS(obj);
 
-mr = host_memory_backend_get_memory(dimm->hostmem, errp);
+mr = ddc->get_memory_region(dimm);
 value = memory_region_size(mr);
 
 visit_type_int(v, &value, name, errp);
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 28/32] nvdimm: support DSM_CMD_NAMESPACE_LABEL_SIZE function

2015-10-10 Thread Xiao Guangrong
Function 4 is used to get Namespace label size

Signed-off-by: Xiao Guangrong 
---
 hw/mem/nvdimm/acpi.c | 90 +---
 1 file changed, 86 insertions(+), 4 deletions(-)

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index cb6a428..b420e2f 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -379,13 +379,29 @@ enum {
| (1 << DSM_CMD_GET_NAMESPACE_LABEL_DATA)  \
| (1 << DSM_CMD_SET_NAMESPACE_LABEL_DATA))
 
+struct cmd_in_get_label_data {
+uint32_t offset;
+uint32_t length;
+} QEMU_PACKED;
+typedef struct cmd_in_get_label_data cmd_in_get_label_data;
+
+struct cmd_in_set_label_data {
+uint32_t offset;
+uint32_t length;
+uint8_t in_buf[0];
+} QEMU_PACKED;
+typedef struct cmd_in_set_label_data cmd_in_set_label_data;
+
 struct dsm_in {
 uint32_t handle;
 uint8_t arg0[16];
 uint32_t arg1;
 uint32_t arg2;
/* the remaining size in the page is used by arg3. */
-uint8_t arg3[0];
+union {
+uint8_t arg3[0];
+cmd_in_set_label_data cmd_set_label_data;
+};
 } QEMU_PACKED;
 typedef struct dsm_in dsm_in;
 
@@ -394,6 +410,19 @@ struct cmd_out_implemented {
 };
 typedef struct cmd_out_implemented cmd_out_implemented;
 
+struct cmd_out_label_size {
+uint32_t status;
+uint32_t label_size;
+uint32_t max_xfer;
+} QEMU_PACKED;
+typedef struct cmd_out_label_size cmd_out_label_size;
+
+struct cmd_out_get_label_data {
+uint32_t status;
+uint8_t out_buf[0];
+} QEMU_PACKED;
+typedef struct cmd_out_get_label_data cmd_out_get_label_data;
+
 struct dsm_out {
 /* the size of buffer filled by QEMU. */
 uint16_t len;
@@ -401,6 +430,8 @@ struct dsm_out {
 uint8_t data[0];
 uint32_t status;
 cmd_out_implemented cmd_implemented;
+cmd_out_label_size cmd_label_size;
+cmd_out_get_label_data cmd_get_label_data;
 };
 } QEMU_PACKED;
 typedef struct dsm_out dsm_out;
@@ -425,8 +456,56 @@ static void dsm_write_root(uint32_t function, dsm_in *in, 
dsm_out *out)
 nvdebug("Return status %#x.\n", out->status);
 }
 
-static void dsm_write_nvdimm(uint32_t handle, uint32_t function, dsm_in *in,
- dsm_out *out)
+/*
+ * the max transfer size is the max size transfered by both a
+ * DSM_CMD_GET_NAMESPACE_LABEL_DATA and a DSM_CMD_SET_NAMESPACE_LABEL_DATA
+ * command.
+ */
+static uint32_t max_xfer_label_size(MemoryRegion *dsm_ram_mr)
+{
+dsm_in *in;
+dsm_out *out;
+uint32_t mr_size, max_get_size, max_set_size;
+
+mr_size = memory_region_size(dsm_ram_mr);
+
+/*
+ * the max data ACPI can read one time which is transfered by
+ * the response of DSM_CMD_GET_NAMESPACE_LABEL_DATA.
+ */
+max_get_size = mr_size - offsetof(dsm_out, data) -
+   sizeof(out->cmd_get_label_data);
+
+/*
+ * the max data ACPI can write one time which is transfered by
+ * DSM_CMD_SET_NAMESPACE_LABEL_DATA
+ */
+max_set_size = mr_size - offsetof(dsm_in, arg3) -
+   sizeof(in->cmd_set_label_data);
+
+return MIN(max_get_size, max_set_size);
+}
+
+static uint32_t
+dsm_cmd_label_size(MemoryRegion *dsm_ram_mr, NVDIMMDevice *nvdimm,
+dsm_out *out)
+{
+uint32_t label_size, mxfer;
+
+label_size = nvdimm->label_size;
+mxfer = max_xfer_label_size(dsm_ram_mr);
+
+out->cmd_label_size.label_size = cpu_to_le32(label_size);
+out->cmd_label_size.max_xfer = cpu_to_le32(mxfer);
+out->len = sizeof(out->cmd_label_size);
+
+nvdebug("%s label_size %#x, max_xfer %#x.\n", __func__, label_size, mxfer);
+
+return DSM_STATUS_SUCCESS;
+}
+
+static void dsm_write_nvdimm(MemoryRegion *dsm_ram_mr, uint32_t handle,
+ uint32_t function, dsm_in *in, dsm_out *out)
 {
 GSList *list = nvdimm_get_built_list();
 NVDIMMDevice *nvdimm = get_nvdimm_device_by_handle(list, handle);
@@ -444,6 +523,9 @@ static void dsm_write_nvdimm(uint32_t handle, uint32_t 
function, dsm_in *in,
 out->len = sizeof(out->cmd_implemented);
 out->cmd_implemented.cmd_list = cpu_to_le64(cmd_list);
 goto free;
+case DSM_CMD_NAMESPACE_LABEL_SIZE:
+status = dsm_cmd_label_size(dsm_ram_mr, nvdimm, out);
+break;
 default:
 out->len = sizeof(out->status);
 status = DSM_STATUS_NOT_SUPPORTED;
@@ -511,7 +593,7 @@ static void dsm_write(void *opaque, hwaddr addr,
 goto exit;
 }
 
-return dsm_write_nvdimm(handle, function, in, out);
+return dsm_write_nvdimm(dsm_ram_mr, handle, function, in, out);
 
 exit:
 out->len = sizeof(out->status);
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 19/32] dimm: keep the state of the whole backend memory

2015-10-10 Thread Xiao Guangrong
QEMU keeps the state of memory of dimm device during live migration,
however, it is not enough for nvdimm device as its memory does not
contain its label data, so that we should protect the whole backend
memory instead

Signed-off-by: Xiao Guangrong 
---
 hw/mem/dimm.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index b307511..efe964a 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -128,9 +128,16 @@ void dimm_memory_plug(DeviceState *dev, MemoryHotplugState 
*hpms,
 }
 
 memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
-vmstate_register_ram(mr, dev);
 numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
 
+/*
+ * save the state only for @mr is not enough as it does not contain
+ * the label data of NVDIMM device, so that we keep the state of
+ * whole hostmem instead.
+ */
+vmstate_register_ram(host_memory_backend_get_memory(dimm->hostmem, errp),
+ dev);
+
 out:
 error_propagate(errp, local_err);
 }
@@ -139,10 +146,13 @@ void dimm_memory_unplug(DeviceState *dev, 
MemoryHotplugState *hpms,
MemoryRegion *mr)
 {
 DIMMDevice *dimm = DIMM(dev);
+MemoryRegion *backend_mr;
+
+backend_mr = host_memory_backend_get_memory(dimm->hostmem, &error_abort);
 
 numa_unset_mem_node_id(dimm->addr, memory_region_size(mr), dimm->node);
 memory_region_del_subregion(&hpms->mr, mr);
-vmstate_unregister_ram(mr, dev);
+vmstate_unregister_ram(backend_mr, dev);
 }
 
 int qmp_dimm_device_list(Object *obj, void *opaque)
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 15/32] stubs: rename qmp_pc_dimm_device_list.c

2015-10-10 Thread Xiao Guangrong
Rename qmp_pc_dimm_device_list.c to qmp_dimm_device_list.c

Signed-off-by: Xiao Guangrong 
---
 stubs/Makefile.objs | 2 +-
 stubs/{qmp_pc_dimm_device_list.c => qmp_dimm_device_list.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename stubs/{qmp_pc_dimm_device_list.c => qmp_dimm_device_list.c} (100%)

diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 85e4e81..c2fdcbb 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -37,5 +37,5 @@ stub-obj-y += vmstate.o
 stub-obj-$(CONFIG_WIN32) += fd-register.o
 stub-obj-y += cpus.o
 stub-obj-y += kvm.o
-stub-obj-y += qmp_pc_dimm_device_list.o
+stub-obj-y += qmp_dimm_device_list.o
 stub-obj-y += target-monitor-defs.o
diff --git a/stubs/qmp_pc_dimm_device_list.c b/stubs/qmp_dimm_device_list.c
similarity index 100%
rename from stubs/qmp_pc_dimm_device_list.c
rename to stubs/qmp_dimm_device_list.c
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 30/32] nvdimm: support DSM_CMD_SET_NAMESPACE_LABEL_DATA

2015-10-10 Thread Xiao Guangrong
Function 6 is used to set Namespace Label Data

Signed-off-by: Xiao Guangrong 
---
 hw/mem/nvdimm/acpi.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index e0a37cb..6f05b37 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -424,6 +424,11 @@ struct cmd_out_get_label_data {
 } QEMU_PACKED;
 typedef struct cmd_out_get_label_data cmd_out_get_label_data;
 
+struct cmd_out_set_label_data {
+uint32_t status;
+};
+typedef struct cmd_out_set_label_data cmd_out_set_label_data;
+
 struct dsm_out {
 /* the size of buffer filled by QEMU. */
 uint16_t len;
@@ -433,6 +438,7 @@ struct dsm_out {
 cmd_out_implemented cmd_implemented;
 cmd_out_label_size cmd_label_size;
 cmd_out_get_label_data cmd_get_label_data;
+cmd_out_set_label_data cmd_set_label_data;
 };
 } QEMU_PACKED;
 typedef struct dsm_out dsm_out;
@@ -534,6 +540,33 @@ exit:
 return status;
 }
 
+static uint32_t
+dsm_cmd_set_label_data(NVDIMMDevice *nvdimm, dsm_in *in, dsm_out *out)
+{
+cmd_in_set_label_data *cmd_in = &in->cmd_set_label_data;
+uint32_t length, offset, status;
+
+length = cmd_in->length;
+offset = cmd_in->offset;
+le32_to_cpus(&length);
+le32_to_cpus(&offset);
+
+nvdebug("Write Label Data: offset %#x length %#x.\n", offset, length);
+if (nvdimm->label_size < length + offset) {
+nvdebug("position %#x is beyond config data (len = %#lx).\n",
+length + offset, nvdimm->label_size);
+out->len = sizeof(out->status);
+status = DSM_STATUS_INVALID_PARAS;
+goto exit;
+}
+
+status = DSM_STATUS_SUCCESS;
+memcpy(nvdimm->label_data + offset, cmd_in->in_buf, length);
+out->len = sizeof(status);
+exit:
+return status;
+}
+
 static void dsm_write_nvdimm(MemoryRegion *dsm_ram_mr, uint32_t handle,
  uint32_t function, dsm_in *in, dsm_out *out)
 {
@@ -559,6 +592,9 @@ static void dsm_write_nvdimm(MemoryRegion *dsm_ram_mr, 
uint32_t handle,
 case DSM_CMD_GET_NAMESPACE_LABEL_DATA:
 status = dsm_cmd_get_label_data(nvdimm, in, out);
 break;
+case DSM_CMD_SET_NAMESPACE_LABEL_DATA:
+status = dsm_cmd_set_label_data(nvdimm, in, out);
+break;
 default:
 out->len = sizeof(out->status);
 status = DSM_STATUS_NOT_SUPPORTED;
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 14/32] pc-dimm: drop the prefix of pc-dimm

2015-10-10 Thread Xiao Guangrong
This patch is generated by this script:

find ./ -name "*.[ch]" -o -name "*.json" -o -name "trace-events" -type f \
| xargs sed -i "s/PC_DIMM/DIMM/g"

find ./ -name "*.[ch]" -o -name "*.json" -o -name "trace-events" -type f \
| xargs sed -i "s/PCDIMM/DIMM/g"

find ./ -name "*.[ch]" -o -name "*.json" -o -name "trace-events" -type f \
| xargs sed -i "s/pc_dimm/dimm/g"

find ./ -name "trace-events" -type f | xargs sed -i "s/pc-dimm/dimm/g"

It prepares the work which abstracts dimm device type for both pc-dimm and
nvdimm

Signed-off-by: Xiao Guangrong 
---
 hmp.c   |   2 +-
 hw/acpi/ich9.c  |   6 +-
 hw/acpi/memory_hotplug.c|  16 ++---
 hw/acpi/piix4.c |   6 +-
 hw/i386/pc.c|  32 -
 hw/mem/pc-dimm.c| 148 
 hw/ppc/spapr.c  |  18 ++---
 include/hw/mem/pc-dimm.h|  62 -
 numa.c  |   2 +-
 qapi-schema.json|   8 +--
 qmp.c   |   2 +-
 stubs/qmp_pc_dimm_device_list.c |   2 +-
 trace-events|   8 +--
 13 files changed, 156 insertions(+), 156 deletions(-)

diff --git a/hmp.c b/hmp.c
index 5048eee..5c617d2 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1952,7 +1952,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict 
*qdict)
 MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
 MemoryDeviceInfoList *info;
 MemoryDeviceInfo *value;
-PCDIMMDeviceInfo *di;
+DIMMDeviceInfo *di;
 
 for (info = info_list; info; info = info->next) {
 value = info->value;
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 1c7fcfa..b0d6a67 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -440,7 +440,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, 
Error **errp)
 void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
 {
 if (pm->acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
@@ -455,7 +455,7 @@ void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, 
DeviceState *dev,
   Error **errp)
 {
 if (pm->acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
 acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq,
   &pm->acpi_memory_hotplug, dev, errp);
 } else {
@@ -468,7 +468,7 @@ void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, 
DeviceState *dev,
   Error **errp)
 {
 if (pm->acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
 acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for not supported device"
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 2ff0d5c..1f6 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -54,23 +54,23 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, 
hwaddr addr,
 o = OBJECT(mdev->dimm);
 switch (addr) {
 case 0x0: /* Lo part of phys address where DIMM is mapped */
-val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) : 0;
+val = o ? object_property_get_int(o, DIMM_ADDR_PROP, NULL) : 0;
 trace_mhp_acpi_read_addr_lo(mem_st->selector, val);
 break;
 case 0x4: /* Hi part of phys address where DIMM is mapped */
-val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 
0;
+val = o ? object_property_get_int(o, DIMM_ADDR_PROP, NULL) >> 32 : 0;
 trace_mhp_acpi_read_addr_hi(mem_st->selector, val);
 break;
 case 0x8: /* Lo part of DIMM size */
-val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) : 0;
+val = o ? object_property_get_int(o, DIMM_SIZE_PROP, NULL) : 0;
 trace_mhp_acpi_read_size_lo(mem_st->selector, val);
 break;
 case 0xc: /* Hi part of DIMM size */
-val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 
0;
+val = o ? object_property_get_int(o, DIMM_SIZE_PROP, NULL) >> 32 : 0;
 trace_mhp_acpi_read_size_hi(mem_st->selector, val);
 break;
 case 0x10: /* node proximity for _PXM method */
-val = o ? object_property_get_int(o, PC_DIMM_NODE_PROP, NULL) : 0;
+val = o ? object_property_get_int(o, DIMM_NODE_PROP, NULL) : 0;
 trace_mhp_acpi_read_pxm(mem_st->selector, val);
 break;
 case 0x14: /* pack and return is_* fields */

[Qemu-devel] [PATCH v3 20/32] dimm: introduce realize callback

2015-10-10 Thread Xiao Guangrong
nvdimm need check if the backend memory is large enough to contain label
data and init its memory region when the device is realized, so introduce
realize callback which is called after common dimm has been realize

Signed-off-by: Xiao Guangrong 
---
 hw/mem/dimm.c | 5 +
 include/hw/mem/dimm.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index efe964a..7a87761 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -422,6 +422,7 @@ static void dimm_init(Object *obj)
 static void dimm_realize(DeviceState *dev, Error **errp)
 {
 DIMMDevice *dimm = DIMM(dev);
+DIMMDeviceClass *ddc = DIMM_GET_CLASS(dimm);
 
 if (!dimm->hostmem) {
 error_setg(errp, "'" DIMM_MEMDEV_PROP "' property is not set");
@@ -434,6 +435,10 @@ static void dimm_realize(DeviceState *dev, Error **errp)
dimm->node, nb_numa_nodes ? nb_numa_nodes : 1);
 return;
 }
+
+if (ddc->realize) {
+ddc->realize(dimm, errp);
+}
 }
 
 static void dimm_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 84a62ed..663288d 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -65,6 +65,7 @@ typedef struct DIMMDeviceClass {
 DeviceClass parent_class;
 
 /* public */
+void (*realize)(DIMMDevice *dimm, Error **errp);
 MemoryRegion *(*get_memory_region)(DIMMDevice *dimm);
 } DIMMDeviceClass;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 32/32] nvdimm: add maintain info

2015-10-10 Thread Xiao Guangrong
Add NVDIMM maintainer

Signed-off-by: Xiao Guangrong 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9bde832..204d82a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -868,6 +868,12 @@ M: Jiri Pirko 
 S: Maintained
 F: hw/net/rocker/
 
+NVDIMM
+M: Xiao Guangrong 
+S: Maintained
+F: hw/mem/nvdimm/*
+F: include/hw/mem/nvdimm.h
+
 Subsystems
 --
 Audio
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 24/32] nvdimm: init the address region used by DSM method

2015-10-10 Thread Xiao Guangrong
Map the NVDIMM ACPI memory region to guest address space

Signed-off-by: Xiao Guangrong 
---
 hw/mem/nvdimm/acpi.c | 75 
 hw/mem/nvdimm/internal.h |  8 ++
 2 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index 62b1e02..1450a6a 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -271,8 +271,6 @@ static int build_structure_dcr(void *buf, NVDIMMDevice 
*nvdimm)
 
 static void build_device_structure(GSList *device_list, char *buf)
 {
-buf += sizeof(nfit);
-
 for (; device_list; device_list = device_list->next) {
 NVDIMMDevice *nvdimm = device_list->data;
 
@@ -290,7 +288,7 @@ static void build_device_structure(GSList *device_list, 
char *buf)
 }
 }
 
-static void build_nfit(GSList *device_list, GArray *table_offsets,
+static void build_nfit(void *fit, GSList *device_list, GArray *table_offsets,
GArray *table_data, GArray *linker)
 {
 size_t total;
@@ -304,12 +302,76 @@ static void build_nfit(GSList *device_list, GArray 
*table_offsets,
 acpi_add_table(table_offsets, table_data);
 
 buf = acpi_data_push(table_data, total);
-build_device_structure(device_list, buf);
+memcpy(buf + sizeof(nfit), fit, total - sizeof(nfit));
 
 build_header(linker, table_data, (void *)(table_data->data + nfit_start),
  "NFIT", table_data->len - nfit_start, 1);
 }
 
+static uint64_t dsm_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+return 0;
+}
+
+static void dsm_write(void *opaque, hwaddr addr,
+  uint64_t val, unsigned size)
+{
+}
+
+static const MemoryRegionOps dsm_ops = {
+.read = dsm_read,
+.write = dsm_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static MemoryRegion *build_dsm_memory(NVDIMMState *state)
+{
+MemoryRegion *dsm_ram_mr, *dsm_mmio_mr, *dsm_fit_mr;
+uint64_t fit_size = memory_region_size(&state->mr) - state->page_size * 2;
+
+/* DSM memory has already been built. */
+dsm_fit_mr = memory_region_find(&state->mr, state->page_size * 2,
+fit_size).mr;
+if (dsm_fit_mr) {
+nvdebug("DSM FIT has already been built by %s.\n", dsm_fit_mr->name);
+memory_region_unref(dsm_fit_mr);
+return dsm_fit_mr;
+}
+
+/*
+ * the first page is MMIO-based used to transfer control from guest
+ * ACPI to QEMU.
+ */
+dsm_mmio_mr = g_new(MemoryRegion, 1);
+memory_region_init_io(dsm_mmio_mr, NULL, &dsm_ops, state,
+  "nvdimm.dsm_mmio", state->page_size);
+
+/*
+ * the second page is RAM-based used to transfer data between guest
+ * ACPI and QEMU.
+ */
+dsm_ram_mr = g_new(MemoryRegion, 1);
+memory_region_init_ram(dsm_ram_mr, NULL, "nvdimm.dsm_ram",
+   state->page_size, &error_abort);
+vmstate_register_ram_global(dsm_ram_mr);
+
+/*
+ * the left is RAM-based which is _FIT buffer returned by _FIT
+ * method.
+ */
+dsm_fit_mr = g_new(MemoryRegion, 1);
+memory_region_init_ram(dsm_fit_mr, NULL, "nvdimm.fit", fit_size,
+   &error_abort);
+vmstate_register_ram_global(dsm_fit_mr);
+
+memory_region_add_subregion(&state->mr, 0, dsm_mmio_mr);
+memory_region_add_subregion(&state->mr, state->page_size, dsm_ram_mr);
+memory_region_add_subregion(&state->mr, state->page_size * 2, dsm_fit_mr);
+
+return dsm_fit_mr;
+}
+
 void nvdimm_build_acpi_table(NVDIMMState *state, GArray *table_offsets,
  GArray *table_data, GArray *linker)
 {
@@ -321,7 +383,10 @@ void nvdimm_build_acpi_table(NVDIMMState *state, GArray 
*table_offsets,
 }
 
 if (device_list) {
-build_nfit(device_list, table_offsets, table_data, linker);
+void *fit = memory_region_get_ram_ptr(build_dsm_memory(state));
+
+build_device_structure(device_list, fit);
+build_nfit(fit, device_list, table_offsets, table_data, linker);
 g_slist_free(device_list);
 }
 }
diff --git a/hw/mem/nvdimm/internal.h b/hw/mem/nvdimm/internal.h
index 5551448..1e95363 100644
--- a/hw/mem/nvdimm/internal.h
+++ b/hw/mem/nvdimm/internal.h
@@ -13,6 +13,14 @@
 #ifndef NVDIMM_INTERNAL_H
 #define NVDIMM_INTERNAL_H
 
+#define NVDIMM_DEBUG 0
+#define nvdebug(fmt, ...) \
+do {  \
+if (NVDIMM_DEBUG) {   \
+fprintf(stderr, "nvdimm: " fmt, ## __VA_ARGS__);  \
+} \
+} while (0)
+
 #define MIN_NAMESPACE_LABEL_SIZE(128UL << 10)
 
 struct uuid_le {
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 16/32] pc-dimm: rename pc-dimm.c and pc-dimm.h

2015-10-10 Thread Xiao Guangrong
Rename:
   pc-dimm.c => dimm.c
   pc-dimm.h => dimm.h

It prepares the work which abstracts dimm device type for both pc-dimm and
nvdimm

Signed-off-by: Xiao Guangrong 
---
 hw/Makefile.objs | 2 +-
 hw/acpi/ich9.c   | 2 +-
 hw/acpi/memory_hotplug.c | 4 ++--
 hw/acpi/piix4.c  | 2 +-
 hw/i386/pc.c | 2 +-
 hw/mem/Makefile.objs | 2 +-
 hw/mem/{pc-dimm.c => dimm.c} | 2 +-
 hw/ppc/spapr.c   | 2 +-
 include/hw/i386/pc.h | 2 +-
 include/hw/mem/{pc-dimm.h => dimm.h} | 0
 include/hw/ppc/spapr.h   | 2 +-
 numa.c   | 2 +-
 qmp.c| 2 +-
 stubs/qmp_dimm_device_list.c | 2 +-
 14 files changed, 14 insertions(+), 14 deletions(-)
 rename hw/mem/{pc-dimm.c => dimm.c} (99%)
 rename include/hw/mem/{pc-dimm.h => dimm.h} (100%)

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 7e7c241..12ecda9 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -30,8 +30,8 @@ devices-dirs-$(CONFIG_SOFTMMU) += vfio/
 devices-dirs-$(CONFIG_VIRTIO) += virtio/
 devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
 devices-dirs-$(CONFIG_SOFTMMU) += xen/
-devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
 devices-dirs-$(CONFIG_SMBIOS) += smbios/
+devices-dirs-y += mem/
 devices-dirs-y += core/
 common-obj-y += $(devices-dirs-y)
 obj-y += $(devices-dirs-y)
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index b0d6a67..1e9ae20 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -35,7 +35,7 @@
 #include "exec/address-spaces.h"
 
 #include "hw/i386/ich9.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 
 //#define DEBUG
 
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 1f6..e232641 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -1,6 +1,6 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/pc-hotplug.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "hw/boards.h"
 #include "hw/qdev-core.h"
 #include "trace.h"
@@ -148,7 +148,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr 
addr, uint64_t data,
 
 dev = DEVICE(mdev->dimm);
 hotplug_ctrl = qdev_get_hotplug_handler(dev);
-/* call pc-dimm unplug cb */
+/* call dimm unplug cb */
 hotplug_handler_unplug(hotplug_ctrl, dev, &local_err);
 if (local_err) {
 trace_mhp_acpi_dimm_delete_failed(mem_st->selector);
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 0b2cb6e..b2f5b2c 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -33,7 +33,7 @@
 #include "hw/acpi/pcihp.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/hotplug.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/xen/xen.h"
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d6b9fa7..6694b18 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -62,7 +62,7 @@
 #include "hw/boards.h"
 #include "hw/pci/pci_host.h"
 #include "acpi-build.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "qapi/visitor.h"
 #include "qapi-visit.h"
 
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index b000fb4..7563ef5 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1 +1 @@
-common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
+common-obj-$(CONFIG_MEM_HOTPLUG) += dimm.o
diff --git a/hw/mem/pc-dimm.c b/hw/mem/dimm.c
similarity index 99%
rename from hw/mem/pc-dimm.c
rename to hw/mem/dimm.c
index 9e26bf7..e007271 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/dimm.c
@@ -18,7 +18,7 @@
  * License along with this library; if not, see 
  */
 
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "qemu/config-file.h"
 #include "qapi/visitor.h"
 #include "qemu/range.h"
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4fb91a5..171fa77 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2138,7 +2138,7 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
  *
  * - Memory gets hotplugged to a different node than what the user
  *   specified.
- * - Since pc-dimm subsystem in QEMU still thinks that memory belongs
+ * - Since dimm subsystem in QEMU still thinks that memory belongs
  *   to memory-less node, a reboot will set things accordingly
  *   and the previously hotplugged memory now ends in the right node.
  *   This appears as if some memory moved from one node to another.
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 0503485..693b6c5 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -16,7 +16,7 @@
 #include "hw/pci/pci.h"
 #include "hw/boards.h"
 #include "hw/compat.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 
 #define HPET_INTCAP "hpet-intcap"
 
diff --git a/include/hw/mem/pc-dimm.h b

[Qemu-devel] [PATCH v3 25/32] nvdimm: build ACPI nvdimm devices

2015-10-10 Thread Xiao Guangrong
NVDIMM devices is defined in ACPI 6.0 9.20 NVDIMM Devices

There is a root device under \_SB and specified NVDIMM devices are under the
root device. Each NVDIMM device has _ADR which returns its handle used to
associate MEMDEV structure in NFIT

We reserve handle 0 for root device. In this patch, we save handle, arg0,
arg1 and arg2. Arg3 is conditionally saved in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/mem/nvdimm/acpi.c | 203 +++
 1 file changed, 203 insertions(+)

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index 1450a6a..d9fa0fd 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -308,15 +308,38 @@ static void build_nfit(void *fit, GSList *device_list, 
GArray *table_offsets,
  "NFIT", table_data->len - nfit_start, 1);
 }
 
+#define NOTIFY_VALUE  0x99
+
+struct dsm_in {
+uint32_t handle;
+uint8_t arg0[16];
+uint32_t arg1;
+uint32_t arg2;
+   /* the remaining size in the page is used by arg3. */
+uint8_t arg3[0];
+} QEMU_PACKED;
+typedef struct dsm_in dsm_in;
+
+struct dsm_out {
+/* the size of buffer filled by QEMU. */
+uint16_t len;
+uint8_t data[0];
+} QEMU_PACKED;
+typedef struct dsm_out dsm_out;
+
 static uint64_t dsm_read(void *opaque, hwaddr addr,
  unsigned size)
 {
+fprintf(stderr, "BUG: we never read DSM notification MMIO.\n");
 return 0;
 }
 
 static void dsm_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
+if (val != NOTIFY_VALUE) {
+fprintf(stderr, "BUG: unexepected notify value 0x%" PRIx64, val);
+}
 }
 
 static const MemoryRegionOps dsm_ops = {
@@ -372,6 +395,183 @@ static MemoryRegion *build_dsm_memory(NVDIMMState *state)
 return dsm_fit_mr;
 }
 
+#define BUILD_STA_METHOD(_dev_, _method_)  \
+do {   \
+_method_ = aml_method("_STA", 0);  \
+aml_append(_method_, aml_return(aml_int(0x0f)));   \
+aml_append(_dev_, _method_);   \
+} while (0)
+
+#define SAVE_ARG012_HANDLE_LOCK(_method_, _handle_)\
+do {   \
+aml_append(_method_, aml_acquire(aml_name("NLCK"), 0x));   \
+aml_append(_method_, aml_store(_handle_, aml_name("HDLE")));   \
+aml_append(_method_, aml_store(aml_arg(0), aml_name("ARG0"))); \
+aml_append(_method_, aml_store(aml_arg(1), aml_name("ARG1"))); \
+aml_append(_method_, aml_store(aml_arg(2), aml_name("ARG2"))); \
+} while (0)
+
+#define NOTIFY_AND_RETURN_UNLOCK(_method_)   \
+do {   \
+aml_append(_method_, aml_store(aml_int(NOTIFY_VALUE),  \
+   aml_name("NOTI"))); \
+aml_append(_method_, aml_store(aml_name("RLEN"), aml_local(6)));   \
+aml_append(_method_, aml_store(aml_shiftleft(aml_local(6), \
+  aml_int(3)), aml_local(6))); \
+aml_append(_method_, aml_create_field(aml_name("ODAT"), aml_int(0),\
+  aml_local(6) , "OBUF")); \
+aml_append(_method_, aml_name_decl("ZBUF", aml_buffer(0, NULL)));  \
+aml_append(_method_, aml_concatenate(aml_name("ZBUF"), \
+  aml_name("OBUF"), aml_arg(6)));  \
+aml_append(_method_, aml_release(aml_name("NLCK")));   \
+aml_append(_method_, aml_return(aml_arg(6)));  \
+} while (0)
+
+#define BUILD_FIELD_UNIT_STRUCT(_field_, _s_, _f_, _name_) \
+aml_append(_field_, aml_named_field(_name_,\
+   sizeof(typeof_field(_s_, _f_)) * BITS_PER_BYTE))
+
+#define BUILD_FIELD_UNIT_SIZE(_field_, _byte_, _name_) \
+aml_append(_field_, aml_named_field(_name_, (_byte_) * BITS_PER_BYTE))
+
+static void build_nvdimm_devices(NVDIMMState *state, GSList *device_list,
+ Aml *root_dev)
+{
+for (; device_list; device_list = device_list->next) {
+NVDIMMDevice *nvdimm = device_list->data;
+int slot = object_property_get_int(OBJECT(nvdimm), DIMM_SLOT_PROP,
+   NULL);
+uint32_t handle = nvdimm_slot_to_handle(slot);
+Aml *dev, *method;
+
+dev = aml_device("NV%02X", slot);
+aml_append(dev, aml_name_decl("_ADR", aml_int(handle)));
+
+BUILD_STA_METHOD(dev, method);
+
+method = aml_method("_DSM", 4);
+{
+SAVE_ARG012_HANDLE_LOCK(method, aml_int(handle));
+  

[Qemu-devel] [PATCH v3 23/32] nvdimm: build ACPI NFIT table

2015-10-10 Thread Xiao Guangrong
NFIT is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT)

Currently, we only support PMEM mode. Each device has 3 structures:
- SPA structure, defines the PMEM region info

- MEM DEV structure, it has the @handle which is used to associate specified
  ACPI NVDIMM  device we will introduce in later patch.
  Also we can happily ignored the memory device's interleave, the real
  nvdimm hardware access is hidden behind host

- DCR structure, it defines vendor ID used to associate specified vendor
  nvdimm driver. Since we only implement PMEM mode this time, Command
  window and Data window are not needed

Signed-off-by: Xiao Guangrong 
---
 hw/i386/acpi-build.c |   4 +
 hw/mem/nvdimm/acpi.c | 209 ++-
 hw/mem/nvdimm/internal.h |  13 +++
 hw/mem/nvdimm/nvdimm.c   |  25 ++
 include/hw/mem/nvdimm.h  |   2 +
 5 files changed, 252 insertions(+), 1 deletion(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 95e0c65..c637dc8 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1661,6 +1661,7 @@ static bool acpi_has_iommu(void)
 static
 void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
 {
+PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
 GArray *table_offsets;
 unsigned facs, ssdt, dsdt, rsdt;
 AcpiCpuInfo cpu;
@@ -1742,6 +1743,9 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables 
*tables)
 build_dmar_q35(tables_blob, tables->linker);
 }
 
+nvdimm_build_acpi_table(&pcms->nvdimm_memory, table_offsets, tables_blob,
+tables->linker);
+
 /* Add tables supplied by user (if any) */
 for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
 unsigned len = acpi_table_len(u);
diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index b640874..62b1e02 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -32,6 +32,46 @@
 #include "hw/mem/nvdimm.h"
 #include "internal.h"
 
+static void nfit_spa_uuid_pm(uuid_le *uuid)
+{
+uuid_le uuid_pm = UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d,
+  0x33, 0x18, 0xb7, 0x8c, 0xdb);
+memcpy(uuid, &uuid_pm, sizeof(uuid_pm));
+}
+
+enum {
+NFIT_STRUCTURE_SPA = 0,
+NFIT_STRUCTURE_MEMDEV = 1,
+NFIT_STRUCTURE_IDT = 2,
+NFIT_STRUCTURE_SMBIOS = 3,
+NFIT_STRUCTURE_DCR = 4,
+NFIT_STRUCTURE_BDW = 5,
+NFIT_STRUCTURE_FLUSH = 6,
+};
+
+enum {
+EFI_MEMORY_UC = 0x1ULL,
+EFI_MEMORY_WC = 0x2ULL,
+EFI_MEMORY_WT = 0x4ULL,
+EFI_MEMORY_WB = 0x8ULL,
+EFI_MEMORY_UCE = 0x10ULL,
+EFI_MEMORY_WP = 0x1000ULL,
+EFI_MEMORY_RP = 0x2000ULL,
+EFI_MEMORY_XP = 0x4000ULL,
+EFI_MEMORY_NV = 0x8000ULL,
+EFI_MEMORY_MORE_RELIABLE = 0x1ULL,
+};
+
+/*
+ * NVDIMM Firmware Interface Table
+ * @signature: "NFIT"
+ */
+struct nfit {
+ACPI_TABLE_HEADER_DEF
+uint32_t reserved;
+} QEMU_PACKED;
+typedef struct nfit nfit;
+
 /* System Physical Address Range Structure */
 struct nfit_spa {
 uint16_t type;
@@ -40,13 +80,21 @@ struct nfit_spa {
 uint16_t flags;
 uint32_t reserved;
 uint32_t proximity_domain;
-uint8_t type_guid[16];
+uuid_le type_guid;
 uint64_t spa_base;
 uint64_t spa_length;
 uint64_t mem_attr;
 } QEMU_PACKED;
 typedef struct nfit_spa nfit_spa;
 
+/*
+ * Control region is strictly for management during hot add/online
+ * operation.
+ */
+#define SPA_FLAGS_ADD_ONLINE_ONLY (1)
+/* Data in Proximity Domain field is valid. */
+#define SPA_FLAGS_PROXIMITY_VALID (1 << 1)
+
 /* Memory Device to System Physical Address Range Mapping Structure */
 struct nfit_memdev {
 uint16_t type;
@@ -91,12 +139,20 @@ struct nfit_dcr {
 } QEMU_PACKED;
 typedef struct nfit_dcr nfit_dcr;
 
+#define REVSISON_ID1
+#define NFIT_FIC1  0x201
+
 static uint64_t nvdimm_device_structure_size(uint64_t slots)
 {
 /* each nvdimm has three structures. */
 return slots * (sizeof(nfit_spa) + sizeof(nfit_memdev) + sizeof(nfit_dcr));
 }
 
+static uint64_t get_nfit_total_size(uint64_t slots)
+{
+return sizeof(struct nfit) + nvdimm_device_structure_size(slots);
+}
+
 static uint64_t nvdimm_acpi_memory_size(uint64_t slots, uint64_t page_size)
 {
 uint64_t size = nvdimm_device_structure_size(slots);
@@ -118,3 +174,154 @@ void nvdimm_init_memory_state(NVDIMMState *state, 
MemoryRegion*system_memory,
NVDIMM_ACPI_MEM_SIZE);
 memory_region_add_subregion(system_memory, state->base, &state->mr);
 }
+
+static uint32_t nvdimm_slot_to_sn(int slot)
+{
+return 0x123456 + slot;
+}
+
+static uint32_t nvdimm_slot_to_handle(int slot)
+{
+return slot + 1;
+}
+
+static uint16_t nvdimm_slot_to_spa_index(int slot)
+{
+return (slot + 1) << 1;
+}
+
+static uint32_t nvdimm_slot_to_dcr_index(int slot)
+{
+return nvdimm_slot_to_spa_index(slot) + 1;
+}
+
+static int build_structure_spa(void *buf, NVDIMMDevice *nvdimm)
+{
+nfit_spa *nfit_spa

[Qemu-devel] [PATCH v3 26/32] nvdimm: save arg3 for NVDIMM device _DSM method

2015-10-10 Thread Xiao Guangrong
Check if the input Arg3 is valid then store it into dsm_in if needed

We only do the save on NVDIMM device since we are not going to support any
function on root device

Signed-off-by: Xiao Guangrong 
---
 hw/mem/nvdimm/acpi.c | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index d9fa0fd..3b9399c 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -442,7 +442,7 @@ static void build_nvdimm_devices(NVDIMMState *state, GSList 
*device_list,
 int slot = object_property_get_int(OBJECT(nvdimm), DIMM_SLOT_PROP,
NULL);
 uint32_t handle = nvdimm_slot_to_handle(slot);
-Aml *dev, *method;
+Aml *dev, *method, *ifctx;
 
 dev = aml_device("NV%02X", slot);
 aml_append(dev, aml_name_decl("_ADR", aml_int(handle)));
@@ -452,6 +452,24 @@ static void build_nvdimm_devices(NVDIMMState *state, 
GSList *device_list,
 method = aml_method("_DSM", 4);
 {
 SAVE_ARG012_HANDLE_LOCK(method, aml_int(handle));
+
+/* Arg3 is passed as Package and it has one element? */
+ifctx = aml_if(aml_and(aml_equal(aml_object_type(aml_arg(3)),
+ aml_int(4)),
+   aml_equal(aml_sizeof(aml_arg(3)),
+ aml_int(1;
+{
+/* Local0 = Index(Arg3, 0) */
+aml_append(ifctx, aml_store(aml_index(aml_arg(3), aml_int(0)),
+aml_local(0)));
+/* Local3 = DeRefOf(Local0) */
+aml_append(ifctx, aml_store(aml_derefof(aml_local(0)),
+aml_local(3)));
+/* ARG3 = Local3 */
+aml_append(ifctx, aml_store(aml_local(3), aml_name("ARG3")));
+}
+aml_append(method, ifctx);
+
 NOTIFY_AND_RETURN_UNLOCK(method);
 }
 aml_append(dev, method);
@@ -534,6 +552,7 @@ static void nvdimm_build_acpi_devices(NVDIMMState *state, 
GSList *device_list,
 method = aml_method("_DSM", 4);
 {
 SAVE_ARG012_HANDLE_LOCK(method, aml_int(0));
+/* no command we support on ROOT device has Arg3. */
 NOTIFY_AND_RETURN_UNLOCK(method);
 }
 aml_append(dev, method);
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 29/32] nvdimm: support DSM_CMD_GET_NAMESPACE_LABEL_DATA

2015-10-10 Thread Xiao Guangrong
Function 5 is used to get Namespace Label Data

Signed-off-by: Xiao Guangrong 
---
 hw/mem/nvdimm/acpi.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index b420e2f..e0a37cb 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -401,6 +401,7 @@ struct dsm_in {
 union {
 uint8_t arg3[0];
 cmd_in_set_label_data cmd_set_label_data;
+cmd_in_get_label_data cmd_get_label_data;
 };
 } QEMU_PACKED;
 typedef struct dsm_in dsm_in;
@@ -504,6 +505,35 @@ dsm_cmd_label_size(MemoryRegion *dsm_ram_mr, NVDIMMDevice 
*nvdimm,
 return DSM_STATUS_SUCCESS;
 }
 
+static uint32_t dsm_cmd_get_label_data(NVDIMMDevice *nvdimm, dsm_in *in,
+   dsm_out *out)
+{
+cmd_in_get_label_data *cmd_in = &in->cmd_get_label_data;
+uint32_t length, offset, status;
+
+length = cmd_in->length;
+offset = cmd_in->offset;
+le32_to_cpus(&length);
+le32_to_cpus(&offset);
+
+nvdebug("Read Label Data: offset %#x length %#x.\n", offset, length);
+
+if (nvdimm->label_size < length + offset) {
+nvdebug("position %#x is beyond label data (len = %#lx).\n",
+length + offset, nvdimm->label_size);
+out->len = sizeof(out->status);
+status = DSM_STATUS_INVALID_PARAS;
+goto exit;
+}
+
+status = DSM_STATUS_SUCCESS;
+memcpy(out->cmd_get_label_data.out_buf, nvdimm->label_data +
+   offset, length);
+out->len = sizeof(out->cmd_get_label_data) + length;
+exit:
+return status;
+}
+
 static void dsm_write_nvdimm(MemoryRegion *dsm_ram_mr, uint32_t handle,
  uint32_t function, dsm_in *in, dsm_out *out)
 {
@@ -526,6 +556,9 @@ static void dsm_write_nvdimm(MemoryRegion *dsm_ram_mr, 
uint32_t handle,
 case DSM_CMD_NAMESPACE_LABEL_SIZE:
 status = dsm_cmd_label_size(dsm_ram_mr, nvdimm, out);
 break;
+case DSM_CMD_GET_NAMESPACE_LABEL_DATA:
+status = dsm_cmd_get_label_data(nvdimm, in, out);
+break;
 default:
 out->len = sizeof(out->status);
 status = DSM_STATUS_NOT_SUPPORTED;
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v7 05/14] qapi: Lazy creation of array types

2015-10-10 Thread Eric Blake
On 10/07/2015 10:38 AM, Markus Armbruster wrote:
> Eric Blake  writes:
> 
>> Commit ac88219a had several TODO markers about whether we needed
>> to automatically create the corresponding array type alongside
>> any other type.  It turns out that most of the time, we don't!
>>

>> +def _make_simple_variant(self, case, typ, info):
>>  if isinstance(typ, list):
>>  assert len(typ) == 1
>> -typ = self._make_array_type(typ[0])
>> -typ = self._make_implicit_object_type(typ, 'wrapper',
>> -  [self._make_member('data', 
>> typ)])
>> +typ = self._make_array_type(typ[0], info)
>> +typ = self._make_implicit_object_type(
>> +typ, 'wrapper', [self._make_member('data', typ, info)])
> 
> I'd indent the hanging intent a bit more, to make the = stand out.

pep8 doesn't like it:

scripts/qapi.py:1299:17: E126 continuation line over-indented for
hanging indent

but it was okay with:

type = (self._make_implicit_object_type(
type, ...))

and that does look a little better.

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v3 31/32] nvdimm: allow using whole backend memory as pmem

2015-10-10 Thread Xiao Guangrong
Introduce a parameter, named "reserve-label-data", which indicates
that QEMU does not reserve any region on the backend memory to
support label data, instead, it will build a readonly label data
in memory which has a active namespace containing whole backend
memory

This is useful for the users who want to pass whole nvdimm device
and make its data completely be visible to guest

The parameter is false on default

Signed-off-by: Xiao Guangrong 
---
 hw/mem/Makefile.objs  |   3 +-
 hw/mem/nvdimm/acpi.c  |  20 +++
 hw/mem/nvdimm/internal.h  |   3 +
 hw/mem/nvdimm/namespace.c | 309 ++
 hw/mem/nvdimm/nvdimm.c|  36 +-
 include/hw/mem/nvdimm.h   |   4 +
 6 files changed, 369 insertions(+), 6 deletions(-)
 create mode 100644 hw/mem/nvdimm/namespace.c

diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index 7310bac..fc76ca5 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1,3 +1,4 @@
 common-obj-$(CONFIG_DIMM) += dimm.o
 common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
-common-obj-$(CONFIG_NVDIMM) += nvdimm/nvdimm.o nvdimm/acpi.o
+common-obj-$(CONFIG_NVDIMM) += nvdimm/nvdimm.o nvdimm/acpi.o   \
+   nvdimm/namespace.o
diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index 6f05b37..e6694bc 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -305,6 +305,8 @@ static void build_device_structure(GSList *device_list, 
char *buf)
 {
 for (; device_list; device_list = device_list->next) {
 NVDIMMDevice *nvdimm = device_list->data;
+nfit_memdev *memdev;
+nfit_dcr *dcr;
 
 /* build System Physical Address Range Description Table. */
 buf += build_structure_spa(buf, nvdimm);
@@ -313,10 +315,15 @@ static void build_device_structure(GSList *device_list, 
char *buf)
  * build Memory Device to System Physical Address Range Mapping
  * Table.
  */
+memdev = (nfit_memdev *)buf;
 buf += build_structure_memdev(buf, nvdimm);
 
 /* build Control Region Descriptor Table. */
+dcr = (struct nfit_dcr *)buf;
 buf += build_structure_dcr(buf, nvdimm);
+
+calculate_nvdimm_isetcookie(nvdimm, memdev->region_offset,
+dcr->serial_number);
 }
 }
 
@@ -560,6 +567,12 @@ dsm_cmd_set_label_data(NVDIMMDevice *nvdimm, dsm_in *in, 
dsm_out *out)
 goto exit;
 }
 
+if (!nvdimm->reserve_label_data) {
+out->len = sizeof(out->status);
+status = DSM_STATUS_NOT_SUPPORTED;
+goto exit;
+}
+
 status = DSM_STATUS_SUCCESS;
 memcpy(nvdimm->label_data + offset, cmd_in->in_buf, length);
 out->len = sizeof(status);
@@ -583,6 +596,10 @@ static void dsm_write_nvdimm(MemoryRegion *dsm_ram_mr, 
uint32_t handle,
 switch (function) {
 case DSM_CMD_IMPLEMENTED:
 cmd_list = DIMM_SUPPORT_CMD;
+if (!nvdimm->reserve_label_data) {
+cmd_list &= ~(1 << DSM_CMD_SET_NAMESPACE_LABEL_DATA);
+}
+
 out->len = sizeof(out->cmd_implemented);
 out->cmd_implemented.cmd_list = cpu_to_le64(cmd_list);
 goto free;
@@ -936,6 +953,9 @@ void nvdimm_build_acpi_table(NVDIMMState *state, GArray 
*table_offsets,
 
 nvdimm_build_ssdt(state, device_list, table_offsets, table_data,
   linker);
+
+build_nvdimm_label_data(device_list);
+
 g_slist_free(device_list);
 }
 }
diff --git a/hw/mem/nvdimm/internal.h b/hw/mem/nvdimm/internal.h
index 1e95363..f523175 100644
--- a/hw/mem/nvdimm/internal.h
+++ b/hw/mem/nvdimm/internal.h
@@ -35,4 +35,7 @@ typedef struct uuid_le uuid_le;
 (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
 
 GSList *nvdimm_get_built_list(void);
+void calculate_nvdimm_isetcookie(NVDIMMDevice *nvdimm, uint64_t spa_offset,
+ uint32_t sn);
+void build_nvdimm_label_data(GSList *device_list);
 #endif
diff --git a/hw/mem/nvdimm/namespace.c b/hw/mem/nvdimm/namespace.c
new file mode 100644
index 000..fe58f9a
--- /dev/null
+++ b/hw/mem/nvdimm/namespace.c
@@ -0,0 +1,309 @@
+/*
+ * NVDIMM  Namespace Support
+ *
+ * Copyright(C) 2015 Intel Corporation.
+ *
+ * Author:
+ *  Xiao Guangrong 
+ *
+ * NVDIMM namespace specification can be found at:
+ *  http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along wit

[Qemu-devel] Arm virtual machine networking problem with build for 64bit host

2015-10-10 Thread mar.krzeminski

Hello,

I have my own virtual machine (already asked some questions about that 
here).
I also have my own gmac model. I am building qemu (version 2.4.0.1) for 
32 and 64 linux hosts.
The problem is with 64 bit binary. If I run as guest under qemu linux, I 
could not even ping my machine.
In 32 bit version it works fine. And if I run in this 64 bit host u-boot 
pingf from u-boot qorks fine.
From debugging it seems that under linux (32 bit arm) started on 64 
linux host can_receive function from my model,
is called only once when virtual machine is booting, there is no 
furthers call so that is why I can not ping.

I am running qemu in this way (based on yocto scripts):

/qemu-system-arm -kernel zImage.bin -net nic,vlan=0 -net 
tap,vlan=0,ifname=tap0,script=no,downscript=no -M macine-a9 -dtb 
zImage.dtb -serial null -serial null -serial null -serial mon:stdio 
-serial null -nographic -smp 2 -readconfig config -m 512 --append 
"ip=192.168.7.2::192.168.7.1:255.255.255.0 noinitrd console=ttyS3,19200 
earlyprintk debug=31"/


As there is lack of documentation (or maybe there is but I haven't got 
it ), my question is where should I start debugging what is going wrong?
As for now it seems that my model does not receive ping and it is not 
asked if can receive one. Situation is same when I ping from quest the 
host's tap,

or from host guest machine.

Regards,
Marcin


Re: [Qemu-devel] [PULL 41/48] tests: add ivshmem qtest

2015-10-10 Thread Michael Roth
Quoting marcandre.lur...@redhat.com (2015-10-06 14:19:37)
> From: Marc-André Lureau 
> 
> Adds 4 ivshmemtests:
> - single qemu instance and basic IO
> - pair of instances, check memory sharing
> - pair of instances with server, and MSIX
> - hot plug/unplug
> 
> A temporary shm is created as well as a directory to place server
> socket, both should be clear on exit and abort.
> 
> Cc: Cam Macdonell 
> CC: Andreas Färber 
> Signed-off-by: Marc-André Lureau 
> Reviewed-by: Claudio Fontana 
> ---
>  tests/Makefile   |   3 +
>  tests/ivshmem-test.c | 484 
> +++
>  2 files changed, 487 insertions(+)
>  create mode 100644 tests/ivshmem-test.c
> 
> diff --git a/tests/Makefile b/tests/Makefile
> index e6474ba..4f78ea4 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -146,6 +146,8 @@ gcov-files-pci-y += hw/display/virtio-gpu-pci.c
>  gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c
>  check-qtest-pci-y += tests/intel-hda-test$(EXESUF)
>  gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
> +check-qtest-pci-$(CONFIG_LINUX) += tests/ivshmem-test$(EXESUF)
> +gcov-files-pci-y += hw/misc/ivshmem.c
> 
>  check-qtest-i386-y = tests/endianness-test$(EXESUF)
>  check-qtest-i386-y += tests/fdc-test$(EXESUF)
> @@ -437,6 +439,7 @@ tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o 
> qemu-char.o qemu-timer.o
>  tests/qemu-iotests/socket_scm_helper$(EXESUF): 
> tests/qemu-iotests/socket_scm_helper.o
>  tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
>  tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
> $(test-block-obj-y)
> +tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o 
> contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
> 
>  ifeq ($(CONFIG_POSIX),y)
>  LIBS += -lutil
> diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
> new file mode 100644
> index 000..f872592
> --- /dev/null
> +++ b/tests/ivshmem-test.c
> @@ -0,0 +1,484 @@
> +/*
> + * QTest testcase for ivshmem
> + *
> + * Copyright (c) 2015 Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "contrib/ivshmem-server/ivshmem-server.h"
> +#include "libqos/pci-pc.h"
> +#include "libqtest.h"
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +
> +#if GLIB_CHECK_VERSION(2, 32, 0)
> +#define HAVE_THREAD_NEW
> +#endif
> +
> +#define TMPSHMSIZE (1 << 20)
> +static char *tmpshm;
> +static void *tmpshmem;
> +static char *tmpdir;
> +static char *tmpserver;
> +
> +static void save_fn(QPCIDevice *dev, int devfn, void *data)
> +{
> +QPCIDevice **pdev = (QPCIDevice **) data;
> +
> +*pdev = dev;
> +}
> +
> +static QPCIDevice *get_device(void)
> +{
> +QPCIDevice *dev;
> +QPCIBus *pcibus;
> +
> +pcibus = qpci_init_pc();
> +qpci_device_foreach(pcibus, 0x1af4, 0x1110, save_fn, &dev);
> +g_assert(dev != NULL);
> +
> +return dev;
> +}
> +
> +typedef struct _IVState {
> +QTestState *qtest;
> +void *reg_base, *mem_base;
> +QPCIDevice *dev;
> +} IVState;
> +
> +enum Reg {
> +INTRMASK = 0,
> +INTRSTATUS = 4,
> +IVPOSITION = 8,
> +DOORBELL = 12,
> +};
> +
> +static const char* reg2str(enum Reg reg) {
> +switch (reg) {
> +case INTRMASK:
> +return "IntrMask";
> +case INTRSTATUS:
> +return "IntrStatus";
> +case IVPOSITION:
> +return "IVPosition";
> +case DOORBELL:
> +return "DoorBell";
> +default:
> +return NULL;
> +}
> +}
> +
> +static inline unsigned in_reg(IVState *s, enum Reg reg)
> +{
> +const char *name = reg2str(reg);
> +QTestState *qtest = global_qtest;
> +unsigned res;
> +
> +global_qtest = s->qtest;
> +res = qpci_io_readl(s->dev, s->reg_base + reg);
> +g_test_message("*%s -> %x\n", name, res);
> +global_qtest = qtest;
> +
> +return res;
> +}
> +
> +static inline void out_reg(IVState *s, enum Reg reg, unsigned v)
> +{
> +const char *name = reg2str(reg);
> +QTestState *qtest = global_qtest;
> +
> +global_qtest = s->qtest;
> +g_test_message("%x -> *%s\n", v, name);
> +qpci_io_writel(s->dev, s->reg_base + reg, v);
> +global_qtest = qtest;
> +}
> +
> +static void setup_vm_cmd(IVState *s, const char *cmd, bool msix)
> +{
> +uint64_t barsize;
> +
> +s->qtest = qtest_start(cmd);
> +
> +s->dev = get_device();
> +
> +/* FIXME: other bar order fails, mappings changes */
> +s->mem_base = qpci_iomap(s->dev, 2, &barsize);
> +g_assert_nonnull(s->mem_base);
> +g_assert_cmpuint(barsize, ==, TMPSHMSIZE);
> +
> +if (msix) {
> +qpci_msix_enable(s->dev);
> +}
> +
> +s->reg_base = qpci_iomap(s->dev, 0, &barsize);
> +g_assert_nonnull(s->reg_base);
> +g_assert_cmpuint(barsize, ==, 256);
> +
> +qpci_devic

[Qemu-devel] [PATCH 1/2] tests: Add ivshmem qtest

2015-10-10 Thread Andreas Färber
Note that it launches two instances, as sharing memory is the purpose
of Nahanni/ivshmem.

Cc: Cam Macdonell 
Cc: Marc-André Lureau 
Signed-off-by: Andreas Färber 
---
 tests/Makefile   |  3 +++
 tests/ivshmem-test.c | 51 +++
 2 files changed, 54 insertions(+)
 create mode 100644 tests/ivshmem-test.c

diff --git a/tests/Makefile b/tests/Makefile
index e6474ba..3b7e6ac 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -191,6 +191,8 @@ gcov-files-i386-y += hw/pci-host/q35.c
 ifeq ($(CONFIG_VHOST_NET),y)
 check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
 endif
+check-qtest-i386-y += tests/ivshmem-test$(EXESUF)
+gcov-files-i386-y += i386-softmmu/hw/misc/ivshmem.c
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -434,6 +436,7 @@ tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o 
$(libqos-usb-obj-y)
 tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
 tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
 tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o 
qemu-timer.o $(qtest-obj-y)
+tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o
 tests/qemu-iotests/socket_scm_helper$(EXESUF): 
tests/qemu-iotests/socket_scm_helper.o
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
 tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
$(test-block-obj-y)
diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
new file mode 100644
index 000..45fe2ae
--- /dev/null
+++ b/tests/ivshmem-test.c
@@ -0,0 +1,51 @@
+/*
+ * QTest testcase for Nahanni
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+static char dev_shm_path[] = "/dev/shm/qtest.XX";
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+QTestState *s1, *s2;
+char *cmd;
+int ret, fd;
+
+g_test_init(&argc, &argv, NULL);
+qtest_add_func("/ivshmem/nop", nop);
+
+fd = mkstemp(dev_shm_path);
+g_assert(fd >= 0);
+close(fd);
+unlink(dev_shm_path);
+
+cmd = g_strdup_printf("-device ivshmem,shm=%s,size=1M", &dev_shm_path[9]);
+s1 = qtest_start(cmd);
+s2 = qtest_start(cmd);
+g_free(cmd);
+
+ret = g_test_run();
+
+qtest_quit(s1);
+qtest_quit(s2);
+
+unlink(dev_shm_path);
+
+return ret;
+}
-- 
2.1.4




[Qemu-devel] [PATCH 2/2] ivshmem-test: Implement tests

2015-10-10 Thread Andreas Färber
From: Marc-André Lureau 

Add 4 ivshmem tests:
- single qemu instance and basic IO
- pair of instances, check memory sharing
- pair of instances with server, and MSIX
- hot plug/unplug

A temporary shm is created as well as a directory to place server
socket, both should be clear on exit and abort.

Cc: Cam Macdonell 
Signed-off-by: Marc-André Lureau 
Reviewed-by: Claudio Fontana 
Signed-off-by: Andreas Färber 
---
 tests/Makefile   |   6 +-
 tests/ivshmem-test.c | 474 ---
 2 files changed, 457 insertions(+), 23 deletions(-)

diff --git a/tests/Makefile b/tests/Makefile
index 3b7e6ac..324829b 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -146,6 +146,8 @@ gcov-files-pci-y += hw/display/virtio-gpu-pci.c
 gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c
 check-qtest-pci-y += tests/intel-hda-test$(EXESUF)
 gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
+check-qtest-pci-$(CONFIG_LINUX) += tests/ivshmem-test$(EXESUF)
+gcov-files-pci-y += hw/misc/ivshmem.c
 
 check-qtest-i386-y = tests/endianness-test$(EXESUF)
 check-qtest-i386-y += tests/fdc-test$(EXESUF)
@@ -191,8 +193,6 @@ gcov-files-i386-y += hw/pci-host/q35.c
 ifeq ($(CONFIG_VHOST_NET),y)
 check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
 endif
-check-qtest-i386-y += tests/ivshmem-test$(EXESUF)
-gcov-files-i386-y += i386-softmmu/hw/misc/ivshmem.c
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -436,7 +436,7 @@ tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o 
$(libqos-usb-obj-y)
 tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
 tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
 tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o 
qemu-timer.o $(qtest-obj-y)
-tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o
+tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o 
contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
 tests/qemu-iotests/socket_scm_helper$(EXESUF): 
tests/qemu-iotests/socket_scm_helper.o
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
 tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
$(test-block-obj-y)
diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
index 45fe2ae..c146640 100644
--- a/tests/ivshmem-test.c
+++ b/tests/ivshmem-test.c
@@ -2,50 +2,484 @@
  * QTest testcase for Nahanni
  *
  * Copyright (c) 2014 SUSE LINUX Products GmbH
+ * Copyright (c) 2015 Red Hat, Inc.
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
 
+#include 
+#include 
 #include 
-#include 
+#include 
 #include 
+#include 
 #include 
+#include "contrib/ivshmem-server/ivshmem-server.h"
+#include "libqos/pci-pc.h"
 #include "libqtest.h"
 #include "qemu/osdep.h"
+#include "qemu-common.h"
 
-static char dev_shm_path[] = "/dev/shm/qtest.XX";
+#if GLIB_CHECK_VERSION(2, 32, 0)
+#define HAVE_THREAD_NEW
+#endif
 
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void nop(void)
+#define TMPSHMSIZE (1 << 20)
+static char *tmpshm;
+static void *tmpshmem;
+static char *tmpdir;
+static char *tmpserver;
+
+static void save_fn(QPCIDevice *dev, int devfn, void *data)
+{
+QPCIDevice **pdev = (QPCIDevice **) data;
+
+*pdev = dev;
+}
+
+static QPCIDevice *get_device(void)
+{
+QPCIDevice *dev;
+QPCIBus *pcibus;
+
+pcibus = qpci_init_pc();
+qpci_device_foreach(pcibus, 0x1af4, 0x1110, save_fn, &dev);
+g_assert(dev != NULL);
+
+return dev;
+}
+
+typedef struct _IVState {
+QTestState *qtest;
+void *reg_base, *mem_base;
+QPCIDevice *dev;
+} IVState;
+
+enum Reg {
+INTRMASK = 0,
+INTRSTATUS = 4,
+IVPOSITION = 8,
+DOORBELL = 12,
+};
+
+static const char* reg2str(enum Reg reg) {
+switch (reg) {
+case INTRMASK:
+return "IntrMask";
+case INTRSTATUS:
+return "IntrStatus";
+case IVPOSITION:
+return "IVPosition";
+case DOORBELL:
+return "DoorBell";
+default:
+return NULL;
+}
+}
+
+static inline unsigned in_reg(IVState *s, enum Reg reg)
+{
+const char *name = reg2str(reg);
+QTestState *qtest = global_qtest;
+unsigned res;
+
+global_qtest = s->qtest;
+res = qpci_io_readl(s->dev, s->reg_base + reg);
+g_test_message("*%s -> %x\n", name, res);
+global_qtest = qtest;
+
+return res;
+}
+
+static inline void out_reg(IVState *s, enum Reg reg, unsigned v)
+{
+const char *name = reg2str(reg);
+QTestState *qtest = global_qtest;
+
+global_qtest = s->qtest;
+g_test_message("%x -> *%s\n", v, name);
+qpci_io_writel(s->dev, s->reg_base + reg, v);
+global_qtest = qtest;
+}
+
+static void setup_vm_cmd(IVState *s, const char *cmd, bool msix)
+{
+uint64_t barsize

Re: [Qemu-devel] [PATCH 2/2] ivshmem-test: Implement tests

2015-10-10 Thread Andreas Färber
Am 11.10.2015 um 00:18 schrieb Andreas Färber:
> diff --git a/tests/Makefile b/tests/Makefile
> index 3b7e6ac..324829b 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -146,6 +146,8 @@ gcov-files-pci-y += hw/display/virtio-gpu-pci.c
>  gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c
>  check-qtest-pci-y += tests/intel-hda-test$(EXESUF)
>  gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
> +check-qtest-pci-$(CONFIG_LINUX) += tests/ivshmem-test$(EXESUF)
> +gcov-files-pci-y += hw/misc/ivshmem.c
>  
>  check-qtest-i386-y = tests/endianness-test$(EXESUF)
>  check-qtest-i386-y += tests/fdc-test$(EXESUF)
> @@ -191,8 +193,6 @@ gcov-files-i386-y += hw/pci-host/q35.c
>  ifeq ($(CONFIG_VHOST_NET),y)
>  check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
>  endif
> -check-qtest-i386-y += tests/ivshmem-test$(EXESUF)
> -gcov-files-i386-y += i386-softmmu/hw/misc/ivshmem.c
>  check-qtest-x86_64-y = $(check-qtest-i386-y)
>  gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
>  gcov-files-x86_64-y = $(subst 
> i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
[snip]

This is a quick rebase onto the last version of my older patch. I notice
that the gcov path is different: hw/misc/Makefile.objs has it in obj-y,
not common-obj-y; the .c path counter-intuitively needs to match the .o
file, not the .c file.

Untested whether adding i386-softmmu/ prefix would work for
check-qtest-pci-y, too.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton; HRB 21284 (AG Nürnberg)



Re: [Qemu-devel] [PATCH 1/2] tests: Add ivshmem qtest

2015-10-10 Thread Marc-André Lureau
Hi Andreas,

Thanks for the patches. I suppose I should insert it in my ivshmem
series, since the second patch requires it.

On Sun, Oct 11, 2015 at 12:18 AM, Andreas Färber  wrote:
> + * QTest testcase for Nahanni

I think nahanni is an archaic codename (not used in qemu code),
ivshmem is really more clear today.

(I'll try to verify/review your test asap)




-- 
Marc-André Lureau



Re: [Qemu-devel] [PATCH v3 00/32] implement vNVDIMM

2015-10-10 Thread Dan Williams
On Sat, Oct 10, 2015 at 8:52 PM, Xiao Guangrong
 wrote:
[..]
> == Test ==
> In host
> 1) create memory backed file, e.g # dd if=zero of=/tmp/nvdimm bs=1G count=10
> 2) append "-object memory-backend-file,share,id=mem1,
>mem-path=/tmp/nvdimm -device nvdimm,memdev=mem1,reserve-label-data,
>id=nv1" in QEMU command line
>
> In guest, download the latest upsteam kernel (4.2 merge window) and enable
> ACPI_NFIT, LIBNVDIMM and BLK_DEV_PMEM.
> 1) insmod drivers/nvdimm/libnvdimm.ko
> 2) insmod drivers/acpi/nfit.ko
> 3) insmod drivers/nvdimm/nd_btt.ko
> 4) insmod drivers/nvdimm/nd_pmem.ko
> You can see the whole nvdimm device used as a single namespace and /dev/pmem0
> appears. You can do whatever on /dev/pmem0 including DAX access.
>
> Currently Linux NVDIMM driver does not support namespace operation on this
> kind of PMEM, apply below changes to support dynamical namespace:
>
> @@ -798,7 +823,8 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc 
> *a
> continue;
> }
>
> -   if (nfit_mem->bdw && nfit_mem->memdev_pmem)
> +   //if (nfit_mem->bdw && nfit_mem->memdev_pmem)
> +   if (nfit_mem->memdev_pmem)
> flags |= NDD_ALIASING;

This is just for testing purposes, right?  I expect guests can
sub-divide persistent memory capacity by partitioning the resulting
block device(s).