Re: [PATCH v2 08/21] aspeed/sdhci: Fix reset sequence

2020-08-24 Thread Joel Stanley
On Wed, 19 Aug 2020 at 10:10, Cédric Le Goater  wrote:
>
> BIT(0) of the ASPEED_SDHCI_INFO register is set by SW and polled until
> the bit is cleared by HW.
>
> Use the number of supported slots to define the default value of this
> register (The AST2600 eMMC Controller only has one). Fix the reset
> sequence by clearing automatically the RESET bit.
>
> Cc: Eddie James 
> Fixes: 2bea128c3d0b ("hw/sd/aspeed_sdhci: New device")
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Joel Stanley 

> ---
>  hw/sd/aspeed_sdhci.c | 14 --
>  1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
> index 22cafce0fbdc..4f24b7d2f942 100644
> --- a/hw/sd/aspeed_sdhci.c
> +++ b/hw/sd/aspeed_sdhci.c
> @@ -16,7 +16,9 @@
>  #include "hw/qdev-properties.h"
>
>  #define ASPEED_SDHCI_INFO0x00
> -#define  ASPEED_SDHCI_INFO_RESET 0x0003
> +#define  ASPEED_SDHCI_INFO_SLOT1 (1 << 17)
> +#define  ASPEED_SDHCI_INFO_SLOT0 (1 << 16)
> +#define  ASPEED_SDHCI_INFO_RESET (1 << 0)
>  #define ASPEED_SDHCI_DEBOUNCE0x04
>  #define  ASPEED_SDHCI_DEBOUNCE_RESET 0x0005
>  #define ASPEED_SDHCI_BUS 0x08
> @@ -67,6 +69,10 @@ static void aspeed_sdhci_write(void *opaque, hwaddr addr, 
> uint64_t val,
>  AspeedSDHCIState *sdhci = opaque;
>
>  switch (addr) {
> +case ASPEED_SDHCI_INFO:
> +/* The RESET bit automatically clears. */
> +sdhci->regs[TO_REG(addr)] = (uint32_t)val & ~ASPEED_SDHCI_INFO_RESET;
> +break;
>  case ASPEED_SDHCI_SDIO_140:
>  sdhci->slots[0].capareg = (uint64_t)(uint32_t)val;
>  break;
> @@ -155,7 +161,11 @@ static void aspeed_sdhci_reset(DeviceState *dev)
>  AspeedSDHCIState *sdhci = ASPEED_SDHCI(dev);
>
>  memset(sdhci->regs, 0, ASPEED_SDHCI_REG_SIZE);
> -sdhci->regs[TO_REG(ASPEED_SDHCI_INFO)] = ASPEED_SDHCI_INFO_RESET;
> +
> +sdhci->regs[TO_REG(ASPEED_SDHCI_INFO)] = ASPEED_SDHCI_INFO_SLOT0;
> +if (sdhci->num_slots == 2) {
> +sdhci->regs[TO_REG(ASPEED_SDHCI_INFO)] |= ASPEED_SDHCI_INFO_SLOT1;
> +}
>  sdhci->regs[TO_REG(ASPEED_SDHCI_DEBOUNCE)] = ASPEED_SDHCI_DEBOUNCE_RESET;
>  }
>
> --
> 2.25.4
>



Re: Contributor wanting to get started with simple contributions

2020-08-24 Thread Thomas Huth

On 25/08/2020 04.26, Rohit Shinde wrote:

Hey John,

I sent this email a couple of weeks ago to the qemu mailing list since I 
didn't really know who to approach.


 Hi Rohit,

The qemu-devel mailing list is very high traffic. So I'm sorry, but you 
might need to be a little bit more specific with your questions if you 
expect an answer...



I have built qemu from source and I have my machine setup for
git-publish via email.

I would like to start contributing with one of the bite sized tasks
mentioned in the wiki page. The one that interests me and which I
think is the easiest are the sections on "Compiler Driven Cleanup"
and "Dead Code Removal". I think this is a good way to get
introduced to the codebase.


Sure, just go ahead and have a try! Once you've successfully wrote a 
patch, please have a look at 
https://wiki.qemu.org/Contribute/SubmitAPatch how to submit it.



I plan to stay and become a long term contributor. Is there any CS


What does "CS" stand for?


theory that I would need to know other than what I mentioned above?
Is it possible to "learn on the go"?


You certainly have to "learn on the go", since it is likely quite 
impossible to grasp a huge project like QEMU at once.


 Cheers,
  Thomas




Re: [PATCH 6/6] virtio-vga: Use typedef name for instance_size

2020-08-24 Thread Gerd Hoffmann
On Mon, Aug 24, 2020 at 05:59:36PM -0400, Eduardo Habkost wrote:
> This makes the code consistent with the rest of QOM code in QEMU,
> and will make automated conversion to type declaration macros
> simpler.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Gerd Hoffmann 




Re: [PATCH] usb: fix setup_len init (CVE-2020-14364)

2020-08-24 Thread Li Qiang
Gerd Hoffmann  于2020年8月25日周二 下午1:37写道:
>
> Store calculated setup_len in a local variable, verify it, and only
> write it to the struct (USBDevice->setup_len) in case it passed the
> sanity checks.
>
> This prevents other code (do_token_{in,out} functions specifically)
> from working with invalid USBDevice->setup_len values and overrunning
> the USBDevice->setup_buf[] buffer.
>
> Fixes: CVE-2020-14364
> Signed-off-by: Gerd Hoffmann 
> Tested-by: Gonglei 

Reviewed-by: Li Qiang 

Just see the page.
-->https://access.redhat.com/security/cve/CVE-2020-14364

The 'Attack Vector' of the CVSS score here is 'local'.

Hi Prasad,
I think this should be 'network' as the guest user can touch this in
cloud environment?
What's the consideration here?

Thanks,
Li Qiang

> ---
>  hw/usb/core.c | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/hw/usb/core.c b/hw/usb/core.c
> index 5abd128b6bc5..5234dcc73fea 100644
> --- a/hw/usb/core.c
> +++ b/hw/usb/core.c
> @@ -129,6 +129,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
>  static void do_token_setup(USBDevice *s, USBPacket *p)
>  {
>  int request, value, index;
> +unsigned int setup_len;
>
>  if (p->iov.size != 8) {
>  p->status = USB_RET_STALL;
> @@ -138,14 +139,15 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
>  usb_packet_copy(p, s->setup_buf, p->iov.size);
>  s->setup_index = 0;
>  p->actual_length = 0;
> -s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
> -if (s->setup_len > sizeof(s->data_buf)) {
> +setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
> +if (setup_len > sizeof(s->data_buf)) {
>  fprintf(stderr,
>  "usb_generic_handle_packet: ctrl buffer too small (%d > 
> %zu)\n",
> -s->setup_len, sizeof(s->data_buf));
> +setup_len, sizeof(s->data_buf));
>  p->status = USB_RET_STALL;
>  return;
>  }
> +s->setup_len = setup_len;
>
>  request = (s->setup_buf[0] << 8) | s->setup_buf[1];
>  value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
> @@ -259,26 +261,28 @@ static void do_token_out(USBDevice *s, USBPacket *p)
>  static void do_parameter(USBDevice *s, USBPacket *p)
>  {
>  int i, request, value, index;
> +unsigned int setup_len;
>
>  for (i = 0; i < 8; i++) {
>  s->setup_buf[i] = p->parameter >> (i*8);
>  }
>
>  s->setup_state = SETUP_STATE_PARAM;
> -s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
>  s->setup_index = 0;
>
>  request = (s->setup_buf[0] << 8) | s->setup_buf[1];
>  value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
>  index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
>
> -if (s->setup_len > sizeof(s->data_buf)) {
> +setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
> +if (setup_len > sizeof(s->data_buf)) {
>  fprintf(stderr,
>  "usb_generic_handle_packet: ctrl buffer too small (%d > 
> %zu)\n",
> -s->setup_len, sizeof(s->data_buf));
> +setup_len, sizeof(s->data_buf));
>  p->status = USB_RET_STALL;
>  return;
>  }
> +s->setup_len = setup_len;
>
>  if (p->pid == USB_TOKEN_OUT) {
>  usb_packet_copy(p, s->data_buf, s->setup_len);
> --
> 2.27.0
>
>



Re: [PATCH] configure: default to PIE disabled on Windows platforms

2020-08-24 Thread Thomas Huth

On 24/08/2020 18.31, Daniel P. Berrangé wrote:

If Windows EXE files are built with -pie/-fpie they will fail to
launch. Historically QEMU defaulted to disabling PIE for Windows,
but this setting was accidentally lost when the configure summary
text was removed in

   commit f9332757898a764d85e19d339ec421236e885b68
   Author: Paolo Bonzini 
   Date:   Mon Feb 3 13:28:38 2020 +0100

 meson: move summary to meson.build

 Signed-off-by: Paolo Bonzini 

Fixes: f9332757898a764d85e19d339ec421236e885b68
Signed-off-by: Daniel P. Berrangé 
---
  configure | 1 +
  1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 67832e3bab..b6f3b6e191 100755
--- a/configure
+++ b/configure
@@ -857,6 +857,7 @@ MINGW32*)
  audio_drv_list=""
fi
supported_os="yes"
+  pie="no"
  ;;
  GNU/kFreeBSD)
bsd="yes"



Reviewed-by: Thomas Huth 




[PATCH] usb: fix setup_len init (CVE-2020-14364)

2020-08-24 Thread Gerd Hoffmann
Store calculated setup_len in a local variable, verify it, and only
write it to the struct (USBDevice->setup_len) in case it passed the
sanity checks.

This prevents other code (do_token_{in,out} functions specifically)
from working with invalid USBDevice->setup_len values and overrunning
the USBDevice->setup_buf[] buffer.

Fixes: CVE-2020-14364
Signed-off-by: Gerd Hoffmann 
Tested-by: Gonglei 
---
 hw/usb/core.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/usb/core.c b/hw/usb/core.c
index 5abd128b6bc5..5234dcc73fea 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -129,6 +129,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
 static void do_token_setup(USBDevice *s, USBPacket *p)
 {
 int request, value, index;
+unsigned int setup_len;
 
 if (p->iov.size != 8) {
 p->status = USB_RET_STALL;
@@ -138,14 +139,15 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
 usb_packet_copy(p, s->setup_buf, p->iov.size);
 s->setup_index = 0;
 p->actual_length = 0;
-s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
-if (s->setup_len > sizeof(s->data_buf)) {
+setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
+if (setup_len > sizeof(s->data_buf)) {
 fprintf(stderr,
 "usb_generic_handle_packet: ctrl buffer too small (%d > 
%zu)\n",
-s->setup_len, sizeof(s->data_buf));
+setup_len, sizeof(s->data_buf));
 p->status = USB_RET_STALL;
 return;
 }
+s->setup_len = setup_len;
 
 request = (s->setup_buf[0] << 8) | s->setup_buf[1];
 value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
@@ -259,26 +261,28 @@ static void do_token_out(USBDevice *s, USBPacket *p)
 static void do_parameter(USBDevice *s, USBPacket *p)
 {
 int i, request, value, index;
+unsigned int setup_len;
 
 for (i = 0; i < 8; i++) {
 s->setup_buf[i] = p->parameter >> (i*8);
 }
 
 s->setup_state = SETUP_STATE_PARAM;
-s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
 s->setup_index = 0;
 
 request = (s->setup_buf[0] << 8) | s->setup_buf[1];
 value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
 index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
 
-if (s->setup_len > sizeof(s->data_buf)) {
+setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
+if (setup_len > sizeof(s->data_buf)) {
 fprintf(stderr,
 "usb_generic_handle_packet: ctrl buffer too small (%d > 
%zu)\n",
-s->setup_len, sizeof(s->data_buf));
+setup_len, sizeof(s->data_buf));
 p->status = USB_RET_STALL;
 return;
 }
+s->setup_len = setup_len;
 
 if (p->pid == USB_TOKEN_OUT) {
 usb_packet_copy(p, s->data_buf, s->setup_len);
-- 
2.27.0




Re: [PATCH 2/2] nbd: disable signals and forking on Windows builds

2020-08-24 Thread Thomas Huth

On 24/08/2020 19.02, Daniel P. Berrangé wrote:

Disabling these parts are sufficient to get the qemu-nbd program
compiling in a Windows build.


Maybe add:
"This also enables compilation of qemu-nbd on macOS again (which got 
disabled by accident during the conversion to the meson build system)"



Signed-off-by: Daniel P. Berrangé 
---
  meson.build |  7 ++-
  qemu-nbd.c  | 10 +-
  2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/meson.build b/meson.build
index df5bf728b5..1071871605 100644
--- a/meson.build
+++ b/meson.build
@@ -1074,12 +1074,9 @@ if have_tools
   dependencies: [authz, block, crypto, io, qom, qemuutil], 
install: true)
qemu_io = executable('qemu-io', files('qemu-io.c'),
   dependencies: [block, qemuutil], install: true)
-  qemu_block_tools += [qemu_img, qemu_io]
-  if targetos == 'linux' or targetos == 'sunos' or targetos.endswith('bsd')
-qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
+  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
 dependencies: [block, qemuutil], install: true)
-qemu_block_tools += [qemu_nbd]
-  endif
+  qemu_block_tools += [qemu_img, qemu_io, qemu_nbd]
  
subdir('storage-daemon')

subdir('contrib/rdmacm-mux')
diff --git a/qemu-nbd.c b/qemu-nbd.c
index b102874f0f..c6fd6524d3 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -155,12 +155,13 @@ QEMU_COPYRIGHT "\n"
  , name);
  }
  
+#ifndef WIN32

  static void termsig_handler(int signum)
  {
  atomic_cmpxchg(, RUNNING, TERMINATE);
  qemu_notify_event();
  }
-
+#endif
  
  static int qemu_nbd_client_list(SocketAddress *saddr, QCryptoTLSCreds *tls,

  const char *hostname)
@@ -587,6 +588,7 @@ int main(int argc, char **argv)
  unsigned socket_activation;
  const char *pid_file_name = NULL;
  
+#ifndef WIN32

  /* The client thread uses SIGTERM to interrupt the server.  A signal
   * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
   */
@@ -594,6 +596,7 @@ int main(int argc, char **argv)
  memset(_sigterm, 0, sizeof(sa_sigterm));
  sa_sigterm.sa_handler = termsig_handler;
  sigaction(SIGTERM, _sigterm, NULL);
+#endif
  
  #ifdef CONFIG_POSIX


I wonder why the CONFIG_POSIX does not simply start earlier here ... I 
think you could replace your #ifndef WIN32 with #ifdef CONFIG_POSIX that 
way?



  signal(SIGPIPE, SIG_IGN);
@@ -896,6 +899,7 @@ int main(int argc, char **argv)
  #endif
  
  if ((device && !verbose) || fork_process) {

+#ifndef WIN32
  int stderr_fd[2];
  pid_t pid;
  int ret;
@@ -959,6 +963,10 @@ int main(int argc, char **argv)
   */
  exit(errors);
  }
+#else /* WIN32 */
+error_report("Unable to fork into background on Windows hosts");
+exit(EXIT_FAILURE);
+#endif /* WIN32 */
  }
  
  if (device != NULL && sockpath == NULL) {




 Thomas




RE: Known issue? qemu is much slower when built with clang vs gcc

2020-08-24 Thread Brian Cain
Taylor,

I can report that the performance looks to be in the ballpark of parity with 
gcc when we move from clang 8.0 to 11.0 rc2.   Perhaps we can attribute this to 
a since-fixed defect in clang?

-Brian

From: Taylor Simpson 
Sent: Monday, August 24, 2020 11:54 AM
To: qemu-devel@nongnu.org
Cc: Brian Cain 
Subject: Known issue? qemu is much slower when built with clang vs gcc

We're seeing significant slowdowns when we build qemu with clang instead of 
gcc.  I'm hoping this is a known issue and there is a workaround or fix.  
Please advise.

I have an example where qemu is 29X slower when built with clang.  My first 
hunch was that there was something different happening in configure (e.g., 
passing -O0 to clang instead of -O2).  However, I have ruled this out.

Further investigation shows that we are calling the translator more often.  The 
same code is getting translated multiple times.  So, my current theory is some 
different behavior in the translation block hashing causing the lookup not to 
find existing translations.  I know clang can be overly aggressive about 
optimizing undefined behavior.  So, I turned on clang's undefined behavior 
sanitizer.  Interestingly, it did not report anything, *and* we don't see the 
large performance difference.

Thanks,
Taylor



[PATCH v2 1/2] QSLIST: add atomic replace operation

2020-08-24 Thread wanghonghao
Replace a queue with another atomicly. It's useful when we need to transfer
queues between threads.

Signed-off-by: wanghonghao 
---
 include/qemu/queue.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 456a5b01ee..62efad2438 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -226,6 +226,10 @@ struct {   
 \
 (dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL);\
 } while (/*CONSTCOND*/0)
 
+#define QSLIST_REPLACE_ATOMIC(dest, src, old) do {\
+(old)->slh_first = atomic_xchg(&(dest)->slh_first, (src)->slh_first); \
+} while (/*CONSTCOND*/0)
+
 #define QSLIST_REMOVE_HEAD(head, field) do { \
 typeof((head)->slh_first) elm = (head)->slh_first;   \
 (head)->slh_first = elm->field.sle_next; \
-- 
2.24.3 (Apple Git-128)




[PATCH v2 2/2] coroutine: take exactly one batch from global pool at a time

2020-08-24 Thread wanghonghao
This patch replace the global coroutine queue with a lock-free stack of which
the elements are coroutine queues. Threads can put coroutine queues into the
stack or take queues from it and each coroutine queue has exactly
POOL_BATCH_SIZE coroutines. Note that the stack is not strictly LIFO, but it's
enough for buffer pool.

Coroutines will be put into thread-local pools first while release. Now the
fast pathes of both allocation and release are atomic-free, and there won't
be too many coroutines remain in a single thread since POOL_BATCH_SIZE has been
reduced to 16.

In practice, I've run a VM with two block devices binding to two different
iothreads, and run fio with iodepth 128 on each device. It maintains around
400 coroutines and has about 1% chance of calling to `qemu_coroutine_new`
without this patch. And with this patch, it maintains no more than 273
coroutines and doesn't call `qemu_coroutine_new` after initial allocations.

Signed-off-by: wanghonghao 
---
 util/qemu-coroutine.c | 63 ---
 1 file changed, 42 insertions(+), 21 deletions(-)

diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
index c3caa6c770..9202ec9c85 100644
--- a/util/qemu-coroutine.c
+++ b/util/qemu-coroutine.c
@@ -21,13 +21,14 @@
 #include "block/aio.h"
 
 enum {
-POOL_BATCH_SIZE = 64,
+POOL_BATCH_SIZE = 16,
+POOL_MAX_BATCHES = 32,
 };
 
-/** Free list to speed up creation */
-static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool);
-static unsigned int release_pool_size;
-static __thread QSLIST_HEAD(, Coroutine) alloc_pool = 
QSLIST_HEAD_INITIALIZER(pool);
+/** Free stack to speed up creation */
+static QSLIST_HEAD(, Coroutine) pool[POOL_MAX_BATCHES];
+static int pool_top;
+static __thread QSLIST_HEAD(, Coroutine) alloc_pool;
 static __thread unsigned int alloc_pool_size;
 static __thread Notifier coroutine_pool_cleanup_notifier;
 
@@ -49,20 +50,26 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, 
void *opaque)
 if (CONFIG_COROUTINE_POOL) {
 co = QSLIST_FIRST(_pool);
 if (!co) {
-if (release_pool_size > POOL_BATCH_SIZE) {
-/* Slow path; a good place to register the destructor, too.  */
-if (!coroutine_pool_cleanup_notifier.notify) {
-coroutine_pool_cleanup_notifier.notify = 
coroutine_pool_cleanup;
-qemu_thread_atexit_add(_pool_cleanup_notifier);
+int top;
+
+/* Slow path; a good place to register the destructor, too.  */
+if (!coroutine_pool_cleanup_notifier.notify) {
+coroutine_pool_cleanup_notifier.notify = 
coroutine_pool_cleanup;
+qemu_thread_atexit_add(_pool_cleanup_notifier);
+}
+
+while ((top = atomic_read(_top)) > 0) {
+if (atomic_cmpxchg(_top, top, top - 1) != top) {
+continue;
 }
 
-/* This is not exact; there could be a little skew between
- * release_pool_size and the actual size of release_pool.  But
- * it is just a heuristic, it does not need to be perfect.
- */
-alloc_pool_size = atomic_xchg(_pool_size, 0);
-QSLIST_MOVE_ATOMIC(_pool, _pool);
+QSLIST_MOVE_ATOMIC(_pool, [top - 1]);
 co = QSLIST_FIRST(_pool);
+
+if (co) {
+alloc_pool_size = POOL_BATCH_SIZE;
+break;
+}
 }
 }
 if (co) {
@@ -86,16 +93,30 @@ static void coroutine_delete(Coroutine *co)
 co->caller = NULL;
 
 if (CONFIG_COROUTINE_POOL) {
-if (release_pool_size < POOL_BATCH_SIZE * 2) {
-QSLIST_INSERT_HEAD_ATOMIC(_pool, co, pool_next);
-atomic_inc(_pool_size);
-return;
-}
+int top, value, old;
+
 if (alloc_pool_size < POOL_BATCH_SIZE) {
 QSLIST_INSERT_HEAD(_pool, co, pool_next);
 alloc_pool_size++;
 return;
 }
+
+for (top = atomic_read(_top); top < POOL_MAX_BATCHES; top++) {
+QSLIST_REPLACE_ATOMIC([top], _pool, _pool);
+if (!QSLIST_EMPTY(_pool)) {
+continue;
+}
+
+value = top + 1;
+
+do {
+old = atomic_cmpxchg(_top, top, value);
+} while (old != top && (top = old) < value);
+
+QSLIST_INSERT_HEAD(_pool, co, pool_next);
+alloc_pool_size = 1;
+return;
+}
 }
 
 qemu_coroutine_delete(co);
-- 
2.24.3 (Apple Git-128)




Re: [External] Re: [PATCH 1/2] QSLIST: add atomic replace operation

2020-08-24 Thread 王洪浩
This function is indeed a bit vague in semantics.
I'll modify this function to make it more in line with `replace`.

Stefan Hajnoczi  于2020年8月24日周一 下午11:27写道:
>
> On Mon, Aug 24, 2020 at 12:31:20PM +0800, wanghonghao wrote:
> > Replace a queue with another atomicly. It's useful when we need to transfer
> > queues between threads.
> >
> > Signed-off-by: wanghonghao 
> > ---
> >  include/qemu/queue.h | 4 
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/include/qemu/queue.h b/include/qemu/queue.h
> > index 456a5b01ee..a3ff544193 100644
> > --- a/include/qemu/queue.h
> > +++ b/include/qemu/queue.h
> > @@ -226,6 +226,10 @@ struct {   
> >  \
> >  (dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL);\
> >  } while (/*CONSTCOND*/0)
> >
> > +#define QSLIST_REPLACE_ATOMIC(dest, src) do {  
> >\
> > +(src)->slh_first = atomic_xchg(&(dest)->slh_first, 
> > (src)->slh_first); \
> > +} while (/*CONSTCOND*/0)
>
> This is atomic for dest but not src.
>
> Maybe the name should make this clear: QSLIST_REPLACE_ATOMIC_DEST().
>
> Please also add a doc comment mentioning that the modification to src is
> not atomic.
>
> Stefan



Re: [PATCH 02/10] numa: introduce MachineClass::forbid_asymmetrical_numa

2020-08-24 Thread David Gibson
On Mon, Aug 24, 2020 at 08:45:12AM -0300, Daniel Henrique Barboza wrote:
> 
> 
> On 8/24/20 3:08 AM, David Gibson wrote:
> > On Fri, Aug 21, 2020 at 09:47:47AM -0300, Daniel Henrique Barboza wrote:
> > > 
> > > 
> > > On 8/21/20 5:55 AM, Igor Mammedov wrote:
> > > > On Thu, 20 Aug 2020 12:51:03 -0400
> > > > Eduardo Habkost  wrote:
> > > > 
> > > > > On Thu, Aug 20, 2020 at 02:15:04PM +1000, David Gibson wrote:
> > > > > > On Wed, Aug 19, 2020 at 10:11:28PM -0400, Eduardo Habkost wrote:
> > > > > > > On Thu, Aug 20, 2020 at 11:17:26AM +1000, David Gibson wrote:
> > > > > > > > On Fri, Aug 14, 2020 at 05:54:16PM -0300, Daniel Henrique 
> > > > > > > > Barboza wrote:
> > > > > > > > > The pSeries machine does not support asymmetrical NUMA
> > > > > > > > > configurations.
> > > > > > > > 
> > > > > > > > This seems a bit oddly specific to have as a global machine 
> > > > > > > > class
> > > > > > > > property.
> > > > > > > > 
> > > > > > > > Would it make more sense for machines with specific NUMA 
> > > > > > > > constraints
> > > > > > > > to just verify those during their initialization?
> > > > > > > 
> > > > > > > This would be much simpler.  However, I like the idea of
> > > > > > > representing machine-specific configuration validation rules as
> > > > > > > data that can eventually be exported to management software.
> > > > > > 
> > > > > > Ah, ok, so basically the usual tradeoff between flexibility and
> > > > > > advertisability.
> > > > > > 
> > > > > > So, in that case, I guess the question is whether we envisage "no
> > > > > > assymmetry" as a constraint common enough that it's worth creating 
> > > > > > an
> > > > > > advertisable rule or not.  If we only ever have one user, then we
> > > > > > haven't really done any better than hard coding the constraint in 
> > > > > > the
> > > > > > manageent software.
> > > > > > 
> > > > > > Of course to complicate matters, in the longer term we're looking at
> > > > > > removing that constraint from pseries - but doing so will be 
> > > > > > dependent
> > > > > > on the guest kernel understanding a new format for the NUMA
> > > > > > information in the device tree.  So qemu alone won't have enough
> > > > > > information to tell if such a configuration is possible or not.
> > > > > 
> > > > > Requiring both QEMU (and possibly management software) to be
> > > > > patched again after the guest kernel is fixed sounds undesirable.
> > > > If we drop this restriction, then we don't need to touch QEMU when
> > > > guest kernel is ready.
> > > > 
> > > > Btw, what spapr spec says about the matter?
> > > 
> > > LOPAPR support a somewhat asymmetrical NUMA setup in its current
> > > form,
> > 
> > Huh, I didn't even realize that.  What's the mechanism?
> 
> LOPAPR mentions that a single resource/node can have multiple associativity
> arrays. The idea is to contemplate the situations where the node has
> more than one connection with the board.
> 
> I say "somewhat" because, right after mentioning that, the spec also says that
> the OS should consider that the distance between two nodes must always be
> the shortest one of all available arrays. I'll copy/paste the except here
> (end of section 15.2, "Numa Resource Associativity":

Ah.  I didn't think that's what "asymmetric NUMA" meant... but come to
think of it, I'm not very sure about that.

> -
> 
> The reason that the “ibm,associativity” property may contain multiple 
> associativity
> lists is that a resource may be multiply connected into the platform. This 
> resource
> then has a different associativity characteristics relative to its multiple 
> connections.
> To determine the associativity between any two resources, the OS scans down 
> the two
> resources associativity lists in all pair wise combinations counting how many 
> domains
> are the same until the first domain where the two list do not agree. The 
> highest such
> count is the associativity between the two resources.
> 
> 
> 
> 
> DHB
> 
> 
> > 
> > > but
> > > the Linux kernel doesn't support it. The effort to implement it in the 
> > > current
> > > spapr machine code, given that Linux wouldn't mind it, is not worth it. 
> > > This
> > > is why I chose to invalidate it for pseries.
> > 
> > Igor,
> > 
> > It's kind of difficult to answer that question - PAPR doesn't
> > specifically describe limitations, it's just that the representation
> > it uses is inherently limited.  Instead of the obvious, simple and
> > pretty much universal method (used in the generic kernel and qemu) of
> > having a matrix of distance between all the nodes, it instead
> > describes the hierarchy of components that give rise to the different
> > distances.
> > 
> > So, for each NUMA relevant object (cpu, memory block, host bridge,
> > etc.) there is a vector of IDs.  Each number in the vector gives one
> > level of the objects location in the heirarchy.
> > 
> > So, for example the first number might be the physical chip/socket.
> > the second one 

Re: Contributor wanting to get started with simple contributions

2020-08-24 Thread Rohit Shinde
Hey John,

I sent this email a couple of weeks ago to the qemu mailing list since I
didn't really know who to approach.

I am interested in contributing to the python-qemu package. I have quite a
bit of experience in Python, but no experience in packaging libraries.
Whatever you mentioned in the reply to my comment on the bug, was pretty
interesting. I would like to get started with at least ensuring that all
python code is flake8/pylint compliant.

Do let me know what you think of this.

Thanks,
Rohit.

On Thu, Aug 13, 2020 at 7:18 AM Rohit Shinde 
wrote:

> Hello everyone,
>
> I am a hobby programmer (working as an SDE in the industry) and I have
> been observing qemu for quite a while. I have always wanted to contribute
> but I couldn't manage my time. I am good at Java and Python but quite a bit
> rusty with C++ and C (although working with it will not be a problem, I
> might have to google more than usual). On the theory side, I have a good
> grasp of data structures and algorithms and a decent understanding of OS
> and Compilers.
>
> I have built qemu from source and I have my machine setup for git-publish
> via email.
>
> I would like to start contributing with one of the bite sized tasks
> mentioned in the wiki page. The one that interests me and which I think is
> the easiest are the sections on "Compiler Driven Cleanup" and "Dead Code
> Removal". I think this is a good way to get introduced to the codebase.
>
> I plan to stay and become a long term contributor. Is there any CS theory
> that I would need to know other than what I mentioned above? Is it possible
> to "learn on the go"?
>
> I realize this is quite a long email and I would like to thank everyone in
> advance for reading this!
>
> Regards,
> Rohit.
>


[PATCH v5 12/12] migration/dirtyrate: Add trace_calls to make it easier to debug

2020-08-24 Thread Chuan Zheng
Add trace_calls to  make it easier to debug

Signed-off-by: Chuan Zheng 
---
 migration/dirtyrate.c  | 7 +++
 migration/trace-events | 8 
 2 files changed, 15 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 08c46d3..3513ef3 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -23,6 +23,7 @@
 #include "qapi/qapi-commands-migration.h"
 #include "migration.h"
 #include "ram.h"
+#include "trace.h"
 #include "dirtyrate.h"
 
 static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
@@ -55,6 +56,7 @@ static int64_t get_sample_page_period(int64_t sec)
 static int dirtyrate_set_state(int *state, int old_state, int new_state)
 {
 assert(new_state < DIRTY_RATE_STATUS__MAX);
+trace_dirtyrate_set_state(DirtyRateStatus_str(new_state));
 if (atomic_cmpxchg(state, old_state, new_state) == old_state) {
 return 0;
 } else {
@@ -78,6 +80,7 @@ static struct DirtyRateInfo *query_dirty_rate_info(void)
  * Only support query once for each calculation,
  * reset as DIRTY_RATE_STATUS_UNSTARTED after query
  */
+trace_query_dirty_rate_info(DirtyRateStatus_str(CalculatingState));
 (void)dirtyrate_set_state(, CalculatingState,
   DIRTY_RATE_STATUS_UNSTARTED);
 
@@ -129,6 +132,7 @@ static uint32_t get_ramblock_vfn_hash(struct 
RamblockDirtyInfo *info,
 
 crc = crc32(0, iov_array.iov_base, iov_array.iov_len);
 
+trace_get_ramblock_vfn_hash(info->idstr, vfn, crc);
 return crc;
 }
 
@@ -246,6 +250,7 @@ static int skip_sample_ramblock(RAMBlock *block)
  * want to sample.
  */
 if (ramblock_size < MIN_RAMBLOCK_SIZE) {
+trace_skip_sample_ramblock(block->idstr, ramblock_size);
 return -1;
 }
 
@@ -292,6 +297,7 @@ static int calc_page_dirty_rate(struct RamblockDirtyInfo 
*info)
 for (i = 0; i < info->sample_pages_count; i++) {
 crc = get_ramblock_vfn_hash(info, info->sample_page_vfn[i]);
 if (crc != info->hash_result[i]) {
+trace_calc_page_dirty_rate(info->idstr, crc, info->hash_result[i]);
 info->sample_dirty_count++;
 }
 }
@@ -317,6 +323,7 @@ static bool find_page_matched(RAMBlock *block, struct 
RamblockDirtyInfo *infos,
 if (infos[i].ramblock_addr != qemu_ram_get_host_addr(block) ||
 infos[i].ramblock_pages !=
 (qemu_ram_get_used_length(block) >> DIRTYRATE_PAGE_SHIFT_KB)) {
+trace_find_page_matched(block->idstr);
 return false;
 }
 
diff --git a/migration/trace-events b/migration/trace-events
index 4ab0a50..34569b9 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -312,3 +312,11 @@ dirty_bitmap_load_bits_zeroes(void) ""
 dirty_bitmap_load_header(uint32_t flags) "flags 0x%x"
 dirty_bitmap_load_enter(void) ""
 dirty_bitmap_load_success(void) ""
+
+# dirtyrate.c
+dirtyrate_set_state(const char *new_state) "new state %s"
+query_dirty_rate_info(const char *new_state) "current state %s"
+get_ramblock_vfn_hash(const char *idstr, uint64_t vfn, uint32_t crc) "ramblock 
name: %s, vfn: %"PRIu64 ", crc: %" PRIu32
+calc_page_dirty_rate(const char *idstr, uint32_t new_crc, uint32_t old_crc) 
"ramblock name: %s, new crc: %" PRIu32 ", old crc: %" PRIu32
+skip_sample_ramblock(const char *idstr, int64_t ramblock_size) "ramblock name: 
%s, ramblock size: %" PRIu64
+find_page_matched(const char *idstr) "ramblock %s addr or size changed"
-- 
1.8.3.1




[PATCH v5 09/12] migration/dirtyrate: Implement get_sample_page_period() and block_sample_page_period()

2020-08-24 Thread Chuan Zheng
Implement get_sample_page_period() and set_sample_page_period() to
sleep specific time between sample actions.

Signed-off-by: Chuan Zheng 
Reviewed-by: Dr. David Alan Gilbert 
---
 migration/dirtyrate.c | 24 
 migration/dirtyrate.h |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index bd398b7..d1c0a78 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -28,6 +28,30 @@
 static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
 static struct DirtyRateStat DirtyStat;
 
+static int64_t set_sample_page_period(int64_t msec, int64_t initial_time)
+{
+int64_t current_time;
+
+current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+if ((current_time - initial_time) >= msec) {
+msec = current_time - initial_time;
+} else {
+g_usleep((msec + initial_time - current_time) * 1000);
+}
+
+return msec;
+}
+
+static int64_t get_sample_page_period(int64_t sec)
+{
+if (sec <= MIN_FETCH_DIRTYRATE_TIME_SEC ||
+sec > MAX_FETCH_DIRTYRATE_TIME_SEC) {
+sec = DEFAULT_FETCH_DIRTYRATE_TIME_SEC;
+}
+
+return sec;
+}
+
 static int dirtyrate_set_state(int *state, int old_state, int new_state)
 {
 assert(new_state < DIRTY_RATE_STATUS__MAX);
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 600bceb..cf14647 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -51,6 +51,8 @@
 
 /* Take 1s as default for calculation duration */
 #define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
+#define MIN_FETCH_DIRTYRATE_TIME_SEC  0
+#define MAX_FETCH_DIRTYRATE_TIME_SEC  60
 
 struct DirtyRateConfig {
 uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
-- 
1.8.3.1




[PATCH v5 10/12] migration/dirtyrate: Implement calculate_dirtyrate() function

2020-08-24 Thread Chuan Zheng
Implement calculate_dirtyrate() function.

Signed-off-by: Chuan Zheng 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 45 +++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index d1c0a78..9f52f5f 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -171,6 +171,21 @@ static void get_ramblock_dirty_info(RAMBlock *block,
 strcpy(info->idstr, qemu_ram_get_idstr(block));
 }
 
+static void free_ramblock_dirty_info(struct RamblockDirtyInfo *infos, int 
count)
+{
+int i;
+
+if (!infos) {
+return;
+}
+
+for (i = 0; i < count; i++) {
+g_free(infos[i].sample_page_vfn);
+g_free(infos[i].hash_result);
+}
+g_free(infos);
+}
+
 static struct RamblockDirtyInfo *
 alloc_ramblock_dirty_info(int *block_index,
   struct RamblockDirtyInfo *block_dinfo)
@@ -316,8 +331,34 @@ static int compare_page_hash_info(struct RamblockDirtyInfo 
*info,
 
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
-/* todo */
-return;
+struct RamblockDirtyInfo *block_dinfo = NULL;
+int block_index = 0;
+int64_t msec = 0;
+int64_t initial_time;
+
+rcu_register_thread();
+reset_dirtyrate_stat();
+initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+rcu_read_lock();
+if (record_ramblock_hash_info(_dinfo, config, _index) < 0) {
+goto out;
+}
+rcu_read_unlock();
+
+msec = config.sample_period_seconds * 1000;
+msec = set_sample_page_period(msec, initial_time);
+
+rcu_read_lock();
+if (compare_page_hash_info(block_dinfo, block_index) < 0) {
+goto out;
+}
+
+update_dirtyrate(msec);
+
+out:
+rcu_read_unlock();
+free_ramblock_dirty_info(block_dinfo, block_index + 1);
+rcu_unregister_thread();
 }
 
 void *get_dirtyrate_thread(void *arg)
-- 
1.8.3.1




[PATCH v5 02/12] migration/dirtyrate: add DirtyRateStatus to denote calculation status

2020-08-24 Thread Chuan Zheng
add DirtyRateStatus to denote calculating status.

Signed-off-by: Chuan Zheng 
---
 migration/dirtyrate.c | 22 ++
 qapi/migration.json   | 17 +
 2 files changed, 39 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 366f4e9..91987c5 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -23,6 +23,19 @@
 #include "migration.h"
 #include "dirtyrate.h"
 
+static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
+
+static int dirtyrate_set_state(int *state, int old_state, int new_state)
+{
+assert(new_state < DIRTY_RATE_STATUS__MAX);
+if (atomic_cmpxchg(state, old_state, new_state) == old_state) {
+return 0;
+} else {
+return -1;
+}
+}
+
+
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
 /* todo */
@@ -32,8 +45,17 @@ static void calculate_dirtyrate(struct DirtyRateConfig 
config)
 void *get_dirtyrate_thread(void *arg)
 {
 struct DirtyRateConfig config = *(struct DirtyRateConfig *)arg;
+int ret;
+
+ret = dirtyrate_set_state(, DIRTY_RATE_STATUS_UNSTARTED,
+  DIRTY_RATE_STATUS_MEASURING);
+if (ret == -1) {
+return NULL;
+}
 
 calculate_dirtyrate(config);
 
+ret = dirtyrate_set_state(, DIRTY_RATE_STATUS_MEASURING,
+  DIRTY_RATE_STATUS_MEASURED);
 return NULL;
 }
diff --git a/qapi/migration.json b/qapi/migration.json
index 5f6b061..d640165 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1720,3 +1720,20 @@
 ##
 { 'event': 'UNPLUG_PRIMARY',
   'data': { 'device-id': 'str' } }
+
+##
+# @DirtyRateStatus:
+#
+# An enumeration of dirtyrate status.
+#
+# @unstarted: query-dirtyrate thread is not initial.
+#
+# @measuring: query-dirtyrate thread is created and start to measure.
+#
+# @measured:  query-dirtyrate thread is end, we can get result.
+#
+# Since: 5.2
+#
+##
+{ 'enum': 'DirtyRateStatus',
+  'data': [ 'unstarted', 'measuring', 'measured'] }
-- 
1.8.3.1




[PATCH v5 07/12] migration/dirtyrate: Compare page hash results for recorded sampled page

2020-08-24 Thread Chuan Zheng
Compare page hash results for recorded sampled page.

Signed-off-by: Chuan Zheng 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 64 +++
 1 file changed, 64 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 66de426..050270d 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -202,6 +202,70 @@ static int record_ramblock_hash_info(struct 
RamblockDirtyInfo **block_dinfo,
 return 0;
 }
 
+static int calc_page_dirty_rate(struct RamblockDirtyInfo *info)
+{
+uint32_t crc;
+int i;
+
+for (i = 0; i < info->sample_pages_count; i++) {
+crc = get_ramblock_vfn_hash(info, info->sample_page_vfn[i]);
+if (crc != info->hash_result[i]) {
+info->sample_dirty_count++;
+}
+}
+
+return 0;
+}
+
+static bool find_page_matched(RAMBlock *block, struct RamblockDirtyInfo *infos,
+  int count, struct RamblockDirtyInfo **matched)
+{
+int i;
+
+for (i = 0; i < count; i++) {
+if (!strcmp(infos[i].idstr, qemu_ram_get_idstr(block))) {
+break;
+}
+}
+
+if (i == count) {
+return false;
+}
+
+if (infos[i].ramblock_addr != qemu_ram_get_host_addr(block) ||
+infos[i].ramblock_pages !=
+(qemu_ram_get_used_length(block) >> DIRTYRATE_PAGE_SHIFT_KB)) {
+return false;
+}
+
+*matched = [i];
+return true;
+}
+
+static int compare_page_hash_info(struct RamblockDirtyInfo *info,
+  int block_index)
+{
+struct RamblockDirtyInfo *block_dinfo = NULL;
+RAMBlock *block = NULL;
+
+RAMBLOCK_FOREACH_MIGRATABLE(block) {
+block_dinfo = NULL;
+if (!find_page_matched(block, info, block_index + 1, _dinfo)) {
+continue;
+}
+if (calc_page_dirty_rate(block_dinfo) < 0) {
+return -1;
+}
+update_dirtyrate_stat(block_dinfo);
+}
+
+if (!DirtyStat.total_sample_count) {
+return -1;
+}
+
+return 0;
+}
+
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
 /* todo */
-- 
1.8.3.1




[PATCH v5 06/12] migration/dirtyrate: Record hash results for each sampled page

2020-08-24 Thread Chuan Zheng
Record hash results for each sampled page, crc32 is taken to calculate
hash results for each sampled 4K-page.

Signed-off-by: Chuan Zheng 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 136 ++
 migration/dirtyrate.h |  15 ++
 2 files changed, 151 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index f6a94d8..66de426 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -10,6 +10,7 @@
  * See the COPYING file in the top-level directory.
  */
 
+#include 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hash.h"
@@ -66,6 +67,141 @@ static void update_dirtyrate(uint64_t msec)
 DirtyStat.dirty_rate = dirtyrate;
 }
 
+/*
+ * get hash result for the sampled memory with length of 4K byte in ramblock,
+ * which starts from ramblock base address.
+ */
+static uint32_t get_ramblock_vfn_hash(struct RamblockDirtyInfo *info,
+  uint64_t vfn)
+{
+struct iovec iov_array;
+uint32_t crc;
+
+iov_array.iov_base = info->ramblock_addr +
+ vfn * DIRTYRATE_SAMPLE_PAGE_SIZE;
+iov_array.iov_len = DIRTYRATE_SAMPLE_PAGE_SIZE;
+
+crc = crc32(0, iov_array.iov_base, iov_array.iov_len);
+
+return crc;
+}
+
+static int save_ramblock_hash(struct RamblockDirtyInfo *info)
+{
+unsigned int sample_pages_count;
+int i;
+int ret = -1;
+GRand *rand = g_rand_new();
+
+sample_pages_count = info->sample_pages_count;
+
+/* ramblock size less than one page, return success to skip this ramblock 
*/
+if (unlikely(info->ramblock_pages == 0 || sample_pages_count == 0)) {
+ret = 0;
+goto out;
+}
+
+info->hash_result = g_try_malloc0_n(sample_pages_count,
+sizeof(uint32_t));
+if (!info->hash_result) {
+ret = -1;
+goto out;
+}
+
+info->sample_page_vfn = g_try_malloc0_n(sample_pages_count,
+sizeof(uint64_t));
+if (!info->sample_page_vfn) {
+g_free(info->hash_result);
+ret = -1;
+goto out;
+}
+
+for (i = 0; i < sample_pages_count; i++) {
+info->sample_page_vfn[i] = g_rand_int_range(rand, 0,
+info->ramblock_pages - 1);
+info->hash_result[i] = get_ramblock_vfn_hash(info,
+ info->sample_page_vfn[i]);
+}
+ret = 0;
+
+out:
+g_rand_free(rand);
+return ret;
+}
+
+static void get_ramblock_dirty_info(RAMBlock *block,
+struct RamblockDirtyInfo *info,
+struct DirtyRateConfig *config)
+{
+uint64_t sample_pages_per_gigabytes = config->sample_pages_per_gigabytes;
+
+/* Right shift 30 bits to calc block size in GB */
+info->sample_pages_count = (qemu_ram_get_used_length(block) *
+sample_pages_per_gigabytes) >>
+DIRTYRATE_PAGE_SHIFT_GB;
+
+/* Right shift 12 bits to calc page count in 4KB */
+info->ramblock_pages = qemu_ram_get_used_length(block) >>
+   DIRTYRATE_PAGE_SHIFT_KB;
+info->ramblock_addr = qemu_ram_get_host_addr(block);
+strcpy(info->idstr, qemu_ram_get_idstr(block));
+}
+
+static struct RamblockDirtyInfo *
+alloc_ramblock_dirty_info(int *block_index,
+  struct RamblockDirtyInfo *block_dinfo)
+{
+struct RamblockDirtyInfo *info = NULL;
+int index = *block_index;
+
+if (!block_dinfo) {
+index = 0;
+block_dinfo = g_try_new(struct RamblockDirtyInfo, 1);
+} else {
+index++;
+block_dinfo = g_try_realloc(block_dinfo, (index + 1) *
+sizeof(struct RamblockDirtyInfo));
+}
+if (!block_dinfo) {
+return NULL;
+}
+
+info = _dinfo[index];
+*block_index = index;
+memset(info, 0, sizeof(struct RamblockDirtyInfo));
+
+return block_dinfo;
+}
+
+static int record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
+ struct DirtyRateConfig config,
+ int *block_index)
+{
+struct RamblockDirtyInfo *info = NULL;
+struct RamblockDirtyInfo *dinfo = NULL;
+RAMBlock *block = NULL;
+int index = 0;
+
+RAMBLOCK_FOREACH_MIGRATABLE(block) {
+dinfo = alloc_ramblock_dirty_info(, dinfo);
+if (dinfo == NULL) {
+return -1;
+}
+info = [index];
+get_ramblock_dirty_info(block, info, );
+if (save_ramblock_hash(info) < 0) {
+*block_dinfo = dinfo;
+*block_index = index;
+return -1;
+}
+}
+
+*block_dinfo = dinfo;
+*block_index = index;
+
+return 0;
+}
+
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
 /* todo */

[PATCH v5 03/12] migration/dirtyrate: Add RamlockDirtyInfo to store sampled page info

2020-08-24 Thread Chuan Zheng
Add RamlockDirtyInfo to store sampled page info of each ramblock.

Signed-off-by: Chuan Zheng 
---
 migration/dirtyrate.h | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 33669b7..dc45419 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -19,6 +19,11 @@
  */
 #define DIRTYRATE_DEFAULT_SAMPLE_PAGES512
 
+/*
+ * Record ramblock idstr
+ */
+#define RAMBLOCK_INFO_MAX_LEN 256
+
 /* Take 1s as default for calculation duration */
 #define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
 
@@ -27,6 +32,19 @@ struct DirtyRateConfig {
 int64_t sample_period_seconds; /* time duration between two sampling */
 };
 
+/*
+ * Store dirtypage info for each ramblock.
+ */
+struct RamblockDirtyInfo {
+char idstr[RAMBLOCK_INFO_MAX_LEN]; /* idstr for each ramblock */
+uint8_t *ramblock_addr; /* base address of ramblock we measure */
+uint64_t ramblock_pages; /* ramblock size in 4K-page */
+uint64_t *sample_page_vfn; /* relative offset address for sampled page */
+uint64_t sample_pages_count; /* count of sampled pages */
+uint64_t sample_dirty_count; /* count of dirty pages we measure */
+uint32_t *hash_result; /* array of hash result for sampled pages */
+};
+
 void *get_dirtyrate_thread(void *arg);
 #endif
 
-- 
1.8.3.1




[PATCH v5 05/12] migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into ram.h

2020-08-24 Thread Chuan Zheng
RAMBLOCK_FOREACH_MIGRATABLE is need in dirtyrate measure,
move the existing definition up into migration/ram.h

Signed-off-by: Chuan Zheng 
Reviewed-by: Dr. David Alan Gilbert 
---
 migration/dirtyrate.c |  1 +
 migration/ram.c   | 11 +--
 migration/ram.h   | 10 ++
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 0d7163f..f6a94d8 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -21,6 +21,7 @@
 #include "qemu/rcu_queue.h"
 #include "qapi/qapi-commands-migration.h"
 #include "migration.h"
+#include "ram.h"
 #include "dirtyrate.h"
 
 static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
diff --git a/migration/ram.c b/migration/ram.c
index 76d4fee..37ef0da 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -158,21 +158,12 @@ out:
 return ret;
 }
 
-static bool ramblock_is_ignored(RAMBlock *block)
+bool ramblock_is_ignored(RAMBlock *block)
 {
 return !qemu_ram_is_migratable(block) ||
(migrate_ignore_shared() && qemu_ram_is_shared(block));
 }
 
-/* Should be holding either ram_list.mutex, or the RCU lock. */
-#define RAMBLOCK_FOREACH_NOT_IGNORED(block)\
-INTERNAL_RAMBLOCK_FOREACH(block)   \
-if (ramblock_is_ignored(block)) {} else
-
-#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
-INTERNAL_RAMBLOCK_FOREACH(block)   \
-if (!qemu_ram_is_migratable(block)) {} else
-
 #undef RAMBLOCK_FOREACH
 
 int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque)
diff --git a/migration/ram.h b/migration/ram.h
index 2eeaacf..011e854 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -37,6 +37,16 @@ extern MigrationStats ram_counters;
 extern XBZRLECacheStats xbzrle_counters;
 extern CompressionStats compression_counters;
 
+bool ramblock_is_ignored(RAMBlock *block);
+/* Should be holding either ram_list.mutex, or the RCU lock. */
+#define RAMBLOCK_FOREACH_NOT_IGNORED(block)\
+INTERNAL_RAMBLOCK_FOREACH(block)   \
+if (ramblock_is_ignored(block)) {} else
+
+#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
+INTERNAL_RAMBLOCK_FOREACH(block)   \
+if (!qemu_ram_is_migratable(block)) {} else
+
 int xbzrle_cache_resize(int64_t new_size, Error **errp);
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_total(void);
-- 
1.8.3.1




[PATCH v5 08/12] migration/dirtyrate: skip sampling ramblock with size below MIN_RAMBLOCK_SIZE

2020-08-24 Thread Chuan Zheng
In order to sample real RAM, skip ramblock with size below MIN_RAMBLOCK_SIZE
which is set as 128M.

Signed-off-by: Chuan Zheng 
---
 migration/dirtyrate.c | 24 
 migration/dirtyrate.h | 10 ++
 2 files changed, 34 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 050270d..bd398b7 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -173,6 +173,24 @@ alloc_ramblock_dirty_info(int *block_index,
 return block_dinfo;
 }
 
+static int skip_sample_ramblock(RAMBlock *block)
+{
+int64_t ramblock_size;
+
+/* ramblock size in MB */
+ramblock_size = qemu_ram_get_used_length(block) >> DIRTYRATE_PAGE_SHIFT_MB;
+
+/*
+ * Consider ramblock with size larger than 128M is what we
+ * want to sample.
+ */
+if (ramblock_size < MIN_RAMBLOCK_SIZE) {
+return -1;
+}
+
+return 0;
+}
+
 static int record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
  struct DirtyRateConfig config,
  int *block_index)
@@ -183,6 +201,9 @@ static int record_ramblock_hash_info(struct 
RamblockDirtyInfo **block_dinfo,
 int index = 0;
 
 RAMBLOCK_FOREACH_MIGRATABLE(block) {
+if (skip_sample_ramblock(block) < 0) {
+continue;
+}
 dinfo = alloc_ramblock_dirty_info(, dinfo);
 if (dinfo == NULL) {
 return -1;
@@ -249,6 +270,9 @@ static int compare_page_hash_info(struct RamblockDirtyInfo 
*info,
 RAMBlock *block = NULL;
 
 RAMBLOCK_FOREACH_MIGRATABLE(block) {
+if (skip_sample_ramblock(block) < 0) {
+continue;
+}
 block_dinfo = NULL;
 if (!find_page_matched(block, info, block_index + 1, _dinfo)) {
 continue;
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index e3adead..600bceb 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -35,10 +35,20 @@
 #define DIRTYRATE_PAGE_SHIFT_KB   12
 
 /*
+ * Sample page size MB shift
+ */
+#define DIRTYRATE_PAGE_SHIFT_MB   20
+
+/*
  * Sample page size 1G shift
  */
 #define DIRTYRATE_PAGE_SHIFT_GB   30
 
+/*
+ * minimum ramblock size to sampled
+ */
+#define MIN_RAMBLOCK_SIZE 128
+
 /* Take 1s as default for calculation duration */
 #define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
 
-- 
1.8.3.1




[PATCH v5 00/12] *** A Method for evaluating dirty page rate ***

2020-08-24 Thread Chuan Zheng
v4 -> v5:
fix git apply failed due to meson-build
add review-by for patches in v3

v3 -> v4:
use crc32 to get hash result instead of md5
add DirtyRateStatus to denote calculation status
add some trace_calls to make it easier to debug
fix some comments accroding to review

v2 -> v3:
fix size_t compile warning
fix codestyle checked by checkpatch.pl

v1 -> v2:
use g_rand_new() to generate rand_buf
move RAMBLOCK_FOREACH_MIGRATABLE into migration/ram.h
add skip_sample_ramblock to filter sampled ramblock
fix multi-numa vm coredump when query dirtyrate
rename qapi interface and rename some structures and functions
succeed to compile by appling each patch
add test for migrating vm

Sometimes it is neccessary to evaluate dirty page rate before migration.
Users could decide whether to proceed migration based on the evaluation
in case of vm performance loss due to heavy workload.
Unlikey simulating dirtylog sync which could do harm on runnning vm,
we provide a sample-hash method to compare hash results for samping page.
In this way, it would have hardly no impact on vm performance.

Evaluate the dirtypage rate both on running and migration vm.
The VM specifications for migration are as follows:
- VM use 4-K page;
- the number of VCPU is 32;
- the total memory is 32Gigabit;
- use 'mempress' tool to pressurize VM(mempress 4096 1024);
- migration bandwidth is 1GB/s

+++
|  |  running  |  migrating 
  |
+++
| no mempress  |   4MB/s   |  8MB/s  (migrated success) 
  |
---
| mempress 4096 1024   |  1060MB/s | 456MB/s ~ 1142MB/s (cpu throttle 
triggered)  |
+++
| mempress 4096 4096   |  4114MB/s | 688MB/s ~ 4132MB/s (cpu throttle 
triggered)  |
+++

Test dirtyrate by qmp command like this:
1.  virsh qemu-monitor-command [vmname] '{"execute":"calc-dirty-rate", 
"arguments": {"calc-time": [sleep-time]}}'; 
2.  sleep specific time which is a bit larger than sleep-time
3.  virsh qemu-monitor-command [vmname] '{"execute":"query-dirty-rate"}'

Further test dirtyrate by libvirt api like this:
virsh getdirtyrate [vmname] [sleep-time]

Chuan Zheng (12):
  migration/dirtyrate: setup up query-dirtyrate framwork
  migration/dirtyrate: add DirtyRateStatus to denote calculation status
  migration/dirtyrate: Add RamlockDirtyInfo to store sampled page info
  migration/dirtyrate: Add dirtyrate statistics series functions
  migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into ram.h
  migration/dirtyrate: Record hash results for each sampled page
  migration/dirtyrate: Compare page hash results for recorded sampled
page
  migration/dirtyrate: skip sampling ramblock with size below
MIN_RAMBLOCK_SIZE
  migration/dirtyrate: Implement get_sample_page_period() and
block_sample_page_period()
  migration/dirtyrate: Implement calculate_dirtyrate() function
  migration/dirtyrate: Implement
qmp_cal_dirty_rate()/qmp_get_dirty_rate() function
  migration/dirtyrate: Add trace_calls to make it easier to debug

 migration/dirtyrate.c  | 432 +
 migration/dirtyrate.h  |  87 ++
 migration/meson.build  |   1 +
 migration/ram.c|  11 +-
 migration/ram.h|  10 ++
 migration/trace-events |   8 +
 qapi/migration.json|  61 +++
 7 files changed, 600 insertions(+), 10 deletions(-)
 create mode 100644 migration/dirtyrate.c
 create mode 100644 migration/dirtyrate.h

-- 
1.8.3.1




[PATCH v5 01/12] migration/dirtyrate: setup up query-dirtyrate framwork

2020-08-24 Thread Chuan Zheng
Add get_dirtyrate_thread() functions to setup query-dirtyrate
framework.

Signed-off-by: Chuan Zheng 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 39 +++
 migration/dirtyrate.h | 32 
 migration/meson.build |  1 +
 3 files changed, 72 insertions(+)
 create mode 100644 migration/dirtyrate.c
 create mode 100644 migration/dirtyrate.h

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
new file mode 100644
index 000..366f4e9
--- /dev/null
+++ b/migration/dirtyrate.c
@@ -0,0 +1,39 @@
+/*
+ * Dirtyrate implement code
+ *
+ * Copyright (c) 2017-2020 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * Authors:
+ *  Chuan Zheng 
+ *
+ * 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 "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/hash.h"
+#include "crypto/random.h"
+#include "qemu/config-file.h"
+#include "exec/memory.h"
+#include "exec/ramblock.h"
+#include "exec/target_page.h"
+#include "qemu/rcu_queue.h"
+#include "qapi/qapi-commands-migration.h"
+#include "migration.h"
+#include "dirtyrate.h"
+
+static void calculate_dirtyrate(struct DirtyRateConfig config)
+{
+/* todo */
+return;
+}
+
+void *get_dirtyrate_thread(void *arg)
+{
+struct DirtyRateConfig config = *(struct DirtyRateConfig *)arg;
+
+calculate_dirtyrate(config);
+
+return NULL;
+}
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
new file mode 100644
index 000..33669b7
--- /dev/null
+++ b/migration/dirtyrate.h
@@ -0,0 +1,32 @@
+/*
+ *  Dirtyrate common functions
+ *
+ *  Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ *  Authors:
+ *  Chuan Zheng 
+ *
+ *  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 QEMU_MIGRATION_DIRTYRATE_H
+#define QEMU_MIGRATION_DIRTYRATE_H
+
+/*
+ * Sample 512 pages per GB as default.
+ * TODO: Make it configurable.
+ */
+#define DIRTYRATE_DEFAULT_SAMPLE_PAGES512
+
+/* Take 1s as default for calculation duration */
+#define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
+
+struct DirtyRateConfig {
+uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
+int64_t sample_period_seconds; /* time duration between two sampling */
+};
+
+void *get_dirtyrate_thread(void *arg);
+#endif
+
diff --git a/migration/meson.build b/migration/meson.build
index ac8ff14..30cc6c3 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -21,6 +21,7 @@ softmmu_ss.add(files(
   'channel.c',
   'colo-failover.c',
   'colo.c',
+  'dirtyrate.c',
   'exec.c',
   'fd.c',
   'global_state.c',
-- 
1.8.3.1




[PATCH v5 11/12] migration/dirtyrate: Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function

2020-08-24 Thread Chuan Zheng
Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function which could be 
called

Signed-off-by: Chuan Zheng 
---
 migration/dirtyrate.c | 45 +
 qapi/migration.json   | 44 
 2 files changed, 89 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 9f52f5f..08c46d3 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -62,6 +62,28 @@ static int dirtyrate_set_state(int *state, int old_state, 
int new_state)
 }
 }
 
+static struct DirtyRateInfo *query_dirty_rate_info(void)
+{
+int64_t dirty_rate = DirtyStat.dirty_rate;
+struct DirtyRateInfo *info = g_malloc0(sizeof(DirtyRateInfo));
+
+if (CalculatingState == DIRTY_RATE_STATUS_MEASURED) {
+info->dirty_rate = dirty_rate;
+} else {
+info->dirty_rate = -1;
+}
+
+info->status = CalculatingState;
+/*
+ * Only support query once for each calculation,
+ * reset as DIRTY_RATE_STATUS_UNSTARTED after query
+ */
+(void)dirtyrate_set_state(, CalculatingState,
+  DIRTY_RATE_STATUS_UNSTARTED);
+
+return info;
+}
+
 static void reset_dirtyrate_stat(void)
 {
 DirtyStat.total_dirty_samples = 0;
@@ -378,3 +400,26 @@ void *get_dirtyrate_thread(void *arg)
   DIRTY_RATE_STATUS_MEASURED);
 return NULL;
 }
+
+void qmp_calc_dirty_rate(int64_t calc_time, Error **errp)
+{
+static struct DirtyRateConfig config;
+QemuThread thread;
+
+/*
+ * We don't begin calculating thread only when it's in calculating status.
+ */
+if (CalculatingState == DIRTY_RATE_STATUS_MEASURING) {
+return;
+}
+
+config.sample_period_seconds = get_sample_page_period(calc_time);
+config.sample_pages_per_gigabytes = DIRTYRATE_DEFAULT_SAMPLE_PAGES;
+qemu_thread_create(, "get_dirtyrate", get_dirtyrate_thread,
+   (void *), QEMU_THREAD_DETACHED);
+}
+
+struct DirtyRateInfo *qmp_query_dirty_rate(Error **errp)
+{
+return query_dirty_rate_info();
+}
diff --git a/qapi/migration.json b/qapi/migration.json
index d640165..826bfd7 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1737,3 +1737,47 @@
 ##
 { 'enum': 'DirtyRateStatus',
   'data': [ 'unstarted', 'measuring', 'measured'] }
+
+##
+# @DirtyRateInfo:
+#
+# Information about current dirty page rate of vm.
+#
+# @dirty-rate: @dirtyrate describing the dirty page rate of vm
+#  in units of MB/s.
+#  If this field return '-1', it means querying is not
+#  start or not complete.
+#
+# @status: status containing dirtyrate query status includes
+#  'unstarted' or 'measuring' or 'measured'
+#
+# Since: 5.2
+#
+##
+{ 'struct': 'DirtyRateInfo',
+  'data': {'dirty-rate': 'int64',
+   'status': 'DirtyRateStatus'} }
+
+##
+# @calc-dirty-rate:
+#
+# start calculating dirty page rate for vm
+#
+# @calc-time: time in units of second for sample dirty pages
+#
+# Since: 5.2
+#
+# Example:
+#   {"command": "cal-dirty-rate", "data": {"calc-time": 1} }
+#
+##
+{ 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64'} }
+
+##
+# @query-dirty-rate:
+#
+# query dirty page rate in units of MB/s for vm
+#
+# Since: 5.2
+##
+{ 'command': 'query-dirty-rate', 'returns': 'DirtyRateInfo' }
-- 
1.8.3.1




[PATCH v5 04/12] migration/dirtyrate: Add dirtyrate statistics series functions

2020-08-24 Thread Chuan Zheng
Add dirtyrate statistics to record/update dirtyrate info.

Signed-off-by: Chuan Zheng 
---
 migration/dirtyrate.c | 29 +
 migration/dirtyrate.h | 10 ++
 2 files changed, 39 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 91987c5..0d7163f 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -24,6 +24,7 @@
 #include "dirtyrate.h"
 
 static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
+static struct DirtyRateStat DirtyStat;
 
 static int dirtyrate_set_state(int *state, int old_state, int new_state)
 {
@@ -35,6 +36,34 @@ static int dirtyrate_set_state(int *state, int old_state, 
int new_state)
 }
 }
 
+static void reset_dirtyrate_stat(void)
+{
+DirtyStat.total_dirty_samples = 0;
+DirtyStat.total_sample_count = 0;
+DirtyStat.total_block_mem_MB = 0;
+DirtyStat.dirty_rate = 0;
+}
+
+static void update_dirtyrate_stat(struct RamblockDirtyInfo *info)
+{
+DirtyStat.total_dirty_samples += info->sample_dirty_count;
+DirtyStat.total_sample_count += info->sample_pages_count;
+/* size of 4K pages in MB */
+DirtyStat.total_block_mem_MB += info->ramblock_pages / 256;
+}
+
+static void update_dirtyrate(uint64_t msec)
+{
+uint64_t dirtyrate;
+uint64_t total_dirty_samples = DirtyStat.total_dirty_samples;
+uint64_t total_sample_count = DirtyStat.total_sample_count;
+uint64_t total_block_mem_MB = DirtyStat.total_block_mem_MB;
+
+dirtyrate = total_dirty_samples * total_block_mem_MB *
+ 1000 / (total_sample_count * msec);
+
+DirtyStat.dirty_rate = dirtyrate;
+}
 
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index dc45419..8e25d93 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -45,6 +45,16 @@ struct RamblockDirtyInfo {
 uint32_t *hash_result; /* array of hash result for sampled pages */
 };
 
+/*
+ * Store calculation statistics for each measure.
+ */
+struct DirtyRateStat {
+uint64_t total_dirty_samples; /* total dirty sampled page */
+uint64_t total_sample_count; /* total sampled pages */
+uint64_t total_block_mem_MB; /* size of total sampled pages in MB */
+int64_t dirty_rate; /* dirty rate in MB/s */
+};
+
 void *get_dirtyrate_thread(void *arg);
 #endif
 
-- 
1.8.3.1




[PATCH v8 11/14] hw/arm: Wire up BMC boot flash for npcm750-evb and quanta-gsj

2020-08-24 Thread Havard Skinnemoen via
This allows these NPCM7xx-based boards to boot from a flash image, e.g.
one built with OpenBMC. For example like this:

IMAGE=${OPENBMC}/build/tmp/deploy/images/gsj/image-bmc
qemu-system-arm -machine quanta-gsj -nographic \
-drive file=${IMAGE},if=mtd,bus=0,unit=0,format=raw,snapshot=on

Reviewed-by: Tyrone Ting 
Reviewed-by: Cédric Le Goater 
Tested-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx_boards.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index b67e45e913..70e5c34216 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -19,6 +19,7 @@
 #include "hw/arm/npcm7xx.h"
 #include "hw/core/cpu.h"
 #include "hw/loader.h"
+#include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "qemu/units.h"
@@ -55,6 +56,22 @@ static void npcm7xx_load_bootrom(MachineState *machine, 
NPCM7xxState *soc)
 }
 }
 
+static void npcm7xx_connect_flash(NPCM7xxFIUState *fiu, int cs_no,
+  const char *flash_type, DriveInfo *dinfo)
+{
+DeviceState *flash;
+qemu_irq flash_cs;
+
+flash = qdev_new(flash_type);
+if (dinfo) {
+qdev_prop_set_drive(flash, "drive", blk_by_legacy_dinfo(dinfo));
+}
+qdev_realize_and_unref(flash, BUS(fiu->spi), _fatal);
+
+flash_cs = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0);
+qdev_connect_gpio_out_named(DEVICE(fiu), "cs", cs_no, flash_cs);
+}
+
 static void npcm7xx_connect_dram(NPCM7xxState *soc, MemoryRegion *dram)
 {
 memory_region_add_subregion(get_system_memory(), NPCM7XX_DRAM_BA, dram);
@@ -92,6 +109,7 @@ static void npcm750_evb_init(MachineState *machine)
 qdev_realize(DEVICE(soc), NULL, _fatal);
 
 npcm7xx_load_bootrom(machine, soc);
+npcm7xx_connect_flash(>fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
 npcm7xx_load_kernel(machine, soc);
 }
 
@@ -104,6 +122,8 @@ static void quanta_gsj_init(MachineState *machine)
 qdev_realize(DEVICE(soc), NULL, _fatal);
 
 npcm7xx_load_bootrom(machine, soc);
+npcm7xx_connect_flash(>fiu[0], 0, "mx25l25635e",
+  drive_get(IF_MTD, 0, 0));
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.28.0.297.g1956fa8f8d-goog




[PATCH v8 08/14] hw/nvram: NPCM7xx OTP device model

2020-08-24 Thread Havard Skinnemoen via
This supports reading and writing OTP fuses and keys. Only fuse reading
has been tested. Protection is not implemented.

Reviewed-by: Avi Fishman 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/arm/npcm7xx.h   |   3 +
 include/hw/nvram/npcm7xx_otp.h |  79 ++
 hw/arm/npcm7xx.c   |  29 +++
 hw/nvram/npcm7xx_otp.c | 439 +
 hw/nvram/meson.build   |   1 +
 5 files changed, 551 insertions(+)
 create mode 100644 include/hw/nvram/npcm7xx_otp.h
 create mode 100644 hw/nvram/npcm7xx_otp.c

diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index ba7495869d..5816a07a72 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -20,6 +20,7 @@
 #include "hw/cpu/a9mpcore.h"
 #include "hw/misc/npcm7xx_clk.h"
 #include "hw/misc/npcm7xx_gcr.h"
+#include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "target/arm/cpu.h"
 
@@ -68,6 +69,8 @@ typedef struct NPCM7xxState {
 NPCM7xxGCRState gcr;
 NPCM7xxCLKState clk;
 NPCM7xxTimerCtrlState tim[3];
+NPCM7xxOTPState key_storage;
+NPCM7xxOTPState fuse_array;
 } NPCM7xxState;
 
 #define TYPE_NPCM7XX"npcm7xx"
diff --git a/include/hw/nvram/npcm7xx_otp.h b/include/hw/nvram/npcm7xx_otp.h
new file mode 100644
index 00..156bbd151a
--- /dev/null
+++ b/include/hw/nvram/npcm7xx_otp.h
@@ -0,0 +1,79 @@
+/*
+ * Nuvoton NPCM7xx OTP (Fuse Array) Interface
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM7XX_OTP_H
+#define NPCM7XX_OTP_H
+
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+
+/* Each OTP module holds 8192 bits of one-time programmable storage */
+#define NPCM7XX_OTP_ARRAY_BITS (8192)
+#define NPCM7XX_OTP_ARRAY_BYTES (NPCM7XX_OTP_ARRAY_BITS / BITS_PER_BYTE)
+
+/* Fuse array offsets */
+#define NPCM7XX_FUSE_FUSTRAP (0)
+#define NPCM7XX_FUSE_CP_FUSTRAP (12)
+#define NPCM7XX_FUSE_DAC_CALIB (16)
+#define NPCM7XX_FUSE_ADC_CALIB (24)
+#define NPCM7XX_FUSE_DERIVATIVE (64)
+#define NPCM7XX_FUSE_TEST_SIG (72)
+#define NPCM7XX_FUSE_DIE_LOCATION (74)
+#define NPCM7XX_FUSE_GP1 (80)
+#define NPCM7XX_FUSE_GP2 (128)
+
+/*
+ * Number of registers in our device state structure. Don't change this without
+ * incrementing the version_id in the vmstate.
+ */
+#define NPCM7XX_OTP_NR_REGS (0x18 / sizeof(uint32_t))
+
+/**
+ * struct NPCM7xxOTPState - Device state for one OTP module.
+ * @parent: System bus device.
+ * @mmio: Memory region through which registers are accessed.
+ * @regs: Register contents.
+ * @array: OTP storage array.
+ */
+typedef struct NPCM7xxOTPState {
+SysBusDevice parent;
+
+MemoryRegion mmio;
+uint32_t regs[NPCM7XX_OTP_NR_REGS];
+uint8_t array[NPCM7XX_OTP_ARRAY_BYTES];
+} NPCM7xxOTPState;
+
+#define TYPE_NPCM7XX_OTP "npcm7xx-otp"
+#define NPCM7XX_OTP(obj) OBJECT_CHECK(NPCM7xxOTPState, (obj), TYPE_NPCM7XX_OTP)
+
+#define TYPE_NPCM7XX_KEY_STORAGE "npcm7xx-key-storage"
+#define TYPE_NPCM7XX_FUSE_ARRAY "npcm7xx-fuse-array"
+
+typedef struct NPCM7xxOTPClass NPCM7xxOTPClass;
+
+/**
+ * npcm7xx_otp_array_write - ECC encode and write data to OTP array.
+ * @s: OTP module.
+ * @data: Data to be encoded and written.
+ * @offset: Offset of first byte to be written in the OTP array.
+ * @len: Number of bytes before ECC encoding.
+ *
+ * Each nibble of data is encoded into a byte, so the number of bytes written
+ * to the array will be @len * 2.
+ */
+extern void npcm7xx_otp_array_write(NPCM7xxOTPState *s, const void *data,
+unsigned int offset, unsigned int len);
+
+#endif /* NPCM7XX_OTP_H */
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 9669ac5fa0..9166002598 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -34,6 +34,10 @@
 #define NPCM7XX_MMIO_BA (0x8000)
 #define NPCM7XX_MMIO_SZ (0x7ffd)
 
+/* OTP key storage and fuse strap array */
+#define NPCM7XX_OTP1_BA (0xf0189000)
+#define NPCM7XX_OTP2_BA (0xf018a000)
+
 /* Core system modules. */
 #define NPCM7XX_L2C_BA  (0xf03fc000)
 #define NPCM7XX_CPUP_BA (0xf03fe000)
@@ -144,6 +148,20 @@ void npcm7xx_load_kernel(MachineState *machine, 
NPCM7xxState *soc)
 arm_load_kernel(>cpu[0], machine, _binfo);
 }
 
+static void npcm7xx_init_fuses(NPCM7xxState *s)
+{
+NPCM7xxClass *nc = NPCM7XX_GET_CLASS(s);
+uint32_t value;
+
+/*
+ * The initial mask of disabled modules indicates the chip derivative (e.g.
+   

Re: [PATCH 2/2] target/i386: Add missed features to Cooperlake CPU model

2020-08-24 Thread Xiaoyao Li

On 8/25/2020 6:07 AM, Eduardo Habkost wrote:

On Wed, Dec 25, 2019 at 02:30:18PM +0800, Xiaoyao Li wrote:

It lacks VMX features and two security feature bits (disclosed recently) in
MSR_IA32_ARCH_CAPABILITIES in current Cooperlake CPU model, so add them.

Fixes: 22a866b6166d ("i386: Add new CPU model Cooperlake")
Signed-off-by: Xiaoyao Li 
---
  target/i386/cpu.c | 51 ++-
  1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index e1eb9f473989..c9798ac8652b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3198,7 +3198,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
  CPUID_7_0_EDX_SPEC_CTRL_SSBD | CPUID_7_0_EDX_ARCH_CAPABILITIES,
  .features[FEAT_ARCH_CAPABILITIES] =
  MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL |
-MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO,
+MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO |
+MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO,


This seems to break on some Cooperlake hosts, see:

https://bugzilla.redhat.com/show_bug.cgi?id=1860743

Are all Cooperlake hosts supposed to have TAA_NO set?  Are there
hosts where this requires a microcode update to be installed?



All the production CPX in market should have IAA_NO bit. We can check it 
directly with rdmsr(0x10a).


The problem of this issue is due to commit db616173d787 ("x86/tsx: Add 
config options to set tsx=on|off|auto"), which sets the default to "off" 
for 100% safety. However, default to off may cause noticeable 
regressions on TSX safe platform, e.g., CPX.


Maybe we need to set CONFIG_X86_INTEL_TSX_MODE_AUTO=y for OSV released 
kernel?






[PATCH v8 14/14] tests/acceptance: console boot tests for quanta-gsj

2020-08-24 Thread Havard Skinnemoen via
This adds two acceptance tests for the quanta-gsj machine.

One test downloads a lightly patched openbmc flash image from github and
verifies that it boots all the way to the login prompt.

The other test downloads a kernel, initrd and dtb built from the same
openbmc source and verifies that the kernel detects all CPUs and boots
to the point where it can't find the root filesystem (because we have no
flash image in this case).

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 tests/acceptance/boot_linux_console.py | 83 ++
 1 file changed, 83 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index aaa781a581..4a366ce93e 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -568,6 +568,89 @@ class BootLinuxConsole(LinuxKernelTest):
 'sda')
 # cubieboard's reboot is not functioning; omit reboot test.
 
+def test_arm_quanta_gsj(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:quanta-gsj
+"""
+# 25 MiB compressed, 32 MiB uncompressed.
+image_url = (
+'https://github.com/hskinnemoen/openbmc/releases/download/'
+'20200711-gsj-qemu-0/obmc-phosphor-image-gsj.static.mtd.gz')
+image_hash = '14895e634923345cb5c8776037ff7876df96f6b1'
+image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash)
+image_name = 'obmc.mtd'
+image_path = os.path.join(self.workdir, image_name)
+archive.gzip_uncompress(image_path_gz, image_path)
+
+self.vm.set_console()
+drive_args = 'file=' + image_path + ',if=mtd,bus=0,unit=0'
+self.vm.add_args('-drive', drive_args)
+self.vm.launch()
+
+# Disable drivers and services that stall for a long time during boot,
+# to avoid running past the 90-second timeout. These may be removed
+# as the corresponding device support is added.
+kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + (
+'console=${console} '
+'mem=${mem} '
+'initcall_blacklist=npcm_i2c_bus_driver_init '
+'systemd.mask=systemd-random-seed.service '
+'systemd.mask=dropbearkey.service '
+)
+
+self.wait_for_console_pattern('> BootBlock by Nuvoton')
+self.wait_for_console_pattern('>Device: Poleg BMC NPCM730')
+self.wait_for_console_pattern('>Skip DDR init.')
+self.wait_for_console_pattern('U-Boot ')
+interrupt_interactive_console_until_pattern(
+self, 'Hit any key to stop autoboot:', 'U-Boot>')
+exec_command_and_wait_for_pattern(
+self, "setenv bootargs ${bootargs} " + kernel_command_line,
+'U-Boot>')
+exec_command_and_wait_for_pattern(
+self, 'run romboot', 'Booting Kernel from flash')
+self.wait_for_console_pattern('Booting Linux on physical CPU 0x0')
+self.wait_for_console_pattern('CPU1: thread -1, cpu 1, socket 0')
+self.wait_for_console_pattern('OpenBMC Project Reference Distro')
+self.wait_for_console_pattern('gsj login:')
+
+def test_arm_quanta_gsj_initrd(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:quanta-gsj
+"""
+initrd_url = (
+'https://github.com/hskinnemoen/openbmc/releases/download/'
+'20200711-gsj-qemu-0/obmc-phosphor-initramfs-gsj.cpio.xz')
+initrd_hash = '98fefe5d7e56727b1eb17d5c00311b1b5c945300'
+initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
+kernel_url = (
+'https://github.com/hskinnemoen/openbmc/releases/download/'
+'20200711-gsj-qemu-0/uImage-gsj.bin')
+kernel_hash = 'fa67b2f141d56d39b3c54305c0e8a899c99eb2c7'
+kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
+dtb_url = (
+'https://github.com/hskinnemoen/openbmc/releases/download/'
+'20200711-gsj-qemu-0/nuvoton-npcm730-gsj.dtb')
+dtb_hash = '18315f7006d7b688d8312d5c727eecd819aa36a4'
+dtb_path = self.fetch_asset(dtb_url, asset_hash=dtb_hash)
+
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'console=ttyS0,115200n8 '
+   'earlycon=uart8250,mmio32,0xf0001000')
+self.vm.add_args('-kernel', kernel_path,
+ '-initrd', initrd_path,
+ '-dtb', dtb_path,
+ '-append', kernel_command_line)
+self.vm.launch()
+
+self.wait_for_console_pattern('Booting Linux on physical CPU 0x0')
+self.wait_for_console_pattern('CPU1: thread -1, cpu 1, socket 0')
+

[PATCH v8 12/14] hw/arm/npcm7xx: add board setup stub for CPU and UART clocks

2020-08-24 Thread Havard Skinnemoen via
When booting directly into a kernel, bypassing the boot loader, the CPU and
UART clocks are not set up correctly. This makes the system appear very
slow, and causes the initrd boot test to fail when optimization is off.

The UART clock must run at 24 MHz. The default 25 MHz reference clock
cannot achieve this, so switch to PLL2/2 @ 480 MHz, which works
perfectly with the default /20 divider.

The CPU clock should run at 800 MHz, so switch it to PLL1/2. PLL1 runs
at 800 MHz by default, so we need to double the feedback divider as well
to make it run at 1600 MHz (so PLL1/2 runs at 800 MHz).

We don't bother checking for PLL lock because we know our emulated PLLs
lock instantly.

Signed-off-by: Havard Skinnemoen 
---
 include/hw/arm/npcm7xx.h |  1 +
 hw/arm/npcm7xx.c | 32 
 2 files changed, 33 insertions(+)

diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 78d0d78c52..13106af215 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -37,6 +37,7 @@
 #define NPCM7XX_SMP_LOADER_START(0x)  /* Boot ROM */
 #define NPCM7XX_SMP_BOOTREG_ADDR(0xf080013c)  /* GCR.SCRPAD */
 #define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100)  /* GIC within A9 */
+#define NPCM7XX_BOARD_SETUP_ADDR(0x1000)  /* Boot ROM */
 
 typedef struct NPCM7xxMachine {
 MachineStateparent;
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 7884b2b03d..037f3a26f2 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -55,6 +55,13 @@
 #define NPCM7XX_ROM_BA  (0x)
 #define NPCM7XX_ROM_SZ  (64 * KiB)
 
+/* Clock configuration values to be fixed up when bypassing bootloader */
+
+/* Run PLL1 at 1600 MHz */
+#define NPCM7XX_PLLCON1_FIXUP_VAL   (0x00402101)
+/* Run the CPU from PLL1 and UART from PLL2 */
+#define NPCM7XX_CLKSEL_FIXUP_VAL(0x004aaba9)
+
 /*
  * Interrupt lines going into the GIC. This does not include internal Cortex-A9
  * interrupts.
@@ -132,6 +139,29 @@ static const struct {
 },
 };
 
+static void npcm7xx_write_board_setup(ARMCPU *cpu,
+  const struct arm_boot_info *info)
+{
+uint32_t board_setup[] = {
+0xe59f0010, /* ldr r0, clk_base_addr */
+0xe59f1010, /* ldr r1, pllcon1_value */
+0xe5801010, /* str r1, [r0, #16] */
+0xe59f100c, /* ldr r1, clksel_value */
+0xe5801004, /* str r1, [r0, #4] */
+0xe12fff1e, /* bx lr */
+NPCM7XX_CLK_BA,
+NPCM7XX_PLLCON1_FIXUP_VAL,
+NPCM7XX_CLKSEL_FIXUP_VAL,
+};
+int i;
+
+for (i = 0; i < ARRAY_SIZE(board_setup); i++) {
+board_setup[i] = tswap32(board_setup[i]);
+}
+rom_add_blob_fixed("board-setup", board_setup, sizeof(board_setup),
+   info->board_setup_addr);
+}
+
 static void npcm7xx_write_secondary_boot(ARMCPU *cpu,
  const struct arm_boot_info *info)
 {
@@ -170,6 +200,8 @@ static struct arm_boot_info npcm7xx_binfo = {
 .gic_cpu_if_addr= NPCM7XX_GIC_CPU_IF_ADDR,
 .write_secondary_boot   = npcm7xx_write_secondary_boot,
 .board_id   = -1,
+.board_setup_addr   = NPCM7XX_BOARD_SETUP_ADDR,
+.write_board_setup  = npcm7xx_write_board_setup,
 };
 
 void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc)
-- 
2.28.0.297.g1956fa8f8d-goog




[PATCH v8 06/14] roms: Add virtual Boot ROM for NPCM7xx SoCs

2020-08-24 Thread Havard Skinnemoen via
This is a minimalistic boot ROM written specifically for use with QEMU.
It supports loading the second-stage loader from SPI flash into RAM, SMP
boot, and not much else.

Signed-off-by: Havard Skinnemoen 
---
 Makefile|   1 +
 .gitmodules |   3 +++
 MAINTAINERS |   2 ++
 pc-bios/README  |   6 ++
 pc-bios/npcm7xx_bootrom.bin | Bin 0 -> 768 bytes
 roms/Makefile   |   7 +++
 roms/vbootrom   |   1 +
 7 files changed, 20 insertions(+)
 create mode 100644 pc-bios/npcm7xx_bootrom.bin
 create mode 16 roms/vbootrom

diff --git a/Makefile b/Makefile
index 81794d5c34..08e9af3793 100644
--- a/Makefile
+++ b/Makefile
@@ -246,6 +246,7 @@ s390-ccw.img s390-netboot.img \
 slof.bin skiboot.lid \
 palcode-clipper \
 u-boot.e500 u-boot-sam460-20100605.bin \
+npcm7xx_bootrom.bin \
 qemu_vga.ndrv \
 edk2-licenses.txt \
 hppa-firmware.img \
diff --git a/.gitmodules b/.gitmodules
index ce979398a8..9ffb9f3f4f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -61,3 +61,6 @@
 [submodule "meson"]
path = meson
url = https://github.com/mesonbuild/meson/
+[submodule "roms/vbootrom"]
+   path = roms/vbootrom
+   url = https://github.com/google/vbootrom.git
diff --git a/MAINTAINERS b/MAINTAINERS
index 3f72250630..d71afedc20 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -756,6 +756,8 @@ L: qemu-...@nongnu.org
 S: Supported
 F: hw/*/npcm7xx*
 F: include/hw/*/npcm7xx*
+F: pc-bios/npcm7xx_bootrom.bin
+F: roms/vbootrom
 
 nSeries
 M: Andrzej Zaborowski 
diff --git a/pc-bios/README b/pc-bios/README
index fa8b58b797..4d6297fca7 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -71,3 +71,9 @@
   ("Simplified BSD License" or "FreeBSD License", SPDX: BSD-2-Clause). OpenSBI
   source code also contains code reused from other projects desribed here:
   https://github.com/riscv/opensbi/blob/master/ThirdPartyNotices.md.
+
+- npcm7xx_bootrom.bin is a simplified, free (Apache 2.0) boot ROM for Nuvoton
+  NPCM7xx BMC devices. It currently implements the bare minimum to load, parse,
+  initialize and run boot images stored in SPI flash, but may grow more
+  features over time as needed. The source code is available at:
+  https://github.com/google/vbootrom
diff --git a/pc-bios/npcm7xx_bootrom.bin b/pc-bios/npcm7xx_bootrom.bin
new file mode 100644
index 
..38f89d1b97b0c2e133af2a9fbed0521be132065b
GIT binary patch
literal 768
zcmd5)JxClu6n-9S05p1#kf90Sj5Z(jG8}+)IZIp~iXK=T&)dL`%d-q*8aR#mq{7
z9`=6;Dr(H0ACe72R5x?!)^86Qj-X%{+!K9iZNA@*wkBAV(l^I9?!Gz=S2I_*1d
zr+tTQDHjvyzKnw(hu00yX`u!FvC;DilBe_YlkeSUVHA-crNk+k
jtiF_MudA

[PATCH v8 07/14] hw/arm: Load -bios image as a boot ROM for npcm7xx

2020-08-24 Thread Havard Skinnemoen via
If a -bios option is specified on the command line, load the image into
the internal ROM memory region, which contains the first instructions
run by the CPU after reset.

If -bios is not specified, the vbootrom included with qemu is loaded by
default.

Reviewed-by: Tyrone Ting 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx_boards.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 0b9dce2b35..b67e45e913 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -18,12 +18,43 @@
 
 #include "hw/arm/npcm7xx.h"
 #include "hw/core/cpu.h"
+#include "hw/loader.h"
 #include "qapi/error.h"
+#include "qemu-common.h"
 #include "qemu/units.h"
+#include "sysemu/sysemu.h"
 
 #define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
 #define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
 
+static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
+
+static void npcm7xx_load_bootrom(MachineState *machine, NPCM7xxState *soc)
+{
+g_autofree char *filename = NULL;
+int ret;
+
+if (machine->kernel_filename) {
+/* Don't load the bootrom if user requested direct kernel boot. */
+return;
+}
+
+if (!bios_name) {
+bios_name = npcm7xx_default_bootrom;
+}
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+if (!filename) {
+error_report("Could not find ROM image '%s'", bios_name);
+exit(1);
+}
+ret = load_image_mr(filename, >irom);
+if (ret < 0) {
+error_report("Failed to load ROM image '%s'", filename);
+exit(1);
+}
+}
+
 static void npcm7xx_connect_dram(NPCM7xxState *soc, MemoryRegion *dram)
 {
 memory_region_add_subregion(get_system_memory(), NPCM7XX_DRAM_BA, dram);
@@ -60,6 +91,7 @@ static void npcm750_evb_init(MachineState *machine)
 npcm7xx_connect_dram(soc, machine->ram);
 qdev_realize(DEVICE(soc), NULL, _fatal);
 
+npcm7xx_load_bootrom(machine, soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
@@ -71,6 +103,7 @@ static void quanta_gsj_init(MachineState *machine)
 npcm7xx_connect_dram(soc, machine->ram);
 qdev_realize(DEVICE(soc), NULL, _fatal);
 
+npcm7xx_load_bootrom(machine, soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.28.0.297.g1956fa8f8d-goog




[PATCH v8 04/14] hw/arm: Add NPCM730 and NPCM750 SoC models

2020-08-24 Thread Havard Skinnemoen via
The Nuvoton NPCM7xx SoC family are used to implement Baseboard
Management Controllers in servers. While the family includes four SoCs,
this patch implements limited support for two of them: NPCM730 (targeted
for Data Center applications) and NPCM750 (targeted for Enterprise
applications).

This patch includes little more than the bare minimum needed to boot a
Linux kernel built with NPCM7xx support in direct-kernel mode:

  - Two Cortex-A9 CPU cores with built-in periperhals.
  - Global Configuration Registers.
  - Clock Management.
  - 3 Timer Modules with 5 timers each.
  - 4 serial ports.

The chips themselves have a lot more features, some of which will be
added to the model at a later stage.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/arm/npcm7xx.h |  85 
 hw/arm/npcm7xx.c | 407 +++
 hw/arm/Kconfig   |   5 +
 hw/arm/meson.build   |   1 +
 4 files changed, 498 insertions(+)
 create mode 100644 include/hw/arm/npcm7xx.h
 create mode 100644 hw/arm/npcm7xx.c

diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
new file mode 100644
index 00..e68d9c79e6
--- /dev/null
+++ b/include/hw/arm/npcm7xx.h
@@ -0,0 +1,85 @@
+/*
+ * Nuvoton NPCM7xx SoC family.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM7XX_H
+#define NPCM7XX_H
+
+#include "hw/boards.h"
+#include "hw/cpu/a9mpcore.h"
+#include "hw/misc/npcm7xx_clk.h"
+#include "hw/misc/npcm7xx_gcr.h"
+#include "hw/timer/npcm7xx_timer.h"
+#include "target/arm/cpu.h"
+
+#define NPCM7XX_MAX_NUM_CPUS(2)
+
+/* The first half of the address space is reserved for DDR4 DRAM. */
+#define NPCM7XX_DRAM_BA (0x)
+#define NPCM7XX_DRAM_SZ (2 * GiB)
+
+/* Magic addresses for setting up direct kernel booting and SMP boot stubs. */
+#define NPCM7XX_LOADER_START(0x)  /* Start of SDRAM */
+#define NPCM7XX_SMP_LOADER_START(0x)  /* Boot ROM */
+#define NPCM7XX_SMP_BOOTREG_ADDR(0xf080013c)  /* GCR.SCRPAD */
+#define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100)  /* GIC within A9 */
+
+typedef struct NPCM7xxState {
+DeviceState parent;
+
+ARMCPU  cpu[NPCM7XX_MAX_NUM_CPUS];
+A9MPPrivState   a9mpcore;
+
+MemoryRegionsram;
+MemoryRegionirom;
+MemoryRegionram3;
+MemoryRegion*dram;
+
+NPCM7xxGCRState gcr;
+NPCM7xxCLKState clk;
+NPCM7xxTimerCtrlState tim[3];
+} NPCM7xxState;
+
+#define TYPE_NPCM7XX"npcm7xx"
+#define NPCM7XX(obj)OBJECT_CHECK(NPCM7xxState, (obj), TYPE_NPCM7XX)
+
+#define TYPE_NPCM730"npcm730"
+#define TYPE_NPCM750"npcm750"
+
+typedef struct NPCM7xxClass {
+DeviceClass parent;
+
+/* Bitmask of modules that are permanently disabled on this chip. */
+uint32_tdisabled_modules;
+/* Number of CPU cores enabled in this SoC class (may be 1 or 2). */
+uint32_tnum_cpus;
+} NPCM7xxClass;
+
+#define NPCM7XX_CLASS(klass)\
+OBJECT_CLASS_CHECK(NPCM7xxClass, (klass), TYPE_NPCM7XX)
+#define NPCM7XX_GET_CLASS(obj)  \
+OBJECT_GET_CLASS(NPCM7xxClass, (obj), TYPE_NPCM7XX)
+
+/**
+ * npcm7xx_load_kernel - Loads memory with everything needed to boot
+ * @machine - The machine containing the SoC to be booted.
+ * @soc - The SoC containing the CPU to be booted.
+ *
+ * This will set up the ARM boot info structure for the specific NPCM7xx
+ * derivative and call arm_load_kernel() to set up loading of the kernel, etc.
+ * into memory, if requested by the user.
+ */
+void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc);
+
+#endif /* NPCM7XX_H */
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
new file mode 100644
index 00..9669ac5fa0
--- /dev/null
+++ b/hw/arm/npcm7xx.c
@@ -0,0 +1,407 @@
+/*
+ * Nuvoton NPCM7xx SoC family.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * 

[PATCH v8 13/14] docs/system: Add Nuvoton machine documentation

2020-08-24 Thread Havard Skinnemoen via
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 docs/system/arm/nuvoton.rst | 90 +
 docs/system/target-arm.rst  |  1 +
 2 files changed, 91 insertions(+)
 create mode 100644 docs/system/arm/nuvoton.rst

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
new file mode 100644
index 00..36bf901122
--- /dev/null
+++ b/docs/system/arm/nuvoton.rst
@@ -0,0 +1,90 @@
+Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
+=
+
+The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
+designed to be used as Baseboard Management Controllers (BMCs) in various
+servers. They all feature one or two ARM Cortex A9 CPU cores, as well as an
+assortment of peripherals targeted for either Enterprise or Data Center /
+Hyperscale applications. The former is a superset of the latter, so NPCM750 has
+all the peripherals of NPCM730 and more.
+
+.. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
+
+The NPCM750 SoC has two Cortex A9 cores and is targeted for the Enterprise
+segment. The following machines are based on this chip :
+
+- ``npcm750-evb``   Nuvoton NPCM750 Evaluation board
+
+The NPCM730 SoC has two Cortex A9 cores and is targeted for Data Center and
+Hyperscale applications. The following machines are based on this chip :
+
+- ``quanta-gsj``Quanta GSJ server BMC
+
+There are also two more SoCs, NPCM710 and NPCM705, which are single-core
+variants of NPCM750 and NPCM730, respectively. These are currently not
+supported by QEMU.
+
+Supported devices
+-
+
+ * SMP (Dual Core Cortex-A9)
+ * Cortex-A9MPCore built-in peripherals: SCU, GIC, Global Timer, Private Timer
+   and Watchdog.
+ * SRAM, ROM and DRAM mappings
+ * System Global Control Registers (GCR)
+ * Clock and reset controller (CLK)
+ * Timer controller (TIM)
+ * Serial ports (16550-based)
+ * DDR4 memory controller (dummy interface indicating memory training is done)
+ * OTP controllers (no protection features)
+ * Flash Interface Unit (FIU; no protection features)
+
+Missing devices
+---
+
+ * GPIO controller
+ * LPC/eSPI host-to-BMC interface, including
+
+   * Keyboard and mouse controller interface (KBCI)
+   * Keyboard Controller Style (KCS) channels
+   * BIOS POST code FIFO
+   * System Wake-up Control (SWC)
+   * Shared memory (SHM)
+   * eSPI slave interface
+
+ * Ethernet controllers (GMAC and EMC)
+ * USB host (USBH)
+ * USB device (USBD)
+ * SMBus controller (SMBF)
+ * Peripheral SPI controller (PSPI)
+ * Analog to Digital Converter (ADC)
+ * SD/MMC host
+ * Random Number Generator (RNG)
+ * PECI interface
+ * Pulse Width Modulation (PWM)
+ * Tachometer
+ * PCI and PCIe root complex and bridges
+ * VDM and MCTP support
+ * Serial I/O expansion
+ * LPC/eSPI host
+ * Coprocessor
+ * Graphics
+ * Video capture
+ * Encoding compression engine
+ * Security features
+
+Boot options
+
+
+The Nuvoton machines can boot from an OpenBMC firmware image, or directly into
+a kernel using the ``-kernel`` option. OpenBMC images for `quanta-gsj` and
+possibly others can be downloaded from the OpenPOWER jenkins :
+
+   https://openpower.xyz/
+
+The firmware image should be attached as an MTD drive. Example :
+
+.. code-block:: bash
+
+  $ qemu-system-arm -machine quanta-gsj -nographic \
+  -drive file=image-bmc,if=mtd,bus=0,unit=0,format=raw
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index afdb37e738..fdcf25c237 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -86,6 +86,7 @@ undocumented; you can get a complete list by running
arm/musicpal
arm/gumstix
arm/nseries
+   arm/nuvoton
arm/orangepi
arm/palm
arm/xscale
-- 
2.28.0.297.g1956fa8f8d-goog




[PATCH v8 05/14] hw/arm: Add two NPCM7xx-based machines

2020-08-24 Thread Havard Skinnemoen via
This adds two new machines, both supported by OpenBMC:

  - npcm750-evb: Nuvoton NPCM750 Evaluation Board.
  - quanta-gsj: A board with a NPCM730 chip.

They rely on the NPCM7xx SoC device to do the heavy lifting. They are
almost completely identical at the moment, apart from the SoC type,
which currently only changes the reset contents of one register
(GCR.MDLR), but they might grow apart a bit more as more functionality
is added.

Both machines can boot the Linux kernel into /bin/sh.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 default-configs/arm-softmmu.mak |   1 +
 include/hw/arm/npcm7xx.h|  19 +
 hw/arm/npcm7xx_boards.c | 144 
 hw/arm/meson.build  |   2 +-
 4 files changed, 165 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/npcm7xx_boards.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 8fc09a4a51..9a94ebd0be 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -27,6 +27,7 @@ CONFIG_GUMSTIX=y
 CONFIG_SPITZ=y
 CONFIG_TOSA=y
 CONFIG_Z2=y
+CONFIG_NPCM7XX=y
 CONFIG_COLLIE=y
 CONFIG_ASPEED_SOC=y
 CONFIG_NETDUINO2=y
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index e68d9c79e6..ba7495869d 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -35,6 +35,25 @@
 #define NPCM7XX_SMP_BOOTREG_ADDR(0xf080013c)  /* GCR.SCRPAD */
 #define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100)  /* GIC within A9 */
 
+typedef struct NPCM7xxMachine {
+MachineStateparent;
+} NPCM7xxMachine;
+
+#define TYPE_NPCM7XX_MACHINE MACHINE_TYPE_NAME("npcm7xx")
+#define NPCM7XX_MACHINE(obj)\
+OBJECT_CHECK(NPCM7xxMachine, (obj), TYPE_NPCM7XX_MACHINE)
+
+typedef struct NPCM7xxMachineClass {
+MachineClassparent;
+
+const char  *soc_type;
+} NPCM7xxMachineClass;
+
+#define NPCM7XX_MACHINE_CLASS(klass)\
+OBJECT_CLASS_CHECK(NPCM7xxMachineClass, (klass), TYPE_NPCM7XX_MACHINE)
+#define NPCM7XX_MACHINE_GET_CLASS(obj)  \
+OBJECT_GET_CLASS(NPCM7xxMachineClass, (obj), TYPE_NPCM7XX_MACHINE)
+
 typedef struct NPCM7xxState {
 DeviceState parent;
 
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
new file mode 100644
index 00..0b9dce2b35
--- /dev/null
+++ b/hw/arm/npcm7xx_boards.c
@@ -0,0 +1,144 @@
+/*
+ * Machine definitions for boards featuring an NPCM7xx SoC.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/arm/npcm7xx.h"
+#include "hw/core/cpu.h"
+#include "qapi/error.h"
+#include "qemu/units.h"
+
+#define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
+#define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
+
+static void npcm7xx_connect_dram(NPCM7xxState *soc, MemoryRegion *dram)
+{
+memory_region_add_subregion(get_system_memory(), NPCM7XX_DRAM_BA, dram);
+
+object_property_set_link(OBJECT(soc), "dram-mr", OBJECT(dram),
+ _abort);
+}
+
+static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
+uint32_t hw_straps)
+{
+NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_GET_CLASS(machine);
+MachineClass *mc = >parent;
+Object *obj;
+
+if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
+error_report("This board can only be used with %s",
+ mc->default_cpu_type);
+exit(1);
+}
+
+obj = object_new_with_props(nmc->soc_type, OBJECT(machine), "soc",
+_abort, NULL);
+object_property_set_uint(obj, "power-on-straps", hw_straps, _abort);
+
+return NPCM7XX(obj);
+}
+
+static void npcm750_evb_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine, NPCM750_EVB_POWER_ON_STRAPS);
+npcm7xx_connect_dram(soc, machine->ram);
+qdev_realize(DEVICE(soc), NULL, _fatal);
+
+npcm7xx_load_kernel(machine, soc);
+}
+
+static void quanta_gsj_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine, QUANTA_GSJ_POWER_ON_STRAPS);
+npcm7xx_connect_dram(soc, machine->ram);
+qdev_realize(DEVICE(soc), NULL, _fatal);
+
+npcm7xx_load_kernel(machine, soc);
+}
+
+static void 

[PATCH v8 09/14] hw/mem: Stubbed out NPCM7xx Memory Controller model

2020-08-24 Thread Havard Skinnemoen via
This just implements the bare minimum to cause the boot block to skip
memory initialization.

Reviewed-by: Tyrone Ting 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/arm/npcm7xx.h|  2 +
 include/hw/mem/npcm7xx_mc.h | 36 
 hw/arm/npcm7xx.c|  6 +++
 hw/mem/npcm7xx_mc.c | 84 +
 hw/mem/meson.build  |  1 +
 5 files changed, 129 insertions(+)
 create mode 100644 include/hw/mem/npcm7xx_mc.h
 create mode 100644 hw/mem/npcm7xx_mc.c

diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 5816a07a72..9fa84a0702 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -18,6 +18,7 @@
 
 #include "hw/boards.h"
 #include "hw/cpu/a9mpcore.h"
+#include "hw/mem/npcm7xx_mc.h"
 #include "hw/misc/npcm7xx_clk.h"
 #include "hw/misc/npcm7xx_gcr.h"
 #include "hw/nvram/npcm7xx_otp.h"
@@ -71,6 +72,7 @@ typedef struct NPCM7xxState {
 NPCM7xxTimerCtrlState tim[3];
 NPCM7xxOTPState key_storage;
 NPCM7xxOTPState fuse_array;
+NPCM7xxMCState  mc;
 } NPCM7xxState;
 
 #define TYPE_NPCM7XX"npcm7xx"
diff --git a/include/hw/mem/npcm7xx_mc.h b/include/hw/mem/npcm7xx_mc.h
new file mode 100644
index 00..7ed38be243
--- /dev/null
+++ b/include/hw/mem/npcm7xx_mc.h
@@ -0,0 +1,36 @@
+/*
+ * Nuvoton NPCM7xx Memory Controller stub
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM7XX_MC_H
+#define NPCM7XX_MC_H
+
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+
+/**
+ * struct NPCM7xxMCState - Device state for the memory controller.
+ * @parent: System bus device.
+ * @mmio: Memory region through which registers are accessed.
+ */
+typedef struct NPCM7xxMCState {
+SysBusDevice parent;
+
+MemoryRegion mmio;
+} NPCM7xxMCState;
+
+#define TYPE_NPCM7XX_MC "npcm7xx-mc"
+#define NPCM7XX_MC(obj) OBJECT_CHECK(NPCM7xxMCState, (obj), TYPE_NPCM7XX_MC)
+
+#endif /* NPCM7XX_MC_H */
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 9166002598..6bb1693833 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -43,6 +43,7 @@
 #define NPCM7XX_CPUP_BA (0xf03fe000)
 #define NPCM7XX_GCR_BA  (0xf080)
 #define NPCM7XX_CLK_BA  (0xf0801000)
+#define NPCM7XX_MC_BA   (0xf0824000)
 
 /* Internal AHB SRAM */
 #define NPCM7XX_RAM3_BA (0xc0008000)
@@ -186,6 +187,7 @@ static void npcm7xx_init(Object *obj)
 TYPE_NPCM7XX_KEY_STORAGE);
 object_initialize_child(obj, "otp2", >fuse_array,
 TYPE_NPCM7XX_FUSE_ARRAY);
+object_initialize_child(obj, "mc", >mc, TYPE_NPCM7XX_MC);
 
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
 object_initialize_child(obj, "tim[*]", >tim[i], TYPE_NPCM7XX_TIMER);
@@ -261,6 +263,10 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>fuse_array), 0, NPCM7XX_OTP2_BA);
 npcm7xx_init_fuses(s);
 
+/* Fake Memory Controller (MC). Cannot fail. */
+sysbus_realize(SYS_BUS_DEVICE(>mc), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>mc), 0, NPCM7XX_MC_BA);
+
 /* Timer Modules (TIM). Cannot fail. */
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
diff --git a/hw/mem/npcm7xx_mc.c b/hw/mem/npcm7xx_mc.c
new file mode 100644
index 00..0435d06ab4
--- /dev/null
+++ b/hw/mem/npcm7xx_mc.c
@@ -0,0 +1,84 @@
+/*
+ * Nuvoton NPCM7xx Memory Controller stub
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/mem/npcm7xx_mc.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#define NPCM7XX_MC_REGS_SIZE (4 * KiB)
+
+static uint64_t npcm7xx_mc_read(void *opaque, hwaddr addr, unsigned int size)
+{
+/*
+ * If bits 8..11 @ offset 0 are not zero, the boot block thinks the memory
+ * controller 

[PATCH v8 02/14] hw/misc: Add NPCM7xx Clock Controller device model

2020-08-24 Thread Havard Skinnemoen via
Enough functionality to boot the Linux kernel has been implemented. This
includes:

  - Correct power-on reset values so the various clock rates can be
accurately calculated.
  - Clock enables stick around when written.

In addition, a best effort attempt to implement SECCNT and CNTR25M was
made even though I don't think the kernel needs them.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/misc/npcm7xx_clk.h |  48 ++
 hw/misc/npcm7xx_clk.c | 266 ++
 hw/misc/meson.build   |   1 +
 hw/misc/trace-events  |   4 +
 4 files changed, 319 insertions(+)
 create mode 100644 include/hw/misc/npcm7xx_clk.h
 create mode 100644 hw/misc/npcm7xx_clk.c

diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm7xx_clk.h
new file mode 100644
index 00..cdcc9e8534
--- /dev/null
+++ b/include/hw/misc/npcm7xx_clk.h
@@ -0,0 +1,48 @@
+/*
+ * Nuvoton NPCM7xx Clock Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM7XX_CLK_H
+#define NPCM7XX_CLK_H
+
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+
+/*
+ * The reference clock frequency for the timer modules, and the SECCNT and
+ * CNTR25M registers in this module, is always 25 MHz.
+ */
+#define NPCM7XX_TIMER_REF_HZ(2500)
+
+/*
+ * Number of registers in our device state structure. Don't change this without
+ * incrementing the version_id in the vmstate.
+ */
+#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t))
+
+typedef struct NPCM7xxCLKState {
+SysBusDevice parent;
+
+MemoryRegion iomem;
+
+uint32_t regs[NPCM7XX_CLK_NR_REGS];
+
+/* Time reference for SECCNT and CNTR25M, initialized by power on reset */
+int64_t ref_ns;
+} NPCM7xxCLKState;
+
+#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
+#define NPCM7XX_CLK(obj) OBJECT_CHECK(NPCM7xxCLKState, (obj), TYPE_NPCM7XX_CLK)
+
+#endif /* NPCM7XX_CLK_H */
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
new file mode 100644
index 00..21ab4200d1
--- /dev/null
+++ b/hw/misc/npcm7xx_clk.c
@@ -0,0 +1,266 @@
+/*
+ * Nuvoton NPCM7xx Clock Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/misc/npcm7xx_clk.h"
+#include "migration/vmstate.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+#define PLLCON_LOKI BIT(31)
+#define PLLCON_LOKS BIT(30)
+#define PLLCON_PWDENBIT(12)
+
+enum NPCM7xxCLKRegisters {
+NPCM7XX_CLK_CLKEN1,
+NPCM7XX_CLK_CLKSEL,
+NPCM7XX_CLK_CLKDIV1,
+NPCM7XX_CLK_PLLCON0,
+NPCM7XX_CLK_PLLCON1,
+NPCM7XX_CLK_SWRSTR,
+NPCM7XX_CLK_IPSRST1 = 0x20 / sizeof(uint32_t),
+NPCM7XX_CLK_IPSRST2,
+NPCM7XX_CLK_CLKEN2,
+NPCM7XX_CLK_CLKDIV2,
+NPCM7XX_CLK_CLKEN3,
+NPCM7XX_CLK_IPSRST3,
+NPCM7XX_CLK_WD0RCR,
+NPCM7XX_CLK_WD1RCR,
+NPCM7XX_CLK_WD2RCR,
+NPCM7XX_CLK_SWRSTC1,
+NPCM7XX_CLK_SWRSTC2,
+NPCM7XX_CLK_SWRSTC3,
+NPCM7XX_CLK_SWRSTC4,
+NPCM7XX_CLK_PLLCON2,
+NPCM7XX_CLK_CLKDIV3,
+NPCM7XX_CLK_CORSTC,
+NPCM7XX_CLK_PLLCONG,
+NPCM7XX_CLK_AHBCKFI,
+NPCM7XX_CLK_SECCNT,
+NPCM7XX_CLK_CNTR25M,
+NPCM7XX_CLK_REGS_END,
+};
+
+/*
+ * These reset values were taken from version 0.91 of the NPCM750R data sheet.
+ *
+ * All are loaded on power-up reset. CLKENx and SWRSTR should also be loaded on
+ * core domain reset, but this reset type is not yet supported by QEMU.
+ */
+static const uint32_t cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
+[NPCM7XX_CLK_CLKEN1]= 0x,
+[NPCM7XX_CLK_CLKSEL]= 0x004a,
+[NPCM7XX_CLK_CLKDIV1]   = 0x5413f855,
+[NPCM7XX_CLK_PLLCON0]   = 0x00222101 | PLLCON_LOKI,
+[NPCM7XX_CLK_PLLCON1]   = 0x00202101 | PLLCON_LOKI,
+[NPCM7XX_CLK_IPSRST1]   = 

[PATCH v8 10/14] hw/ssi: NPCM7xx Flash Interface Unit device model

2020-08-24 Thread Havard Skinnemoen via
This implements a device model for the NPCM7xx SPI flash controller.

Direct reads and writes, and user-mode transactions have been tested in
various modes. Protection features are not implemented yet.

All the FIU instances are available in the SoC's address space,
regardless of whether or not they're connected to actual flash chips.

Reviewed-by: Tyrone Ting 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/arm/npcm7xx.h |   2 +
 include/hw/ssi/npcm7xx_fiu.h |  73 +
 hw/arm/npcm7xx.c |  58 
 hw/ssi/npcm7xx_fiu.c | 572 +++
 hw/arm/Kconfig   |   1 +
 hw/ssi/meson.build   |   1 +
 hw/ssi/trace-events  |  11 +
 7 files changed, 718 insertions(+)
 create mode 100644 include/hw/ssi/npcm7xx_fiu.h
 create mode 100644 hw/ssi/npcm7xx_fiu.c

diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 9fa84a0702..78d0d78c52 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -23,6 +23,7 @@
 #include "hw/misc/npcm7xx_gcr.h"
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
+#include "hw/ssi/npcm7xx_fiu.h"
 #include "target/arm/cpu.h"
 
 #define NPCM7XX_MAX_NUM_CPUS(2)
@@ -73,6 +74,7 @@ typedef struct NPCM7xxState {
 NPCM7xxOTPState key_storage;
 NPCM7xxOTPState fuse_array;
 NPCM7xxMCState  mc;
+NPCM7xxFIUState fiu[2];
 } NPCM7xxState;
 
 #define TYPE_NPCM7XX"npcm7xx"
diff --git a/include/hw/ssi/npcm7xx_fiu.h b/include/hw/ssi/npcm7xx_fiu.h
new file mode 100644
index 00..a3a1704289
--- /dev/null
+++ b/include/hw/ssi/npcm7xx_fiu.h
@@ -0,0 +1,73 @@
+/*
+ * Nuvoton NPCM7xx Flash Interface Unit (FIU)
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM7XX_FIU_H
+#define NPCM7XX_FIU_H
+
+#include "hw/ssi/ssi.h"
+#include "hw/sysbus.h"
+
+/*
+ * Number of registers in our device state structure. Don't change this without
+ * incrementing the version_id in the vmstate.
+ */
+#define NPCM7XX_FIU_NR_REGS (0x7c / sizeof(uint32_t))
+
+typedef struct NPCM7xxFIUState NPCM7xxFIUState;
+
+/**
+ * struct NPCM7xxFIUFlash - Per-chipselect flash controller state.
+ * @direct_access: Memory region for direct flash access.
+ * @fiu: Pointer to flash controller shared state.
+ */
+typedef struct NPCM7xxFIUFlash {
+MemoryRegion direct_access;
+NPCM7xxFIUState *fiu;
+} NPCM7xxFIUFlash;
+
+/**
+ * NPCM7xxFIUState - Device state for one Flash Interface Unit.
+ * @parent: System bus device.
+ * @mmio: Memory region for register access.
+ * @cs_count: Number of flash chips that may be connected to this module.
+ * @active_cs: Currently active chip select, or -1 if no chip is selected.
+ * @cs_lines: GPIO lines that may be wired to flash chips.
+ * @flash: Array of @cs_count per-flash-chip state objects.
+ * @spi: The SPI bus mastered by this controller.
+ * @regs: Register contents.
+ *
+ * Each FIU has a shared bank of registers, and controls up to four chip
+ * selects. Each chip select has a dedicated memory region which may be used to
+ * read and write the flash connected to that chip select as if it were memory.
+ */
+struct NPCM7xxFIUState {
+SysBusDevice parent;
+
+MemoryRegion mmio;
+
+int32_t cs_count;
+int32_t active_cs;
+qemu_irq *cs_lines;
+NPCM7xxFIUFlash *flash;
+
+SSIBus *spi;
+
+uint32_t regs[NPCM7XX_FIU_NR_REGS];
+};
+
+#define TYPE_NPCM7XX_FIU "npcm7xx-fiu"
+#define NPCM7XX_FIU(obj) OBJECT_CHECK(NPCM7xxFIUState, (obj), TYPE_NPCM7XX_FIU)
+
+#endif /* NPCM7XX_FIU_H */
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 6bb1693833..7884b2b03d 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -99,6 +99,39 @@ static const hwaddr npcm7xx_uart_addr[] = {
 0xf0004000,
 };
 
+/* Direct memory-mapped access to SPI0 CS0-1. */
+static const hwaddr npcm7xx_fiu0_flash_addr[] = {
+0x8000, /* CS0 */
+0x8800, /* CS1 */
+};
+
+/* Direct memory-mapped access to SPI3 CS0-3. */
+static const hwaddr npcm7xx_fiu3_flash_addr[] = {
+0xa000, /* CS0 */
+0xa800, /* CS1 */
+0xb000, /* CS2 */
+0xb800, /* CS3 */
+};
+
+static const struct {
+const char *name;
+hwaddr regs_addr;
+int cs_count;
+const hwaddr *flash_addr;
+} npcm7xx_fiu[] = {
+{
+.name = "fiu0",
+.regs_addr = 0xfb00,
+.cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
+.flash_addr 

[PATCH v8 01/14] hw/misc: Add NPCM7xx System Global Control Registers device model

2020-08-24 Thread Havard Skinnemoen via
Implement a device model for the System Global Control Registers in the
NPCM730 and NPCM750 BMC SoCs.

This is primarily used to enable SMP boot (the boot ROM spins reading
the SCRPAD register) and DDR memory initialization; other registers are
best effort for now.

The reset values of the MDLR and PWRON registers are determined by the
SoC variant (730 vs 750) and board straps respectively.

Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/misc/npcm7xx_gcr.h |  43 ++
 hw/misc/npcm7xx_gcr.c | 269 ++
 MAINTAINERS   |   8 +
 hw/arm/Kconfig|   3 +
 hw/misc/meson.build   |   3 +
 hw/misc/trace-events  |   4 +
 6 files changed, 330 insertions(+)
 create mode 100644 include/hw/misc/npcm7xx_gcr.h
 create mode 100644 hw/misc/npcm7xx_gcr.c

diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
new file mode 100644
index 00..13109d9d32
--- /dev/null
+++ b/include/hw/misc/npcm7xx_gcr.h
@@ -0,0 +1,43 @@
+/*
+ * Nuvoton NPCM7xx System Global Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM7XX_GCR_H
+#define NPCM7XX_GCR_H
+
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+
+/*
+ * Number of registers in our device state structure. Don't change this without
+ * incrementing the version_id in the vmstate.
+ */
+#define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t))
+
+typedef struct NPCM7xxGCRState {
+SysBusDevice parent;
+
+MemoryRegion iomem;
+
+uint32_t regs[NPCM7XX_GCR_NR_REGS];
+
+uint32_t reset_pwron;
+uint32_t reset_mdlr;
+uint32_t reset_intcr3;
+} NPCM7xxGCRState;
+
+#define TYPE_NPCM7XX_GCR "npcm7xx-gcr"
+#define NPCM7XX_GCR(obj) OBJECT_CHECK(NPCM7xxGCRState, (obj), TYPE_NPCM7XX_GCR)
+
+#endif /* NPCM7XX_GCR_H */
diff --git a/hw/misc/npcm7xx_gcr.c b/hw/misc/npcm7xx_gcr.c
new file mode 100644
index 00..745f690809
--- /dev/null
+++ b/hw/misc/npcm7xx_gcr.c
@@ -0,0 +1,269 @@
+/*
+ * Nuvoton NPCM7xx System Global Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/misc/npcm7xx_gcr.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+#define NPCM7XX_GCR_MIN_DRAM_SIZE   (128 * MiB)
+#define NPCM7XX_GCR_MAX_DRAM_SIZE   (2 * GiB)
+
+enum NPCM7xxGCRRegisters {
+NPCM7XX_GCR_PDID,
+NPCM7XX_GCR_PWRON,
+NPCM7XX_GCR_MFSEL1  = 0x0c / sizeof(uint32_t),
+NPCM7XX_GCR_MFSEL2,
+NPCM7XX_GCR_MISCPE,
+NPCM7XX_GCR_SPSWC   = 0x038 / sizeof(uint32_t),
+NPCM7XX_GCR_INTCR,
+NPCM7XX_GCR_INTSR,
+NPCM7XX_GCR_HIFCR   = 0x050 / sizeof(uint32_t),
+NPCM7XX_GCR_INTCR2  = 0x060 / sizeof(uint32_t),
+NPCM7XX_GCR_MFSEL3,
+NPCM7XX_GCR_SRCNT,
+NPCM7XX_GCR_RESSR,
+NPCM7XX_GCR_RLOCKR1,
+NPCM7XX_GCR_FLOCKR1,
+NPCM7XX_GCR_DSCNT,
+NPCM7XX_GCR_MDLR,
+NPCM7XX_GCR_SCRPAD3,
+NPCM7XX_GCR_SCRPAD2,
+NPCM7XX_GCR_DAVCLVLR= 0x098 / sizeof(uint32_t),
+NPCM7XX_GCR_INTCR3,
+NPCM7XX_GCR_VSINTR  = 0x0ac / sizeof(uint32_t),
+NPCM7XX_GCR_MFSEL4,
+NPCM7XX_GCR_CPBPNTR = 0x0c4 / sizeof(uint32_t),
+NPCM7XX_GCR_CPCTL   = 0x0d0 / sizeof(uint32_t),
+NPCM7XX_GCR_CP2BST,
+NPCM7XX_GCR_B2CPNT,
+NPCM7XX_GCR_CPPCTL,
+NPCM7XX_GCR_I2CSEGSEL,
+NPCM7XX_GCR_I2CSEGCTL,
+NPCM7XX_GCR_VSRCR,
+NPCM7XX_GCR_MLOCKR,
+NPCM7XX_GCR_SCRPAD  = 0x013c / sizeof(uint32_t),
+NPCM7XX_GCR_USB1PHYCTL,
+NPCM7XX_GCR_USB2PHYCTL,
+NPCM7XX_GCR_REGS_END,
+};
+
+static const uint32_t cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
+[NPCM7XX_GCR_PDID]  = 0x04a92750,   /* Poleg A1 */
+[NPCM7XX_GCR_MISCPE]= 

[PATCH v8 03/14] hw/timer: Add NPCM7xx Timer device model

2020-08-24 Thread Havard Skinnemoen via
The NPCM730 and NPCM750 SoCs have three timer modules each holding five
timers and some shared registers (e.g. interrupt status).

Each timer runs at 25 MHz divided by a prescaler, and counts down from a
configurable initial value to zero. When zero is reached, the interrupt
flag for the timer is set, and the timer is disabled (one-shot mode) or
reloaded from its initial value (periodic mode).

This implementation is sufficient to boot a Linux kernel configured for
NPCM750. Note that the kernel does not seem to actually turn on the
interrupts.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/timer/npcm7xx_timer.h |  78 +
 hw/timer/npcm7xx_timer.c | 509 +++
 hw/timer/meson.build |   1 +
 hw/timer/trace-events|   5 +
 4 files changed, 593 insertions(+)
 create mode 100644 include/hw/timer/npcm7xx_timer.h
 create mode 100644 hw/timer/npcm7xx_timer.c

diff --git a/include/hw/timer/npcm7xx_timer.h b/include/hw/timer/npcm7xx_timer.h
new file mode 100644
index 00..878a365a79
--- /dev/null
+++ b/include/hw/timer/npcm7xx_timer.h
@@ -0,0 +1,78 @@
+/*
+ * Nuvoton NPCM7xx Timer Controller
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM7XX_TIMER_H
+#define NPCM7XX_TIMER_H
+
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+
+/* Each Timer Module (TIM) instance holds five 25 MHz timers. */
+#define NPCM7XX_TIMERS_PER_CTRL (5)
+
+/*
+ * Number of registers in our device state structure. Don't change this without
+ * incrementing the version_id in the vmstate.
+ */
+#define NPCM7XX_TIMER_NR_REGS (0x54 / sizeof(uint32_t))
+
+typedef struct NPCM7xxTimerCtrlState NPCM7xxTimerCtrlState;
+
+/**
+ * struct NPCM7xxTimer - Individual timer state.
+ * @irq: GIC interrupt line to fire on expiration (if enabled).
+ * @qtimer: QEMU timer that notifies us on expiration.
+ * @expires_ns: Absolute virtual expiration time.
+ * @remaining_ns: Remaining time until expiration if timer is paused.
+ * @tcsr: The Timer Control and Status Register.
+ * @ticr: The Timer Initial Count Register.
+ */
+typedef struct NPCM7xxTimer {
+NPCM7xxTimerCtrlState *ctrl;
+
+qemu_irqirq;
+QEMUTimer   qtimer;
+int64_t expires_ns;
+int64_t remaining_ns;
+
+uint32_ttcsr;
+uint32_tticr;
+} NPCM7xxTimer;
+
+/**
+ * struct NPCM7xxTimerCtrlState - Timer Module device state.
+ * @parent: System bus device.
+ * @iomem: Memory region through which registers are accessed.
+ * @tisr: The Timer Interrupt Status Register.
+ * @wtcr: The Watchdog Timer Control Register.
+ * @timer: The five individual timers managed by this module.
+ */
+struct NPCM7xxTimerCtrlState {
+SysBusDevice parent;
+
+MemoryRegion iomem;
+
+uint32_ttisr;
+uint32_twtcr;
+
+NPCM7xxTimer timer[NPCM7XX_TIMERS_PER_CTRL];
+};
+
+#define TYPE_NPCM7XX_TIMER "npcm7xx-timer"
+#define NPCM7XX_TIMER(obj)  \
+OBJECT_CHECK(NPCM7xxTimerCtrlState, (obj), TYPE_NPCM7XX_TIMER)
+
+#endif /* NPCM7XX_TIMER_H */
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
new file mode 100644
index 00..ad5ebd9878
--- /dev/null
+++ b/hw/timer/npcm7xx_timer.c
@@ -0,0 +1,509 @@
+/*
+ * Nuvoton NPCM7xx Timer Controller
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/irq.h"
+#include "hw/misc/npcm7xx_clk.h"
+#include "hw/timer/npcm7xx_timer.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+/* 32-bit register indices. */
+enum NPCM7xxTimerRegisters {
+NPCM7XX_TIMER_TCSR0,
+NPCM7XX_TIMER_TCSR1,
+NPCM7XX_TIMER_TICR0,
+NPCM7XX_TIMER_TICR1,
+NPCM7XX_TIMER_TDR0,
+NPCM7XX_TIMER_TDR1,

[PATCH v8 00/14] Add Nuvoton NPCM730/NPCM750 SoCs and two BMC machines

2020-08-24 Thread Havard Skinnemoen via
I also pushed this and the previous patchsets to my qemu fork on github.
The branches are named npcm7xx-v[1-8].

  https://github.com/hskinnemoen/qemu

This patch series models enough of the Nuvoton NPCM730 and NPCM750 SoCs to boot
an OpenBMC image built for quanta-gsj. This includes device models for:

  - Global Configuration Registers
  - Clock Control
  - Timers
  - Fuses
  - Memory Controller
  - Flash Controller

These modules, along with the existing Cortex A9 CPU cores and built-in
peripherals, are integrated into a NPCM730 or NPCM750 SoC, which in turn form
the foundation for the quanta-gsj and npcm750-evb machines, respectively. The
two SoCs are very similar; the only difference is that NPCM730 is missing some
peripherals that NPCM750 has, and which are not considered essential for
datacenter use (e.g. graphics controllers). For more information, see

https://www.nuvoton.com/products/cloud-computing/ibmc/

Both quanta-gsj and npcm750-evb correspond to real boards supported by OpenBMC.
At the end of the series, qemu can boot an OpenBMC image built for one of these
boards with some minor modifications.

The patches in this series were developed by Google and reviewed by Nuvoton. We
will be maintaining the machine and peripheral support together.

The data sheet for these SoCs is not generally available. Please let me know if
more comments are needed to understand the device behavior.

Changes since v7:

  - Move register enums to .c files throughout, leaving a single
NPCM7XX_FOO_NR_REGS definition behind in the .h file. A QEMU_BUILD_BUG_ON
should alert anyone accidentally expanding the register enum that they need
to update the corresponding NR_REGS define, which in turn has a comment
reminding them to update the vmstate version_id as well.
  - Skip loading the bootrom if a kernel filename is provided by the user.
  - New patch adding a board setup stub to tweak clocks before booting directly
into the kernel.
  - Add stuff to meson files instead of Makefiles.
  - Try to disable the slowest drivers and services to speed up the flash boot
acceptance test a bit. This is somewhat based on the following
systemd-analyze blame report:
https://gist.github.com/hskinnemoen/475cb0676530cd2cebaa1754cf16ca97

Changes since v6:

  - Use size_to_str to report DRAM sizes in npcm7xx_gcr.
  - Simplify the interrupt logic in npcm7xx_timer.
  - Update global bios_name instead of temporary.
  - Add npcm7xx_bootrom to MAINTAINERS and pc-bios/README.
  - Use a predefined name for the gsj boot image in the acceptance test.

Changes since v5:

  - Boot ROM included, as a git submodule and a binary blob, and loaded by
default, so the -bios option is usually not necessary anymore.
  - Two acceptance tests added (openbmc image boot, and direct kernel boot).
  - npcm7xx_load_kernel() moved to SoC code.
  - NPCM7XX_TIMER_REF_HZ definition moved to CLK header.
  - Comments added clarifying available SPI flash chip selects.
  - Error handling adjustments:
  - Errors from CPU and GCR realization are propagated through the SoC
since they may be triggered by user-configurable parameters.
  - Machine init uses error_fatal instead of error_abort for SoC
realization flash init. This makes error messages more helpful.
  - Comments added to indicate whether peripherals may fail to realize.
  - Use ERRP_GUARD() instead of Error *err when possible.
  - Default CPU type is now set, and attempting to set it to anything else
will fail.
  - Format string fixes (use HWADDR_PRIx, etc.)
  - Simplified memory size encoding and error checking in npcm7xx_gcr.
  - Encapsulate non-obvious pointer subtraction into helper functions in the
FIU and TIMER modules.
  - Incorporate review feedback into the FIU module:
  - Add select/deselect trace events.
  - Use npcm7xx_fiu_{de,}select() consistently.
  - Use extract/deposit in more places for consistency.
  - Use -Wimplicit-fallthrough compatible fallthrough comments.
  - Use qdev_init_gpio_out_named instead of sysbus_init_irq for chip
selects.
  - Incorporate review feedback into the TIMER module:
  - Assert that we never pause a timer that has already expired, instead of
trying to handle it. This should be safe since QEMU_CLOCK_VIRTUAL is
stopped while this code is running.
  - Simplify the switch blocks in the read and write handlers.

I made a change to error out if a flash drive was not specified, but reverted
it because it caused make check to fail (qom-test). When specifying a NULL
block device, the m25p flash device initializes its in-memory storage with 0xff
and doesn't attempt to write anything back. This seems correct to me.

Changes since v4:

  - OTP cleanups suggested by Philippe Mathieu-Daudé.
  - Added fuse array definitions based on public Nuvoton bootblock code.
  - Moved class structure to .c file since it's only used internally.
  - Readability 

[PATCH] meson: Mingw64 gcc doesn't recognize system include_type for sdl2

2020-08-24 Thread luoyonggang
From: Yonggang Luo 

---
 meson.build | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/meson.build b/meson.build
index df5bf728b5..a3585881e1 100644
--- a/meson.build
+++ b/meson.build
@@ -224,8 +224,7 @@ if 'CONFIG_BRLAPI' in config_host
   brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
 endif
 
-sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static,
- include_type: 'system')
+sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
 sdl_image = not_found
 if sdl.found()
   # work around 2.0.8 bug
-- 
2.27.0.windows.1




Re: [PATCH v6 4/8] ppc/e500: Use start-powered-off CPUState property

2020-08-24 Thread Thiago Jung Bauermann


Philippe Mathieu-Daudé  writes:

> On 8/22/20 10:59 AM, Cédric Le Goater wrote:
>> Hello,
>> 
>> On 8/19/20 6:43 PM, Thiago Jung Bauermann wrote:
>>> Instead of setting CPUState::halted to 1 in ppce500_cpu_reset_sec(), use
>>> the start-powered-off property which makes cpu_common_reset() initialize it
>>> to 1 in common code.
>>>
>>> Also change creation of CPU object from cpu_create() to object_new() and
>>> qdev_realize_and_unref() because cpu_create() realizes the CPU and it's not
>>> possible to set a property after the object is realized.
>>>
>>> Reviewed-by: Philippe Mathieu-Daudé 
>>> Signed-off-by: Thiago Jung Bauermann 
>> 
>> 
>> This is breaking make check : 
>> 
>> tests/qtest/libqtest.c:175: kill_qemu() detected QEMU death from signal 
>> 11 (Segmentation fault) (core dumped)
>> ERROR boot-serial-test - too few tests run (expected 7, got 0)
>> make: *** 
>> [/home/legoater/work/qemu/qemu-powernv-5.2.git/tests/Makefile.include:650: 
>> check-qtest-ppc64] Error 1
>> make: *** Waiting for unfinished jobs
>> 
>> 
>> gdb --args build/ppc64-softmmu/qemu-system-ppc64  -display none   -M 
>> ppce500
>> ...
>> Thread 1 "qemu-system-ppc" received signal SIGSEGV, Segmentation fault.
>> 0x5596ebf2 in ppce500_init (machine=0x567aa6e0)
>> at /home/legoater/work/qemu/qemu-powernv-5.2.git/hw/ppc/e500.c:880
>> 880  irqs[i].irq[OPENPIC_OUTPUT_INT] = 
>> input[PPCE500_INPUT_INT];
>>  
>> 
>> AFAIUI, 'input is not initialized since the CPU is not yet realized.
>
> Thiago, see ad938fc1d53 ("hw/arm/palm.c: Encapsulate misc GPIO handling
> in a device") and eventually f8a865d36dc ("hw/arm/allwinner-a10:
> Simplify by passing IRQs with qdev_pass_gpios") to get an idea how you
> can fix that.

Thanks for the references, those are very useful.

-- 
Thiago Jung Bauermann
IBM Linux Technology Center



Re: [PATCH v6 4/8] ppc/e500: Use start-powered-off CPUState property

2020-08-24 Thread Thiago Jung Bauermann


David Gibson  writes:

> On Sat, Aug 22, 2020 at 10:59:56AM +0200, Cédric Le Goater wrote:
>> Hello,
>> 
>> On 8/19/20 6:43 PM, Thiago Jung Bauermann wrote:
>> > Instead of setting CPUState::halted to 1 in ppce500_cpu_reset_sec(), use
>> > the start-powered-off property which makes cpu_common_reset() initialize it
>> > to 1 in common code.
>> > 
>> > Also change creation of CPU object from cpu_create() to object_new() and
>> > qdev_realize_and_unref() because cpu_create() realizes the CPU and it's not
>> > possible to set a property after the object is realized.
>> > 
>> > Reviewed-by: Philippe Mathieu-Daudé 
>> > Signed-off-by: Thiago Jung Bauermann 
>> 
>> 
>> This is breaking make check : 
>> 
>> tests/qtest/libqtest.c:175: kill_qemu() detected QEMU death from signal 
>> 11 (Segmentation fault) (core dumped)
>> ERROR boot-serial-test - too few tests run (expected 7, got 0)
>> make: *** 
>> [/home/legoater/work/qemu/qemu-powernv-5.2.git/tests/Makefile.include:650: 
>> check-qtest-ppc64] Error 1
>> make: *** Waiting for unfinished jobs
>> 
>> 
>> gdb --args build/ppc64-softmmu/qemu-system-ppc64  -display none   -M 
>> ppce500
>> ...
>> Thread 1 "qemu-system-ppc" received signal SIGSEGV, Segmentation fault.
>> 0x5596ebf2 in ppce500_init (machine=0x567aa6e0)
>> at /home/legoater/work/qemu/qemu-powernv-5.2.git/hw/ppc/e500.c:880
>> 880  irqs[i].irq[OPENPIC_OUTPUT_INT] = 
>> input[PPCE500_INPUT_INT];
>>  
>> 
>> AFAIUI, 'input is not initialized since the CPU is not yet
>> realized.
>
> Sigh.  For future reference, Thiago, running an all-targets make check
> is pretty much a minimum bar to test before posting.

Sorry for the breakage. I'm working on it.

-- 
Thiago Jung Bauermann
IBM Linux Technology Center



[PATCH 2/2] fixes relpath may fail on win32.

2020-08-24 Thread luoyonggang
From: Yonggang Luo 

---
 scripts/mtest2make.py | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py
index bdb257bbd9..d7a51bf97e 100644
--- a/scripts/mtest2make.py
+++ b/scripts/mtest2make.py
@@ -53,9 +53,16 @@ i = 0
 for test in json.load(sys.stdin):
 env = ' '.join(('%s=%s' % (shlex.quote(k), shlex.quote(v))
 for k, v in test['env'].items()))
-executable = os.path.relpath(test['cmd'][0])
+executable = test['cmd'][0]
+try:
+executable = os.path.relpath(executable)
+except:
+pass
 if test['workdir'] is not None:
-test['cmd'][0] = os.path.relpath(test['cmd'][0], test['workdir'])
+try:
+test['cmd'][0] = os.path.relpath(executable, test['workdir'])
+except:
+test['cmd'][0] = executable
 else:
 test['cmd'][0] = executable
 cmd = '$(.test.env) %s %s' % (env, ' '.join((shlex.quote(x) for x in 
test['cmd'])))
-- 
2.27.0.windows.1




[PATCH 1/2] SIMPLE_PATH_RE should match the full path token. Maybe also apply to others such as STRING_RE and TOPLEVEL_RE, not for sure

2020-08-24 Thread luoyonggang
From: Yonggang Luo 

---
 scripts/ninjatool.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/ninjatool.py b/scripts/ninjatool.py
index cc77d51aa8..6ca8be6f10 100755
--- a/scripts/ninjatool.py
+++ b/scripts/ninjatool.py
@@ -55,7 +55,7 @@ else:
 
 PATH_RE = r"[^$\s:|]+|\$[$ :]|\$[a-zA-Z0-9_-]+|\$\{[a-zA-Z0-9_.-]+\}"
 
-SIMPLE_PATH_RE = re.compile(r"[^$\s:|]+")
+SIMPLE_PATH_RE = re.compile(r"^[^$\s:|]+$")
 IDENT_RE = re.compile(r"[a-zA-Z0-9_.-]+$")
 STRING_RE = re.compile(r"(" + PATH_RE + r"|[\s:|])(?:\r?\n)?|.")
 TOPLEVEL_RE = re.compile(r"([=:#]|\|\|?|^ +|(?:" + PATH_RE + r")+)\s*|.")
-- 
2.27.0.windows.1




[PATCH v2 1/2] linux-user: Add support for ppoll_time64() and pselect6_time64()

2020-08-24 Thread Filip Bozuta
This patch introduces functionality for following time64 syscalls:

*ppoll_time64

This is a year 2038 safe variant of:

int poll(struct pollfd *fds, nfds_t nfds, int timeout)
-- wait for some event on a file descriptor --
man page: https://man7.org/linux/man-pages/man2/ppoll.2.html

*pselect6_time64

This is a year 2038 safe variant of:

int pselect6(int nfds, fd_set *readfds, fd_set *writefds,
 fd_set *exceptfds, const struct timespec *timeout,
 const sigset_t *sigmask);
-- synchronous I/O multiplexing --
man page: https://man7.org/linux/man-pages/man2/pselect6.2.html

Implementation notes:

Year 2038 safe syscalls in this patch were implemented
with the same code as their regular variants (ppoll() and pselect()).
This code was moved to new functions ('do_ppoll()' and 'do_pselect6()')
that take a 'bool time64' from which a right 'struct timespec' converting
function is called.
(target_to_host/host_to_target_timespec() for regular and
 target_to_host/host_to_target_timespec64() for time64 variants)

Signed-off-by: Filip Bozuta 
---
 linux-user/syscall.c | 462 +++
 1 file changed, 251 insertions(+), 211 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1211e759c2..fc6a6e32e4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -397,7 +397,7 @@ static int sys_getcwd1(char *buf, size_t size)
   return strlen(buf)+1;
 }
 
-#ifdef TARGET_NR_utimensat
+#if defined(TARGET_NR_utimensat)
 #if defined(__NR_utimensat)
 #define __NR_sys_utimensat __NR_utimensat
 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
@@ -763,11 +763,11 @@ safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, 
siginfo_t *, infop, \
   int, options, struct rusage *, rusage)
 safe_syscall3(int, execve, const char *, filename, char **, argv, char **, 
envp)
 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
-defined(TARGET_NR_pselect6)
+defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
 safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, 
\
   fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
 #endif
-#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_poll)
+#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_ppoll_time64)
 safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
   struct timespec *, tsp, const sigset_t *, sigmask,
   size_t, sigsetsize)
@@ -984,7 +984,7 @@ abi_long do_brk(abi_ulong new_brk)
 }
 
 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
-defined(TARGET_NR_pselect6)
+defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
 static inline abi_long copy_from_user_fdset(fd_set *fds,
 abi_ulong target_fds_addr,
 int n)
@@ -1252,7 +1252,8 @@ static inline abi_long target_to_host_timespec(struct 
timespec *host_ts,
 }
 #endif
 
-#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64)
+#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64) || \
+defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64)
 static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
  abi_ulong target_addr)
 {
@@ -1458,6 +1459,237 @@ static abi_long do_old_select(abi_ulong arg1)
 #endif
 #endif
 
+#if defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
+static abi_long do_pselect6(abi_long arg1, abi_long arg2, abi_long arg3,
+abi_long arg4, abi_long arg5, abi_long arg6,
+bool time64)
+{
+abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
+fd_set rfds, wfds, efds;
+fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+struct timespec ts, *ts_ptr;
+abi_long ret;
+
+/*
+ * The 6th arg is actually two args smashed together,
+ * so we cannot use the C library.
+ */
+sigset_t set;
+struct {
+sigset_t *set;
+size_t size;
+} sig, *sig_ptr;
+
+abi_ulong arg_sigset, arg_sigsize, *arg7;
+target_sigset_t *target_sigset;
+
+n = arg1;
+rfd_addr = arg2;
+wfd_addr = arg3;
+efd_addr = arg4;
+ts_addr = arg5;
+
+ret = copy_from_user_fdset_ptr(, _ptr, rfd_addr, n);
+if (ret) {
+return ret;
+}
+ret = copy_from_user_fdset_ptr(, _ptr, wfd_addr, n);
+if (ret) {
+return ret;
+}
+ret = copy_from_user_fdset_ptr(, _ptr, efd_addr, n);
+if (ret) {
+return ret;
+}
+
+/*
+ * This takes a timespec, and not a timeval, so we cannot
+ * use the do_select() helper ...
+ */
+if (ts_addr) {
+if (time64) {
+if (target_to_host_timespec64(, ts_addr)) {
+return -TARGET_EFAULT;

Re: [PATCH] meson: drop keymaps symlink

2020-08-24 Thread Alistair Francis
On Mon, Aug 24, 2020 at 12:42 AM Gerd Hoffmann  wrote:
>
> We are building the keymaps by default now.  Drop the keymaps symlink
> so the generated files are actually written to the build tree not the
> source tree.
>
> Signed-off-by: Gerd Hoffmann 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  configure | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/configure b/configure
> index 67832e3bab76..428fa33be140 100755
> --- a/configure
> +++ b/configure
> @@ -8119,7 +8119,7 @@ DIRS="$DIRS roms/seabios"
>  LINKS="Makefile"
>  LINKS="$LINKS tests/tcg/lm32/Makefile"
>  LINKS="$LINKS tests/tcg/Makefile.target"
> -LINKS="$LINKS pc-bios/optionrom/Makefile pc-bios/keymaps"
> +LINKS="$LINKS pc-bios/optionrom/Makefile"
>  LINKS="$LINKS pc-bios/s390-ccw/Makefile"
>  LINKS="$LINKS roms/seabios/Makefile"
>  LINKS="$LINKS pc-bios/qemu-icon.bmp"
> --
> 2.27.0
>
>



[PATCH v2 0/2] linux-user: Adding support for a group of 4 time64 syscalls

2020-08-24 Thread Filip Bozuta
This two patch series introduces functionality for following
Year 2038 safe syscalls:

--Introduced in first patch--
*ppoll_time64()
*pselect6_time64()

--Introduced in second patch--
*utimensat_time64()
*semtimedop_time64()

Testing notes:

   The implementations of these time64 syscalls was tested
   using tests from the LTP test suite which was built inside
   a chroot.

v2:

   -Moved code of 'ppoll()' and 'pselect6()' to a separate
function
   -Changed 'time64' from 'int' to 'bool'

Filip Bozuta (2):
  linux-user: Add support for ppoll_time64() and pselect6_time64()
  linux-user: Add support for utimensat_time64() and semtimedop_time64()

 linux-user/syscall.c | 520 +--
 1 file changed, 300 insertions(+), 220 deletions(-)

-- 
2.25.1




Re: [PATCH 4/6] xilinx_axienet: Use typedef name for instance_size

2020-08-24 Thread Alistair Francis
On Mon, Aug 24, 2020 at 3:02 PM Eduardo Habkost  wrote:
>
> This makes the code consistent with the rest of QOM code in QEMU,
> and will make automated conversion to type declaration macros
> simpler.
>
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Cc: "Edgar E. Iglesias" 
> Cc: Alistair Francis 
> Cc: Peter Maydell 
> Cc: Jason Wang 
> Cc: qemu-...@nongnu.org
> Cc: qemu-devel@nongnu.org
> ---
>  hw/net/xilinx_axienet.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
> index 1e48eb70c9..ceb4652938 100644
> --- a/hw/net/xilinx_axienet.c
> +++ b/hw/net/xilinx_axienet.c
> @@ -1069,7 +1069,7 @@ static const TypeInfo xilinx_enet_info = {
>  static const TypeInfo xilinx_enet_data_stream_info = {
>  .name  = TYPE_XILINX_AXI_ENET_DATA_STREAM,
>  .parent= TYPE_OBJECT,
> -.instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
> +.instance_size = sizeof(XilinxAXIEnetStreamSlave),
>  .class_init= xilinx_enet_data_stream_class_init,
>  .interfaces = (InterfaceInfo[]) {
>  { TYPE_STREAM_SLAVE },
> @@ -1080,7 +1080,7 @@ static const TypeInfo xilinx_enet_data_stream_info = {
>  static const TypeInfo xilinx_enet_control_stream_info = {
>  .name  = TYPE_XILINX_AXI_ENET_CONTROL_STREAM,
>  .parent= TYPE_OBJECT,
> -.instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
> +.instance_size = sizeof(XilinxAXIEnetStreamSlave),
>  .class_init= xilinx_enet_control_stream_class_init,
>  .interfaces = (InterfaceInfo[]) {
>  { TYPE_STREAM_SLAVE },
> --
> 2.26.2
>
>



[PATCH v2 2/2] linux-user: Add support for utimensat_time64() and semtimedop_time64()

2020-08-24 Thread Filip Bozuta
This patch introduces functionality for following time64 syscalls:

*utimensat_time64()

int utimensat(int dirfd, const char *pathname,
  const struct timespec times[2], int flags);
-- change file timestamps with nanosecond precision --
man page: https://man7.org/linux/man-pages/man2/utimensat.2.html

*semtimedop_time64()

int semtimedop(int semid, struct sembuf *sops, size_t nsops,
   const struct timespec *timeout);
-- System V semaphore operations --
man page: https://www.man7.org/linux/man-pages/man2/semtimedop.2.html

Implementation notes:

   Syscall 'utimensat_time64()' is implemented in similar way as its
   regular variants only difference being that time64 converting function
   is used to convert values of 'struct timespec' between host and target
   ('target_to_host_timespec64()').

   For syscall 'semtimedop_time64()' and additional argument is added
   in function 'do_semtimedop()' through which the aproppriate 'struct timespec'
   converting function is called (false for regular target_to_host_timespec()
   and true for target_to_host_timespec64()). For 'do_ipc()' a
   check was added as that additional argument: 'TARGET_ABI_BITS == 64'.

Signed-off-by: Filip Bozuta 
Reviewed-by: Laurent Vivier 
---
 linux-user/syscall.c | 60 
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fc6a6e32e4..4d460af744 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1253,7 +1253,8 @@ static inline abi_long target_to_host_timespec(struct 
timespec *host_ts,
 #endif
 
 #if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64) || \
-defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64)
+defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64) || \
+defined(TARGET_NR_utimensat_time64) || defined(TARGET_NR_semtimedop_time64)
 static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
  abi_ulong target_addr)
 {
@@ -4117,7 +4118,7 @@ static inline abi_long target_to_host_sembuf(struct 
sembuf *host_sembuf,
 }
 
 #if defined(TARGET_NR_ipc) || defined(TARGET_NR_semop) || \
-defined(TARGET_NR_semtimedop)
+defined(TARGET_NR_semtimedop) || defined(TARGET_NR_semtimedop_time64)
 
 /*
  * This macro is required to handle the s390 variants, which passes the
@@ -4134,7 +4135,7 @@ static inline abi_long target_to_host_sembuf(struct 
sembuf *host_sembuf,
 static inline abi_long do_semtimedop(int semid,
  abi_long ptr,
  unsigned nsops,
- abi_long timeout)
+ abi_long timeout, bool time64)
 {
 struct sembuf sops[nsops];
 struct timespec ts, *pts = NULL;
@@ -4142,8 +4143,14 @@ static inline abi_long do_semtimedop(int semid,
 
 if (timeout) {
 pts = 
-if (target_to_host_timespec(pts, timeout)) {
-return -TARGET_EFAULT;
+if (time64) {
+if (target_to_host_timespec64(pts, timeout)) {
+return -TARGET_EFAULT;
+}
+} else {
+if (target_to_host_timespec(pts, timeout)) {
+return -TARGET_EFAULT;
+}
 }
 }
 
@@ -4657,7 +4664,7 @@ static abi_long do_ipc(CPUArchState *cpu_env,
 
 switch (call) {
 case IPCOP_semop:
-ret = do_semtimedop(first, ptr, second, 0);
+ret = do_semtimedop(first, ptr, second, 0, false);
 break;
 case IPCOP_semtimedop:
 /*
@@ -4667,9 +4674,9 @@ static abi_long do_ipc(CPUArchState *cpu_env,
  * to a struct timespec where the generic variant uses fifth parameter.
  */
 #if defined(TARGET_S390X)
-ret = do_semtimedop(first, ptr, second, third);
+ret = do_semtimedop(first, ptr, second, third, TARGET_ABI_BITS == 64);
 #else
-ret = do_semtimedop(first, ptr, second, fifth);
+ret = do_semtimedop(first, ptr, second, fifth, TARGET_ABI_BITS == 64);
 #endif
 break;
 
@@ -9887,11 +9894,15 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 #endif
 #ifdef TARGET_NR_semop
 case TARGET_NR_semop:
-return do_semtimedop(arg1, arg2, arg3, 0);
+return do_semtimedop(arg1, arg2, arg3, 0, false);
 #endif
 #ifdef TARGET_NR_semtimedop
 case TARGET_NR_semtimedop:
-return do_semtimedop(arg1, arg2, arg3, arg4);
+return do_semtimedop(arg1, arg2, arg3, arg4, false);
+#endif
+#ifdef TARGET_NR_semtimedop_time64
+case TARGET_NR_semtimedop_time64:
+return do_semtimedop(arg1, arg2, arg3, arg4, true);
 #endif
 #ifdef TARGET_NR_semctl
 case TARGET_NR_semctl:
@@ -11938,6 +11949,35 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 return ret;
 #endif
+#ifdef 

Re: [PATCH V1 18/32] osdep: import MADV_DOEXEC

2020-08-24 Thread Alex Williamson
On Wed, 19 Aug 2020 17:52:26 -0400
Steven Sistare  wrote:

> On 8/17/2020 10:42 PM, Alex Williamson wrote:
> > On Mon, 17 Aug 2020 15:44:03 -0600
> > Alex Williamson  wrote:
> >   
> >> On Mon, 17 Aug 2020 17:20:57 -0400
> >> Steven Sistare  wrote:
> >>  
> >>> On 8/17/2020 4:48 PM, Alex Williamson wrote:
>  On Mon, 17 Aug 2020 14:30:51 -0400
>  Steven Sistare  wrote:
>    
> > On 7/30/2020 11:14 AM, Steve Sistare wrote:  
> >> Anonymous memory segments used by the guest are preserved across a 
> >> re-exec
> >> of qemu, mapped at the same VA, via a proposed madvise(MADV_DOEXEC) 
> >> option
> >> in the Linux kernel. For the madvise patches, see:
> >>
> >> https://lore.kernel.org/lkml/1595869887-23307-1-git-send-email-anthony.yzn...@oracle.com/
> >>
> >> Signed-off-by: Steve Sistare 
> >> ---
> >>  include/qemu/osdep.h | 7 +++
> >>  1 file changed, 7 insertions(+)
> >
> > Hi Alex,
> >   The MADV_DOEXEC functionality, which is a pre-requisite for the 
> > entire qemu 
> > live update series, is getting a chilly reception on lkml.  We could 
> > instead 
> > create guest memory using memfd_create and preserve the fd across exec. 
> >  However, 
> > the subsequent mmap(fd) will return a different VA than was used 
> > previously, 
> > which  is a problem for memory that was registered with vfio, as the 
> > original VA 
> > is remembered in the kernel struct vfio_dma and used in various kernel 
> > functions, 
> > such as vfio_iommu_replay.
> >
> > To fix, we could provide a VFIO_IOMMU_REMAP_DMA ioctl taking iova, 
> > size, and
> > new_vaddr.  The implementation finds an exact match for (iova, size) 
> > and replaces 
> > vaddr with new_vaddr.  Flags cannot be changed.
> >
> > memfd_create plus VFIO_IOMMU_REMAP_DMA would replace MADV_DOEXEC.
> > vfio on any form of shared memory (shm, dax, etc) could also be 
> > preserved across
> > exec with shmat/mmap plus VFIO_IOMMU_REMAP_DMA.
> >
> > What do you think  
> 
>  Your new REMAP ioctl would have parameters identical to the MAP_DMA
>  ioctl, so I think we should just use one of the flag bits on the
>  existing MAP_DMA ioctl for this variant.  
> >>>
> >>> Sounds good.
> >>> 
>  Reading through the discussion on the kernel side there seems to be
>  some confusion around why vfio needs the vaddr beyond the user call to
>  MAP_DMA though.  Originally this was used to test for virtually
>  contiguous mappings for merging and splitting purposes.  This is
>  defunct in the v2 interface, however the vaddr is now used largely for
>  mdev devices.  If an mdev device is not backed by an IOMMU device and
>  does not share a container with an IOMMU device, then a user MAP_DMA
>  ioctl essentially just registers the translation within the vfio
>  container.  The mdev vendor driver can then later either request pages
>  to be pinned for device DMA or can perform copy_to/from_user() to
>  simulate DMA via the CPU.
> 
>  Therefore I don't see that there's a simple re-architecture of the vfio
>  IOMMU backend that could drop vaddr use.
> >>>
> >>> Yes.  I did not explain on lkml as you do here (thanks), but I reached 
> >>> the 
> >>> same conclusion.
> >>> 
>  I'm a bit concerned this new
>  remap proposal also raises the question of how do we prevent userspace
>  remapping vaddrs racing with asynchronous kernel use of the previous
>  vaddrs.
> >>>
> >>> Agreed.  After a quick glance at the code, holding iommu->lock during 
> >>> remap might be sufficient, but it needs more study.
> >>
> >> Unless you're suggesting an extended hold of the lock across the entire
> >> re-exec of QEMU, that's only going to prevent a race between a remap
> >> and a vendor driver pin or access, the time between the previous vaddr
> >> becoming invalid and the remap is unprotected.  
> 
> OK.  What if we exclude mediated devices?  Its appears they are the only
> ones where the kernel may async'ly use the vaddr, via call chains ending in 
> vfio_iommu_type1_pin_pages or vfio_iommu_type1_dma_rw_chunk.
> 
> The other functions that use dma->vaddr are
> vfio_dma_do_map 
> vfio_pin_map_dma 
> vfio_iommu_replay 
> vfio_pin_pages_remote
> and they are all initiated via userland ioctl (if I have traced all the code 
> paths correctly).  Thus iommu->lock would protect them.
> 
> We would block live update in qemu if the config includes a mediated device.
> 
> VFIO_IOMMU_REMAP_DMA would return EINVAL if the container has a mediated 
> device.

That's not a solution I'd really be in favor of.  We're eliminating an
entire class of devices because they _might_ make use of these
interfaces, but anyone can add a vfio bus driver, even exposing the
same device API, and maybe make 

Re: [PATCH 1/6] xilinx_axidma: Use typedef name for instance_size

2020-08-24 Thread Alistair Francis
On Mon, Aug 24, 2020 at 2:58 PM Eduardo Habkost  wrote:
>
> This makes the code consistent with the rest of QOM code in QEMU,
> and will make automated conversion to type declaration macros
> simpler.
>
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Cc: "Edgar E. Iglesias" 
> Cc: Alistair Francis 
> Cc: Peter Maydell 
> Cc: qemu-...@nongnu.org
> Cc: qemu-devel@nongnu.org
> ---
>  hw/dma/xilinx_axidma.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
> index a4812e480a..5ad8bd3d2e 100644
> --- a/hw/dma/xilinx_axidma.c
> +++ b/hw/dma/xilinx_axidma.c
> @@ -634,7 +634,7 @@ static const TypeInfo axidma_info = {
>  static const TypeInfo xilinx_axidma_data_stream_info = {
>  .name  = TYPE_XILINX_AXI_DMA_DATA_STREAM,
>  .parent= TYPE_OBJECT,
> -.instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
> +.instance_size = sizeof(XilinxAXIDMAStreamSlave),
>  .class_init= xilinx_axidma_stream_class_init,
>  .class_data= _axidma_data_stream_class,
>  .interfaces = (InterfaceInfo[]) {
> @@ -646,7 +646,7 @@ static const TypeInfo xilinx_axidma_data_stream_info = {
>  static const TypeInfo xilinx_axidma_control_stream_info = {
>  .name  = TYPE_XILINX_AXI_DMA_CONTROL_STREAM,
>  .parent= TYPE_OBJECT,
> -.instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
> +.instance_size = sizeof(XilinxAXIDMAStreamSlave),
>  .class_init= xilinx_axidma_stream_class_init,
>  .class_data= _axidma_control_stream_class,
>  .interfaces = (InterfaceInfo[]) {
> --
> 2.26.2
>
>



[PATCH 5/6] vhost-user-vga: Use typedef name for instance_size

2020-08-24 Thread Eduardo Habkost
This makes the code consistent with the rest of QOM code in QEMU,
and will make automated conversion to type declaration macros
simpler.

Signed-off-by: Eduardo Habkost 
---
Cc: "Michael S. Tsirkin" 
Cc: "Marc-André Lureau" 
Cc: Gerd Hoffmann 
Cc: qemu-devel@nongnu.org
---
 hw/display/vhost-user-vga.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/vhost-user-vga.c b/hw/display/vhost-user-vga.c
index 1690f6b610..78f58bd340 100644
--- a/hw/display/vhost-user-vga.c
+++ b/hw/display/vhost-user-vga.c
@@ -39,7 +39,7 @@ static void vhost_user_vga_inst_initfn(Object *obj)
 static const VirtioPCIDeviceTypeInfo vhost_user_vga_info = {
 .generic_name  = TYPE_VHOST_USER_VGA,
 .parent= TYPE_VIRTIO_VGA_BASE,
-.instance_size = sizeof(struct VhostUserVGA),
+.instance_size = sizeof(VhostUserVGA),
 .instance_init = vhost_user_vga_inst_initfn,
 };
 
-- 
2.26.2




Re: [PATCH 2/2] target/i386: Add missed features to Cooperlake CPU model

2020-08-24 Thread Eduardo Habkost
On Wed, Dec 25, 2019 at 02:30:18PM +0800, Xiaoyao Li wrote:
> It lacks VMX features and two security feature bits (disclosed recently) in
> MSR_IA32_ARCH_CAPABILITIES in current Cooperlake CPU model, so add them.
> 
> Fixes: 22a866b6166d ("i386: Add new CPU model Cooperlake")
> Signed-off-by: Xiaoyao Li 
> ---
>  target/i386/cpu.c | 51 ++-
>  1 file changed, 50 insertions(+), 1 deletion(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index e1eb9f473989..c9798ac8652b 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -3198,7 +3198,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>  CPUID_7_0_EDX_SPEC_CTRL_SSBD | CPUID_7_0_EDX_ARCH_CAPABILITIES,
>  .features[FEAT_ARCH_CAPABILITIES] =
>  MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL |
> -MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO,
> +MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO |
> +MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO,

This seems to break on some Cooperlake hosts, see:

https://bugzilla.redhat.com/show_bug.cgi?id=1860743

Are all Cooperlake hosts supposed to have TAA_NO set?  Are there
hosts where this requires a microcode update to be installed?

-- 
Eduardo




[PATCH 3/6] lpc_ich9: Use typedef name for instance_size

2020-08-24 Thread Eduardo Habkost
This makes the code consistent with the rest of QOM code in QEMU,
and will make automated conversion to type declaration macros
simpler.

Signed-off-by: Eduardo Habkost 
---
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: qemu-devel@nongnu.org
---
 hw/isa/lpc_ich9.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index cd6e169d47..3303d2eab6 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -792,7 +792,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void 
*data)
 static const TypeInfo ich9_lpc_info = {
 .name   = TYPE_ICH9_LPC_DEVICE,
 .parent = TYPE_PCI_DEVICE,
-.instance_size = sizeof(struct ICH9LPCState),
+.instance_size = sizeof(ICH9LPCState),
 .instance_init = ich9_lpc_initfn,
 .class_init  = ich9_lpc_class_init,
 .interfaces = (InterfaceInfo[]) {
-- 
2.26.2




Re: [PATCH 1/4] configure: Use discovered make for in-source build

2020-08-24 Thread Roman Bolshakov
On Mon, Aug 24, 2020 at 09:37:07AM -0500, Eric Blake wrote:
> On 8/22/20 4:21 PM, Roman Bolshakov wrote:
> > @@ -38,6 +38,8 @@ then
> >   # This file is auto-generated by configure to support in-source tree
> >   # 'make' command invocation
> > +include build/config-host.mak
> 
> Should this use '-include' (also spelled 'sinclude'), to avoid halting the
> build if build/config-host.mak doesn't exist for whatever reason?
> 

Sure I can do (and thanks for the noticed typos) but I tested that if
the build is interrupted too early (before Makefile is symlinked to
build directory but after GNUmakefile is created) it would fail even if
-include is used:

$ make
changing dir to build for /Library/Developer/CommandLineTools/usr/bin/make ""...
make[1]: Makefile: No such file or directory
make[1]: *** No rule to make target `Makefile'.  Stop.
changing dir to build for /Library/Developer/CommandLineTools/usr/bin/make ""...
make[1]: Makefile: No such file or directory
make[1]: *** No rule to make target `Makefile'.  Stop.
make: *** [all] Error 2

I'm also curious why the switch happens twice... According to the debug
trace, it tries to remake build/config-host.mak using the implicit force
rule:

GNUmakefile:12: update target 'build/config-host.mak' due to: force

Then there should be an explicit empty rule for build/config-host.mak. I
will send a fix for that in v2. Then it would fail like this:

$ make
changing dir to build for /Library/Developer/CommandLineTools/usr/bin/make ""...
make[1]: Makefile: No such file or directory
make[1]: *** No rule to make target `Makefile'.  Stop.
make: *** [all] Error 2

Regards,
Roman

> > +
> >   ifeq ($(MAKECMDGOALS),)
> >   recurse: all
> >   endif
> > 
> 



[PATCH 2/6] omap_intc: Use typedef name for instance_size

2020-08-24 Thread Eduardo Habkost
This makes the code consistent with the rest of QOM code in QEMU,
and will make automated conversion to type declaration macros
simpler.

Signed-off-by: Eduardo Habkost 
---
Cc: Peter Maydell 
Cc: qemu-...@nongnu.org
Cc: qemu-devel@nongnu.org
---
 hw/intc/omap_intc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
index b8a1d1fd7d..d7183d035e 100644
--- a/hw/intc/omap_intc.c
+++ b/hw/intc/omap_intc.c
@@ -676,7 +676,7 @@ static const TypeInfo omap2_intc_info = {
 static const TypeInfo omap_intc_type_info = {
 .name  = TYPE_OMAP_INTC,
 .parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(struct omap_intr_handler_s),
+.instance_size = sizeof(omap_intr_handler),
 .abstract  = true,
 };
 
-- 
2.26.2




[REPORT] Nightly Performance Tests - Monday, August 24, 2020

2020-08-24 Thread Ahmed Karaman

Host CPU : Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Host Memory  : 15.49 GB

Start Time (UTC) : 2020-08-24 21:30:01
End Time (UTC)   : 2020-08-24 22:02:34
Execution Time   : 0:32:33.288312

Status   : SUCCESS

Note:
Changes denoted by '-' are less than 0.01%.


SUMMARY REPORT - COMMIT 30aa1944

AVERAGE RESULTS

Target  Instructions  Latest  v5.1.0
--    --  --
aarch642 158 336 369   - +1.692%
alpha  1 914 963 828   - +3.524%
arm8 076 406 621   - +2.304%
hppa   4 268 707 368   - +3.355%
m68k   2 690 268 056   - +7.131%
mips   1 862 013 209   - +2.492%
mipsel 2 008 201 160   - +2.673%
mips64 1 918 633 309   - +2.818%
mips64el   2 051 562 603   - +3.026%
ppc2 480 494 245   - +3.116%
ppc64  2 576 749 439   - +3.143%
ppc64le2 558 895 447   - +3.174%
riscv641 406 714 486   - +2.651%
s390x  3 158 130 515   - +3.118%
sh42 364 446 984   -  +3.33%
sparc643 318 536 224   -  +3.85%
x86_64 1 775 853 879   - +2.157%


   DETAILED RESULTS

Test Program: dijkstra_double

Target  Instructions  Latest  v5.1.0
--    --  --
aarch643 062 565 290   - +1.423%
alpha  3 191 861 945   - +3.696%
arm   16 357 168 614   - +2.347%
hppa   7 238 406 927   - +3.229%
m68k   4 294 010 671   - +9.692%
mips   3 051 404 978   - +2.426%
mipsel 3 231 499 722   - +2.869%
mips64 3 245 835 252   - +2.596%
mips64el   3 414 195 149   - +3.021%
ppc4 916 527 458   - +4.782%
ppc64  5 098 142 111   - +4.565%
ppc64le5 082 413 487   -  +4.58%
riscv642 192 308 138   - +1.956%
s390x  4 584 495 400   - +2.896%
sh43 949 034 207   - +3.464%
sparc644 586 194 372   - +4.237%
x86_64 2 484 102 186   - +1.751%


Test Program: dijkstra_int32

Target  Instructions  Latest  v5.1.0
--    --  --
aarch642 210 178 166   - +1.493%
alpha  1 494 130 687   -  +2.15%
arm8 262 938 105   - +2.665%
hppa   5 207 303 578   - +3.047%
m68k   1 725 851 873   - +2.526%
mips   1 495 206 180   - +1.491%
mipsel 1 497 138 038   - +1.478%
mips64 1 715 388 602   - +1.892%
mips64el   1 695 271 234   - +1.913%
ppc2 014 568 021   -  +1.82%
ppc64  2 206 259 282   - +2.138%
ppc64le2 197 993 199   - +2.146%
riscv641 354 923 136   - +2.396%
s390x  2 916 235 947   - +1.241%
sh41 990 530 126   - +2.669%
sparc642 872 225 164   - +3.757%
x86_64 1 553 989 229   -  +2.12%


Test Program: matmult_double

Target  Instructions  Latest  v5.1.0
--    --  --
aarch641 412 251 532   -   +0.3%
alpha  3 233 986 239   - +7.473%
arm8 545 174 231   - +1.088%
hppa   3 528 318 810   -  +5.81%
m68k   3 919 059 909   -+18.431%
mips   2 344 753 389   -  +4.09%
mipsel 3 329 876 697   - +5.176%
mips64 2 359 044 360   - +4.076%

[PATCH 1/6] xilinx_axidma: Use typedef name for instance_size

2020-08-24 Thread Eduardo Habkost
This makes the code consistent with the rest of QOM code in QEMU,
and will make automated conversion to type declaration macros
simpler.

Signed-off-by: Eduardo Habkost 
---
Cc: "Edgar E. Iglesias" 
Cc: Alistair Francis 
Cc: Peter Maydell 
Cc: qemu-...@nongnu.org
Cc: qemu-devel@nongnu.org
---
 hw/dma/xilinx_axidma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index a4812e480a..5ad8bd3d2e 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -634,7 +634,7 @@ static const TypeInfo axidma_info = {
 static const TypeInfo xilinx_axidma_data_stream_info = {
 .name  = TYPE_XILINX_AXI_DMA_DATA_STREAM,
 .parent= TYPE_OBJECT,
-.instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
+.instance_size = sizeof(XilinxAXIDMAStreamSlave),
 .class_init= xilinx_axidma_stream_class_init,
 .class_data= _axidma_data_stream_class,
 .interfaces = (InterfaceInfo[]) {
@@ -646,7 +646,7 @@ static const TypeInfo xilinx_axidma_data_stream_info = {
 static const TypeInfo xilinx_axidma_control_stream_info = {
 .name  = TYPE_XILINX_AXI_DMA_CONTROL_STREAM,
 .parent= TYPE_OBJECT,
-.instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
+.instance_size = sizeof(XilinxAXIDMAStreamSlave),
 .class_init= xilinx_axidma_stream_class_init,
 .class_data= _axidma_control_stream_class,
 .interfaces = (InterfaceInfo[]) {
-- 
2.26.2




[PATCH 6/6] virtio-vga: Use typedef name for instance_size

2020-08-24 Thread Eduardo Habkost
This makes the code consistent with the rest of QOM code in QEMU,
and will make automated conversion to type declaration macros
simpler.

Signed-off-by: Eduardo Habkost 
---
Cc: "Michael S. Tsirkin" 
Cc: Gerd Hoffmann 
Cc: qemu-devel@nongnu.org
---
 hw/display/virtio-vga.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index f533d7d1b4..7c995ddc81 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -194,8 +194,8 @@ static void virtio_vga_base_class_init(ObjectClass *klass, 
void *data)
 static TypeInfo virtio_vga_base_info = {
 .name  = TYPE_VIRTIO_VGA_BASE,
 .parent= TYPE_VIRTIO_PCI,
-.instance_size = sizeof(struct VirtIOVGABase),
-.class_size= sizeof(struct VirtIOVGABaseClass),
+.instance_size = sizeof(VirtIOVGABase),
+.class_size= sizeof(VirtIOVGABaseClass),
 .class_init= virtio_vga_base_class_init,
 .abstract  = true,
 };
@@ -224,7 +224,7 @@ static void virtio_vga_inst_initfn(Object *obj)
 static VirtioPCIDeviceTypeInfo virtio_vga_info = {
 .generic_name  = TYPE_VIRTIO_VGA,
 .parent= TYPE_VIRTIO_VGA_BASE,
-.instance_size = sizeof(struct VirtIOVGA),
+.instance_size = sizeof(VirtIOVGA),
 .instance_init = virtio_vga_inst_initfn,
 };
 
-- 
2.26.2




[PATCH 4/6] xilinx_axienet: Use typedef name for instance_size

2020-08-24 Thread Eduardo Habkost
This makes the code consistent with the rest of QOM code in QEMU,
and will make automated conversion to type declaration macros
simpler.

Signed-off-by: Eduardo Habkost 
---
Cc: "Edgar E. Iglesias" 
Cc: Alistair Francis 
Cc: Peter Maydell 
Cc: Jason Wang 
Cc: qemu-...@nongnu.org
Cc: qemu-devel@nongnu.org
---
 hw/net/xilinx_axienet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 1e48eb70c9..ceb4652938 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -1069,7 +1069,7 @@ static const TypeInfo xilinx_enet_info = {
 static const TypeInfo xilinx_enet_data_stream_info = {
 .name  = TYPE_XILINX_AXI_ENET_DATA_STREAM,
 .parent= TYPE_OBJECT,
-.instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
+.instance_size = sizeof(XilinxAXIEnetStreamSlave),
 .class_init= xilinx_enet_data_stream_class_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_STREAM_SLAVE },
@@ -1080,7 +1080,7 @@ static const TypeInfo xilinx_enet_data_stream_info = {
 static const TypeInfo xilinx_enet_control_stream_info = {
 .name  = TYPE_XILINX_AXI_ENET_CONTROL_STREAM,
 .parent= TYPE_OBJECT,
-.instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
+.instance_size = sizeof(XilinxAXIEnetStreamSlave),
 .class_init= xilinx_enet_control_stream_class_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_STREAM_SLAVE },
-- 
2.26.2




[PATCH 0/6] qom: Use typedefs instead of struct names on instance_size/class_size

2020-08-24 Thread Eduardo Habkost
This changes existing QOM boilerplate to use existing typedef
names when setting instance_size and class_size on TypeInfo
variables.  This makes the code more consistent and will make
future conversion to QOM type declaration macros easier.

Cc: "Michael S. Tsirkin" 
Cc: "Marc-André Lureau" 
Cc: Gerd Hoffmann 
Cc: "Edgar E. Iglesias" 
Cc: Alistair Francis 
Cc: Peter Maydell 
Cc: Marcel Apfelbaum 
Cc: Jason Wang 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org

Eduardo Habkost (6):
  xilinx_axidma: Use typedef name for instance_size
  omap_intc: Use typedef name for instance_size
  lpc_ich9: Use typedef name for instance_size
  xilinx_axienet: Use typedef name for instance_size
  vhost-user-vga: Use typedef name for instance_size
  virtio-vga: Use typedef name for instance_size

 hw/display/vhost-user-vga.c | 2 +-
 hw/display/virtio-vga.c | 6 +++---
 hw/dma/xilinx_axidma.c  | 4 ++--
 hw/intc/omap_intc.c | 2 +-
 hw/isa/lpc_ich9.c   | 2 +-
 hw/net/xilinx_axienet.c | 4 ++--
 6 files changed, 10 insertions(+), 10 deletions(-)

-- 
2.26.2





Re: [PATCH v1 1/1] core/register: Specify instance_size in the TypeInfo

2020-08-24 Thread Eduardo Habkost
On Fri, Aug 21, 2020 at 10:33:06PM -0700, Alistair Francis wrote:
> Reported-by: Eduardo Habkost 
> Signed-off-by: Alistair Francis 
> ---
>  hw/core/register.c | 14 +-
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/core/register.c b/hw/core/register.c
> index ddf91eb445..5e8e8199d0 100644
> --- a/hw/core/register.c
> +++ b/hw/core/register.c
> @@ -180,11 +180,7 @@ void register_init(RegisterInfo *reg)
>  {
>  assert(reg);
>  
> -if (!reg->data || !reg->access) {
> -return;
> -}
>  
> -object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
>  }
>  
>  void register_write_memory(void *opaque, hwaddr addr,
> @@ -269,13 +265,20 @@ static RegisterInfoArray 
> *register_init_block(DeviceState *owner,
>  int index = rae[i].addr / data_size;
>  RegisterInfo *r = [index];
>  
> +if (data + data_size * index == 0 || ![i]) {
> +continue;
> +}
> +
> +/* Init the register, this will zero it. */
> +object_initialize((void *)r, sizeof(*r), TYPE_REGISTER);
> +
> +/* Set the properties of the register */
>  *r = (RegisterInfo) {
>  .data = data + data_size * index,
>  .data_size = data_size,
>  .access = [i],
>  .opaque = owner,
>  };

This doesn't look right.  Won't this wipe out all DeviceState
data in r->parent_obj?

> -register_init(r);
>  
>  r_array->r[i] = r;
>  }
> @@ -329,6 +332,7 @@ static const TypeInfo register_info = {
>  .name  = TYPE_REGISTER,
>  .parent = TYPE_DEVICE,
>  .class_init = register_class_init,
> +.instance_size = sizeof(RegisterInfo),
>  };
>  
>  static void register_register_types(void)
> -- 
> 2.28.0
> 
> 

-- 
Eduardo




[PATCH 0/6] qom: Use typedefs instead of struct names on instance_size/class_size

2020-08-24 Thread Eduardo Habkost
This changes existing QOM boilerplate to use existing typedef
names when setting instance_size and class_size on TypeInfo
variables.  This makes the code more consistent and will make
future conversion to QOM type declaration macros easier.

Cc: "Michael S. Tsirkin" 
Cc: "Marc-André Lureau" 
Cc: Gerd Hoffmann 
Cc: "Edgar E. Iglesias" 
Cc: Alistair Francis 
Cc: Peter Maydell 
Cc: Marcel Apfelbaum 
Cc: Jason Wang 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org

Eduardo Habkost (6):
  xilinx_axidma: Use typedef name for instance_size
  omap_intc: Use typedef name for instance_size
  lpc_ich9: Use typedef name for instance_size
  xilinx_axienet: Use typedef name for instance_size
  vhost-user-vga: Use typedef name for instance_size
  virtio-vga: Use typedef name for instance_size

 hw/display/vhost-user-vga.c | 2 +-
 hw/display/virtio-vga.c | 6 +++---
 hw/dma/xilinx_axidma.c  | 4 ++--
 hw/intc/omap_intc.c | 2 +-
 hw/isa/lpc_ich9.c   | 2 +-
 hw/net/xilinx_axienet.c | 4 ++--
 6 files changed, 10 insertions(+), 10 deletions(-)

-- 
2.26.2





[PATCH 1/6] xilinx_axidma: Use typedef name for instance_size

2020-08-24 Thread Eduardo Habkost
This makes the code consistent with the rest of QOM code in QEMU,
and will make automated conversion to type declaration macros
simpler.

Signed-off-by: Eduardo Habkost 
---
Cc: "Edgar E. Iglesias" 
Cc: Alistair Francis 
Cc: Peter Maydell 
Cc: qemu-...@nongnu.org
Cc: qemu-devel@nongnu.org
---
 hw/dma/xilinx_axidma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index a4812e480a..5ad8bd3d2e 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -634,7 +634,7 @@ static const TypeInfo axidma_info = {
 static const TypeInfo xilinx_axidma_data_stream_info = {
 .name  = TYPE_XILINX_AXI_DMA_DATA_STREAM,
 .parent= TYPE_OBJECT,
-.instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
+.instance_size = sizeof(XilinxAXIDMAStreamSlave),
 .class_init= xilinx_axidma_stream_class_init,
 .class_data= _axidma_data_stream_class,
 .interfaces = (InterfaceInfo[]) {
@@ -646,7 +646,7 @@ static const TypeInfo xilinx_axidma_data_stream_info = {
 static const TypeInfo xilinx_axidma_control_stream_info = {
 .name  = TYPE_XILINX_AXI_DMA_CONTROL_STREAM,
 .parent= TYPE_OBJECT,
-.instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
+.instance_size = sizeof(XilinxAXIDMAStreamSlave),
 .class_init= xilinx_axidma_stream_class_init,
 .class_data= _axidma_control_stream_class,
 .interfaces = (InterfaceInfo[]) {
-- 
2.26.2




Re: [PULL v2 00/24] target/xtensa updates for 5.2

2020-08-24 Thread Max Filippov
On Mon, Aug 24, 2020 at 2:33 PM Peter Maydell  wrote:
> On Sat, 22 Aug 2020 at 20:48, Max Filippov  wrote:
> > On Sat, Aug 22, 2020 at 3:20 AM Philippe Mathieu-Daudé  
> > wrote:
> > >
> > > Where does that come from?
> >
> > Generated by xtensa processor generator, as one of many output artifacts.
>
> Is there anything different with the source for these cores
> compared to the ones we already have in the tree, or are
> these just "more cores, generated the same way as the old ones" ?

They are generated the same way as the old ones, but they have different
configurations: they support FPU2000 and DFPU opcodes implemented
earlier in this series. I've added them to enable testing of these opcodes.
de233_fpu is supposed to be a platform for further xtensa gcc development.

-- 
Thanks.
-- Max



Re: [PULL v2 00/24] target/xtensa updates for 5.2

2020-08-24 Thread Peter Maydell
On Sat, 22 Aug 2020 at 20:48, Max Filippov  wrote:
>
> On Sat, Aug 22, 2020 at 3:20 AM Philippe Mathieu-Daudé  
> wrote:
> > On 8/21/20 10:50 PM, Max Filippov wrote:
> > > please pull the following batch of updates for target/xtensa.
> >
> > 3.12MiB of generated data...
> >
> > Where does that come from?
>
> Generated by xtensa processor generator, as one of many output artifacts.

Is there anything different with the source for these cores
compared to the ones we already have in the tree, or are
these just "more cores, generated the same way as the old ones" ?

thanks
-- PMM



Re: unknown fs driver type 'virtiofs'

2020-08-24 Thread Pedro Serrano
Dave

 

Thanks for your attention.   I have gone as far forward upgrading qemu and libvirt packages without going beyond stable+backports.   I believe it is now a waiting game for Debian Buster backports to catch up with the release of newer versions that work with QEMU 5.0.0.

 

If you have any more suggestions they will be appreciated.   And sorry for the HTML on the email.   I'm not using an email client, just my email provider's website.  I'll install Thunderbird or Evolution to avoid this in the future.

 

Best regards

 

Pedro

 
 

Sent: Monday, August 24, 2020 at 1:45 PM
From: "Dr. David Alan Gilbert" 
To: "Pedro Serrano" 
Cc: qemu-devel@nongnu.org, stefa...@gmail.com
Subject: Re: unknown fs driver type 'virtiofs'

* Pedro Serrano (k...@gmx.us) wrote:
> Folks
>
> The instructions posted on http://blog.vmsplice.net/2020/04/virtio-fs-has-landed-in-qemu-50.html are simple and I followed them.
>
> Ive updated my Debian Buster QEMU and LIBVIRT packages to all the newest buster-backports versions, and am running on:
>
> Linux ps01ubx 5.7.0-0.bpo.2-amd64 #1 SMP Debian 5.7.10-1~bpo10+1 (2020-07-30) x86_64 GNU/Linux
>
> lsmodgrep virtio
> virtiofs 32768 0
> virtio_ring 36864 1 virtiofs
> virtio 16384 1 virtiofs
> fuse 139264 4 virtiofs
>
> dpkg -l gir1.2-libvirt-glib-1.0:amd64 ipxe-qemu libvirglrenderer0:amd64 libvirt-clients libvirt-daemon libvirt-daemon-system libvirt-glib-1.0-0:amd64 libvirt0:amd64 python3-libvirt qemu qemu-block-extra qemu-system-common qemu-system-data qemu-system-gui:amd64 qemu-system-x86 qemu-utils
> Desired=Unknown/Install/Remove/Purge/Hold
>  Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
> / Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
> / Name Version Architecture Desc
> +++-=---
> ii gir1.2-libvirt-glib-1.0:amd64 1.0.0-1 amd64 GObj
> ii ipxe-qemu 1.0.0+git-20190125.36a4c85-1 all PXE
> ii libvirglrenderer0:amd64 0.7.0-2 amd64 virt
> ii libvirt-clients 5.0.0-4+deb10u1 amd64 Prog
> ii libvirt-daemon 5.0.0-4+deb10u1 amd64 Virt
> ii libvirt-daemon-system 5.0.0-4+deb10u1 amd64 Libv
> ii libvirt-glib-1.0-0:amd64 1.0.0-1 amd64 libv
> ii libvirt0:amd64 5.0.0-4+deb10u1 amd64 libr
> ii python3-libvirt 5.0.0-1 amd64 libv
> ii qemu 1:5.0-14~bpo10+1 amd64 fast
> ii qemu-block-extra 1:5.0-14~bpo10+1 amd64 extr
> ii qemu-system-common 1:5.0-14~bpo10+1 amd64 QEMU
> ii qemu-system-data 1:5.0-14~bpo10+1 all QEMU
> ii qemu-system-gui:amd64 1:5.0-14~bpo10+1 amd64 QEMU
> ii qemu-system-x86 1:5.0-14~bpo10+1 amd64 QEMU
> ii qemu-utils 1:5.0-14~bpo10+1 amd64 QEMU
>
> Whenever I add a filesystem to the vm xml (virsh edit vm) virt-manager spits out an error message. Because virt-manager doesnt have a virtiofs line in the drop-down choices I first choose PATH and then try to change the XML.
>
> filesystem type=mount accessmode=passthrough
> driver type=virtiofs/
>
>
>
> The result is similar, whether I use virt-manager or virsh edit vm:
>

I think your libvirt is too old; my reckoning is it went in v6.1.0 (or
was it 6.2.0?)

> virtio-manager replies: unknown fs driver type virtiofs
>
> virsh edit vm does not let me save the file. It replies:
> error: XML document failed to validate against schema: Unable to validate doc against /usr/share/libvirt/schemas/domain.rng
> Extra element devices in interleave
> Element domain failed to validate content
>
> Failed. Try again? [y,n,i,f,?]:
>
>
> What am I doing wrong?

You're also using HTML mail without plaintext!

Dave

> Regards
>
> Pedro Serrano
>
>
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
 






Re: [PATCH v3 2/2] linux-user: Add support for 'mq_timedsend_time64()' and 'mq_timedreceive_time64()'

2020-08-24 Thread Laurent Vivier
Le 24/08/2020 à 21:37, Filip Bozuta a écrit :
> This patch implements functionality for following time64 syscalls:
> 
> *mq_timedsend_time64()
> 
> This is a year 2038 safe vairant of syscall:
> 
> int mq_timedsend(mqd_t mqdes, const char *msg_ptr,
>  size_t msg_len, unsigned int msg_prio,
>  const struct timespec *abs_timeout)
> --send a message to a message queue--
> man page: https://www.man7.org/linux/man-pages/man2/mq_timedsend.2.html
> 
> *mq_timedreceive_time64()
> 
> This is a year 2038 safe variant of syscall:
> 
> ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr,
> size_t msg_len, unsigned int *msg_prio,
> const struct timespec *abs_timeout)
> --receive a message from a message queue--
> man page: https://man7.org/linux/man-pages/man3/mq_receive.3.html
> 
> Implementation notes:
> 
> These syscalls were implemented in similar ways like
> 'mq_timedsend()' and 'mq_timedreceive' except that
> functions 'target_to_host_timespec64()' and
> 'host_to_target_timespec64()' were used to convert
> values of 'struct timespec' between host and target.
> 
> Signed-off-by: Filip Bozuta 
> Reviewed-by: Laurent Vivier 
> ---
>  linux-user/syscall.c | 58 +---
>  1 file changed, 55 insertions(+), 3 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 4ee1de6e65..3331ec9fea 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -829,11 +829,13 @@ safe_syscall5(int, msgrcv, int, msgid, void *, msgp, 
> size_t, sz,
>  safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
>unsigned, nsops, const struct timespec *, timeout)
>  #endif
> -#ifdef TARGET_NR_mq_timedsend
> +#if defined(TARGET_NR_mq_timedsend) || \
> +defined(TARGET_NR_mq_timedsend_time64)
>  safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
>size_t, len, unsigned, prio, const struct timespec *, timeout)
>  #endif
> -#ifdef TARGET_NR_mq_timedreceive
> +#if defined(TARGET_NR_mq_timedreceive) || \
> +defined(TARGET_NR_mq_timedreceive_time64)
>  safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
>size_t, len, unsigned *, prio, const struct timespec *, 
> timeout)
>  #endif
> @@ -1243,7 +1245,9 @@ static inline abi_long target_to_host_timespec(struct 
> timespec *host_ts,
>  }
>  #endif
>  
> -#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64)
> +#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64) || 
> \
> +defined(TARGET_NR_mq_timedsend_time64) || \
> +defined(TARGET_NR_mq_timedreceive_time64)
>  static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
>   abi_ulong target_addr)
>  {
> @@ -11831,6 +11835,27 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  }
>  return ret;
>  #endif
> +#ifdef TARGET_NR_mq_timedsend_time64
> +case TARGET_NR_mq_timedsend_time64:
> +{
> +struct timespec ts;
> +
> +p = lock_user(VERIFY_READ, arg2, arg3, 1);
> +if (arg5 != 0) {
> +if (target_to_host_timespec64(, arg5)) {
> +return -TARGET_EFAULT;
> +}
> +ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, ));
> +if (!is_error(ret) && host_to_target_timespec64(arg5, )) {
> +return -TARGET_EFAULT;
> +}
> +} else {
> +ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, 
> NULL));
> +}
> +unlock_user(p, arg2, arg3);
> +}
> +return ret;
> +#endif
>  
>  #ifdef TARGET_NR_mq_timedreceive
>  case TARGET_NR_mq_timedreceive:
> @@ -11858,6 +11883,33 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  }
>  return ret;
>  #endif
> +#ifdef TARGET_NR_mq_timedreceive_time64
> +case TARGET_NR_mq_timedreceive_time64:
> +{
> +struct timespec ts;
> +unsigned int prio;
> +
> +p = lock_user(VERIFY_READ, arg2, arg3, 1);
> +if (arg5 != 0) {
> +if (target_to_host_timespec64(, arg5)) {
> +return -TARGET_EFAULT;
> +}
> +ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
> + , ));
> +if (!is_error(ret) && host_to_target_timespec64(arg5, )) {
> +return -TARGET_EFAULT;
> +}
> +} else {
> +ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
> + , NULL));
> +}
> +unlock_user(p, arg2, arg3);
> +if (arg4 

Re: [PATCH v3 1/2] linux-user: Add support for 'clock_nanosleep_time64()' and 'clock_adjtime64()'

2020-08-24 Thread Laurent Vivier
Le 24/08/2020 à 21:21, Filip Bozuta a écrit :
> This patch implements functionality for following time64 syscall:
> 
> *clock_nanosleep_time64()
> 
> This is a year 2038 safe vairant of syscall:
> int clock_nanosleep(clockid_t clockid, int flags,
> const struct timespec *request,
> struct timespec *remain)
> --high-resolution sleep with specifiable clock--
> man page: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html
> 
> *clock_adjtime64()
> 
> This is a year 2038 safe variant of syscall:
> int clock_adjtime(clockid_t clk_id, struct timex *buf)
> --tune kernel clock--
> man page: https://man7.org/linux/man-pages/man2/clock_adjtime.2.html
> 
> Implementation notes:
> 
> Syscall 'clock_nanosleep_time64()' was implemented similarly
> to syscall 'clock_nanosleep()' except that 'host_to_target_timespec64()'
> and 'target_to_host_timespec64()' were used instead of the regular
> 'host_to_target_timespec()' and 'target_to_host_timespec()'.
> 
> For 'clock_adjtime64()' a 64-bit target kernel version of 'struct timex'
> was defined in 'syscall_defs.h': 'struct target__kernel_timex'.
> This type was used to convert the values of 64-bit timex type between
> host and target. For this purpose a 64-bit timex converting functions
> 'target_to_host_timex64()' and 'host_to_target_timex64()'. An existing
> function 'copy_to_user_timeval64()' was used to convert the field
> 'time' which if of type 'struct timeval' from host to target.
> Function 'copy_from_user_timveal64()' was added in this patch and
> used to convert the 'time' field from target to host.
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/syscall.c  | 137 +-
>  linux-user/syscall_defs.h |  31 +
>  2 files changed, 166 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 05f03919ff..a359bd8620 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -809,7 +809,8 @@ safe_syscall4(int, accept4, int, fd, struct sockaddr *, 
> addr, socklen_t *, len,
>  safe_syscall2(int, nanosleep, const struct timespec *, req,
>struct timespec *, rem)
>  #endif
> -#ifdef TARGET_NR_clock_nanosleep
> +#if defined(TARGET_NR_clock_nanosleep) || \
> +defined(TARGET_NR_clock_nanosleep_time64)
>  safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
>const struct timespec *, req, struct timespec *, rem)
>  #endif
> @@ -1205,8 +1206,25 @@ static inline abi_long copy_to_user_timeval(abi_ulong 
> target_tv_addr,
>  return 0;
>  }
>  
> +static inline abi_long copy_from_user_timeval64(struct timeval *tv,
> +abi_ulong target_tv_addr)
> +{
> +struct target__kernel_sock_timeval *target_tv;
> +
> +if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) {
> +return -TARGET_EFAULT;
> +}
> +
> +__get_user(tv->tv_sec, _tv->tv_sec);
> +__get_user(tv->tv_usec, _tv->tv_usec);
> +
> +unlock_user_struct(target_tv, target_tv_addr, 0);
> +
> +return 0;
> +}
> +
>  static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr,
> - const struct timeval *tv)
> +  const struct timeval *tv)
>  {
>  struct target__kernel_sock_timeval *target_tv;
>  
> @@ -6771,6 +6789,87 @@ static inline abi_long host_to_target_timex(abi_long 
> target_addr,
>  }
>  #endif
>  
> +
> +#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
> +static inline abi_long target_to_host_timex64(struct timex *host_tx,
> +  abi_long target_addr)
> +{
> +struct target__kernel_timex *target_tx;
> +
> +if (copy_from_user_timeval64(_tx->time, target_addr +
> + offsetof(struct target__kernel_timex,
> +  time))) {
> +return -TARGET_EFAULT;
> +}
> +
> +if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) {
> +return -TARGET_EFAULT;
> +}
> +
> +__get_user(host_tx->modes, _tx->modes);
> +__get_user(host_tx->offset, _tx->offset);
> +__get_user(host_tx->freq, _tx->freq);
> +__get_user(host_tx->maxerror, _tx->maxerror);
> +__get_user(host_tx->esterror, _tx->esterror);
> +__get_user(host_tx->status, _tx->status);
> +__get_user(host_tx->constant, _tx->constant);
> +__get_user(host_tx->precision, _tx->precision);
> +__get_user(host_tx->tolerance, _tx->tolerance);
> +__get_user(host_tx->tick, _tx->tick);
> +__get_user(host_tx->ppsfreq, _tx->ppsfreq);
> +__get_user(host_tx->jitter, _tx->jitter);
> +__get_user(host_tx->shift, _tx->shift);
> +__get_user(host_tx->stabil, _tx->stabil);
> +__get_user(host_tx->jitcnt, 

Re: [PATCH v3 2/2] linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()'

2020-08-24 Thread Laurent Vivier
Le 24/08/2020 à 21:21, Filip Bozuta a écrit :
> This patch implements functionality for following time64 syscalls:
> 
> *rt_sigtimedwait_time64()
> 
> This is a year 2038 safe variant of syscall:
> 
> int rt_sigtimedwait(const sigset_t *set, siginfo_t *info,
> const struct timespec *timeout, size_t sigsetsize)
> --synchronously wait for queued signals--
> man page: https://man7.org/linux/man-pages/man2/rt_sigtimedwait.2.html
> 
> *sched_rr_get_interval_time64()
> 
> This is a year 2038 safe variant of syscall:
> 
> int sched_rr_get_interval(pid_t pid, struct timespec *tp)
> --get  the  SCHED_RR  interval  for the named process--
> man page: 
> https://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html
> 
> Implementation notes:
> 
> These syscalls were implemented in similar ways like
> 'rt_sigtimedwait()' and 'sched_rr_get_interval()' except
> that functions 'target_to_host_timespec64()' and
> 'host_to_target_timespec64()' were used to convert values
> of 'struct timespec' between host and target.
> 
> Signed-off-by: Filip Bozuta 
> Reviewed-by: Laurent Vivier 
> ---
>  linux-user/syscall.c | 53 
>  1 file changed, 53 insertions(+)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index a359bd8620..0533a5a5bb 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8831,6 +8831,48 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  }
>  }
>  return ret;
> +#endif
> +#ifdef TARGET_NR_rt_sigtimedwait_time64
> +case TARGET_NR_rt_sigtimedwait_time64:
> +{
> +sigset_t set;
> +struct timespec uts, *puts;
> +siginfo_t uinfo;
> +
> +if (arg4 != sizeof(target_sigset_t)) {
> +return -TARGET_EINVAL;
> +}
> +
> +p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
> +if (!p) {
> +return -TARGET_EFAULT;
> +}
> +target_to_host_sigset(, p);
> +unlock_user(p, arg1, 0);
> +if (arg3) {
> +puts = 
> +if (target_to_host_timespec64(puts, arg3)) {
> +return -TARGET_EFAULT;
> +}
> +} else {
> +puts = NULL;
> +}
> +ret = get_errno(safe_rt_sigtimedwait(, , puts,
> + SIGSET_T_SIZE));
> +if (!is_error(ret)) {
> +if (arg2) {
> +p = lock_user(VERIFY_WRITE, arg2,
> +  sizeof(target_siginfo_t), 0);
> +if (!p) {
> +return -TARGET_EFAULT;
> +}
> +host_to_target_siginfo(p, );
> +unlock_user(p, arg2, sizeof(target_siginfo_t));
> +}
> +ret = host_to_target_signal(ret);
> +}
> +}
> +return ret;
>  #endif
>  case TARGET_NR_rt_sigqueueinfo:
>  {
> @@ -10351,6 +10393,17 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  }
>  return ret;
>  #endif
> +#ifdef TARGET_NR_sched_rr_get_interval_time64
> +case TARGET_NR_sched_rr_get_interval_time64:
> +{
> +struct timespec ts;
> +ret = get_errno(sched_rr_get_interval(arg1, ));
> +if (!is_error(ret)) {
> +ret = host_to_target_timespec64(arg2, );
> +}
> +}
> +return ret;
> +#endif
>  #if defined(TARGET_NR_nanosleep)
>  case TARGET_NR_nanosleep:
>  {
> 

Applied to my linux-user-for-5.2 branch.

Thanks,
Laurent




Re: [PATCH v3 1/2] linux-user: Fix 'mq_timedsend()' and 'mq_timedreceive()'

2020-08-24 Thread Laurent Vivier
Le 24/08/2020 à 21:37, Filip Bozuta a écrit :
> Implementations of syscalls 'mq_timedsend()' and 'mq_timedreceive()'
> in 'syscall.c' use functions 'target_to_host_timespec()' and
> 'host_to_target_timespec()' to transfer the value of 'struct timespec'
> between target and host. However, the implementations don't check whether
> this conversion succeeds and thus can cause an unaproppriate error instead
> of the 'EFAULT (Bad address)' which is supposed to be set if the conversion
> from target to host fails. This was confirmed with the modified LTP
> test suite where test cases with a bad adress for 'timespec' were
> added. This modified test suite can be found at:
> https://github.com/bozutaf/ltp
> 
> Without the changes from this patch the bad adress testcase for 
> 'mq_timedsend()'
> succeds unexpectedly, while the test returns errno 'ETIMEOUT' for
> 'mq_timedreceive()':
> 
> mq_timedsend01.c:190: FAIL: mq_timedsend() returned 0, expected -1: SUCCESS 
> (0)
> mq_timedreceive01.c:178: FAIL: mq_timedreceive() failed unexpectedly,
> expected EFAULT: ETIMEDOUT (110)
> 
> After the changes from this patch, testcases for both syscalls fail with 
> EFAULT
> as expected, which is the same test result that is received with native 
> execution:
> 
> mq_timedsend01.c:187: PASS: mq_timedsend() failed expectedly: EFAULT (14)
> mq_timedreceive01.c:180: PASS: mq_timedreceive() failed expectedly: EFAULT 
> (14)
> 
> (Patch with this new test case will be sent to LTP mailing list soon)
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/syscall.c | 16 
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 05f03919ff..4ee1de6e65 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -11817,9 +11817,13 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  
>  p = lock_user (VERIFY_READ, arg2, arg3, 1);
>  if (arg5 != 0) {
> -target_to_host_timespec(, arg5);
> +if (target_to_host_timespec(, arg5)) {
> +return -TARGET_EFAULT;
> +}
>  ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, ));
> -host_to_target_timespec(arg5, );
> +if (!is_error(ret) && host_to_target_timespec(arg5, )) {
> +return -TARGET_EFAULT;
> +}
>  } else {
>  ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, 
> NULL));
>  }
> @@ -11836,10 +11840,14 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  
>  p = lock_user (VERIFY_READ, arg2, arg3, 1);
>  if (arg5 != 0) {
> -target_to_host_timespec(, arg5);
> +if (target_to_host_timespec(, arg5)) {
> +return -TARGET_EFAULT;
> +}
>  ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
>   , ));
> -host_to_target_timespec(arg5, );
> +if (!is_error(ret) && host_to_target_timespec(arg5, )) {
> +return -TARGET_EFAULT;
> +}
>  } else {
>  ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
>   , NULL));
> 

Applied to my linux-user-for-5.2 branch.

Thanks,
Laurent




Re: [PATCH v4 5/5] linux-user: Add strace support for printing arguments of some clock and time functions

2020-08-24 Thread Laurent Vivier
Le 11/08/2020 à 18:45, Filip Bozuta a écrit :
> This patch implements strace argument printing functionality for following 
> syscalls:
> 
> * clock_getres, clock_gettime, clock_settime - clock and time functions
> 
> int clock_getres(clockid_t clockid, struct timespec *res)
> int clock_gettime(clockid_t clockid, struct timespec *tp)
> int clock_settime(clockid_t clockid, const struct timespec *tp)
> man page: https://man7.org/linux/man-pages/man2/clock_getres.2.html
> 
> * gettimeofday - get time
> 
> int gettimeofday(struct timeval *tv, struct timezone *tz)
> man page: https://man7.org/linux/man-pages/man2/gettimeofday.2.html
> 
> * getitimer, setitimer - get or set value of an interval timer
> 
> int getitimer(int which, struct itimerval *curr_value)
> int setitimer(int which, const struct itimerval *new_value,
>   struct itimerval *old_value)
> man page: https://man7.org/linux/man-pages/man2/getitimer.2.html
> 
> Implementation notes:
> 
> All of the syscalls have some structue types as argument types and thus
> a separate printing function was stated in file "strace.list" for each
> of them. All of these functions use existing functions for their
> appropriate structure types ("print_timeval()" and "print_timezone()").
> 
> Functions "print_timespec()" and "print_itimerval()" were added in this
> patch so that they can be used to print types "struct timespec" and
> "struct itimerval" used by some of the syscalls. Function 
> "print_itimerval()"
> uses the existing function "print_timeval()" to print fields of the
> structure "struct itimerval" that are of type "struct timeval".
> 
> Function "print_enums()", which was introduced in the previous patch, is 
> used
> to print the interval timer type which is the first argument of 
> "getitimer()"
> and "setitimer()". Also, this function is used to print the clock id which
> is the first argument of "clock_getres()" and "clock_gettime()". For that
> reason, the existing function "print_clockid()" was removed in this patch.
> Existing function "print_clock_adjtime()" was also changed for this reason
> to use "print_enums()".
> 
> The existing function "print_timeval()" was changed a little so that it
> prints the field names beside the values.
> 
> Syscalls "clock_getres()" and "clock_gettime()" have the same number
> and types of arguments and thus their print functions "print_clock_getres"
> and "print_clock_gettime" share a common definition in file "strace.c".
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/strace.c| 287 +++--
>  linux-user/strace.list |  17 ++-
>  2 files changed, 232 insertions(+), 72 deletions(-)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index def92c4d73..1a5c4c820a 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -78,7 +78,9 @@ UNUSED static void print_string(abi_long, int);
>  UNUSED static void print_buf(abi_long addr, abi_long len, int last);
>  UNUSED static void print_raw_param(const char *, abi_long, int);
>  UNUSED static void print_timeval(abi_ulong, int);
> +UNUSED static void print_timespec(abi_ulong, int);
>  UNUSED static void print_timezone(abi_ulong, int);
> +UNUSED static void print_itimerval(abi_ulong, int);
>  UNUSED static void print_number(abi_long, int);
>  UNUSED static void print_signal(abi_ulong, int);
>  UNUSED static void print_sockaddr(abi_ulong, abi_long, int);
> @@ -578,69 +580,6 @@ print_fdset(int n, abi_ulong target_fds_addr)
>  }
>  #endif
>  
> -#ifdef TARGET_NR_clock_adjtime
> -/* IDs of the various system clocks */
> -#define TARGET_CLOCK_REALTIME  0
> -#define TARGET_CLOCK_MONOTONIC 1
> -#define TARGET_CLOCK_PROCESS_CPUTIME_ID2
> -#define TARGET_CLOCK_THREAD_CPUTIME_ID 3
> -#define TARGET_CLOCK_MONOTONIC_RAW 4
> -#define TARGET_CLOCK_REALTIME_COARSE   5
> -#define TARGET_CLOCK_MONOTONIC_COARSE  6
> -#define TARGET_CLOCK_BOOTTIME  7
> -#define TARGET_CLOCK_REALTIME_ALARM8
> -#define TARGET_CLOCK_BOOTTIME_ALARM9
> -#define TARGET_CLOCK_SGI_CYCLE 10
> -#define TARGET_CLOCK_TAI   11
> -
> -static void
> -print_clockid(int clockid, int last)
> -{
> -switch (clockid) {
> -case TARGET_CLOCK_REALTIME:
> -qemu_log("CLOCK_REALTIME");
> -break;
> -case TARGET_CLOCK_MONOTONIC:
> -qemu_log("CLOCK_MONOTONIC");
> -break;
> -case TARGET_CLOCK_PROCESS_CPUTIME_ID:
> -qemu_log("CLOCK_PROCESS_CPUTIME_ID");
> -break;
> -case TARGET_CLOCK_THREAD_CPUTIME_ID:
> -qemu_log("CLOCK_THREAD_CPUTIME_ID");
> -break;
> -case TARGET_CLOCK_MONOTONIC_RAW:
> -qemu_log("CLOCK_MONOTONIC_RAW");
> -break;
> -case TARGET_CLOCK_REALTIME_COARSE:
> -

Re: msys2/mingw meson building fixes

2020-08-24 Thread Yonggang Luo
After this fixes, the configure succeed, but the make -j10 failed
with
```
$ make -j10
python3 -B /e/CI-Cor-Ready/xemu/qemu.org/meson/meson.py introspect --tests
| python3 -B scripts/mtest2make.py > Makefile.mtest
./ninjatool -t ninja2make --omit clean dist uninstall < build.ninja >
Makefile.ninja
  GIT ui/keycodemapdb tests/fp/berkeley-testfloat-3
tests/fp/berkeley-softfloat-3 meson dtc capstone slirp
  GEN tests/test-qapi-gen
Traceback (most recent call last):
  File "scripts/mtest2make.py", line 56, in 
executable = os.path.relpath(test['cmd'][0])
  File "C:/CI-Tools/msys64/mingw64/lib/python3.8/ntpath.py", line 716, in
relpath
raise ValueError("path is on mount %r, start on mount %r" % (
ValueError: path is on mount 'C:', start on mount 'E:'
make: *** 正在删除文件“Makefile.mtest”
make[1]: 进入目录“/e/CI-Cor-Ready/xemu/qemu.org/slirp”
  GEN /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/libslirp-version.h
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/arp_table.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/bootp.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/cksum.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/dhcpv6.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/dnssearch.o
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_overlay.c
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_check.c
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/if.o
  CC  cs.o
  CC  utils.o
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_addresses.c
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_empty_tree.c
  CC  SStream.o
  CC  MCInstrDesc.o
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_strerror.c
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_rw.c
  CC  MCRegisterInfo.o
  CC  arch/ARM/ARMDisassembler.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ip_icmp.o
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_sw.c
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_wip.c
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ip_input.o
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt_ro.c
 DEP /e/CI-Cor-Ready/xemu/qemu.org/dtc/libfdt/fdt.c
  CC  arch/ARM/ARMInstPrinter.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ip_output.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ip6_icmp.o
  CC  arch/ARM/ARMModule.o
  CC  arch/ARM/ARMMapping.o
  CC  arch/AArch64/AArch64BaseInfo.o
  CC  arch/AArch64/AArch64Disassembler.o
  CC  arch/AArch64/AArch64InstPrinter.o
  CC  arch/AArch64/AArch64Mapping.o
 CC libfdt/fdt.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ip6_input.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ip6_output.o
  CC  arch/AArch64/AArch64Module.o
  CC  arch/Mips/MipsDisassembler.o
  CC  arch/Mips/MipsInstPrinter.o
 CC libfdt/fdt_ro.o
  CC  arch/Mips/MipsMapping.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/mbuf.o
  CC  arch/Mips/MipsModule.o
  CC  arch/PowerPC/PPCDisassembler.o
  CC  arch/PowerPC/PPCInstPrinter.o
 CC libfdt/fdt_wip.o
  CC  arch/PowerPC/PPCMapping.o
 CC libfdt/fdt_sw.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/misc.o
  CC  arch/PowerPC/PPCModule.o
  CC  arch/Sparc/SparcDisassembler.o
 CC libfdt/fdt_rw.o
  CC  arch/Sparc/SparcInstPrinter.o
  CC  arch/Sparc/SparcMapping.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ncsi.o
  CC  arch/Sparc/SparcModule.o
  CC  arch/SystemZ/SystemZDisassembler.o
 CC libfdt/fdt_strerror.o
  CC  arch/SystemZ/SystemZInstPrinter.o
  CC  arch/SystemZ/SystemZMapping.o
  CC  arch/SystemZ/SystemZModule.o
  CC  arch/SystemZ/SystemZMCTargetDesc.o
 CC libfdt/fdt_empty_tree.o
  CC  arch/X86/X86Disassembler.o
  CC  arch/X86/X86DisassemblerDecoder.o
  CC  arch/X86/X86IntelInstPrinter.o
  CC  arch/X86/X86ATTInstPrinter.o
 CC libfdt/fdt_addresses.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/ndp_table.o
 CC libfdt/fdt_overlay.o
  CC  arch/X86/X86Mapping.o
  CC  arch/X86/X86Module.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/sbuf.o
 CC libfdt/fdt_check.o
  CC  arch/XCore/XCoreInstPrinter.o
  CC  arch/XCore/XCoreDisassembler.o
  CC  arch/XCore/XCoreMapping.o
 AR libfdt/libfdt.a
  CC  arch/XCore/XCoreModule.o
  CC  MCInst.o
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/slirp.o
a - libfdt/fdt.o
a - libfdt/fdt_ro.o
a - libfdt/fdt_wip.o
a - libfdt/fdt_sw.o
a - libfdt/fdt_rw.o
a - libfdt/fdt_strerror.o
a - libfdt/fdt_empty_tree.o
a - libfdt/fdt_addresses.o
a - libfdt/fdt_overlay.o
a - libfdt/fdt_check.o
C:/CI-Tools/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ar.exe:
creating libfdt/libfdt.a
  CC  /e/CI-Cor-Ready/xemu/qemu.org-x64/slirp/src/socket.o
  

Fwd: msys2/mingw meson building fixes

2020-08-24 Thread Yonggang Luo
-- Forwarded message -
From: 罗勇刚(Yonggang Luo) 
Date: Tue, Aug 25, 2020 at 4:50 AM
Subject: msys2/mingw meson building fixes
To: qemu-level 


I've create a pull request for fixes python ninja detection and usage on
msys2/mingw
at  https://github.com/mesonbuild/meson/pull/7637


-- 
 此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo


-- 
 此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo


Re: [PATCH v2] linux-user: detect mismatched ELF ABI in qemu-mips[n32][el]

2020-08-24 Thread Laurent Vivier
Le 23/08/2020 à 12:17, Carlo Marcelo Arenas Belón a écrit :
> MIPS provides 2 ILP32 ABIs, and therefore 4 possible qemu-mips binaries
> with 2 pairs using the same endianess and bitness.
> 
> This could lead to an O32 image loading in the N32 binary or vice versa
> and in cryptic errors (if lucky that the CPU doesn't match the FPU used)
> like :
> 
>   qemu: Unexpected FPU mode   (o32 ELF loaded to qemu-mipsn32[el])
>   ELF binary's NaN mode not supported by CPU(n32 -> qemu-mips[el])
> 
> Add an ABI check macro that could be used while checking the ELF header
> that relies in the ABI2 flag to identify n32 binaries and abort instead
> early with a more descriptive error :
> 
>   Invalid ELF image for this architecture
> 
> Signed-off-by: Carlo Marcelo Arenas Belón 
> ---
> Changes since v1:
> - Use the provided definition from include/elf.h (per Laurent)
> - Abort instead of warning (per Laurent, not using a custom error though)
> - Expand the check to all other combinations (per Aleksandar)
> 
>  linux-user/elfload.c | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index fe9dfe795d..69936dcd45 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -918,6 +918,12 @@ static void elf_core_copy_regs(target_elf_gregset_t 
> *regs, const CPUPPCState *en
>  
>  #define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_NANOMIPS)
>  
> +#ifdef TARGET_ABI_MIPSN32
> +#define elf_check_abi(x) ((x) & EF_MIPS_ABI2)
> +#else
> +#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
> +#endif
> +
>  static inline void init_thread(struct target_pt_regs *regs,
> struct image_info *infop)
>  {
> @@ -1487,6 +1493,10 @@ static void elf_core_copy_regs(target_elf_gregset_t 
> *regs,
>  #define elf_check_arch(x) ((x) == ELF_ARCH)
>  #endif
>  
> +#ifndef elf_check_abi
> +#define elf_check_abi(x) (1)
> +#endif
> +
>  #ifndef ELF_HWCAP
>  #define ELF_HWCAP 0
>  #endif
> @@ -1644,6 +1654,7 @@ static bool elf_check_ident(struct elfhdr *ehdr)
>  static bool elf_check_ehdr(struct elfhdr *ehdr)
>  {
>  return (elf_check_arch(ehdr->e_machine)
> +&& elf_check_abi(ehdr->e_flags)
>  && ehdr->e_ehsize == sizeof(struct elfhdr)
>  && ehdr->e_phentsize == sizeof(struct elf_phdr)
>  && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN));
> 


Applied to my linux-user-for-5.2 branch.

Thanks,
Laurent




msys2/mingw meson building fixes

2020-08-24 Thread Yonggang Luo
I've create a pull request for fixes python ninja detection and usage on
msys2/mingw
at  https://github.com/mesonbuild/meson/pull/7637


-- 
 此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo


Re: [PATCH v2 3/3] linux-user: Add strace support for printing arguments for ioctls used for terminals and serial lines

2020-08-24 Thread Laurent Vivier
Le 23/07/2020 à 23:02, Filip Bozuta a écrit :
> Functions "print_ioctl()" and "print_syscall_ret_ioctl()" are used
> to print arguments of "ioctl()" with "-strace". These functions
> use "thunk_print()", which is defined in "thunk.c", to print the
> contents of ioctl's third arguments that are not basic types.
> 
> However, this function doesn't handle ioctls of group ioctl_tty which
> are used for terminals and serial lines. These ioctls use a type
> "struct termios" which thunk type is defined in a non standard
> way using "STRUCT_SPECIAL()". This means that this type is not decoded
> regularly using "thunk_convert()" and uses special converting functions
> "target_to_host_termios()" and "host_to_target_termios()", which are defined
> in "syscall.c" to decode it's values.
> 
> For simillar reasons, this type is also not printed regularly using
> "thunk_print()". That is the reason why a separate printing function
> "print_termios()" is defined in file "strace.c". This function decodes
> and prints flag values of the "termios" structure.
> 
> Implementation notes:
> 
> Function "print_termios()" was implemented in "strace.c" using
> an existing function "print_flags()" to print flag values of
> "struct termios" fields. Also, recently implemented function
> "print_enums()" was also used to print enumareted values which
> are contained in the fields of 'struct termios'.
> 
> These flag values were defined using an existing macro "FLAG_TARGET()"
> that generates aproppriate target flag values and string representations
> of these flags. Also, the recently defined macro "ENUM_TARGET()" was
> used to generate aproppriate enumarated values and their respective
> string representations.
> 
> Function "print_termios()" was declared in "qemu.h" so that it can
> be accessed in "syscall.c". Type "StructEntry" defined in
> "exec/user/thunk.h" contains information that is used to decode
> structure values. Field "void print(void *arg)" was added in this
> structure as a special print function. Also, function "thunk_print()"
> was changed a little so that it uses this special print function
> in case it is defined. This printing function was instantiated with
> the defined "print_termios()" in "syscall.c" in "struct_termios_def".
> 
> Signed-off-by: Filip Bozuta 
> ---
>  include/exec/user/thunk.h |   1 +
>  linux-user/qemu.h |   1 +
>  linux-user/strace.c   | 195 ++
>  linux-user/syscall.c  |   1 +
>  thunk.c   |  23 +++--
>  5 files changed, 212 insertions(+), 9 deletions(-)
> 
> diff --git a/include/exec/user/thunk.h b/include/exec/user/thunk.h
> index 7992475c9f..a5bbb2c733 100644
> --- a/include/exec/user/thunk.h
> +++ b/include/exec/user/thunk.h
> @@ -55,6 +55,7 @@ typedef struct {
>  int *field_offsets[2];
>  /* special handling */
>  void (*convert[2])(void *dst, const void *src);
> +void (*print)(void *arg);
>  int size[2];
>  int align[2];
>  const char *name;
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index f431805e57..a69a0bd347 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -706,6 +706,7 @@ static inline uint64_t target_offset64(uint64_t word0, 
> uint64_t word1)
>  }
>  #endif /* TARGET_ABI_BITS != 32 */
>  
> +void print_termios(void *arg);
>  
>  /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
>  #ifdef TARGET_ARM
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index 3f16bb2c53..b9ba39ce6e 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -1284,6 +1284,140 @@ UNUSED static struct flags falloc_flags[] = {
>  #endif
>  };
>  
> +UNUSED static struct flags termios_iflags[] = {
> +FLAG_TARGET(IGNBRK),
> +FLAG_TARGET(BRKINT),
> +FLAG_TARGET(IGNPAR),
> +FLAG_TARGET(PARMRK),
> +FLAG_TARGET(INPCK),
> +FLAG_TARGET(ISTRIP),
> +FLAG_TARGET(INLCR),
> +FLAG_TARGET(IGNCR),
> +FLAG_TARGET(ICRNL),
> +FLAG_TARGET(IUCLC),
> +FLAG_TARGET(IXON),
> +FLAG_TARGET(IXANY),
> +FLAG_TARGET(IXOFF),
> +FLAG_TARGET(IMAXBEL),
> +FLAG_TARGET(IUTF8),
> +FLAG_END,
> +};
> +
> +UNUSED static struct flags termios_oflags[] = {
> +FLAG_TARGET(OPOST),
> +FLAG_TARGET(OLCUC),
> +FLAG_TARGET(ONLCR),
> +FLAG_TARGET(OCRNL),
> +FLAG_TARGET(ONOCR),
> +FLAG_TARGET(ONLRET),
> +FLAG_TARGET(OFILL),
> +FLAG_TARGET(OFDEL),
> +FLAG_END,
> +};
> +
> +UNUSED static struct enums termios_oflags_NLDLY[] = {
> +ENUM_TARGET(NL0),
> +ENUM_TARGET(NL1),
> +ENUM_END,
> +};
> +
> +UNUSED static struct enums termios_oflags_CRDLY[] = {
> +ENUM_TARGET(CR0),
> +ENUM_TARGET(CR1),
> +ENUM_TARGET(CR2),
> +ENUM_TARGET(CR3),
> +ENUM_END,
> +};
> +
> +UNUSED static struct enums termios_oflags_TABDLY[] = {
> +ENUM_TARGET(TAB0),
> +ENUM_TARGET(TAB1),
> +ENUM_TARGET(TAB2),
> +

Re: [PATCH v4 4/5] linux-user: Add an api to print enumareted argument values with strace

2020-08-24 Thread Laurent Vivier
Le 11/08/2020 à 18:45, Filip Bozuta a écrit :
> This patch introduces a type 'struct enums' and function 'print_enums()'
> that can be used to print enumerated argument values of some syscalls
> in strace. This can be used in future strace implementations.
> 
> Also, macros 'ENUM_GENERIC()', 'ENUM_TARGET()' and 'ENUM_END', are
> introduced to enable automatic generation of aproppriate enumarated
> values and their repsective string representations (these macros are
> exactly the same as 'FLAG_GENERIC()', 'FLAG_TARGET()' and 'FLAG_END').
> 
> Future patches are planned to modify all existing print functions in
> 'strace.c' that print arguments of syscalls with enumerated values to
> use this new api.
> 
> Signed-off-by: Filip Bozuta 
> Reviewed-by: Laurent Vivier 
> ---
>  linux-user/strace.c | 31 +++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index 40f863c6e2..def92c4d73 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -52,9 +52,23 @@ struct flags {
>  /* end of flags array */
>  #define FLAG_END   { 0, NULL }
>  
> +/* Structure used to translate enumerated values into strings */
> +struct enums {
> +abi_longe_value;   /* enum value */
> +const char  *e_string; /* stringified enum */
> +};
> +
> +/* common enums for all architectures */
> +#define ENUM_GENERIC(name) { name, #name }
> +/* target specific enums */
> +#define ENUM_TARGET(name)  { TARGET_ ## name, #name }
> +/* end of enums array */
> +#define ENUM_END   { 0, NULL }
> +
>  UNUSED static const char *get_comma(int);
>  UNUSED static void print_pointer(abi_long, int);
>  UNUSED static void print_flags(const struct flags *, abi_long, int);
> +UNUSED static void print_enums(const struct enums *, abi_long, int);
>  UNUSED static void print_at_dirfd(abi_long, int);
>  UNUSED static void print_file_mode(abi_long, int);
>  UNUSED static void print_open_flags(abi_long, int);
> @@ -1248,6 +1262,23 @@ print_flags(const struct flags *f, abi_long flags, int 
> last)
>  }
>  }
>  
> +static void
> +print_enums(const struct enums *e, abi_long enum_arg, int last)
> +{
> +for (; e->e_string != NULL; e++) {
> +if (e->e_value == enum_arg) {
> +qemu_log("%s", e->e_string);
> +break;
> +}
> +}
> +
> +if (e->e_string == NULL) {
> +qemu_log("%#x", (unsigned int)enum_arg);
> +}
> +
> +qemu_log("%s", get_comma(last));
> +}
> +
>  static void
>  print_at_dirfd(abi_long dirfd, int last)
>  {
> 

Applied to my linux-user-for-5.2 branch.

Thanks,
Laurent




Re: [PATCH v4 3/5] linux-user: Add strace support for printing arguments of syscalls used to lock and unlock memory

2020-08-24 Thread Laurent Vivier
Le 11/08/2020 à 18:45, Filip Bozuta a écrit :
> This patch implements strace argument printing functionality for following 
> syscalls:
> 
> * mlock, munlock, mlockall, munlockall - lock and unlock memory
> 
>int mlock(const void *addr, size_t len)
>int munlock(const void *addr, size_t len)
>int mlockall(int flags)
>int munlockall(void)
>man page: https://man7.org/linux/man-pages/man2/mlock.2.html
> 
> Implementation notes:
> 
> Syscall mlockall() takes an argument that is composed of predefined values
> which represent flags that determine the type of locking operation that is
> to be performed. For that reason, a printing function "print_mlockall" was
> stated in file "strace.list". This printing function uses an already 
> existing
> function "print_flags()" to print the "flags" argument.  These flags are 
> stated
> inside an array "mlockall_flags" that contains values of type "struct 
> flags".
> These values are instantiated using an existing macro "FLAG_TARGET()" that
> crates aproppriate target flag values based on those defined in files
> '/target_syscall.h'. These target flag values were changed from
> "TARGET_MLOCKALL_MCL*" to "TARGET_MCL_*" so that they can be 
> aproppriately set
> and recognised in "strace.c" with "FLAG_TARGET()". Value for "MCL_ONFAULT"
> was added in this patch. This value was also added in "syscall.c" in 
> function
> "target_to_host_mlockall_arg()". Because this flag value was added in 
> kernel
> version 4.4, it is enwrapped in an #ifdef directive (both in "syscall.c" 
> and
> in "strace.c") as to support older kernel versions.
> The other syscalls have only primitive argument types, so the
> rest of the implementation was handled by stating an appropriate
> printing format in file "strace.list". Syscall mlock2() is not 
> implemented in
> "syscall.c" and thus it's argument printing is not implemented in this 
> patch.
> 
> Signed-off-by: Filip Bozuta 
> Reviewed-by: Laurent Vivier 
> ---
>  linux-user/aarch64/target_syscall.h|  5 +++--
>  linux-user/alpha/target_syscall.h  |  5 +++--
>  linux-user/arm/target_syscall.h|  6 --
>  linux-user/cris/target_syscall.h   |  5 +++--
>  linux-user/hppa/target_syscall.h   |  5 +++--
>  linux-user/i386/target_syscall.h   |  5 +++--
>  linux-user/m68k/target_syscall.h   |  6 +++---
>  linux-user/microblaze/target_syscall.h |  5 +++--
>  linux-user/mips/target_syscall.h   |  5 +++--
>  linux-user/mips64/target_syscall.h |  5 +++--
>  linux-user/nios2/target_syscall.h  |  5 +++--
>  linux-user/openrisc/target_syscall.h   |  5 +++--
>  linux-user/ppc/target_syscall.h|  5 +++--
>  linux-user/riscv/target_syscall.h  |  5 +++--
>  linux-user/s390x/target_syscall.h  |  5 +++--
>  linux-user/sh4/target_syscall.h|  5 +++--
>  linux-user/sparc/target_syscall.h  |  5 +++--
>  linux-user/sparc64/target_syscall.h|  5 +++--
>  linux-user/strace.c| 21 +
>  linux-user/strace.list |  8 
>  linux-user/syscall.c   | 10 --
>  linux-user/tilegx/target_syscall.h |  5 +++--
>  linux-user/x86_64/target_syscall.h |  5 +++--
>  linux-user/xtensa/target_syscall.h |  5 +++--
>  24 files changed, 97 insertions(+), 49 deletions(-)
> 
> diff --git a/linux-user/aarch64/target_syscall.h 
> b/linux-user/aarch64/target_syscall.h
> index 995e475c73..3194e6b009 100644
> --- a/linux-user/aarch64/target_syscall.h
> +++ b/linux-user/aarch64/target_syscall.h
> @@ -16,8 +16,9 @@ struct target_pt_regs {
>  #define UNAME_MINIMUM_RELEASE "3.8.0"
>  #define TARGET_CLONE_BACKWARDS
>  #define TARGET_MINSIGSTKSZ   2048
> -#define TARGET_MLOCKALL_MCL_CURRENT 1
> -#define TARGET_MLOCKALL_MCL_FUTURE  2
> +#define TARGET_MCL_CURRENT 1
> +#define TARGET_MCL_FUTURE  2
> +#define TARGET_MCL_ONFAULT 4
>  
>  #define TARGET_PR_SVE_SET_VL  50
>  #define TARGET_PR_SVE_GET_VL  51
> diff --git a/linux-user/alpha/target_syscall.h 
> b/linux-user/alpha/target_syscall.h
> index 3426cc5b4e..fd389422e3 100644
> --- a/linux-user/alpha/target_syscall.h
> +++ b/linux-user/alpha/target_syscall.h
> @@ -258,7 +258,8 @@ struct target_pt_regs {
>  #define TARGET_UAC_NOFIX 2
>  #define TARGET_UAC_SIGBUS4
>  #define TARGET_MINSIGSTKSZ  4096
> -#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
> -#define TARGET_MLOCKALL_MCL_FUTURE  0x4000
> +#define TARGET_MCL_CURRENT 0x2000
> +#define TARGET_MCL_FUTURE  0x4000
> +#define TARGET_MCL_ONFAULT 0x8000
>  
>  #endif /* ALPHA_TARGET_SYSCALL_H */
> diff --git a/linux-user/arm/target_syscall.h b/linux-user/arm/target_syscall.h
> index f85cbdaf56..e870ed7a54 100644
> --- a/linux-user/arm/target_syscall.h
> +++ b/linux-user/arm/target_syscall.h
> @@ -28,8 +28,10 @@ struct target_pt_regs {
>  #define TARGET_CLONE_BACKWARDS

Re: [PATCH v4 2/5] linux-user: Add strace support for printing arguments of truncate()/ftruncate() and getsid()

2020-08-24 Thread Laurent Vivier
Le 11/08/2020 à 18:45, Filip Bozuta a écrit :
> This patch implements strace argument printing functionality for following 
> syscalls:
> 
> * truncate, ftruncate - truncate a file to a specified length
> 
> int truncate/truncate64(const char *path, off_t length)
> int ftruncate/ftruncate64(int fd, off_t length)
> man page: https://man7.org/linux/man-pages/man2/truncate.2.html
> 
> * getsid - get session ID
> 
> pid_t getsid(pid_t pid)
> man page: https://man7.org/linux/man-pages/man2/getsid.2.html
> 
> Implementation notes:
> 
> Syscalls truncate/truncate64 take string argument types and thus a
> separate print function "print_truncate/print_truncate64" is stated in
> file "strace.list". This function is defined and implemented in "strace.c"
> by using an existing function used to print string arguments: 
> "print_string()".
> For syscall ftruncate64, a separate printing function was also stated in
> "strace.c" as it requires a special kind of handling.
> The other syscalls have only primitive argument types, so the rest of the
> implementation was handled by stating an appropriate printing format in 
> file
> "strace.list".
> Function "regpairs_aligned()" was cut & pasted from "syscall.c" to 
> "qemu.h"
> as it is used by functions "print_truncate64()" and "print_ftruncate64()"
> to print the offset arguments of "truncate64()" and "ftruncate64()".
> 
> Signed-off-by: Filip Bozuta 
> Reviewed-by: Laurent Vivier 
> ---
>  linux-user/qemu.h  | 35 +++
>  linux-user/strace.c| 47 ++
>  linux-user/strace.list | 10 -
>  linux-user/syscall.c   | 32 
>  4 files changed, 87 insertions(+), 37 deletions(-)
> 
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 63ddfe86fd..f431805e57 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -706,6 +706,41 @@ static inline uint64_t target_offset64(uint64_t word0, 
> uint64_t word1)
>  }
>  #endif /* TARGET_ABI_BITS != 32 */
>  
> +
> +/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
> +#ifdef TARGET_ARM
> +static inline int regpairs_aligned(void *cpu_env, int num)
> +{
> +return CPUARMState *)cpu_env)->eabi) == 1) ;
> +}
> +#elif defined(TARGET_MIPS) && (TARGET_ABI_BITS == 32)
> +static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
> +#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
> +/*
> + * SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
> + * of registers which translates to the same as ARM/MIPS, because we start 
> with
> + * r3 as arg1
> + */
> +static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
> +#elif defined(TARGET_SH4)
> +/* SH4 doesn't align register pairs, except for p{read,write}64 */
> +static inline int regpairs_aligned(void *cpu_env, int num)
> +{
> +switch (num) {
> +case TARGET_NR_pread64:
> +case TARGET_NR_pwrite64:
> +return 1;
> +
> +default:
> +return 0;
> +}
> +}
> +#elif defined(TARGET_XTENSA)
> +static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
> +#else
> +static inline int regpairs_aligned(void *cpu_env, int num) { return 0; }
> +#endif
> +
>  /**
>   * preexit_cleanup: housekeeping before the guest exits
>   *
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index f0624b6206..7dc239b9f1 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -1958,6 +1958,53 @@ print_lseek(void *cpu_env, const struct syscallname 
> *name,
>  }
>  #endif
>  
> +#ifdef TARGET_NR_truncate
> +static void
> +print_truncate(void *cpu_env, const struct syscallname *name,
> +   abi_long arg0, abi_long arg1, abi_long arg2,
> +   abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +print_syscall_prologue(name);
> +print_string(arg0, 0);
> +print_raw_param(TARGET_ABI_FMT_ld, arg1, 1);
> +print_syscall_epilogue(name);
> +}
> +#endif
> +
> +#ifdef TARGET_NR_truncate64
> +static void
> +print_truncate64(void *cpu_env, const struct syscallname *name,
> + abi_long arg0, abi_long arg1, abi_long arg2,
> + abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +print_syscall_prologue(name);
> +print_string(arg0, 0);
> +if (regpairs_aligned(cpu_env, TARGET_NR_truncate64)) {
> +arg1 = arg2;
> +arg2 = arg3;
> +}
> +print_raw_param("%" PRIu64, target_offset64(arg1, arg2), 1);
> +print_syscall_epilogue(name);
> +}
> +#endif
> +
> +#ifdef TARGET_NR_ftruncate64
> +static void
> +print_ftruncate64(void *cpu_env, const struct syscallname *name,
> +  abi_long arg0, abi_long arg1, abi_long arg2,
> +  abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +print_syscall_prologue(name);
> +print_raw_param("%d", arg0, 0);
> +if 

Re: [PATCH v4 1/5] linux-user: Make cpu_env accessible in strace.c

2020-08-24 Thread Laurent Vivier
Le 11/08/2020 à 18:45, Filip Bozuta a écrit :
> Variable "cpu_env" is used in file "syscall.c" to store
> the information about the cpu environment. This variable
> is used because values of some syscalls can vary between
> cpu architectures. This patch makes the "cpu_env" accessible
> in "strace.c" so it can enable aproppriate "-strace" argument
> printing for these syscalls. This will be a useful addition
> for future "-strace" implementation in QEMU.
> 
> Implementation notes:
> 
> Functions "print_syscall()" and "print_syscall_ret()" which
> are stated and defined in "qemu.h" and "strace.c" respectively
> are used to print syscall arguments before and after syscall
> execution. These functions were changed with addition of a
> new argument "void *cpu_env". Strucute "struct syscallname"
> in "strace.c" is used to store the information about syscalls.
> Fields "call" and "result" represent pointers to functions which
> are used to print syscall arguments before and after execution.
> These fields were also changed with addition of a new "void *"
> argumetn.
> Also, all defined "print_*" and "print_syscall_ret*" functions
> in "strace.c" were changed to have the new "void *cpu_env".
> This was done to not cause build errors (even though none of
> these functions use this argument).
> 
> Signed-off-by: Filip Bozuta 
> Reviewed-by: Laurent Vivier 
> ---
>  linux-user/qemu.h|   4 +-
>  linux-user/strace.c  | 479 ++-
>  linux-user/syscall.c |   5 +-
>  3 files changed, 247 insertions(+), 241 deletions(-)
> 
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 5c964389c1..63ddfe86fd 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -400,10 +400,10 @@ extern long safe_syscall_base(int *pending, long 
> number, ...);
>  int host_to_target_waitstatus(int status);
>  
>  /* strace.c */
> -void print_syscall(int num,
> +void print_syscall(void *cpu_env, int num,
> abi_long arg1, abi_long arg2, abi_long arg3,
> abi_long arg4, abi_long arg5, abi_long arg6);
> -void print_syscall_ret(int num, abi_long ret,
> +void print_syscall_ret(void *cpu_env, int num, abi_long ret,
> abi_long arg1, abi_long arg2, abi_long arg3,
> abi_long arg4, abi_long arg5, abi_long arg6);
>  /**
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index 13981341b3..f0624b6206 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -16,10 +16,10 @@ struct syscallname {
>  int nr;
>  const char *name;
>  const char *format;
> -void (*call)(const struct syscallname *,
> +void (*call)(void *, const struct syscallname *,
>   abi_long, abi_long, abi_long,
>   abi_long, abi_long, abi_long);
> -void (*result)(const struct syscallname *, abi_long,
> +void (*result)(void *, const struct syscallname *, abi_long,
> abi_long, abi_long, abi_long,
> abi_long, abi_long, abi_long);
>  };
> @@ -634,7 +634,7 @@ print_clockid(int clockid, int last)
>  /* select */
>  #ifdef TARGET_NR__newselect
>  static void
> -print_newselect(const struct syscallname *name,
> +print_newselect(void *cpu_env, const struct syscallname *name,
>  abi_long arg1, abi_long arg2, abi_long arg3,
>  abi_long arg4, abi_long arg5, abi_long arg6)
>  {
> @@ -652,7 +652,7 @@ print_newselect(const struct syscallname *name,
>  
>  #ifdef TARGET_NR_semctl
>  static void
> -print_semctl(const struct syscallname *name,
> +print_semctl(void *cpu_env, const struct syscallname *name,
>   abi_long arg1, abi_long arg2, abi_long arg3,
>   abi_long arg4, abi_long arg5, abi_long arg6)
>  {
> @@ -664,7 +664,7 @@ print_semctl(const struct syscallname *name,
>  #endif
>  
>  static void
> -print_execve(const struct syscallname *name,
> +print_execve(void *cpu_env, const struct syscallname *name,
>   abi_long arg1, abi_long arg2, abi_long arg3,
>   abi_long arg4, abi_long arg5, abi_long arg6)
>  {
> @@ -697,7 +697,7 @@ print_execve(const struct syscallname *name,
>  
>  #ifdef TARGET_NR_ipc
>  static void
> -print_ipc(const struct syscallname *name,
> +print_ipc(void *cpu_env, const struct syscallname *name,
>abi_long arg1, abi_long arg2, abi_long arg3,
>abi_long arg4, abi_long arg5, abi_long arg6)
>  {
> @@ -741,9 +741,10 @@ print_syscall_err(abi_long ret)
>  }
>  
>  static void
> -print_syscall_ret_addr(const struct syscallname *name, abi_long ret,
> -   abi_long arg0, abi_long arg1, abi_long arg2,
> -   abi_long arg3, abi_long arg4, abi_long arg5)
> +print_syscall_ret_addr(void *cpu_env, const struct syscallname *name,
> +   abi_long ret, abi_long arg0, abi_long arg1,
> +   abi_long arg2, abi_long arg3, 

Re: [PATCH v2 2/3] linux-user: Add missing termbits types and values definitions

2020-08-24 Thread Laurent Vivier
Le 23/07/2020 à 23:02, Filip Bozuta a écrit :
> This patch introduces missing target types ('target_flag_t', 'target_cc_t',
> 'target_speed_t') in a few 'termibts.h' header files. Also, two missing
> values ('TARGET_IUTF8' and 'TARGET_EXTPROC') were also added. These values
> were also added in file 'syscall.c' in bitmask tables 'iflag_tbl[]' and
> 'lflag_tbl[]' which are used to convert values of 'struct termios' between
> target and host.
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/alpha/termbits.h   |  1 +
>  linux-user/cris/termbits.h| 18 
>  linux-user/hppa/termbits.h| 17 +++
>  linux-user/mips/termbits.h| 17 +++
>  linux-user/ppc/termbits.h | 21 --
>  linux-user/sh4/termbits.h | 19 +
>  linux-user/sparc/termbits.h   | 18 
>  linux-user/sparc64/termbits.h | 18 
>  linux-user/syscall.c  | 34 +++---
>  linux-user/xtensa/termbits.h  | 53 ++-
>  10 files changed, 130 insertions(+), 86 deletions(-)
> 
> diff --git a/linux-user/alpha/termbits.h b/linux-user/alpha/termbits.h
> index a71425174a..4a4b1e96f2 100644
> --- a/linux-user/alpha/termbits.h
> +++ b/linux-user/alpha/termbits.h
> @@ -159,6 +159,7 @@ struct target_termios {
>  #define TARGET_FLUSHO0x0080
>  #define TARGET_PENDIN0x2000
>  #define TARGET_IEXTEN0x0400
> +#define TARGET_EXTPROC  0x1000
>  
>  #define TARGET_FIOCLEX   TARGET_IO('f', 1)
>  #define TARGET_FIONCLEX  TARGET_IO('f', 2)
> diff --git a/linux-user/cris/termbits.h b/linux-user/cris/termbits.h
> index 475ee70fed..0c8d8fc051 100644
> --- a/linux-user/cris/termbits.h
> +++ b/linux-user/cris/termbits.h
> @@ -5,13 +5,17 @@
>  
>  #define TARGET_NCCS 19
>  
> +typedef unsigned char   target_cc_t;/* cc_t */
> +typedef unsigned inttarget_speed_t; /* speed_t */
> +typedef unsigned inttarget_tcflag_t;/* tcflag_t */
> +
>  struct target_termios {
> -unsigned int c_iflag;   /* input mode flags */
> -unsigned int c_oflag;   /* output mode flags */
> -unsigned int c_cflag;   /* control mode flags */
> -unsigned int c_lflag;   /* local mode flags */
> -unsigned char c_line;/* line discipline */
> -unsigned char c_cc[TARGET_NCCS];/* control characters */
> +target_tcflag_t c_iflag;   /* input mode flags */
> +target_tcflag_t c_oflag;   /* output mode flags */
> +target_tcflag_t c_cflag;   /* control mode flags */
> +target_tcflag_t c_lflag;   /* local mode flags */
> +target_cc_t c_line;/* line discipline */
> +target_cc_t c_cc[TARGET_NCCS]; /* control characters */
>  };
>  
>  /* c_iflag bits */
> @@ -29,6 +33,7 @@ struct target_termios {
>  #define TARGET_IXANY   0004000
>  #define TARGET_IXOFF   001
>  #define TARGET_IMAXBEL 002
> +#define TARGET_IUTF8   004
>  
>  /* c_oflag bits */
>  #define TARGET_OPOST   001
> @@ -118,6 +123,7 @@ struct target_termios {
>  #define TARGET_FLUSHO  001
>  #define TARGET_PENDIN  004
>  #define TARGET_IEXTEN  010
> +#define TARGET_EXTPROC 020
>  
>  /* c_cc character offsets */
>  #define TARGET_VINTR 0
> diff --git a/linux-user/hppa/termbits.h b/linux-user/hppa/termbits.h
> index 8fba839dd4..11fd4eed62 100644
> --- a/linux-user/hppa/termbits.h
> +++ b/linux-user/hppa/termbits.h
> @@ -5,13 +5,17 @@
>  
>  #define TARGET_NCCS 19
>  
> +typedef unsigned char   target_cc_t;/* cc_t */
> +typedef unsigned inttarget_speed_t; /* speed_t */
> +typedef unsigned inttarget_tcflag_t;/* tcflag_t */
> +
>  struct target_termios {
> -unsigned int c_iflag;   /* input mode flags */
> -unsigned int c_oflag;   /* output mode flags */
> -unsigned int c_cflag;   /* control mode flags */
> -unsigned int c_lflag;   /* local mode flags */
> -unsigned char c_line;/* line discipline */
> -unsigned char c_cc[TARGET_NCCS];/* control characters */
> +target_tcflag_t c_iflag;   /* input mode flags */
> +target_tcflag_t c_oflag;   /* output mode flags */
> +target_tcflag_t c_cflag;   /* control mode flags */
> +target_tcflag_t c_lflag;   /* local mode flags */
> +target_cc_t c_line;/* line discipline */
> +target_cc_t c_cc[TARGET_NCCS]; /* control characters */
>  };
>  
>  /* c_iflag bits */
> @@ -120,6 +124,7 @@ struct target_termios {
>  #define TARGET_FLUSHO  001
>  #define TARGET_PENDIN  004
>  #define TARGET_IEXTEN  010
> +#define TARGET_EXTPROC 020
>  
>  /* c_cc character offsets */
>  #define TARGET_VINTR0
> diff --git a/linux-user/mips/termbits.h 

Re: [PATCH v2 1/3] linux-user: Add generic 'termbits.h' for some archs

2020-08-24 Thread Laurent Vivier
Le 23/07/2020 à 23:02, Filip Bozuta a écrit :
> This patch introduces a generic 'termbits.h' file for following
> archs: 'aarch64', 'arm', 'i386, 'm68k', 'microblaze', 'nios2',
> 'openrisc', 'riscv', 's390x', 'x86_64'.
> 
> Since all of these archs have the same termios flag values and
> same ioctl_tty numbers, there is no need for a separate 'termbits.h'
> file for each one of them. For that reason one generic 'termbits.h'
> file was added for all of them and an '#include' directive was
> added for this generic file in every arch 'termbits.h' file.
> 
> Also, some of the flag values that were missing were added in this
> generic file so that it matches the generic 'termibts.h' and 'ioctls.h'
> files from the kernel: 'asm-generic/termbits.h' and 'asm-generic/ioctls.h'.
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/aarch64/termbits.h| 228 +-
>  linux-user/arm/termbits.h| 223 +-
>  linux-user/generic/termbits.h| 318 +++
>  linux-user/i386/termbits.h   | 233 +-
>  linux-user/m68k/termbits.h   | 234 +--
>  linux-user/microblaze/termbits.h | 220 +
>  linux-user/nios2/termbits.h  | 228 +-
>  linux-user/openrisc/termbits.h   | 302 +
>  linux-user/riscv/termbits.h  | 228 +-
>  linux-user/s390x/termbits.h  | 289 +---
>  linux-user/tilegx/termbits.h | 276 +--
>  linux-user/x86_64/termbits.h | 254 +---
>  12 files changed, 329 insertions(+), 2704 deletions(-)
>  create mode 100644 linux-user/generic/termbits.h
> 
> diff --git a/linux-user/aarch64/termbits.h b/linux-user/aarch64/termbits.h
> index 0ab448d090..b1d4f4fedb 100644
> --- a/linux-user/aarch64/termbits.h
> +++ b/linux-user/aarch64/termbits.h
> @@ -1,227 +1 @@
> -/* from asm/termbits.h */
> -/* NOTE: exactly the same as i386 */
> -
> -#ifndef LINUX_USER_AARCH64_TERMBITS_H
> -#define LINUX_USER_AARCH64_TERMBITS_H
> -
> -#define TARGET_NCCS 19
> -
> -struct target_termios {
> -unsigned int c_iflag;   /* input mode flags */
> -unsigned int c_oflag;   /* output mode flags */
> -unsigned int c_cflag;   /* control mode flags */
> -unsigned int c_lflag;   /* local mode flags */
> -unsigned char c_line;/* line discipline */
> -unsigned char c_cc[TARGET_NCCS];/* control characters */
> -};
> -
> -/* c_iflag bits */
> -#define TARGET_IGNBRK  001
> -#define TARGET_BRKINT  002
> -#define TARGET_IGNPAR  004
> -#define TARGET_PARMRK  010
> -#define TARGET_INPCK   020
> -#define TARGET_ISTRIP  040
> -#define TARGET_INLCR   100
> -#define TARGET_IGNCR   200
> -#define TARGET_ICRNL   400
> -#define TARGET_IUCLC   0001000
> -#define TARGET_IXON0002000
> -#define TARGET_IXANY   0004000
> -#define TARGET_IXOFF   001
> -#define TARGET_IMAXBEL 002
> -#define TARGET_IUTF8   004
> -
> -/* c_oflag bits */
> -#define TARGET_OPOST   001
> -#define TARGET_OLCUC   002
> -#define TARGET_ONLCR   004
> -#define TARGET_OCRNL   010
> -#define TARGET_ONOCR   020
> -#define TARGET_ONLRET  040
> -#define TARGET_OFILL   100
> -#define TARGET_OFDEL   200
> -#define TARGET_NLDLY   400
> -#define   TARGET_NL0   000
> -#define   TARGET_NL1   400
> -#define TARGET_CRDLY   0003000
> -#define   TARGET_CR0   000
> -#define   TARGET_CR1   0001000
> -#define   TARGET_CR2   0002000
> -#define   TARGET_CR3   0003000
> -#define TARGET_TABDLY  0014000
> -#define   TARGET_TAB0  000
> -#define   TARGET_TAB1  0004000
> -#define   TARGET_TAB2  001
> -#define   TARGET_TAB3  0014000
> -#define   TARGET_XTABS 0014000
> -#define TARGET_BSDLY   002
> -#define   TARGET_BS0   000
> -#define   TARGET_BS1   002
> -#define TARGET_VTDLY   004
> -#define   TARGET_VT0   000
> -#define   TARGET_VT1   004
> -#define TARGET_FFDLY   010
> -#define   TARGET_FF0   000
> -#define   TARGET_FF1   010
> -
> -/* c_cflag bit meaning */
> -#define TARGET_CBAUD   0010017
> -#define  TARGET_B0 000 /* hang up */
> -#define  TARGET_B50001
> -#define  TARGET_B75002
> -#define  TARGET_B110   003
> -#define  TARGET_B134   004
> -#define  TARGET_B150   005
> -#define  TARGET_B200   006
> -#define  TARGET_B300   007
> -#define  TARGET_B600   010
> -#define  TARGET_B1200  011
> -#define  TARGET_B1800  012
> -#define  TARGET_B2400  013
> -#define  TARGET_B4800  014
> -#define  TARGET_B9600  015
> -#define  TARGET_B19200 016
> -#define  TARGET_B38400 017
> -#define TARGET_EXTA B19200
> -#define TARGET_EXTB B38400
> -#define TARGET_CSIZE   060
> -#define   TARGET_CS5   000
> -#define   TARGET_CS6   

Re: [PATCH v2] linux-user: syscall: ioctls: support DRM_IOCTL_I915_GETPARAM

2020-08-24 Thread Laurent Vivier
Le 02/08/2020 à 15:39, cheng...@emindsoft.com.cn a écrit :
> From: Chen Gang 
> 
> Another DRM_IOCTL_I915 patches will be sent next.
> 
> Signed-off-by: Chen Gang 
> ---
>  linux-user/ioctls.h|  3 +++
>  linux-user/syscall.c   | 35 +++
>  linux-user/syscall_defs.h  |  8 
>  linux-user/syscall_types.h |  4 
>  4 files changed, 50 insertions(+)
> 
> diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
> index 0713ae1311..e2fc09b5a5 100644
> --- a/linux-user/ioctls.h
> +++ b/linux-user/ioctls.h
> @@ -581,6 +581,9 @@
>  #ifdef HAVE_DRM_H
>IOCTL_SPECIAL(DRM_IOCTL_VERSION, IOC_RW, do_ioctl_drm,
>  MK_PTR(MK_STRUCT(STRUCT_drm_version)))
> +
> +  IOCTL_SPECIAL(DRM_IOCTL_I915_GETPARAM, IOC_RW, do_ioctl_drm_i915,
> +MK_PTR(MK_STRUCT(STRUCT_drm_i915_getparam)))
>  #endif
>  
>  #ifdef TARGET_TIOCSTART
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 945fc25279..b0e15f373c 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -114,6 +114,7 @@
>  #include 
>  #ifdef HAVE_DRM_H
>  #include 
> +#include 
>  #endif
>  #include "linux_loop.h"
>  #include "uname.h"
> @@ -5413,6 +5414,40 @@ static abi_long do_ioctl_drm(const IOCTLEntry *ie, 
> uint8_t *buf_temp,
>  return -TARGET_ENOSYS;
>  }
>  
> +static abi_long do_ioctl_drm_i915_getparam(const IOCTLEntry *ie,
> +   struct drm_i915_getparam *gparam,
> +   int fd, abi_long arg)
> +{
> +abi_long ret;
> +int value;
> +struct target_drm_i915_getparam *target_gparam;
> +
> +if (!lock_user_struct(VERIFY_READ, target_gparam, arg, 0)) {
> +return -TARGET_EFAULT;
> +}
> +
> +__get_user(gparam->param, _gparam->param);
> +gparam->value = 
> +ret = get_errno(safe_ioctl(fd, ie->host_cmd, gparam));
> +put_user_s32(value, target_gparam->value);
> +
> +unlock_user_struct(target_gparam, arg, 0);
> +return ret;
> +}
> +
> +static abi_long do_ioctl_drm_i915(const IOCTLEntry *ie, uint8_t *buf_temp,
> +  int fd, int cmd, abi_long arg)
> +{
> +switch (ie->host_cmd) {
> +case DRM_IOCTL_I915_GETPARAM:
> +return do_ioctl_drm_i915_getparam(ie,
> +  (struct drm_i915_getparam 
> *)buf_temp,
> +  fd, arg);
> +default:
> +return -TARGET_ENOSYS;
> +}
> +}
> +
>  #endif
>  
>  IOCTLEntry ioctl_entries[] = {
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 3c261cff0e..5a1692aa26 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -1170,6 +1170,9 @@ struct target_rtc_pll_info {
>  /* drm ioctls */
>  #define TARGET_DRM_IOCTL_VERSION  TARGET_IOWRU('d', 0x00)
>  
> +/* drm i915 ioctls */
> +#define TARGET_DRM_IOCTL_I915_GETPARAM  TARGET_IOWRU('d', 0x46)
> +
>  /* from asm/termbits.h */
>  
>  #define TARGET_NCC 8
> @@ -2613,6 +2616,11 @@ struct target_drm_version {
>  abi_ulong desc;
>  };
>  
> +struct target_drm_i915_getparam {
> +int param;
> +abi_ulong value;
> +};
> +
>  #include "socket.h"
>  
>  #include "errno_defs.h"
> diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
> index 3f1f033464..12bf3484e2 100644
> --- a/linux-user/syscall_types.h
> +++ b/linux-user/syscall_types.h
> @@ -325,6 +325,10 @@ STRUCT(drm_version,
> TYPE_ULONG, /* desc_len */
> TYPE_PTRVOID) /* desc */
>  
> +STRUCT(drm_i915_getparam,
> +   TYPE_INT, /* param */
> +   TYPE_PTRVOID) /* value */
> +
>  STRUCT(file_clone_range,
> TYPE_LONGLONG, /* src_fd */
> TYPE_ULONGLONG, /* src_offset */
> 


Applied to my linux-user-for-5.2 branch.

Thanks,
Laurent




Re: [PATCH] linux-user: Fix 'clock_nanosleep()' implementation

2020-08-24 Thread Laurent Vivier
Le 27/07/2020 à 22:13, Filip Bozuta a écrit :
> Implementation of syscall 'clock_nanosleep()' in 'syscall.c' uses
> functions 'target_to_host_timespec()' and 'host_to_target_timespec()'
> to transfer the value of 'struct timespec' between target and host.
> However, the implementation doesn't check whether this conversion
> succeeds and thus can return an unaproppriate error instead of 'EFAULT'
> that is expected. This was confirmed with the modified LTP test suite
> where testcases with bad 'struct timespec' adress for 'clock_nanosleep()'
> were added. This modified LTP suite can be found at:
> https://github.com/bozutaf/ltp
> 
> (Patch with this new test case will be sent to LTP mailing list soon)
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/syscall.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index f5c4f6b95d..9f06dde947 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -11828,7 +11828,9 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  case TARGET_NR_clock_nanosleep:
>  {
>  struct timespec ts;
> -target_to_host_timespec(, arg3);
> +if (target_to_host_timespec(, arg3)) {
> +return -TARGET_EFAULT;
> +}
>  ret = get_errno(safe_clock_nanosleep(arg1, arg2,
>   , arg4 ?  : NULL));
>  /*
> @@ -11836,8 +11838,9 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>   * with error -TARGET_EINTR and if arg4 is not NULL and arg2 is not
>   * TIMER_ABSTIME, it returns the remaining unslept time in arg4.
>   */
> -if (ret == -TARGET_EINTR && arg4 && arg2 != TIMER_ABSTIME) {
> -host_to_target_timespec(arg4, );
> +if (ret == -TARGET_EINTR && arg4 && arg2 != TIMER_ABSTIME &&
> +host_to_target_timespec(arg4, )) {
> +  return -TARGET_EFAULT;
>  }
>  
>  return ret;
> 

Applied to my linux-user-for-5.2 branch.

Thanks,
Laurent




[Bug 1884719] Re: Function not implemented when using libaio

2020-08-24 Thread Laurent Vivier
The code in my branch has two problems:

- it doesn't work if the host is 64bit and the target 32bit (because the
context id returned by the host is in fact a virtual address and the
data type is long, so the context_id (host long) doesn't fit in target
context_id (target long).

- I played with some stress tests and at some points it crashes.

I don't have enough time to work on this for the moment.

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

Title:
  Function not implemented when using libaio

Status in QEMU:
  New

Bug description:
  Hello

  I experience "Function not implemented" errors when trying to use
  Linux libaio library in foreign architecture, e.g. aarch64.

  I've faced this problem while using 
https://github.com/multiarch/qemu-user-static, i.e. Docker+QEMU. 
  I understand that I do not use plain QEMU and you may count this report as a 
"distribution of QEMU"! Just let me know what are the steps to test it with 
plain QEMU and I will test and update this ticket!

  
  Here are the steps to reproduce the issue:

  1) On x86_64 machine register QEMU:

  `docker run -it --rm --privileged multiarch/qemu-user-static
  --reset --credential yes --persistent yes`

  2) Start a Docker image with foreign CPU architecture, e.g. aarch64

  `docker run -it arm64v8/centos:8 bash`

  3) Inside the Docker container install GCC and libaio

  `yum install gcc libaio libaio-devel`

  4) Compile the following C program

  ```
  #include 
  #include 
  #include 
  #include 

  struct io_control {
  io_context_t ioContext;
  };

  int main() {
  int queueSize = 10;

  struct io_control * theControl = (struct io_control *) 
malloc(sizeof(struct io_control));
  if (theControl == NULL) {
  printf("theControl is NULL");
  return 123;
  }

  int res = io_queue_init(queueSize, >ioContext);
  io_queue_release(theControl->ioContext);
  free(theControl);
  printf("res is: %d", res);
  }
  ```

  ```
  cat > test.c
  [PASTE THE CODE ABOVE HERE]
  ^D
  ```

  `gcc test.c -o out -laio && ./out`

  
  When executed directly on aarch64 machine (i.e. without emulation) or on 
x86_64 Docker image (e.g. centos:8) it prints `res is: 0`, i.e. it successfully 
initialized a LibAIO queue.

  But when executed on Docker image with foreign/emulated CPU
  architecture it prints `res is: -38` (ENOSYS). `man io_queue_init`
  says that error ENOSYS is returned when "Not implemented."

  Environment:

  QEMU version: 5.0.0.2  
(https://github.com/multiarch/qemu-user-static/blob/master/.travis.yml#L24-L28)
  Container application: Docker
  Output of `docker --version`:

  ```
  Client:
   Version:   19.03.8
   API version:   1.40
   Go version:go1.13.8
   Git commit:afacb8b7f0
   Built: Wed Mar 11 23:42:35 2020
   OS/Arch:   linux/amd64
   Experimental:  false

  Server:
   Engine:
Version:  19.03.8
API version:  1.40 (minimum version 1.12)
Go version:   go1.13.8
Git commit:   afacb8b7f0
Built:Wed Mar 11 22:48:33 2020
OS/Arch:  linux/amd64
Experimental: false
   containerd:
Version:  1.3.3-0ubuntu2
GitCommit:
   runc:
Version:  spec: 1.0.1-dev
GitCommit:
   docker-init:
Version:  0.18.0
GitCommit:
  ```

  Same happens with Ubuntu (arm64v8/ubuntu:focal).

  I've tried to `strace` it but :

  ```
  /usr/bin/strace: ptrace(PTRACE_TRACEME, ...): Function not implemented
  /usr/bin/strace: PTRACE_SETOPTIONS: Function not implemented
  /usr/bin/strace: detach: waitpid(112): No child processes
  /usr/bin/strace: Process 112 detached
  ```

  Here are the steps to reproduce the problem with strace:

   ```
   docker run --rm -it --security-opt seccomp:unconfined --security-opt 
apparmor:unconfined --privileged --cap-add ALL arm64v8/centos:8 bash

   yum install -y strace`

   strace echo Test
   ```

  Note: I used --privileged, disabled seccomp and apparmor, and added
  all capabilities

  Disabling security solves the "Permission denied" problem but then
  comes the "Not implemented" one.

  
  Any idea what could be the problem and how to work it around ?
  I've googled a lot but I wasn't able to find any problems related to libaio 
on QEMU.

  Thank you!
  Martin

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



Re: [PATCH v3] linux-user: Fix 'semop()' and 'semtimedop()' implementation

2020-08-24 Thread Laurent Vivier
Le 18/08/2020 à 20:07, Filip Bozuta a écrit :
> The implementations of syscalls 'semop()' and 'semtimedop()' in
> file 'syscall.c' use function 'target_to_host_sembuf()' to convert
> values of 'struct sembuf' from host to target. However, before this
> conversion it should be check whether the number of semaphore operations
> 'nsops' is not bigger than maximum allowed semaphor operations per
> syscall: 'SEMOPM'. In these cases, errno 'E2BIG' ("Arg list too long")
> should be set. But the implementation will set errno 'EFAULT' ("Bad address")
> in this case since the conversion from target to host in this case fails.
> 
> This was confirmed with the LTP test for 'semop()' ('ipc/semop/semop02') in
> test case where 'nsops' is greater than SEMOPM with unaproppriate errno 
> EFAULT:
> 
> semop02.c:130: FAIL: semop failed unexpectedly; expected: E2BIG: EFAULT (14)
> 
> This patch changes this by adding a check whether 'nsops' is bigger than
> 'SEMOPM' before the conversion function 'target_to_host_sembuf()' is called.
> After the changes from this patch, the test works fine along with the other
> LTP testcases for 'semop()'):
> 
> semop02.c:126: PASS: semop failed as expected: E2BIG (7)
> 
> Implementation notes:
> 
> A target value ('TARGET_SEMOPM') was added for 'SEMOPM' as to be sure
> in case the value is not available for some targets.
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/syscall.c  | 13 +++--
>  linux-user/syscall_defs.h |  2 ++
>  2 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 1211e759c2..e4d12c29d3 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -3904,7 +3904,7 @@ static inline abi_long do_semtimedop(int semid,
>   unsigned nsops,
>   abi_long timeout)
>  {
> -struct sembuf sops[nsops];
> +struct sembuf *sops;
>  struct timespec ts, *pts = NULL;
>  abi_long ret;
>  
> @@ -3915,8 +3915,16 @@ static inline abi_long do_semtimedop(int semid,
>  }
>  }
>  
> -if (target_to_host_sembuf(sops, ptr, nsops))
> +if (nsops > TARGET_SEMOPM) {
> +return -TARGET_E2BIG;
> +}
> +
> +sops = g_new(struct sembuf, nsops);
> +
> +if (target_to_host_sembuf(sops, ptr, nsops)) {
> +g_free(sops);
>  return -TARGET_EFAULT;
> +}
>  
>  ret = -TARGET_ENOSYS;
>  #ifdef __NR_semtimedop
> @@ -3928,6 +3936,7 @@ static inline abi_long do_semtimedop(int semid,
>   SEMTIMEDOP_IPC_ARGS(nsops, sops, 
> (long)pts)));
>  }
>  #endif
> +g_free(sops);
>  return ret;
>  }
>  #endif
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 3c261cff0e..f7f77346be 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -46,6 +46,8 @@
>  #define IPCOP_shmget 23
>  #define IPCOP_shmctl 24
>  
> +#define TARGET_SEMOPM 500
> +
>  /*
>   * The following is for compatibility across the various Linux
>   * platforms.  The i386 ioctl numbering scheme doesn't really enforce
> 

Applied to my linux-user-for-5.2 branch.

Thanks,
Laurent




Re: meson: problems building under msys2/mingw-w64 native

2020-08-24 Thread Mark Cave-Ayland
On 24/08/2020 14:18, Paolo Bonzini wrote:

> Il lun 24 ago 2020, 13:06 Mark Cave-Ayland  > ha scritto:
> 
> Within configure the default location to ninja is overridden via
> "NINJA=$PWD/ninjatool $meson setup ..." and subprocess.Popen() sends the 
> filename to
> Win32's CreateProcess() which fails because ninjatool is not a native 
> executable but
> a shell script. Any thoughts as to what would be the best solution here?
> 
> 
> The simplest stopgap solution is to remove the NINJA= override and install 
> ninja. It
> will only be used to build the compile_commands.json file.

I can confirm this works - I changed "NINJA=$PWD/ninjatool $meson setup ..." to
"NINJA=ninja $meson setup ..." and that allows configure to complete 
successfully.
However running make afterwards fails with this error:

/mingw64/bin/python3 -B /home/Mark/qemu/scripts/qapi-gen.py -o tests -p "test-"
/home/Mark/qemu/tests/qapi-schema/qapi-schema-test.json
Makefile.ninja:26: *** multiple target patterns.  Stop.
make[1]: Leaving directory '/home/Mark/qemu/build'
make: *** [GNUmakefile:11: all] Error 2

Looking at build/Makefile.ninja there seems to be an escaping issue with the 
"C:\"
being replaced with "C$$:" throughout the file:

PHONY:
version.rc_version.o: ../version.rc C$$:/msys64/mingw64/bin/windres.EXE
../pc-bios/qemu-nsis.ico | ; ${ninja-command}
...
...

I was able to fix this using the substitution '%s/C\$\$:/C:/g' in vim which 
allows
make to get much further:

"cc" "-Iqemu-system-ppc.exe.p" "-I." "-I.." "-Iqapi" "-Itrace" "-Iui" 
"-Iui/shader"
"-I/home/Mark/qemu/dtc/libfdt" "-I/home/Mark/qemu/capstone/include"
"-I/home/Mark/qemu/slirp/src" "-I/home/Mark/qemu/build/slirp/src"
"-IC:/msys64/mingw64/include/libpng16" "-IC:/msys64/mingw64/include"
"-IC:/msys64/mingw64/include/pixman-1" "-IC:/msys64/mingw64/include/glib-2.0"
"-IC:/msys64/mingw64/lib/glib-2.0/include" "-fdiagnostics-color=always" "-pipe"
"-Wall" "-Winvalid-pch" "-Werror" "-std=gnu99" "-O2" "-g" "-Werror"
"-U_FORTIFY_SOURCE" "-D_FORTIFY_SOURCE=2" "-pthread" "-mms-bitfields" "-m64" 
"-mcx16"
"-D_GNU_SOURCE" "-D_FILE_OFFSET_BITS=64" "-D_LARGEFILE_SOURCE" 
"-Wstrict-prototypes"
"-Wredundant-decls" "-Wundef" "-Wwrite-strings" "-Wmissing-prototypes"
"-fno-strict-aliasing" "-fno-common" "-fwrapv" "-Wold-style-declaration"
"-Wold-style-definition" "-Wtype-limits" "-Wformat-security" "-Wformat-y2k"
"-Winit-self" "-Wignored-qualifiers" "-Wempty-body" "-Wnested-externs"
"-Wendif-labels" "-Wexpansion-to-defined" "-Wno-missing-include-dirs"
"-Wno-shift-negative-value" "-Wno-psabi" "-fstack-protector-strong" "-iquote"
"/home/Mark/qemu/tcg/i386" "-iquote" "." "-iquote" "/home/Mark/qemu" "-iquote"
"/home/Mark/qemu/accel/tcg" "-iquote" "/home/Mark/qemu/include" "-iquote"
"/home/Mark/qemu/disas/libvixl" "-fPIE" "-mms-bitfields" "-mms-bitfields"
"-Dmain=SDL_main" "-isystemC:/msys64/mingw64/include/SDL2" "-Wno-undef"
"-DNEED_CPU_H" "-DCONFIG_TARGET=\"ppc-softmmu-config-target.h\""
"-DCONFIG_DEVICES=\"ppc-softmmu-config-devices.h\"" -MD -MQ
qemu-system-ppc.exe.p/softmmu_main.c.obj -MF
"qemu-system-ppc.exe.p/softmmu_main.c.obj.d" -o
qemu-system-ppc.exe.p/softmmu_main.c.obj "-c" ../softmmu/main.c -MP
../softmmu/main.c:31:10: fatal error: SDL.h: No such file or directory
   31 | #include 
  |  ^~~
compilation terminated.
make[1]: *** [Makefile.ninja:1402: qemu-system-ppc.exe.p/softmmu_main.c.obj] 
Error 1

After checking carefully I spotted the problem is with
"-isystemC:/msys64/mingw64/include/SDL2" not being quoted correctly at multiple
places in Makefile.ninja.

Again I was able to fix this in vim using the substitution 
'%s/isystemC:/isystem"
"C:/g' to turn "-isystemC:/msys64/mingw64/include/SDL2" into "-isystem"
"C:/msys64/mingw64/include/SDL2".

With this I can get all the way to the link phase so I think it's fairly close. 
I'm
not sure whether these escaping/quoting problems are with meson or the way in 
which
configure is using it?


ATB,

Mark.



Re: [PATCH 0/1] qcow2: Skip copy-on-write when allocating a zero cluster

2020-08-24 Thread Alberto Garcia
On Sun 23 Aug 2020 11:59:07 PM CEST, Dave Chinner wrote:
>> >> Option 4 is described above as initial file preallocation whereas
>> >> option 1 is per 64k cluster prealloc. Prealloc mode mixup aside, Berto
>> >> is reporting that the initial file preallocation mode is slower than
>> >> the per cluster prealloc mode. Berto, am I following that right?
>> 
>> After looking more closely at the data I can see that there is a peak of
>> ~30K IOPS during the first 5 or 6 seconds and then it suddenly drops to
>> ~7K for the rest of the test.
>
> How big is the filesystem, how big is the log? (xfs_info output,
> please!)

The size of the filesystem is 126GB and here's the output of xfs_info:

meta-data=/dev/vg/test   isize=512agcount=4, agsize=8248576 blks
 =   sectsz=512   attr=2, projid32bit=1
 =   crc=1finobt=1, sparse=1, rmapbt=0
 =   reflink=0
data =   bsize=4096   blocks=32994304, imaxpct=25
 =   sunit=0  swidth=0 blks
naming   =version 2  bsize=4096   ascii-ci=0, ftype=1
log  =internal log   bsize=4096   blocks=16110, version=2
 =   sectsz=512   sunit=0 blks, lazy-count=1
realtime =none   extsz=4096   blocks=0, rtextents=0

>> I was running fio with --ramp_time=5 which ignores the first 5 seconds
>> of data in order to let performance settle, but if I remove that I can
>> see the effect more clearly. I can observe it with raw files (in 'off'
>> and 'prealloc' modes) and qcow2 files in 'prealloc' mode. With qcow2 and
>> preallocation=off the performance is stable during the whole test.
>
> What does "preallocation=off" mean again? Is that using
> fallocate(ZERO_RANGE) prior to the data write rather than
> preallocating the metadata/entire file?

Exactly, it means that. One fallocate() call before each data write
(unless the area has been allocated by a previous write).

> If so, I would expect the limiting factor is the rate at which IO can
> be issued because of the fallocate() triggered pipeline bubbles. That
> leaves idle device time so you're not pushing the limits of the
> hardware and hence none of the behaviours above will be evident...

The thing is that with raw (i.e. non-qcow2) images the number of IOPS is
similar, but in that case there are no fallocate() calls, only the data
writes.

Berto



Re: [PATCH v3 1/2] linux-user: Fix 'mq_timedsend()' and 'mq_timedreceive()'

2020-08-24 Thread Laurent Vivier
Le 24/08/2020 à 21:37, Filip Bozuta a écrit :
> Implementations of syscalls 'mq_timedsend()' and 'mq_timedreceive()'
> in 'syscall.c' use functions 'target_to_host_timespec()' and
> 'host_to_target_timespec()' to transfer the value of 'struct timespec'
> between target and host. However, the implementations don't check whether
> this conversion succeeds and thus can cause an unaproppriate error instead
> of the 'EFAULT (Bad address)' which is supposed to be set if the conversion
> from target to host fails. This was confirmed with the modified LTP
> test suite where test cases with a bad adress for 'timespec' were
> added. This modified test suite can be found at:
> https://github.com/bozutaf/ltp
> 
> Without the changes from this patch the bad adress testcase for 
> 'mq_timedsend()'
> succeds unexpectedly, while the test returns errno 'ETIMEOUT' for
> 'mq_timedreceive()':
> 
> mq_timedsend01.c:190: FAIL: mq_timedsend() returned 0, expected -1: SUCCESS 
> (0)
> mq_timedreceive01.c:178: FAIL: mq_timedreceive() failed unexpectedly,
> expected EFAULT: ETIMEDOUT (110)
> 
> After the changes from this patch, testcases for both syscalls fail with 
> EFAULT
> as expected, which is the same test result that is received with native 
> execution:
> 
> mq_timedsend01.c:187: PASS: mq_timedsend() failed expectedly: EFAULT (14)
> mq_timedreceive01.c:180: PASS: mq_timedreceive() failed expectedly: EFAULT 
> (14)
> 
> (Patch with this new test case will be sent to LTP mailing list soon)
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/syscall.c | 16 
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 05f03919ff..4ee1de6e65 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -11817,9 +11817,13 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  
>  p = lock_user (VERIFY_READ, arg2, arg3, 1);
>  if (arg5 != 0) {
> -target_to_host_timespec(, arg5);
> +if (target_to_host_timespec(, arg5)) {
> +return -TARGET_EFAULT;
> +}
>  ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, ));
> -host_to_target_timespec(arg5, );
> +if (!is_error(ret) && host_to_target_timespec(arg5, )) {
> +return -TARGET_EFAULT;
> +}
>  } else {
>  ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, 
> NULL));
>  }
> @@ -11836,10 +11840,14 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  
>  p = lock_user (VERIFY_READ, arg2, arg3, 1);
>  if (arg5 != 0) {
> -target_to_host_timespec(, arg5);
> +if (target_to_host_timespec(, arg5)) {
> +return -TARGET_EFAULT;
> +}
>  ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
>   , ));
> -host_to_target_timespec(arg5, );
> +if (!is_error(ret) && host_to_target_timespec(arg5, )) {
> +return -TARGET_EFAULT;
> +}
>  } else {
>  ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
>   , NULL));
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH 1/3] linux-user: Modify 'sendmmsg()' and 'recvmmsg()' implementation

2020-08-24 Thread Laurent Vivier
Le 31/07/2020 à 21:06, Filip Bozuta a écrit :
> Implementations of 'sendmmsg()' and 'recvmmsg()' in 'syscall.c' use
> a loop over a host command of 'sendmsg()' and 'recvmsg()' respectively
> to send/receive individual messages from a socket. This patch changes
> these implementations to use the host commands 'sendmmsg()' and 'recvmmsg()'
> to send all messages without looping over 'sendmsg()' and 'recvmsg()'.
> 
> Implementation notes:
> 
> Parts of code from 'do_sendrecvmsg_locked()', that are used to transfer
> values of 'struct msghdr' between host and target, were moved to separate
> functions 'target_to_host_msghdr()' and 'host_to_target_msghdr()'. These
> functions are used in 'do_sendrecvmmsg()' to transfer the data of each
> individual 'struct msghdr' from the 'msgvec' argument. Memory allocation
> for the 'iovec' field is done outside of these functions as to ensure that
> the memory is freed after the syscall execution.
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/syscall.c | 243 ---
>  1 file changed, 159 insertions(+), 84 deletions(-)
> 

I'm sorry but after studying the changes needed I think it's better to
keep the existing code.

For instance, if we have a EFAULT (or EMSGSIZE) while reading the iovec
we must stop to send  data and exit with the error code.

Your code correctly manages the detection of the error and stops the
conversion of the iovec. Then it uses the converted iovecs with
sendmmsg() and recvmmsg(), but "ret" is overwritten and the error is lost.

So, in the end, and as it is done in kernel, the best is to loop around
sendmsg()... and this is what the existing code does.

Thanks,
Laurent



QEMU | Pipeline #181452066 has failed for master | 30aa1944

2020-08-24 Thread GitLab via


Your pipeline has failed.

Project: QEMU ( https://gitlab.com/qemu-project/qemu )
Branch: master ( https://gitlab.com/qemu-project/qemu/-/commits/master )

Commit: 30aa1944 ( 
https://gitlab.com/qemu-project/qemu/-/commit/30aa19446d82358a30eac3b556b4d6641e00b7c1
 )
Commit Message: Merge remote-tracking branch 'remotes/cschoeneb...
Commit Author: Peter Maydell ( https://gitlab.com/pm215 )

Pipeline #181452066 ( 
https://gitlab.com/qemu-project/qemu/-/pipelines/181452066 ) triggered by Alex 
Bennée ( https://gitlab.com/stsquad )
had 1 failed build.

Job #701254385 ( https://gitlab.com/qemu-project/qemu/-/jobs/701254385/raw )

Stage: test
Name: acceptance-system-fedora
Trace: 19:43:54 ERROR| 
19:43:54 ERROR| Reproduced traceback from: 
/builds/qemu-project/qemu/build/tests/venv/lib64/python3.8/site-packages/avocado/core/test.py:846
19:43:54 ERROR| Traceback (most recent call last):
19:43:54 ERROR|   File 
"/builds/qemu-project/qemu/build/tests/acceptance/avocado_qemu/__init__.py", 
line 171, in setUp
19:43:54 ERROR| self.cancel("No QEMU binary defined or found in the build 
tree")
19:43:54 ERROR|   File 
"/builds/qemu-project/qemu/build/tests/venv/lib64/python3.8/site-packages/avocado/core/test.py",
 line 1081, in cancel
19:43:54 ERROR| raise exceptions.TestCancel(message)
19:43:54 ERROR| avocado.core.exceptions.TestCancel: No QEMU binary defined or 
found in the build tree
19:43:54 ERROR| 
19:43:54 ERROR| CANCEL 
31-tests/acceptance/vnc.py:Vnc.test_change_password_requires_a_password -> 
TestCancel: No QEMU binary defined or found in the build tree
19:43:54 INFO | 
19:43:54 DEBUG| PARAMS (key=arch, path=*, default=None) => None
19:43:54 DEBUG| PARAMS (key=machine, path=*, default=None) => None
19:43:54 DEBUG| PARAMS (key=qemu_bin, path=*, default=None) => None
19:43:54 ERROR| 
19:43:54 ERROR| Reproduced traceback from: 
/builds/qemu-project/qemu/build/tests/venv/lib64/python3.8/site-packages/avocado/core/test.py:846
19:43:54 ERROR| Traceback (most recent call last):
19:43:54 ERROR|   File 
"/builds/qemu-project/qemu/build/tests/acceptance/avocado_qemu/__init__.py", 
line 171, in setUp
19:43:54 ERROR| self.cancel("No QEMU binary defined or found in the build 
tree")
19:43:54 ERROR|   File 
"/builds/qemu-project/qemu/build/tests/venv/lib64/python3.8/site-packages/avocado/core/test.py",
 line 1081, in cancel
19:43:54 ERROR| raise exceptions.TestCancel(message)
19:43:54 ERROR| avocado.core.exceptions.TestCancel: No QEMU binary defined or 
found in the build tree
19:43:54 ERROR| 
19:43:54 ERROR| CANCEL 32-tests/acceptance/vnc.py:Vnc.test_change_password -> 
TestCancel: No QEMU binary defined or found in the build tree
19:43:54 INFO | 
$ du -chs ${CI_PROJECT_DIR}/avocado-cache
323M/builds/qemu-project/qemu/avocado-cache
323Mtotal
section_end:1598298236:after_script
ERROR: Job failed: exit code 1



-- 
You're receiving this email because of your account on gitlab.com.





Re: [PATCH v5 0/8] Remove EPYC mode apicid decode and use generic decode

2020-08-24 Thread Babu Moger
Hi Dave,

On 8/24/20 1:41 PM, Dr. David Alan Gilbert wrote:
> * Babu Moger (babu.mo...@amd.com) wrote:
>> To support some of the complex topology, we introduced EPYC mode apicid 
>> decode.
>> But, EPYC mode decode is running into problems. Also it can become quite a
>> maintenance problem in the future. So, it was decided to remove that code and
>> use the generic decode which works for majority of the topology. Most of the
>> SPECed configuration would work just fine. With some non-SPECed user inputs,
>> it will create some sub-optimal configuration.
>> Here is the discussion thread.
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fqemu-devel%2Fc0bcc1a6-1d84-a6e7-e468-d5b437c1b254%40amd.com%2Fdata=02%7C01%7Cbabu.moger%40amd.com%7C74d90724af9c4adcc75008d8485d4d16%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637338912853492167sdata=GTsMKcpeYXAA0CvpLTirPHKdNSdlJE3RuPjCtSyWtGQ%3Dreserved=0
>>
>> This series removes all the EPYC mode specific apicid changes and use the 
>> generic
>> apicid decode.
> 
> Hi Babu,
>   This does simplify things a lot!
> One worry, what happens about a live migration of a VM from an old qemu
> that was using the node-id to a qemu with this new scheme?

The node_id which we introduced was only used internally. This wasn't
exposed outside. I don't think live migration will be an issue.



[PATCH v3 2/2] linux-user: Add support for 'mq_timedsend_time64()' and 'mq_timedreceive_time64()'

2020-08-24 Thread Filip Bozuta
This patch implements functionality for following time64 syscalls:

*mq_timedsend_time64()

This is a year 2038 safe vairant of syscall:

int mq_timedsend(mqd_t mqdes, const char *msg_ptr,
 size_t msg_len, unsigned int msg_prio,
 const struct timespec *abs_timeout)
--send a message to a message queue--
man page: https://www.man7.org/linux/man-pages/man2/mq_timedsend.2.html

*mq_timedreceive_time64()

This is a year 2038 safe variant of syscall:

ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr,
size_t msg_len, unsigned int *msg_prio,
const struct timespec *abs_timeout)
--receive a message from a message queue--
man page: https://man7.org/linux/man-pages/man3/mq_receive.3.html

Implementation notes:

These syscalls were implemented in similar ways like
'mq_timedsend()' and 'mq_timedreceive' except that
functions 'target_to_host_timespec64()' and
'host_to_target_timespec64()' were used to convert
values of 'struct timespec' between host and target.

Signed-off-by: Filip Bozuta 
Reviewed-by: Laurent Vivier 
---
 linux-user/syscall.c | 58 +---
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4ee1de6e65..3331ec9fea 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -829,11 +829,13 @@ safe_syscall5(int, msgrcv, int, msgid, void *, msgp, 
size_t, sz,
 safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
   unsigned, nsops, const struct timespec *, timeout)
 #endif
-#ifdef TARGET_NR_mq_timedsend
+#if defined(TARGET_NR_mq_timedsend) || \
+defined(TARGET_NR_mq_timedsend_time64)
 safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
   size_t, len, unsigned, prio, const struct timespec *, timeout)
 #endif
-#ifdef TARGET_NR_mq_timedreceive
+#if defined(TARGET_NR_mq_timedreceive) || \
+defined(TARGET_NR_mq_timedreceive_time64)
 safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
   size_t, len, unsigned *, prio, const struct timespec *, timeout)
 #endif
@@ -1243,7 +1245,9 @@ static inline abi_long target_to_host_timespec(struct 
timespec *host_ts,
 }
 #endif
 
-#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64)
+#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64) || \
+defined(TARGET_NR_mq_timedsend_time64) || \
+defined(TARGET_NR_mq_timedreceive_time64)
 static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
  abi_ulong target_addr)
 {
@@ -11831,6 +11835,27 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 return ret;
 #endif
+#ifdef TARGET_NR_mq_timedsend_time64
+case TARGET_NR_mq_timedsend_time64:
+{
+struct timespec ts;
+
+p = lock_user(VERIFY_READ, arg2, arg3, 1);
+if (arg5 != 0) {
+if (target_to_host_timespec64(, arg5)) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, ));
+if (!is_error(ret) && host_to_target_timespec64(arg5, )) {
+return -TARGET_EFAULT;
+}
+} else {
+ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
+}
+unlock_user(p, arg2, arg3);
+}
+return ret;
+#endif
 
 #ifdef TARGET_NR_mq_timedreceive
 case TARGET_NR_mq_timedreceive:
@@ -11858,6 +11883,33 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 return ret;
 #endif
+#ifdef TARGET_NR_mq_timedreceive_time64
+case TARGET_NR_mq_timedreceive_time64:
+{
+struct timespec ts;
+unsigned int prio;
+
+p = lock_user(VERIFY_READ, arg2, arg3, 1);
+if (arg5 != 0) {
+if (target_to_host_timespec64(, arg5)) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
+ , ));
+if (!is_error(ret) && host_to_target_timespec64(arg5, )) {
+return -TARGET_EFAULT;
+}
+} else {
+ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
+ , NULL));
+}
+unlock_user(p, arg2, arg3);
+if (arg4 != 0) {
+put_user_u32(prio, arg4);
+}
+}
+return ret;
+#endif
 
 /* Not implemented for now... */
 /* case TARGET_NR_mq_notify: */
-- 
2.25.1




[PATCH v3 1/2] linux-user: Fix 'mq_timedsend()' and 'mq_timedreceive()'

2020-08-24 Thread Filip Bozuta
Implementations of syscalls 'mq_timedsend()' and 'mq_timedreceive()'
in 'syscall.c' use functions 'target_to_host_timespec()' and
'host_to_target_timespec()' to transfer the value of 'struct timespec'
between target and host. However, the implementations don't check whether
this conversion succeeds and thus can cause an unaproppriate error instead
of the 'EFAULT (Bad address)' which is supposed to be set if the conversion
from target to host fails. This was confirmed with the modified LTP
test suite where test cases with a bad adress for 'timespec' were
added. This modified test suite can be found at:
https://github.com/bozutaf/ltp

Without the changes from this patch the bad adress testcase for 'mq_timedsend()'
succeds unexpectedly, while the test returns errno 'ETIMEOUT' for
'mq_timedreceive()':

mq_timedsend01.c:190: FAIL: mq_timedsend() returned 0, expected -1: SUCCESS (0)
mq_timedreceive01.c:178: FAIL: mq_timedreceive() failed unexpectedly,
expected EFAULT: ETIMEDOUT (110)

After the changes from this patch, testcases for both syscalls fail with EFAULT
as expected, which is the same test result that is received with native 
execution:

mq_timedsend01.c:187: PASS: mq_timedsend() failed expectedly: EFAULT (14)
mq_timedreceive01.c:180: PASS: mq_timedreceive() failed expectedly: EFAULT (14)

(Patch with this new test case will be sent to LTP mailing list soon)

Signed-off-by: Filip Bozuta 
---
 linux-user/syscall.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 05f03919ff..4ee1de6e65 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11817,9 +11817,13 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 
 p = lock_user (VERIFY_READ, arg2, arg3, 1);
 if (arg5 != 0) {
-target_to_host_timespec(, arg5);
+if (target_to_host_timespec(, arg5)) {
+return -TARGET_EFAULT;
+}
 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, ));
-host_to_target_timespec(arg5, );
+if (!is_error(ret) && host_to_target_timespec(arg5, )) {
+return -TARGET_EFAULT;
+}
 } else {
 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
 }
@@ -11836,10 +11840,14 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 
 p = lock_user (VERIFY_READ, arg2, arg3, 1);
 if (arg5 != 0) {
-target_to_host_timespec(, arg5);
+if (target_to_host_timespec(, arg5)) {
+return -TARGET_EFAULT;
+}
 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
  , ));
-host_to_target_timespec(arg5, );
+if (!is_error(ret) && host_to_target_timespec(arg5, )) {
+return -TARGET_EFAULT;
+}
 } else {
 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
  , NULL));
-- 
2.25.1




[PATCH v3 0/2] linux-user: Introducing functionality for two time64 syscalls

2020-08-24 Thread Filip Bozuta
This two patch series introduces functionality for two year
2038 safe syscalls.

The first patch introduces a little correction for already
implemented normal (32-bit) variants of implemented syscalls.

The second patch introduces the implementation of the
syscalls.

Testing method:

The implementation of the implemented syscalls was tested
using recently added time64 test in the LTP test suite.

v3:

-Added an error check before converting back the value
 of 'struct timespec/timespec64' from host to target

Filip Bozuta (2):
  linux-user: Fix 'mq_timedsend()' and 'mq_timedreceive()'
  linux-user: Add support for 'mq_timedsend_time64()' and
'mq_timedreceive_time64()'

 linux-user/syscall.c | 74 +++-
 1 file changed, 67 insertions(+), 7 deletions(-)

-- 
2.25.1




Re: [PATCH v3 1/2] linux-user: Add support for 'clock_nanosleep_time64()' and 'clock_adjtime64()'

2020-08-24 Thread Laurent Vivier
Le 24/08/2020 à 21:21, Filip Bozuta a écrit :
> This patch implements functionality for following time64 syscall:
> 
> *clock_nanosleep_time64()
> 
> This is a year 2038 safe vairant of syscall:
> int clock_nanosleep(clockid_t clockid, int flags,
> const struct timespec *request,
> struct timespec *remain)
> --high-resolution sleep with specifiable clock--
> man page: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html
> 
> *clock_adjtime64()
> 
> This is a year 2038 safe variant of syscall:
> int clock_adjtime(clockid_t clk_id, struct timex *buf)
> --tune kernel clock--
> man page: https://man7.org/linux/man-pages/man2/clock_adjtime.2.html
> 
> Implementation notes:
> 
> Syscall 'clock_nanosleep_time64()' was implemented similarly
> to syscall 'clock_nanosleep()' except that 'host_to_target_timespec64()'
> and 'target_to_host_timespec64()' were used instead of the regular
> 'host_to_target_timespec()' and 'target_to_host_timespec()'.
> 
> For 'clock_adjtime64()' a 64-bit target kernel version of 'struct timex'
> was defined in 'syscall_defs.h': 'struct target__kernel_timex'.
> This type was used to convert the values of 64-bit timex type between
> host and target. For this purpose a 64-bit timex converting functions
> 'target_to_host_timex64()' and 'host_to_target_timex64()'. An existing
> function 'copy_to_user_timeval64()' was used to convert the field
> 'time' which if of type 'struct timeval' from host to target.
> Function 'copy_from_user_timveal64()' was added in this patch and
> used to convert the 'time' field from target to host.
> 
> Signed-off-by: Filip Bozuta 
> ---
>  linux-user/syscall.c  | 137 +-
>  linux-user/syscall_defs.h |  31 +
>  2 files changed, 166 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 05f03919ff..a359bd8620 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -809,7 +809,8 @@ safe_syscall4(int, accept4, int, fd, struct sockaddr *, 
> addr, socklen_t *, len,
>  safe_syscall2(int, nanosleep, const struct timespec *, req,
>struct timespec *, rem)
>  #endif
> -#ifdef TARGET_NR_clock_nanosleep
> +#if defined(TARGET_NR_clock_nanosleep) || \
> +defined(TARGET_NR_clock_nanosleep_time64)
>  safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
>const struct timespec *, req, struct timespec *, rem)
>  #endif
> @@ -1205,8 +1206,25 @@ static inline abi_long copy_to_user_timeval(abi_ulong 
> target_tv_addr,
>  return 0;
>  }
>  
> +static inline abi_long copy_from_user_timeval64(struct timeval *tv,
> +abi_ulong target_tv_addr)
> +{
> +struct target__kernel_sock_timeval *target_tv;
> +
> +if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) {
> +return -TARGET_EFAULT;
> +}
> +
> +__get_user(tv->tv_sec, _tv->tv_sec);
> +__get_user(tv->tv_usec, _tv->tv_usec);
> +
> +unlock_user_struct(target_tv, target_tv_addr, 0);
> +
> +return 0;
> +}
> +
>  static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr,
> - const struct timeval *tv)
> +  const struct timeval *tv)
>  {
>  struct target__kernel_sock_timeval *target_tv;
>  
> @@ -6771,6 +6789,87 @@ static inline abi_long host_to_target_timex(abi_long 
> target_addr,
>  }
>  #endif
>  
> +
> +#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
> +static inline abi_long target_to_host_timex64(struct timex *host_tx,
> +  abi_long target_addr)
> +{
> +struct target__kernel_timex *target_tx;
> +
> +if (copy_from_user_timeval64(_tx->time, target_addr +
> + offsetof(struct target__kernel_timex,
> +  time))) {
> +return -TARGET_EFAULT;
> +}
> +
> +if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) {
> +return -TARGET_EFAULT;
> +}
> +
> +__get_user(host_tx->modes, _tx->modes);
> +__get_user(host_tx->offset, _tx->offset);
> +__get_user(host_tx->freq, _tx->freq);
> +__get_user(host_tx->maxerror, _tx->maxerror);
> +__get_user(host_tx->esterror, _tx->esterror);
> +__get_user(host_tx->status, _tx->status);
> +__get_user(host_tx->constant, _tx->constant);
> +__get_user(host_tx->precision, _tx->precision);
> +__get_user(host_tx->tolerance, _tx->tolerance);
> +__get_user(host_tx->tick, _tx->tick);
> +__get_user(host_tx->ppsfreq, _tx->ppsfreq);
> +__get_user(host_tx->jitter, _tx->jitter);
> +__get_user(host_tx->shift, _tx->shift);
> +__get_user(host_tx->stabil, _tx->stabil);
> +__get_user(host_tx->jitcnt, 

  1   2   3   4   >